Skip to content

Commit

Permalink
Add new columns to vacation, and first implementation of the vacation…
Browse files Browse the repository at this point in the history
… cards
  • Loading branch information
Heibert committed Oct 21, 2024
1 parent 20f679c commit da7898b
Show file tree
Hide file tree
Showing 10 changed files with 306 additions and 231 deletions.
30 changes: 8 additions & 22 deletions INSIGHTSAPI/INSIGHTSAPI/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@
https://docs.djangoproject.com/en/4.2/ref/settings/
"""

import sys
import os
import ssl
import sys
from datetime import datetime, timedelta
from pathlib import Path

import ldap
from datetime import timedelta, datetime
from django_auth_ldap.config import LDAPSearch, LDAPSearchUnion
from dotenv import load_dotenv
from pathlib import Path


ENV_PATH = Path("/var/env/INSIGHTS.env")

Expand Down Expand Up @@ -141,13 +141,15 @@ def str_to_bool(value: str) -> bool:

if not "test" in sys.argv:
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
SECURE_HSTS_SECONDS = 3600
SECURE_BROWSER_XSS_FILTER = True
SECURE_HSTS_SECONDS = 3600
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
# This tell to Django that is behind a proxy
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
SECURE_CONTENT_TYPE_NOSNIFF = True
X_FRAME_OPTIONS = "DENY"

Expand Down Expand Up @@ -232,22 +234,6 @@ def str_to_bool(value: str) -> bool:
"NAME": "staffnet",
"TEST": {"MIRROR": "staffnet"},
},
# 'llamadas': { # MySQL too old
# 'ENGINE': 'django.db.backends.mysql',
# 'HOST': '172.16.0.9',
# 'PORT': '3306',
# 'USER': 'blacklistuser',
# # 'PASSWORD': os.environ['black_list_pass'],
# 'PASSWORD': 'a4dnAGc-',
# 'NAME': 'asteriskdb',
# }
# 'intranet': { # MySQL too old
# "user": "root",
# "password": os.environ["LEYES"],
# "host": "172.16.0.6",
# "port": "3306",
# "database": "userscyc",
# }
}

# Password validation
Expand Down
5 changes: 5 additions & 0 deletions INSIGHTSAPI/vacation/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.contrib import admin

from .models import VacationRequest

admin.site.register(VacationRequest)
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Generated by Django 5.0.8 on 2024-10-21 15:27

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('vacation', '0017_alter_vacationrequest_status'),
]

operations = [
migrations.RenameField(
model_name='vacationrequest',
old_name='hr_approbation',
new_name='hr_is_approved',
),
migrations.RenameField(
model_name='vacationrequest',
old_name='manager_approbation',
new_name='manager_is_approved',
),
migrations.RenameField(
model_name='vacationrequest',
old_name='payroll_approbation',
new_name='payroll_is_approved',
),
migrations.AddField(
model_name='vacationrequest',
name='boss_approved_at',
field=models.DateTimeField(blank=True, null=True),
),
migrations.AddField(
model_name='vacationrequest',
name='boss_is_approved',
field=models.BooleanField(blank=True, null=True),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 5.0.8 on 2024-10-21 15:31

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('vacation', '0018_rename_hr_approbation_vacationrequest_hr_is_approved_and_more'),
]

operations = [
migrations.AlterModelOptions(
name='vacationrequest',
options={'permissions': [('payroll_approval', 'Can approve payroll')]},
),
]
51 changes: 21 additions & 30 deletions INSIGHTSAPI/vacation/models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""This module contains the model for the vacation request """

from datetime import datetime

