def view(request): """ Standard view for dashboard, is empty as all data will be requested through AJAX """ get_admin_executive_or_403(request) return render(request, 'dashboard.html')
def ajax_roles_from_tuple(request): """ parameters: project_id: ID del proyecto seleccionado department_id: ID del proyecto seleccionado returns: lista de objetos {id, nombre} de los roles seleccionables """ logged = get_admin_executive_or_403(request) if "project_id" not in request.GET or "department_id" not in request.GET: raise SuspiciousOperation if is_executive(logged): roles = Role.objects.filter(tier__lt=50) elif logged.user_type == "E": try: myrole = ProjectDepartmentEmployeeRole.objects.get( employee_id=logged, projectDepartment_id__project_id__id=request.GET["project_id"], projectDepartment_id__department_id__id=request. GET["department_id"]) roles = Role.objects.filter(tier__lt=myrole.role_id.tier) except: raise PermissionDenied else: roles = Role.objects.all() data = [] for r in roles: data.append({'id': r.id, 'name': r.name}) return JsonResponse(data, safe=False)
def manage_async(request): """ parameters: form: el formulario con los datos del departamento returns: JSON con un mensaje de respuesta. Es un dict que contiene lo siguiente success: true si hubo exito, false si no errors: array de códigos de error (vacío si success == true) """ logged = get_admin_executive_or_403(request) if request.method == 'POST': form = RoleManagementForm(request.POST) if form.is_valid(): result = process_post_form(logged, form) return JsonResponse({ 'success': result["ok"], 'errors': result['errors'] }) else: return JsonResponse({ 'success': False, 'errors': ['roleCreation_formNotValid'] }) else: raise SuspiciousOperation
def ajax_departments_from_projects(request): """ parameters: project_id: ID del proyecto seleccionado returns: lista de objetos {id, nombre} de los departamentos seleccionables """ logged = get_admin_executive_or_403(request) if "project_id" not in request.GET: raise SuspiciousOperation if logged.user_type == "E" and not is_executive(logged): ids = ProjectDepartmentEmployeeRole.objects.values_list( 'projectDepartment_id__department_id', flat=True).filter( employee_id=logged, role_id__tier__gt=10, projectDepartment_id__department_id__active=True, projectDepartment_id__project_id__id=request.GET["project_id"]) dpts = Department.objects.filter(id__in=ids) else: dpts = Department.objects.filter(active=True, company_id=logged.company_id) data = [] for d in dpts: data.append({'id': d.id, 'name': d.name}) return JsonResponse(data, safe=False)
def recover(request, username): """ url = employee/recover/<username> parameters/returns: Nada, redirecciona a la vista de listado de empleados template: ninguna """ admin = get_admin_executive_or_403(request) employee = get_object_or_404(Employee, user__username=username, user__is_active=False) # Check that the admin has permission to view that employee same_company_or_403(admin, employee) employee_user = employee.user employee_user.is_active = True employee_user.save() EmployeeLog.objects.create(employee_id=employee, event="A", price_per_hour=employee.price_per_hour) return HttpResponseRedirect('/employee/list')
def edit(request, department_id): """ url = department/edit/(department_id)/ parameters/returns: form: el formulario con los datos del departamento repeated_name:true si el nombre ya existe para otro departamento template: department_form.html """ # Check that the current user is an administrator or executive department = get_object_or_404(Department, pk=department_id) admin = get_admin_executive_or_403(request) same_company_or_403(admin, department) repeated_name = False # if this is a POST request we need to process the form data if request.method == 'POST': # create a form instance and populate it with data from the request: form = DepartmentForm(request.POST) # check whether it's valid: if form.is_valid(): # process the data in form.cleaned_data as required # ... # redirect to a new URL: dep = find_name(form.cleaned_data['name'], admin) # dep does not exists or it's the same if dep is None or dep.id == department.id: edit_department(department, form) return HttpResponseRedirect('/department/view/' + str(department.id) + "/") else: repeated_name = True # if a GET (or any other method) we'll create a blank form else: department = get_object_or_404(Department, pk=department_id) form = DepartmentForm(initial={ "name": department.name, "department_id": department.id }) return render(request, 'department/department_form.html', { 'form': form, 'repeated_name': repeated_name })
def ajax_time_per_project(request): """ Devuelve un objeto cuyas claves son las ID de los proyectos y sus valores un objeto {'name': ..., 'time': X} (X en minutos) # Parámetros opcionales: # start_date - fecha en formato YYYY-MM-DD que indica el inicio de la medición. Por defecto, 30 días antes de la fecha actual. # end_date - fecha en formato YYYY-MM-DD que indica el final de la medición. Por defecto, fecha actual. # offset - desplazamiento (huso) horario en formato +/-HH:MM - Por defecto +00:00 # Si se proporcionan pero no tienen el formato correcto se lanzará un error HTTP 400 Bad Request """ logged = get_admin_executive_or_403(request) # Get and parse the dates start_date = request.GET.get("start_date", str(date.today() - timedelta(days=30))) end_date = request.GET.get("end_date", str(date.today())) date_regex = re.compile("^\d{4}-\d{2}-\d{2}$") if date_regex.match(start_date) is None or date_regex.match( end_date) is None: raise SuspiciousOperation("Start/end date are not valid") offset = request.GET.get("offset", "+00:00") offset_regex = re.compile("^(\+|-)\d{2}:\d{2}$") if offset_regex.match(offset) is None: raise SuspiciousOperation("Time offset is not valid") # Append time offsets start_date += " 00:00" + offset end_date += " 00:00" + offset company_projects = Project.objects.filter(deleted=False, company_id=logged.company_id) data = {} # Sum timelogs for each project for project in company_projects: time_total = TimeLog.objects.filter( task_id__active=True, task_id__projectDepartment_id__project_id=project, workDate__range=[start_date, end_date ]).aggregate(Sum('duration'))["duration__sum"] if time_total is None: time_total = 0 data[project.id] = {'name': project.name, 'time': time_total} return JsonResponse(data)
def edit(request, project_id): """ parameters/returns: form: el formulario con los datos del proyecto template: project_form.html """ # Check that the user is logged in admin = get_admin_executive_or_403(request) project = get_object_or_404(Project, pk=project_id) same_company_or_403(admin, project) repeated_name = False error = False # if this is a POST request we need to process the form data if request.method == 'POST': # create a form instance and populate it with data from the request: form = ProjectForm(request.POST) # check whether it's valid: if form.is_valid(): # process the data in form.cleaned_data as required pro = find_name(form.cleaned_data['name'], admin) # pro does not exists or it's the same if pro is None or pro.id == project.id: update_project(project, form) return redirect('project_list') else: repeated_name = True else: error = True # if a GET (or any other method) we'll create a blank form else: #Check is same company form = ProjectForm(initial={ "name": project.name, "project_id": project.id }) return render(request, 'project/project_form.html', { 'form': form, 'repeated_name': repeated_name, 'error': error })
def delete(request, project_id): """ parameters: project_id: the project id to delete returns: nothing template: project_list.html """ # Check that the user is logged in admin = get_admin_executive_or_403(request) project = get_object_or_404(Project, pk=project_id, deleted=False) same_company_or_403(admin, project) delete_project(project) return HttpResponseRedirect('/project/list')
def ajax_departments_per_project(request): """ Gets the number of departments per project """ logged = get_admin_executive_or_403(request) company_projects = Project.objects.filter(deleted=False, company_id=logged.company_id) data = {} for project in company_projects: data[project.id] = { 'name': project.name, 'departments': list( Department.objects.filter( projectdepartment__project_id=project).values( 'id', 'name')) } return JsonResponse(data)
def recover(request, department_id): """ url = department/recover/(department_id)/ parameters: department_id: the department id to recover returns: nothing template: deparment_list.html """ department = get_object_or_404(Department, pk=department_id, active=False) # Check that the current user is an administrator or executive admin = get_admin_executive_or_403(request) same_company_or_403(admin, department) recover_department(department) return HttpResponseRedirect('/department/list')
def ajax_employees_per_project(request): """ Gets the number of employees per project """ logged = get_admin_executive_or_403(request) company_projects = Project.objects.filter(deleted=False, company_id=logged.company_id) data = {} for project in company_projects: data[project.id] = { 'name': project.name, 'employees': list( Employee.objects.filter( projectdepartmentemployeerole__projectDepartment_id__project_id =project).values('id', 'identifier', 'user__username', 'registryDate')) } return JsonResponse(data)
def create(request): """ parameters/returns: form: el formulario con los datos del departamento repeated_name:true si el nombre ya existe para otro departamento template: department_form.html """ # Check that the current user is an administrator admin = get_admin_executive_or_403(request) repeated_name = False # if this is a POST request we need to process the form data if request.method == 'POST': # create a form instance and populate it with data from the request: form = DepartmentForm(request.POST) # check whether it's valid: if form.is_valid(): # process the data in form.cleaned_data as required # ... # redirect to a new URL: dname = form.cleaned_data['name'] dep = find_name(dname, admin) if dep is not None: repeated_name = True else: department = create_department(form, admin) return HttpResponseRedirect('/department/view/' + str(department.id) + "/") # if a GET (or any other method) we'll create a blank form else: form = DepartmentForm(initial={"department_id": 0, "name": ""}) return render(request, 'department/department_form.html', { 'form': form, 'repeated_name': repeated_name })
def create_async(request): """ parameters: form: el formulario con los datos del proyecto returns: data: JSON con un mensaje de respuesta. Es un dict que contiene lo siguiente repeated_name: true si se ha repetido el nombre success:true si hubo exito, false si no """ # Check that the current user is an administrator admin = get_admin_executive_or_403(request) data = {'repeated_name': False, 'success': True} # if this is a POST request we need to process the form data if request.method == 'POST': # create a form instance and populate it with data from the request: form = ProjectForm(request.POST) # check whether it's valid: if form.is_valid(): # process the data in form.cleaned_data as required # ... # redirect to a new URL: pname = form.cleaned_data['name'] pro = find_name(pname, admin) if pro is not None: data['repeated_name'] = True else: create_project(form, admin) return JsonResponse(data) # if a GET (or any other method) we'll create a blank form else: return redirect('project_list') data['success'] = False return JsonResponse(data)
def create(request): """ parameters/returns: form: el formulario con los datos del proyecto template: project_form.html """ # Check that the user is logged in admin = get_admin_executive_or_403(request) repeated_name = False error = False # if this is a POST request we need to process the form data if request.method == 'POST': # create a form instance and populate it with data from the request: form = ProjectForm(request.POST) # check whether it's valid: if form.is_valid(): # process the data in form.cleaned_data as required # ... # redirect to a new URL: pname = form.cleaned_data['name'] pro = find_name(pname, admin) if pro is not None: repeated_name = True else: project = create_project(form, admin) return redirect('project_view', project_id=project.id) else: error = True # if a GET (or any other method) we'll create a blank form else: form = ProjectForm(initial={"project_id": 0}) return render(request, 'project/project_form.html', { 'form': form, 'repeated_name': repeated_name, 'error': error })
def delete(request, role_id): """ url: /roles/delete/<role_id> parameters/returns: role_id: id del rol a borrar returns: redirecciona a la vista del empleado en cuestión o devuelve 404 (si no existe) / 403 (si no está autorizado) El botón de borrar sólo se debería mostrar si el usuario en cuestión está autorizado a borrar el rol, por lo que no se devuelven códigos de error. """ logged = get_admin_executive_or_403(request) role = get_object_or_404(ProjectDepartmentEmployeeRole, id=role_id) check_companies_match(logged, role.employee_id) if not is_role_updatable_by_user(logged, role_id): raise PermissionDenied employee_username = role.employee_id.user.username role.delete() return HttpResponseRedirect('/employee/view/' + employee_username)
def update_password(request, username): """ url = employee/updatePassword/<username> parameters: password1: contraseña a establecer password2: repetición de la contraseña returns: {'success': true/false: 'errors': [...]} errors: 'employeeCreation_formNotValid': si el formulario no es válido 'employeeCreation_passwordsDontMatch' : si las contraseñas no coinciden template: ninguna (ajax) """ # Check that the user is logged in and it's an administrator admin = get_admin_executive_or_403(request) employee = get_object_or_404(Employee, user__username=username, user__is_active=True) # Check that the admin has permission to view that employee same_company_or_403(admin, employee) if request.method == 'POST': # Process the form form = EmployeePasswordForm(request.POST) if form.is_valid(): pass1 = form.cleaned_data["newpass1"] pass2 = form.cleaned_data["newpass2"] # Check password validation if not validate_pass(pass1): return JsonResponse({ 'success': False, 'errors': ['newPasswordInvalid'] }) if pass1 != pass2: return JsonResponse({ 'success': False, 'errors': ['employeeCreation_passwordsDontMatch'] }) user = employee.user user.set_password(pass1) user.save() if form.cleaned_data["send_password_notification"]: notify_password_change( user.email, user.first_name, newpass=pass1, notifynewpass=form.cleaned_data["notify_new_pass"]) return JsonResponse({'success': True, 'errors': []}) else: # Invalid form return JsonResponse({ 'success': False, 'errors': ['employeeCreation_formNotValid'] }) else: # Invalid HTTP operation raise SuspiciousOperation
def create(request): """ parameters: redirect: opcional, incluir en la URL de la petición si se quiere redirigir a la página del empleado creado returns: form: formulario con los datos necesarios para el registro del empleado success: opcional, si se ha tenido éxito al crear un empleado errors: opcional, array de mensajes de error si ha habido algún error errores: (todos empiezan por employeeCreation_) passwordsDontMatch: las contraseñas no coinciden usernameNotUnique: el nombre de usuario ya existe imageNotValid: la imagen no es válida por formato y/o tamaño formNotValid: el formulario contiene errores priceNotValid: el precio debe ser mayor que 0 emailNotUnique:si el correo no es úinco template: employee_register.html """ # Check that the user is logged in and it's an administrator admin = get_admin_executive_or_403(request) # If it's a GET request, return an empty form if request.method == "GET": return render(request, 'employee/employee_register.html', {'form': EmployeeRegisterForm()}) elif request.method == "POST": # We are serving a POST request form = EmployeeRegisterForm(request.POST, request.FILES) if form.is_valid(): errors = [] # Check that the passwords match if not check_passwords(form): errors.append('employeeCreation_passwordsDontMatch') #Check password validation if not validate_pass(form.cleaned_data["password1"]): errors.append('newPasswordInvalid') # Check that the username is unique if not is_username_unique(form.cleaned_data["username"]): errors.append('employeeCreation_usernameNotUnique') # Check that the email is unique if not is_email_unique(form.cleaned_data["email"]): errors.append('employeeCreation_emailNotUnique') # Check that the image is OK if not check_image(form, 'photo'): errors.append('employeeCreation_imageNotValid') # Check that the price is OK if form.cleaned_data['price_per_hour'] <= 0: errors.append('employeeCreation_priceNotValid') if not errors: # Everything is OK, create the employee employee_user = create_employee_user(form) employee = create_employee(employee_user, admin, form) EmployeeLog.objects.create( employee_id=employee, event="A", price_per_hour=employee.price_per_hour) send_register_email(form.cleaned_data["email"], form.cleaned_data["first_name"]) return HttpResponseRedirect('/employee/view/' + form.cleaned_data["username"] + '/') else: # There are errors return render(request, 'employee/employee_register.html', { 'form': form, 'errors': errors }) # Form is not valid else: return render(request, 'employee/employee_register.html', { 'form': form, 'errors': ['employeeCreation_formNotValid'] }) else: # Another request method raise PermissionDenied
def edit(request, username): """ url = employee/edit/<username> parameters/returns: form: formulario de edicion de datos de empleado errors: 'employeeCreation_formNotValid': si el formulario no es válido template: employee_edit.html """ # Check that the user is logged in and it's an administrator admin = get_admin_executive_or_403(request) employee = get_object_or_404(Employee, user__username=username) # Check that the admin has permission to view that employee same_company_or_403(admin, employee) if request.method == "GET": # Return a form filled with the employee's data form = EmployeeEditForm( initial={ 'first_name': employee.user.first_name, 'last_name': employee.user.last_name, 'email': employee.user.email, 'identifier': employee.identifier, 'phone': employee.phone, 'price_per_hour': employee.price_per_hour }) return render( request, 'employee/employee_edit.html', { 'form': form, 'picture': employee.picture, 'username': username, 'pass_form': EmployeePasswordForm(), 'active': employee.user.is_active }) elif request.method == "POST": # Process the received form form = EmployeeEditForm(request.POST, request.FILES) if form.is_valid(): errors = [] # Check that the price is OK if form.cleaned_data['price_per_hour'] <= 0: errors.append('employeeCreation_priceNotValid') # Check that the image is OK if not check_image(form, 'photo'): errors.append('employeeCreation_imageNotValid') # Check that the email is unique if not is_email_unique( form.cleaned_data["email"] ) and employee.user.email != form.cleaned_data["email"]: errors.append('employeeCreation_emailNotUnique') if not errors: # Update employee data employee.identifier = form.cleaned_data["identifier"] employee.phone = form.cleaned_data["phone"] # New log if the salary has changed new_log = employee.price_per_hour != form.cleaned_data[ "price_per_hour"] employee.price_per_hour = form.cleaned_data["price_per_hour"] if form.cleaned_data["photo"]: employee.picture = form.cleaned_data["photo"] # Update user data user = employee.user user.first_name = form.cleaned_data["first_name"] user.last_name = form.cleaned_data["last_name"] user.email = form.cleaned_data["email"] user.save() employee.save() # New log if the salary has changed if new_log: EmployeeLog.objects.create( employee_id=employee, event="C", price_per_hour=form.cleaned_data["price_per_hour"]) return HttpResponseRedirect('/employee/view/' + username + '/') else: # There are errors return render( request, 'employee/employee_edit.html', { 'form': form, 'errors': errors, 'picture': employee.picture, 'username': username, 'pass_form': EmployeePasswordForm(), 'active': employee.user.is_active }) else: # Form is not valid return render( request, 'employee/employee_edit.html', { 'form': form, 'picture': employee.picture, 'errors': ['employeeCreation_formNotValid'], 'username': username, 'pass_form': EmployeePasswordForm(), 'active': employee.user.is_active }) else: raise PermissionDenied
def display_info(request): get_admin_executive_or_403(request) return render(request, "role/role_info.html")
def manage(request): """ parameters: employee_id: id del empleado (si el formulario es nuevo) role_id: id del rol a editar (si se edita uno ya existente) Se devuelve error 400 si no se proporciona al menos uno de los dos returns: employee: datos del empleado que se está editando departments: lista de departamentos que puede usar el usuario/admin logueado projects: lista de proyectos que puede user el usuario/admin logueado roles: lista de roles del sistema (sólo se aceptarán si están por debajo para el dpto/proyecto) form: formulario RoleManagementForm con los valores iniciales adecuados errors: array de códigos de error si los hay template: rol_form.html códigos de error (todos empiezan por roleCreation_): formNotValid - el formulario enviado no es válido employeeDoesNotExist - el empleado indicado no existe en la compañía o no está activo departmentDoesNotExist - el departamento indicado no existe en la compañía o no está activo projectDoesNotExist - el proyecto indicado no existe en la compañía o no está activo roleDoesNotExist - el rol indicado no existe employeeRoleDoesNotExist - el ID de rol de empleado indicado no existe notAuthorizedProjectDepartment - el usuario no está autorizado para crear roles en ese departamento y proyecto notAuthorizedRole - el usuario está autorizado a crear roles pero el que intenta crear es igual o superior al suyo alreadyExists - ya existe un rol para ese usuario, departamento y proyecto (sólo aparece al crear roles, no al editar) editingHigherRole - el usuario está intentando editar un rol de otro usuario que está por encima de él cannotEditHighestRole - el usuario está intentando modificar su rol más alto y eso no pue sé """ logged = get_admin_executive_or_403(request) if request.method == "GET": # Check that at least 'employee_id' or 'role_id' are provided as GET params, raise 400 otherwise if "employee_id" not in request.GET and "role_id" not in request.GET: raise SuspiciousOperation # Return the initial form return get_form(request, logged) elif request.method == "POST": form = RoleManagementForm(request.POST) if form.is_valid(): result = process_post_form(logged, form) if result["ok"]: return HttpResponseRedirect( '/employee/view/' + Employee.objects.get( id=form.cleaned_data["employee_id"]).user.username + '/') else: return return_invalid_form(request, form, logged, result["errors"]) else: # The form is not valid return return_invalid_form(request, form, logged, ['roleCreation_formNotValid']) else: # Other request method, not supported raise SuspiciousOperation