Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ def env_list(name, default=None):
# See docs/03-platform/module-authoring-guide.md to add one.
DOMAIN_MODULES = [
"modules.placement",
"modules.elm",
]

INSTALLED_APPS = (DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS
Expand Down
1 change: 1 addition & 0 deletions config/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
path("api/v1/", include("fusion_auth.urls")),
path("api/v1/directory/", include("modules.directory.api.urls")),
path("api/v1/placement/", include("modules.placement.api.urls")),
path("api/v1/elm/", include("modules.elm.api.urls")),
path("api/schema/", SpectacularAPIView.as_view(), name="schema"),
path("api/docs/", SpectacularSwaggerView.as_view(url_name="schema"), name="docs"),
]
Empty file added modules/elm/__init__.py
Empty file.
Empty file added modules/elm/api/__init__.py
Empty file.
7 changes: 7 additions & 0 deletions modules/elm/api/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from rest_framework import serializers
from modules.elm.models import Leave

class LeaveSerializer(serializers.ModelSerializer):
class Meta:
model = Leave
fields = '__all__'
10 changes: 10 additions & 0 deletions modules/elm/api/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import LeaveViewSet

router = DefaultRouter()
router.register(r'leaves', LeaveViewSet)

urlpatterns = [
path('', include(router.urls)),
]
7 changes: 7 additions & 0 deletions modules/elm/api/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from rest_framework import viewsets
from modules.elm.models import Leave
from .serializers import LeaveSerializer

class LeaveViewSet(viewsets.ModelViewSet):
queryset = Leave.objects.all()
serializer_class = LeaveSerializer
6 changes: 6 additions & 0 deletions modules/elm/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig

class ElmConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'modules.elm'
label = 'elm'
1 change: 1 addition & 0 deletions modules/elm/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .leave import Leave
39 changes: 39 additions & 0 deletions modules/elm/models/leave.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from django.db import models

from core.db.mixins import TimeStampedModel, UserScopedModel


class Leave(TimeStampedModel, UserScopedModel):
LEAVE_CATEGORIES = [
("CL", "Casual Leave"),
("RH", "Restricted Holiday"),
("SCL", "Special Casual Leave"),
("EL", "Extra Leave"),
("COL", "Compensatory Off Leave"),
("VL", "Vacation Leave"),
]

REQUEST_STATUS = [
("PENDING", "Pending"),
("APPROVED", "Approved"),
("REJECTED", "Rejected"),
]

leave_category = models.CharField(max_length=3, choices=LEAVE_CATEGORIES)
start_date = models.DateField()
end_date = models.DateField()
reason = models.TextField()
request_status = models.CharField(
max_length=10,
choices=REQUEST_STATUS,
default="PENDING",
)

class Meta:
db_table = "elm_leave"

def __str__(self):
return (
f"User {self.user_id} - {self.get_leave_category_display()} "
f"from {self.start_date} to {self.end_date}"
)
41 changes: 41 additions & 0 deletions modules/elm/registry.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""What the server tells the shell about this module (ADR-0010).

Nav items carry `required_permission` and the server filters before sending —
the client does zero filtering, so a link a role cannot use never reaches the
browser at all.
"""
MODULE = {
"code": "elm",
"label": "Employee Leave Management",
"icon": "Calendar",
"base_path": "/elm",
"nav_section": "HR",
"sort_order": 20,
"status": "active",
}

NAV_ITEMS = [
{"code": "elm.dashboard", "label": "Dashboard", "icon": "Home", "to": "/elm",
"required_permission": "elm.dashboard.view", "sort_order": 10},
{"code": "elm.leaves", "label": "Leave Requests", "icon": "ClipboardList",
"to": "/elm/leaves", "required_permission": "elm.leave.view", "sort_order": 20},
{"code": "elm.reports", "label": "Reports", "icon": "ChartBar", "to": "/elm/reports",
"required_permission": "elm.report.view", "sort_order": 30},
]

PERMISSIONS = [
("elm.dashboard.view", "View ELM dashboard"),
("elm.leave.view", "View leave requests"),
("elm.leave.create", "Create leave requests"),
("elm.leave.approve", "Approve leave requests"),
("elm.leave.reject", "Reject leave requests"),
("elm.report.view", "View reports"),
]

ROLE_GRANTS = {
"staff": ["elm.dashboard.view", "elm.leave.view", "elm.report.view"],
"hr": ["elm.dashboard.view", "elm.leave.view", "elm.leave.create",
"elm.leave.approve", "elm.leave.reject", "elm.report.view"],
"admin": ["elm.dashboard.view", "elm.leave.view", "elm.leave.create",
"elm.leave.approve", "elm.leave.reject", "elm.report.view"],
}