import pdfkit
from django.conf import settings
from django.core.mail import EmailMessage, send_mail
Expand All @@ -22,11 +24,13 @@ class VacationRequest(models.Model):
end_date = models.DateField()
sat_is_working = models.BooleanField(default=True)
request_file = models.FileField(upload_to="files/vacation_requests/")
manager_approbation = models.BooleanField(null=True, blank=True)
boss_is_approved = models.BooleanField(null=True, blank=True)
boss_approved_at = models.DateTimeField(null=True, blank=True)
manager_is_approved = models.BooleanField(null=True, blank=True)
manager_approved_at = models.DateTimeField(null=True, blank=True)
hr_approbation = models.BooleanField(null=True, blank=True)
hr_is_approved = models.BooleanField(null=True, blank=True)
hr_approved_at = models.DateTimeField(null=True, blank=True)
payroll_approbation = models.BooleanField(null=True, blank=True)
payroll_is_approved = models.BooleanField(null=True, blank=True)
payroll_approved_at = models.DateTimeField(null=True, blank=True)
status = models.CharField(
choices=[
Expand All @@ -49,7 +53,7 @@ class Meta:
"""Meta class for the vacation request model."""

permissions = [
("payroll_approbation", "Can approve payroll"),
("payroll_approval", "Can approve payroll"),
]

@property
Expand All @@ -68,9 +72,9 @@ def __str__(self):
def save(self, *args, **kwargs):
"""Override the save method to update status and create notifications."""
approbation_fields = {
"manager_approbation": "manager_approved_at",
"hr_approbation": "hr_approved_at",
"payroll_approbation": "payroll_approved_at",
"manager_is_approved": "manager_approved_at",
"hr_is_approved": "hr_approved_at",
"payroll_is_approved": "payroll_approved_at",
}

for field, approved_at in approbation_fields.items():
Expand All @@ -88,23 +92,7 @@ def save(self, *args, **kwargs):
f"Tus vacaciones del {self.start_date} al {self.end_date} han sido aprobadas. Esperamos que las disfrutes ⛱!.",
self.user,
)
message = f"""
Hola {self.user.get_full_name()} 👋,
Nos complace informarte que tu solicitud de vacaciones del {self.start_date.strftime("%d de %B del %Y")} al {self.end_date.strftime("%d de %B del %Y")} ha sido aprobada.
Esperamos que disfrutes de este merecido descanso y que regreses con energías renovadas. Si necesitas alguna información adicional o asistencia durante tus vacaciones, no dudes en contactarnos.
¡Te deseamos unas vacaciones maravillosas y relajantes! ⛱
Saludos cordiales,
"""
send_mail(
"Vacaciones aprobadas",
message,
None,
[str(self.user.email)],
)
self.send_approval_email_with_pdf()
elif self.status == "RECHAZADA":
message = f"""
Hola {self.user.get_full_name()} 👋,
Expand Down Expand Up @@ -154,12 +142,12 @@ def send_approval_email_with_pdf(self):
pdf = self.generate_pdf()

# Create the email message
subject = "Your Vacation Request Has Been Approved"
subject = "Solicitud de vacaciones aprobada"
message = (
f"Dear {self.user.get_full_name()},\n\n"
"Your vacation request from {self.start_date} to {self.end_date} has been approved.\n"
"Please find the attached document with the details of your vacation.\n\n"
"Best regards,\nYour Company"
f"Hola {self.user.get_full_name()} 👋,\n\n"
"Nos complace informarte que tu solicitud de vacaciones ha sido aprobada.\n\n"
f"Por favor revisa el archivo adjunto para más detalles sobre tus vacaciones del {self.start_date.strftime('%d de %B del %Y')} al {self.end_date.strftime('%d de %B del %Y')}.\n\n"
"¡Esperamos que disfrutes tus vacaciones! 🏖️\n\n"
)

email = EmailMessage(
Expand All @@ -168,7 +156,9 @@ def send_approval_email_with_pdf(self):

# Attach the generated PDF
email.attach(
filename="vacation_request.pdf", content=pdf, mimetype="application/pdf"
filename="Solicitud de vacaciones.pdf",
content=pdf,
mimetype="application/pdf",
)

# Send the email
Expand All @@ -186,6 +176,7 @@ def generate_pdf(self):
# PDF options
options = {
"page-size": "Letter",
"orientation": "Portrait",
"encoding": "UTF-8",
"margin-top": "0mm",
"margin-right": "0mm",
Expand Down
29 changes: 16 additions & 13 deletions INSIGHTSAPI/vacation/serializers.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
"""Serializers for the vacation app."""

from datetime import datetime
from distutils.util import strtobool

from rest_framework import serializers

from users.models import User
from distutils.util import strtobool
from .utils import is_working_day, get_working_days

from .models import VacationRequest
from .utils import get_working_days, is_working_day


class VacationRequestSerializer(serializers.ModelSerializer):
Expand All @@ -28,11 +31,11 @@ class Meta:
"end_date",
"request_file",
"created_at",
"manager_approbation",
"manager_is_approved",
"manager_approved_at",
"hr_approbation",
"hr_is_approved",
"hr_approved_at",
"payroll_approbation",
"payroll_is_approved",
"payroll_approved_at",
"uploaded_by",
"status",
Expand Down Expand Up @@ -131,7 +134,7 @@ def validate(self, attrs):
else:
# Update
if (
self.instance.manager_approbation
self.instance.manager_is_approved
and "status" in attrs
and attrs["status"] == "CANCELADA"
):
Expand All @@ -142,22 +145,22 @@ def validate(self, attrs):

def create(self, validated_data):
"""Create the vacation request."""
# Remove the approbation fields from the validated data
validated_data.pop("hr_approbation", None)
validated_data.pop("payroll_approbation", None)
validated_data.pop("manager_approbation", None)
# Remove the is_approved fields from the validated data
validated_data.pop("hr_is_approved", None)
validated_data.pop("payroll_is_approved", None)
validated_data.pop("manager_is_approved", None)
validated_data["uploaded_by"] = self.context["request"].user
vacation_request = super().create(validated_data)
return vacation_request

def update(self, instance, validated_data):
"""Update the vacation request."""
allowed_fields = [
"manager_approbation",
"manager_is_approved",
"manager_approved_at",
"hr_approbation",
"hr_is_approved",
"hr_approved_at",
"payroll_approbation",
"payroll_is_approved",
"payroll_approved_at",
"status",
"comment",
Expand Down
Loading

0 comments on commit da7898b

Please sign in to comment.