+ {% comment %}The central-rail segment ends here!{% endcomment %}
+
+ {% comment %}The right-rail segment starts here!{% endcomment %}
+
+
+ {% comment %}
+ TODO: the right rail!
+ {% endcomment %}
-
-
-
-
- {% comment %}The central-rail segment ends here!{% endcomment %}
+{% endblock %}
- {% comment %}The right-rail segment starts here!{% endcomment %}
-
- {% comment %}The right-rail segment ends here!{% endcomment %}
+{% block javascript %}
+
+
+
+
+{% endblock %}
- {% comment %}The right-margin segment!{% endcomment %}
-
- {% comment %}The grid ends here!{% endcomment %}
-{% endblock %}
-{% block javascript %}
-
-
-
-
-{% endblock %}
\ No newline at end of file
diff --git a/FusionIIIT/templates/iwdModuleV2/workOrder.html b/FusionIIIT/templates/iwdModuleV2/workOrder.html
new file mode 100644
index 000000000..11f2f9d93
--- /dev/null
+++ b/FusionIIIT/templates/iwdModuleV2/workOrder.html
@@ -0,0 +1,175 @@
+{% extends 'globals/base.html' %}
+{% load static %}
+
+
+{% block title %}
+Academic
+{% endblock %}
+
+
+{% block body %}
+{% block navBar %}
+{% include 'dashboard/navbar.html' %}
+{% endblock %}
+
+
+
+ {% comment %}The left-margin segment!{% endcomment %}
+
+
+ {% comment %}The left-rail segment starts here!{% endcomment %}
+
+ {% comment %}The user image card starts here!{% endcomment %}
+ {% block usercard %}
+ {% include 'globals/usercard.html' %}
+ {% endblock %}
+ {% comment %}The user image card ends here!{% endcomment %}
+
+
+
+ {% comment %}The Tab-Menu ends here!{% endcomment %}
+
+ {% comment %}
+ The left-rail segment ends here!
+ {% endcomment %}
+
+ {% comment %}
+ The central-rail segment starts here!
+ {% endcomment %}
+
+
+
+
+ {% load static %}
+ {% comment %}the main tab starts here {% endcomment %}
+
+
+
+
+ {% comment %}The central-rail segment ends here!{% endcomment %}
+
+ {% comment %}The right-rail segment starts here!{% endcomment %}
+
+
+ {% comment %}
+ TODO: the right rail!
+ {% endcomment %}
+
+
+ {% comment %}The right-rail segment ends here!{% endcomment %}
+
+ {% comment %}The right-margin segment!{% endcomment %}
+
+
+
+{% comment %}The grid ends here!{% endcomment %}
+
+{% endblock %}
+
+{% block javascript %}
+
+
+
+
+{% endblock %}
+
+
+
+
From a823ed59081ca43ea171ccc5ec1a29b27a4ac330 Mon Sep 17 00:00:00 2001
From: Srivatsa19 <96564832+Srivatsa19@users.noreply.github.com>
Date: Thu, 11 Apr 2024 13:21:37 +0530
Subject: [PATCH 05/19] Gad 2 2025 dashboard integrated (#1356)
* GAD-5: Fix responsiveness (#1125)
Co-authored-by: A Anunaya <76819712+Anunaya07@users.noreply.github.com>
Co-authored-by: Aksh Bansal <63552235+Aksh-Bansal-dev@users.noreply.github.com>
* Implemented the cerate_request, process_request and approve/reject_request use cases.
* GAD -5 Dashboard Changes (#1325)
* dashboard and usercard updated (#1329)
* Fixing ui bugs (#1335)
* Changes made
---------
Co-authored-by: Harshvardhan Singh <73544247+Lawful2002@users.noreply.github.com>
Co-authored-by: A Anunaya <76819712+Anunaya07@users.noreply.github.com>
Co-authored-by: Aksh Bansal <63552235+Aksh-Bansal-dev@users.noreply.github.com>
Co-authored-by: akshatnema <20bcs022@iiitdmj.ac.in>
Co-authored-by: BlackHAWK2001 <150950834+BlackHAWK2001@users.noreply.github.com>
Co-authored-by: Arpit Tak <140220904+Ishu-ji@users.noreply.github.com>
Co-authored-by: SukulSarve <143542658+SukulSarve@users.noreply.github.com>
---
FusionIIIT/Fusion/context_processors.py | 5 +
.../Fusion/middleware/custom_middleware.py | 48 ++
FusionIIIT/Fusion/settings/common.py | 2 +
.../migrations/0002_auto_20240308_1023.py | 38 +
.../eis/migrations/0002_auto_20240308_1023.py | 53 ++
.../filetracking/api/serializers.py | 24 +
.../applications/filetracking/api/urls.py | 22 +
.../applications/filetracking/api/views.py | 111 +++
.../applications/filetracking/decorators.py | 38 +
.../filetracking/filetracking/admin.py | 7 +
.../filetracking/api/serializers.py | 24 +
.../filetracking/filetracking/api/urls.py | 22 +
.../filetracking/filetracking/api/views.py | 111 +++
.../filetracking/filetracking/apps.py | 5 +
.../filetracking/filetracking/decorators.py | 38 +
.../filetracking/migrations/0001_initial.py | 53 ++
.../filetracking/migrations/__init__.py | 0
.../filetracking/filetracking/models.py | 51 ++
.../filetracking/filetracking/sdk/methods.py | 423 ++++++++++
.../filetracking/filetracking/tests.py | 3 +
.../filetracking/filetracking/urls.py | 43 +
.../filetracking/filetracking/utils.py | 7 +
.../filetracking/filetracking/views.py | 732 ++++++++++++++++++
.../migrations/0002_auto_20240308_1023.py | 33 +
.../applications/filetracking/models.py | 12 +-
.../applications/filetracking/sdk/methods.py | 424 ++++++++++
FusionIIIT/applications/filetracking/urls.py | 40 +-
FusionIIIT/applications/filetracking/views.py | 555 +++++++------
.../migrations/0002_auto_20240308_1023.py | 18 +
.../migrations/0003_auto_20240308_1025.py | 18 +
FusionIIIT/applications/globals/urls.py | 3 +-
FusionIIIT/applications/globals/views.py | 87 ++-
.../migrations/0002_bills_requests.py | 41 +
FusionIIIT/applications/iwdModuleV2/models.py | 39 +-
FusionIIIT/applications/iwdModuleV2/urls.py | 25 +-
FusionIIIT/applications/iwdModuleV2/views.py | 454 ++++++++++-
.../migrations/0002_auto_20240308_1023.py | 23 +
.../migrations/0002_auto_20240308_1023.py | 18 +
.../academic_procedures/academic.html | 44 +-
FusionIIIT/templates/dashboard/dashboard.html | 11 +-
FusionIIIT/templates/dashboard/modules.html | 279 +++++--
FusionIIIT/templates/dashboard/navbar.html | 213 +++--
.../templates/dashboard/sidenavbar.html | 46 +-
FusionIIIT/templates/globals/usercard.html | 95 ++-
.../templates/iwdModuleV2/addItemsView.html | 120 +++
.../templates/iwdModuleV2/billsView.html | 147 ++++
.../iwdModuleV2/createdRequests.html | 128 +++
.../templates/iwdModuleV2/dashboard.html | 103 ++-
.../iwdModuleV2/deanProcessedRequests.html | 110 +++
.../templates/iwdModuleV2/editInventory.html | 124 +++
.../engineerProcessedRequests.html | 128 +++
.../templates/iwdModuleV2/inventory.html | 111 +++
.../templates/iwdModuleV2/issueWorkOrder.html | 120 +++
.../iwdModuleV2/requestFromInventory.html | 172 ++++
.../iwdModuleV2/requestsInProgress.html | 134 ++++
.../templates/iwdModuleV2/requestsStatus.html | 114 +++
.../templates/iwdModuleV2/requestsView.html | 135 ++++
.../templates/iwdModuleV2/workOrder.html | 175 +++++
requirements.txt | 2 +-
59 files changed, 5632 insertions(+), 529 deletions(-)
create mode 100644 FusionIIIT/Fusion/context_processors.py
create mode 100644 FusionIIIT/Fusion/middleware/custom_middleware.py
create mode 100644 FusionIIIT/applications/academic_procedures/migrations/0002_auto_20240308_1023.py
create mode 100644 FusionIIIT/applications/eis/migrations/0002_auto_20240308_1023.py
create mode 100644 FusionIIIT/applications/filetracking/api/serializers.py
create mode 100644 FusionIIIT/applications/filetracking/api/urls.py
create mode 100644 FusionIIIT/applications/filetracking/api/views.py
create mode 100644 FusionIIIT/applications/filetracking/decorators.py
create mode 100644 FusionIIIT/applications/filetracking/filetracking/admin.py
create mode 100644 FusionIIIT/applications/filetracking/filetracking/api/serializers.py
create mode 100644 FusionIIIT/applications/filetracking/filetracking/api/urls.py
create mode 100644 FusionIIIT/applications/filetracking/filetracking/api/views.py
create mode 100644 FusionIIIT/applications/filetracking/filetracking/apps.py
create mode 100644 FusionIIIT/applications/filetracking/filetracking/decorators.py
create mode 100644 FusionIIIT/applications/filetracking/filetracking/migrations/0001_initial.py
create mode 100644 FusionIIIT/applications/filetracking/filetracking/migrations/__init__.py
create mode 100644 FusionIIIT/applications/filetracking/filetracking/models.py
create mode 100644 FusionIIIT/applications/filetracking/filetracking/sdk/methods.py
create mode 100644 FusionIIIT/applications/filetracking/filetracking/tests.py
create mode 100644 FusionIIIT/applications/filetracking/filetracking/urls.py
create mode 100644 FusionIIIT/applications/filetracking/filetracking/utils.py
create mode 100644 FusionIIIT/applications/filetracking/filetracking/views.py
create mode 100644 FusionIIIT/applications/filetracking/migrations/0002_auto_20240308_1023.py
create mode 100644 FusionIIIT/applications/filetracking/sdk/methods.py
create mode 100644 FusionIIIT/applications/globals/migrations/0002_auto_20240308_1023.py
create mode 100644 FusionIIIT/applications/globals/migrations/0003_auto_20240308_1025.py
create mode 100644 FusionIIIT/applications/iwdModuleV2/migrations/0002_bills_requests.py
create mode 100644 FusionIIIT/applications/programme_curriculum/migrations/0002_auto_20240308_1023.py
create mode 100644 FusionIIIT/applications/scholarships/migrations/0002_auto_20240308_1023.py
mode change 100755 => 100644 FusionIIIT/templates/academic_procedures/academic.html
mode change 100755 => 100644 FusionIIIT/templates/dashboard/dashboard.html
mode change 100755 => 100644 FusionIIIT/templates/dashboard/modules.html
mode change 100755 => 100644 FusionIIIT/templates/dashboard/navbar.html
mode change 100755 => 100644 FusionIIIT/templates/globals/usercard.html
create mode 100644 FusionIIIT/templates/iwdModuleV2/addItemsView.html
create mode 100644 FusionIIIT/templates/iwdModuleV2/billsView.html
create mode 100644 FusionIIIT/templates/iwdModuleV2/createdRequests.html
create mode 100644 FusionIIIT/templates/iwdModuleV2/deanProcessedRequests.html
create mode 100644 FusionIIIT/templates/iwdModuleV2/editInventory.html
create mode 100644 FusionIIIT/templates/iwdModuleV2/engineerProcessedRequests.html
create mode 100644 FusionIIIT/templates/iwdModuleV2/inventory.html
create mode 100644 FusionIIIT/templates/iwdModuleV2/issueWorkOrder.html
create mode 100644 FusionIIIT/templates/iwdModuleV2/requestFromInventory.html
create mode 100644 FusionIIIT/templates/iwdModuleV2/requestsInProgress.html
create mode 100644 FusionIIIT/templates/iwdModuleV2/requestsStatus.html
create mode 100644 FusionIIIT/templates/iwdModuleV2/requestsView.html
create mode 100644 FusionIIIT/templates/iwdModuleV2/workOrder.html
diff --git a/FusionIIIT/Fusion/context_processors.py b/FusionIIIT/Fusion/context_processors.py
new file mode 100644
index 000000000..54566d56e
--- /dev/null
+++ b/FusionIIIT/Fusion/context_processors.py
@@ -0,0 +1,5 @@
+def global_vars(request):
+ return {
+ 'global_var': request.session.get('currentDesignationSelected', 'default_value'),
+ 'global_var2': request.session.get('allDesignations', 'default_value2'),
+ }
\ No newline at end of file
diff --git a/FusionIIIT/Fusion/middleware/custom_middleware.py b/FusionIIIT/Fusion/middleware/custom_middleware.py
new file mode 100644
index 000000000..f77873534
--- /dev/null
+++ b/FusionIIIT/Fusion/middleware/custom_middleware.py
@@ -0,0 +1,48 @@
+# custom_middleware.py
+from django.contrib.auth.signals import user_logged_in
+from django.dispatch import receiver
+from applications.globals.models import (ExtraInfo, Feedback, HoldsDesignation,
+ Issue, IssueImage, DepartmentInfo)
+from django.shortcuts import get_object_or_404, redirect, render
+
+def user_logged_in_middleware(get_response):
+ @receiver(user_logged_in)
+ def user_logged_in_handler(sender, user, request, **kwargs):
+ if 'function_executed' not in request.session:
+ # Run the function only if the flag is not set
+ # Assuming user is a model with the desired data field, retrieve the data
+ # For example, if your User model has a field named 'custom_field', you can access it like:
+ if user.is_authenticated:
+ desig = list(HoldsDesignation.objects.select_related('user','working','designation').all().filter(working = request.user).values_list('designation'))
+ print(desig)
+ b = [i for sub in desig for i in sub]
+ design = HoldsDesignation.objects.select_related('user','designation').filter(working=request.user)
+
+ designation=[]
+
+ designation.append(str(user.extrainfo.user_type))
+ for i in design:
+ if str(i.designation) != str(user.extrainfo.user_type):
+ print('-------')
+ print(i.designation)
+ print(user.extrainfo.user_type)
+ print('')
+ designation.append(str(i.designation))
+
+ for i in designation:
+ print(i)
+
+ request.session['currentDesignationSelected'] = designation[0]
+ request.session['allDesignations'] = designation
+ print("logged iN")
+
+ # Set the flag in the session to indicate that the function has bee+n executed
+ request.session['function_executed'] = True
+
+ def middleware(request):
+ if request.user.is_authenticated:
+ user_logged_in_handler(request.user, request.user, request)
+ response = get_response(request)
+ return response
+
+ return middleware
\ No newline at end of file
diff --git a/FusionIIIT/Fusion/settings/common.py b/FusionIIIT/Fusion/settings/common.py
index b98ea6960..fabe81ec2 100644
--- a/FusionIIIT/Fusion/settings/common.py
+++ b/FusionIIIT/Fusion/settings/common.py
@@ -163,6 +163,7 @@
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
+ 'Fusion.middleware.custom_middleware.user_logged_in_middleware',
]
ROOT_URLCONF = 'Fusion.urls'
@@ -178,6 +179,7 @@
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
+ 'Fusion.context_processors.global_vars',
],
},
},
diff --git a/FusionIIIT/applications/academic_procedures/migrations/0002_auto_20240308_1023.py b/FusionIIIT/applications/academic_procedures/migrations/0002_auto_20240308_1023.py
new file mode 100644
index 000000000..2b5457988
--- /dev/null
+++ b/FusionIIIT/applications/academic_procedures/migrations/0002_auto_20240308_1023.py
@@ -0,0 +1,38 @@
+# Generated by Django 3.1.5 on 2024-03-08 10:23
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('academic_procedures', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='assistantshipclaim',
+ name='year',
+ field=models.IntegerField(choices=[(2024, 2024), (2023, 2023)]),
+ ),
+ migrations.AlterField(
+ model_name='course_registration',
+ name='working_year',
+ field=models.IntegerField(blank=True, choices=[(2024, 2024), (2023, 2023)], null=True),
+ ),
+ migrations.AlterField(
+ model_name='finalregistrations',
+ name='batch',
+ field=models.IntegerField(default=2024),
+ ),
+ migrations.AlterField(
+ model_name='messdue',
+ name='year',
+ field=models.IntegerField(choices=[(2024, 2024), (2023, 2023)]),
+ ),
+ migrations.AlterField(
+ model_name='register',
+ name='year',
+ field=models.IntegerField(default=2024),
+ ),
+ ]
diff --git a/FusionIIIT/applications/eis/migrations/0002_auto_20240308_1023.py b/FusionIIIT/applications/eis/migrations/0002_auto_20240308_1023.py
new file mode 100644
index 000000000..217222095
--- /dev/null
+++ b/FusionIIIT/applications/eis/migrations/0002_auto_20240308_1023.py
@@ -0,0 +1,53 @@
+# Generated by Django 3.1.5 on 2024-03-08 10:23
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('eis', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='emp_achievement',
+ name='a_year',
+ field=models.IntegerField(blank=True, choices=[(1995, 1995), (1996, 1996), (1997, 1997), (1998, 1998), (1999, 1999), (2000, 2000), (2001, 2001), (2002, 2002), (2003, 2003), (2004, 2004), (2005, 2005), (2006, 2006), (2007, 2007), (2008, 2008), (2009, 2009), (2010, 2010), (2011, 2011), (2012, 2012), (2013, 2013), (2014, 2014), (2015, 2015), (2016, 2016), (2017, 2017), (2018, 2018), (2019, 2019), (2020, 2020), (2021, 2021), (2022, 2022), (2023, 2023), (2024, 2024)], null=True, verbose_name='year'),
+ ),
+ migrations.AlterField(
+ model_name='emp_confrence_organised',
+ name='k_year',
+ field=models.IntegerField(blank=True, choices=[(1995, 1995), (1996, 1996), (1997, 1997), (1998, 1998), (1999, 1999), (2000, 2000), (2001, 2001), (2002, 2002), (2003, 2003), (2004, 2004), (2005, 2005), (2006, 2006), (2007, 2007), (2008, 2008), (2009, 2009), (2010, 2010), (2011, 2011), (2012, 2012), (2013, 2013), (2014, 2014), (2015, 2015), (2016, 2016), (2017, 2017), (2018, 2018), (2019, 2019), (2020, 2020), (2021, 2021), (2022, 2022), (2023, 2023), (2024, 2024)], null=True, verbose_name='year'),
+ ),
+ migrations.AlterField(
+ model_name='emp_expert_lectures',
+ name='l_year',
+ field=models.IntegerField(blank=True, choices=[(1995, 1995), (1996, 1996), (1997, 1997), (1998, 1998), (1999, 1999), (2000, 2000), (2001, 2001), (2002, 2002), (2003, 2003), (2004, 2004), (2005, 2005), (2006, 2006), (2007, 2007), (2008, 2008), (2009, 2009), (2010, 2010), (2011, 2011), (2012, 2012), (2013, 2013), (2014, 2014), (2015, 2015), (2016, 2016), (2017, 2017), (2018, 2018), (2019, 2019), (2020, 2020), (2021, 2021), (2022, 2022), (2023, 2023), (2024, 2024)], null=True, verbose_name='year'),
+ ),
+ migrations.AlterField(
+ model_name='emp_keynote_address',
+ name='k_year',
+ field=models.IntegerField(blank=True, choices=[(1995, 1995), (1996, 1996), (1997, 1997), (1998, 1998), (1999, 1999), (2000, 2000), (2001, 2001), (2002, 2002), (2003, 2003), (2004, 2004), (2005, 2005), (2006, 2006), (2007, 2007), (2008, 2008), (2009, 2009), (2010, 2010), (2011, 2011), (2012, 2012), (2013, 2013), (2014, 2014), (2015, 2015), (2016, 2016), (2017, 2017), (2018, 2018), (2019, 2019), (2020, 2020), (2021, 2021), (2022, 2022), (2023, 2023), (2024, 2024)], null=True, verbose_name='year'),
+ ),
+ migrations.AlterField(
+ model_name='emp_mtechphd_thesis',
+ name='s_year',
+ field=models.IntegerField(blank=True, choices=[(1995, 1995), (1996, 1996), (1997, 1997), (1998, 1998), (1999, 1999), (2000, 2000), (2001, 2001), (2002, 2002), (2003, 2003), (2004, 2004), (2005, 2005), (2006, 2006), (2007, 2007), (2008, 2008), (2009, 2009), (2010, 2010), (2011, 2011), (2012, 2012), (2013, 2013), (2014, 2014), (2015, 2015), (2016, 2016), (2017, 2017), (2018, 2018), (2019, 2019), (2020, 2020), (2021, 2021), (2022, 2022), (2023, 2023), (2024, 2024)], null=True, verbose_name='year'),
+ ),
+ migrations.AlterField(
+ model_name='emp_patents',
+ name='p_year',
+ field=models.IntegerField(blank=True, choices=[(1995, 1995), (1996, 1996), (1997, 1997), (1998, 1998), (1999, 1999), (2000, 2000), (2001, 2001), (2002, 2002), (2003, 2003), (2004, 2004), (2005, 2005), (2006, 2006), (2007, 2007), (2008, 2008), (2009, 2009), (2010, 2010), (2011, 2011), (2012, 2012), (2013, 2013), (2014, 2014), (2015, 2015), (2016, 2016), (2017, 2017), (2018, 2018), (2019, 2019), (2020, 2020), (2021, 2021), (2022, 2022), (2023, 2023), (2024, 2024)], null=True, verbose_name='year'),
+ ),
+ migrations.AlterField(
+ model_name='emp_published_books',
+ name='pyear',
+ field=models.IntegerField(blank=True, choices=[(1995, 1995), (1996, 1996), (1997, 1997), (1998, 1998), (1999, 1999), (2000, 2000), (2001, 2001), (2002, 2002), (2003, 2003), (2004, 2004), (2005, 2005), (2006, 2006), (2007, 2007), (2008, 2008), (2009, 2009), (2010, 2010), (2011, 2011), (2012, 2012), (2013, 2013), (2014, 2014), (2015, 2015), (2016, 2016), (2017, 2017), (2018, 2018), (2019, 2019), (2020, 2020), (2021, 2021), (2022, 2022), (2023, 2023), (2024, 2024)], null=True, verbose_name='year'),
+ ),
+ migrations.AlterField(
+ model_name='emp_research_papers',
+ name='year',
+ field=models.CharField(blank=True, choices=[(1995, 1995), (1996, 1996), (1997, 1997), (1998, 1998), (1999, 1999), (2000, 2000), (2001, 2001), (2002, 2002), (2003, 2003), (2004, 2004), (2005, 2005), (2006, 2006), (2007, 2007), (2008, 2008), (2009, 2009), (2010, 2010), (2011, 2011), (2012, 2012), (2013, 2013), (2014, 2014), (2015, 2015), (2016, 2016), (2017, 2017), (2018, 2018), (2019, 2019), (2020, 2020), (2021, 2021), (2022, 2022), (2023, 2023), (2024, 2024)], max_length=10, null=True),
+ ),
+ ]
diff --git a/FusionIIIT/applications/filetracking/api/serializers.py b/FusionIIIT/applications/filetracking/api/serializers.py
new file mode 100644
index 000000000..bdae2024e
--- /dev/null
+++ b/FusionIIIT/applications/filetracking/api/serializers.py
@@ -0,0 +1,24 @@
+from applications.filetracking.models import File, Tracking
+from django.core.files import File as DjangoFile
+from rest_framework import serializers
+
+
+class FileSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = File
+ fields = '__all__'
+
+
+class TrackingSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = Tracking
+ fields = '__all__'
+
+
+class FileHeaderSerializer(serializers.ModelSerializer):
+ '''
+ This serializes everything except the attachments of a file and whether it is read or not
+ '''
+ class Meta:
+ model = File
+ exclude = ['upload_file', 'is_read']
diff --git a/FusionIIIT/applications/filetracking/api/urls.py b/FusionIIIT/applications/filetracking/api/urls.py
new file mode 100644
index 000000000..90f03b2ef
--- /dev/null
+++ b/FusionIIIT/applications/filetracking/api/urls.py
@@ -0,0 +1,22 @@
+from django.conf.urls import url
+from .views import (
+ CreateFileView,
+ ViewFileView,
+ DeleteFileView,
+ ViewInboxView,
+ ViewOutboxView,
+ ViewHistoryView,
+ ForwardFileView,
+ GetDesignationsView,
+)
+
+urlpatterns = [
+ url(r'^file/$', CreateFileView.as_view(), name='create_file'),
+ url(r'^file/(?P
\d+)/$', ViewFileView.as_view(), name='view_file'),
+ url(r'^file/(?P\d+)/$', DeleteFileView.as_view(), name='delete_file'),
+ url(r'^inbox/$', ViewInboxView.as_view(), name='view_inbox'),
+ url(r'^outbox/$', ViewOutboxView.as_view(), name='view_outbox'),
+ url(r'^history/(?P\d+)/$', ViewHistoryView.as_view(), name='view_history'),
+ url(r'^file/(?P\d+)/$', ForwardFileView.as_view(), name='forward_file'),
+ url(r'^designations/(?P\w+)/$', GetDesignationsView.as_view(), name='get_designations'),
+]
diff --git a/FusionIIIT/applications/filetracking/api/views.py b/FusionIIIT/applications/filetracking/api/views.py
new file mode 100644
index 000000000..c4bb01189
--- /dev/null
+++ b/FusionIIIT/applications/filetracking/api/views.py
@@ -0,0 +1,111 @@
+from rest_framework.views import APIView
+from rest_framework.response import Response
+from rest_framework import status, permissions
+from rest_framework.authentication import TokenAuthentication
+from ..models import File
+from ..sdk.methods import create_file, view_file, delete_file, view_inbox, view_outbox, view_history, forward_file, get_designations
+
+class CreateFileView(APIView):
+ authentication_classes = [TokenAuthentication]
+ permission_classes = [permissions.IsAuthenticated]
+
+ def post(self, request):
+ try:
+ current_user = request.user.username
+ current_designation = request.data.get('designation')
+ receiver_username = request.data.get('receiver_username')
+ receiver_designation = request.data.get('receiver_designation')
+ subject = request.data.get('subject')
+ description = request.data.get('description')
+
+ if None in [current_designation, receiver_username, receiver_designation, subject, description]:
+ return Response({'error': 'One or more required fields are missing.'}, status=status.HTTP_400_BAD_REQUEST)
+
+ file_id = create_file(uploader=current_user, uploader_designation=current_designation,
+ receiver=receiver_username, receiver_designation=receiver_designation, subject=subject, description=description)
+
+ return Response({'file_id': file_id}, status=status.HTTP_201_CREATED)
+ except Exception as e:
+ return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST)
+
+
+class ViewFileView(APIView):
+ authentication_classes = [TokenAuthentication]
+ permission_classes = [permissions.IsAuthenticated]
+
+ def get(self, request, file_id):
+ try:
+ file_details = view_file(int(file_id))
+ return Response(file_details, status=status.HTTP_200_OK)
+ except ValueError:
+ return Response({'error': 'Invalid file ID format.'}, status=status.HTTP_400_BAD_REQUEST)
+ except File.DoesNotExist:
+ return Response({'error': 'File not found.'}, status=status.HTTP_404_NOT_FOUND)
+ except Exception as e:
+ return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST)
+
+
+class DeleteFileView(APIView):
+ #authentication_classes = [TokenAuthentication]
+ #permission_classes = [permissions.IsAuthenticated]
+
+ def delete(self, request, file_id, *args, **kwargs):
+ success = delete_file(int(file_id))
+ if success:
+ return Response({'message': 'File deleted successfully'},
+ status=status.HTTP_204_NO_CONTENT)
+ else:
+ return Response({'error': 'File not found'},
+ status=status.HTTP_404_NOT_FOUND)
+
+
+class ViewInboxView(APIView):
+ #authentication_classes = [TokenAuthentication]
+ #permission_classes = [permissions.IsAuthenticated]
+
+ def get(self, request, *args, **kwargs):
+ inbox_files = view_inbox(
+ request.user.username,
+ request.query_params.get('designation'),
+ request.query_params.get('src_module'))
+ return Response(inbox_files)
+
+
+class ViewOutboxView(APIView):
+ #authentication_classes = [TokenAuthentication]
+ #permission_classes = [permissions.IsAuthenticated]
+
+ def get(self, request, *args, **kwargs):
+ outbox_files = view_outbox(
+ request.user.username,
+ request.query_params.get('designation'),
+ request.query_params.get('src_module'))
+ return Response(outbox_files)
+
+
+class ViewHistoryView(APIView):
+ #authentication_classes = [TokenAuthentication]
+ #permission_classes = [permissions.IsAuthenticated]
+
+ def get(self, request, file_id, *args, **kwargs):
+ history = view_history(int(file_id))
+ return Response(history)
+
+
+class ForwardFileView(APIView):
+ #authentication_classes = [TokenAuthentication]
+ #permission_classes = [permissions.IsAuthenticated]
+
+ def post(self, request, file_id, *args, **kwargs):
+ new_tracking_id = forward_file(int(file_id), **request.data)
+ return Response({'tracking_id': new_tracking_id},
+ status=status.HTTP_201_CREATED)
+
+
+class GetDesignationsView(APIView):
+ #authentication_classes = [TokenAuthentication]
+ #permission_classes = [permissions.IsAuthenticated]
+
+ def get(self, request, username, *args, **kwargs):
+ user_designations = get_designations(username)
+ return Response({'designations': user_designations})
diff --git a/FusionIIIT/applications/filetracking/decorators.py b/FusionIIIT/applications/filetracking/decorators.py
new file mode 100644
index 000000000..05cc7cc51
--- /dev/null
+++ b/FusionIIIT/applications/filetracking/decorators.py
@@ -0,0 +1,38 @@
+from django.shortcuts import render, get_object_or_404
+from django.contrib.auth.models import User
+from applications.globals.models import ExtraInfo, HoldsDesignation
+
+
+def user_check(request):
+ """
+ This function is used to check if the user is a student or not.
+ Its return type is bool.
+ @param:
+ request - contains metadata about the requested page
+
+ @Variables:
+ current_user - get user from request
+ user_details - extract details of the user from the database
+ desig_id - check for designation
+ student - designation for a student
+ final_user - final designation of the request(our user)
+ """
+ try:
+ current_user = get_object_or_404(User, username=request.user.username)
+ user_details = ExtraInfo.objects.select_related('user','department').get(user=request.user)
+ des = HoldsDesignation.objects.all().select_related().filter(user=request.user).first()
+ if str(des.designation) == "student":
+ return True
+ else:
+ return False
+ except Exception as e:
+ return False
+
+def user_is_student(view_func):
+ def _wrapped_view(request, *args, **kwargs):
+ if user_check(request):
+ return render(request, 'filetracking/fileTrackingNotAllowed.html')
+ else:
+ return view_func(request, *args, **kwargs)
+ return _wrapped_view
+
diff --git a/FusionIIIT/applications/filetracking/filetracking/admin.py b/FusionIIIT/applications/filetracking/filetracking/admin.py
new file mode 100644
index 000000000..82b78df95
--- /dev/null
+++ b/FusionIIIT/applications/filetracking/filetracking/admin.py
@@ -0,0 +1,7 @@
+from django.contrib import admin
+
+# Register your models here.
+from applications.filetracking.models import File, Tracking
+
+admin.site.register(File)
+admin.site.register(Tracking)
diff --git a/FusionIIIT/applications/filetracking/filetracking/api/serializers.py b/FusionIIIT/applications/filetracking/filetracking/api/serializers.py
new file mode 100644
index 000000000..bdae2024e
--- /dev/null
+++ b/FusionIIIT/applications/filetracking/filetracking/api/serializers.py
@@ -0,0 +1,24 @@
+from applications.filetracking.models import File, Tracking
+from django.core.files import File as DjangoFile
+from rest_framework import serializers
+
+
+class FileSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = File
+ fields = '__all__'
+
+
+class TrackingSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = Tracking
+ fields = '__all__'
+
+
+class FileHeaderSerializer(serializers.ModelSerializer):
+ '''
+ This serializes everything except the attachments of a file and whether it is read or not
+ '''
+ class Meta:
+ model = File
+ exclude = ['upload_file', 'is_read']
diff --git a/FusionIIIT/applications/filetracking/filetracking/api/urls.py b/FusionIIIT/applications/filetracking/filetracking/api/urls.py
new file mode 100644
index 000000000..90f03b2ef
--- /dev/null
+++ b/FusionIIIT/applications/filetracking/filetracking/api/urls.py
@@ -0,0 +1,22 @@
+from django.conf.urls import url
+from .views import (
+ CreateFileView,
+ ViewFileView,
+ DeleteFileView,
+ ViewInboxView,
+ ViewOutboxView,
+ ViewHistoryView,
+ ForwardFileView,
+ GetDesignationsView,
+)
+
+urlpatterns = [
+ url(r'^file/$', CreateFileView.as_view(), name='create_file'),
+ url(r'^file/(?P\d+)/$', ViewFileView.as_view(), name='view_file'),
+ url(r'^file/(?P\d+)/$', DeleteFileView.as_view(), name='delete_file'),
+ url(r'^inbox/$', ViewInboxView.as_view(), name='view_inbox'),
+ url(r'^outbox/$', ViewOutboxView.as_view(), name='view_outbox'),
+ url(r'^history/(?P\d+)/$', ViewHistoryView.as_view(), name='view_history'),
+ url(r'^file/(?P\d+)/$', ForwardFileView.as_view(), name='forward_file'),
+ url(r'^designations/(?P\w+)/$', GetDesignationsView.as_view(), name='get_designations'),
+]
diff --git a/FusionIIIT/applications/filetracking/filetracking/api/views.py b/FusionIIIT/applications/filetracking/filetracking/api/views.py
new file mode 100644
index 000000000..c4bb01189
--- /dev/null
+++ b/FusionIIIT/applications/filetracking/filetracking/api/views.py
@@ -0,0 +1,111 @@
+from rest_framework.views import APIView
+from rest_framework.response import Response
+from rest_framework import status, permissions
+from rest_framework.authentication import TokenAuthentication
+from ..models import File
+from ..sdk.methods import create_file, view_file, delete_file, view_inbox, view_outbox, view_history, forward_file, get_designations
+
+class CreateFileView(APIView):
+ authentication_classes = [TokenAuthentication]
+ permission_classes = [permissions.IsAuthenticated]
+
+ def post(self, request):
+ try:
+ current_user = request.user.username
+ current_designation = request.data.get('designation')
+ receiver_username = request.data.get('receiver_username')
+ receiver_designation = request.data.get('receiver_designation')
+ subject = request.data.get('subject')
+ description = request.data.get('description')
+
+ if None in [current_designation, receiver_username, receiver_designation, subject, description]:
+ return Response({'error': 'One or more required fields are missing.'}, status=status.HTTP_400_BAD_REQUEST)
+
+ file_id = create_file(uploader=current_user, uploader_designation=current_designation,
+ receiver=receiver_username, receiver_designation=receiver_designation, subject=subject, description=description)
+
+ return Response({'file_id': file_id}, status=status.HTTP_201_CREATED)
+ except Exception as e:
+ return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST)
+
+
+class ViewFileView(APIView):
+ authentication_classes = [TokenAuthentication]
+ permission_classes = [permissions.IsAuthenticated]
+
+ def get(self, request, file_id):
+ try:
+ file_details = view_file(int(file_id))
+ return Response(file_details, status=status.HTTP_200_OK)
+ except ValueError:
+ return Response({'error': 'Invalid file ID format.'}, status=status.HTTP_400_BAD_REQUEST)
+ except File.DoesNotExist:
+ return Response({'error': 'File not found.'}, status=status.HTTP_404_NOT_FOUND)
+ except Exception as e:
+ return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST)
+
+
+class DeleteFileView(APIView):
+ #authentication_classes = [TokenAuthentication]
+ #permission_classes = [permissions.IsAuthenticated]
+
+ def delete(self, request, file_id, *args, **kwargs):
+ success = delete_file(int(file_id))
+ if success:
+ return Response({'message': 'File deleted successfully'},
+ status=status.HTTP_204_NO_CONTENT)
+ else:
+ return Response({'error': 'File not found'},
+ status=status.HTTP_404_NOT_FOUND)
+
+
+class ViewInboxView(APIView):
+ #authentication_classes = [TokenAuthentication]
+ #permission_classes = [permissions.IsAuthenticated]
+
+ def get(self, request, *args, **kwargs):
+ inbox_files = view_inbox(
+ request.user.username,
+ request.query_params.get('designation'),
+ request.query_params.get('src_module'))
+ return Response(inbox_files)
+
+
+class ViewOutboxView(APIView):
+ #authentication_classes = [TokenAuthentication]
+ #permission_classes = [permissions.IsAuthenticated]
+
+ def get(self, request, *args, **kwargs):
+ outbox_files = view_outbox(
+ request.user.username,
+ request.query_params.get('designation'),
+ request.query_params.get('src_module'))
+ return Response(outbox_files)
+
+
+class ViewHistoryView(APIView):
+ #authentication_classes = [TokenAuthentication]
+ #permission_classes = [permissions.IsAuthenticated]
+
+ def get(self, request, file_id, *args, **kwargs):
+ history = view_history(int(file_id))
+ return Response(history)
+
+
+class ForwardFileView(APIView):
+ #authentication_classes = [TokenAuthentication]
+ #permission_classes = [permissions.IsAuthenticated]
+
+ def post(self, request, file_id, *args, **kwargs):
+ new_tracking_id = forward_file(int(file_id), **request.data)
+ return Response({'tracking_id': new_tracking_id},
+ status=status.HTTP_201_CREATED)
+
+
+class GetDesignationsView(APIView):
+ #authentication_classes = [TokenAuthentication]
+ #permission_classes = [permissions.IsAuthenticated]
+
+ def get(self, request, username, *args, **kwargs):
+ user_designations = get_designations(username)
+ return Response({'designations': user_designations})
diff --git a/FusionIIIT/applications/filetracking/filetracking/apps.py b/FusionIIIT/applications/filetracking/filetracking/apps.py
new file mode 100644
index 000000000..7e3d3b6d2
--- /dev/null
+++ b/FusionIIIT/applications/filetracking/filetracking/apps.py
@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class FileTrackingConfig(AppConfig):
+ name = 'applications.filetracking'
diff --git a/FusionIIIT/applications/filetracking/filetracking/decorators.py b/FusionIIIT/applications/filetracking/filetracking/decorators.py
new file mode 100644
index 000000000..05cc7cc51
--- /dev/null
+++ b/FusionIIIT/applications/filetracking/filetracking/decorators.py
@@ -0,0 +1,38 @@
+from django.shortcuts import render, get_object_or_404
+from django.contrib.auth.models import User
+from applications.globals.models import ExtraInfo, HoldsDesignation
+
+
+def user_check(request):
+ """
+ This function is used to check if the user is a student or not.
+ Its return type is bool.
+ @param:
+ request - contains metadata about the requested page
+
+ @Variables:
+ current_user - get user from request
+ user_details - extract details of the user from the database
+ desig_id - check for designation
+ student - designation for a student
+ final_user - final designation of the request(our user)
+ """
+ try:
+ current_user = get_object_or_404(User, username=request.user.username)
+ user_details = ExtraInfo.objects.select_related('user','department').get(user=request.user)
+ des = HoldsDesignation.objects.all().select_related().filter(user=request.user).first()
+ if str(des.designation) == "student":
+ return True
+ else:
+ return False
+ except Exception as e:
+ return False
+
+def user_is_student(view_func):
+ def _wrapped_view(request, *args, **kwargs):
+ if user_check(request):
+ return render(request, 'filetracking/fileTrackingNotAllowed.html')
+ else:
+ return view_func(request, *args, **kwargs)
+ return _wrapped_view
+
diff --git a/FusionIIIT/applications/filetracking/filetracking/migrations/0001_initial.py b/FusionIIIT/applications/filetracking/filetracking/migrations/0001_initial.py
new file mode 100644
index 000000000..6924ae1ff
--- /dev/null
+++ b/FusionIIIT/applications/filetracking/filetracking/migrations/0001_initial.py
@@ -0,0 +1,53 @@
+# Generated by Django 3.1.5 on 2023-03-15 18:53
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+ ('globals', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='File',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('subject', models.CharField(blank=True, max_length=100, null=True)),
+ ('description', models.CharField(blank=True, max_length=400, null=True)),
+ ('upload_date', models.DateTimeField(auto_now_add=True)),
+ ('upload_file', models.FileField(blank=True, upload_to='')),
+ ('is_read', models.BooleanField(default=False)),
+ ('designation', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='upload_designation', to='globals.designation')),
+ ('uploader', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='uploaded_files', to='globals.extrainfo')),
+ ],
+ options={
+ 'db_table': 'File',
+ },
+ ),
+ migrations.CreateModel(
+ name='Tracking',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('receive_date', models.DateTimeField(auto_now_add=True)),
+ ('forward_date', models.DateTimeField(auto_now_add=True)),
+ ('remarks', models.CharField(blank=True, max_length=250, null=True)),
+ ('upload_file', models.FileField(blank=True, upload_to='')),
+ ('is_read', models.BooleanField(default=False)),
+ ('current_design', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='globals.holdsdesignation')),
+ ('current_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='globals.extrainfo')),
+ ('file_id', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='filetracking.file')),
+ ('receive_design', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='rec_design', to='globals.designation')),
+ ('receiver_id', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='receiver_id', to=settings.AUTH_USER_MODEL)),
+ ],
+ options={
+ 'db_table': 'Tracking',
+ },
+ ),
+ ]
diff --git a/FusionIIIT/applications/filetracking/filetracking/migrations/__init__.py b/FusionIIIT/applications/filetracking/filetracking/migrations/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/FusionIIIT/applications/filetracking/filetracking/models.py b/FusionIIIT/applications/filetracking/filetracking/models.py
new file mode 100644
index 000000000..9d78b24c9
--- /dev/null
+++ b/FusionIIIT/applications/filetracking/filetracking/models.py
@@ -0,0 +1,51 @@
+from django.db import models
+from django.contrib.auth.models import User
+from applications.globals.models import ExtraInfo, HoldsDesignation, Designation
+
+
+class File(models.Model):
+ """
+ This is file table which contains the all the files created by user
+ """
+ uploader = models.ForeignKey(ExtraInfo, on_delete=models.CASCADE, related_name='uploaded_files')
+ designation = models.ForeignKey(Designation, on_delete=models.CASCADE, null=True, related_name='upload_designation')
+ subject = models.CharField(max_length=100, null=True, blank=True)
+ description = models.CharField(max_length=400, null=True, blank=True)
+ upload_date = models.DateTimeField(auto_now_add=True)
+ upload_file = models.FileField(blank=True)
+ is_read = models.BooleanField(default = False)
+
+
+ # additions for API
+ src_module = models.CharField(max_length=100, default='filetracking')
+ src_object_id = models.CharField(max_length=100,null=True)
+ file_extra_JSON = models.JSONField(null=True)
+
+ class Meta:
+ db_table = 'File'
+
+ #def __str__(self):
+ #return str(self.ref_id)
+
+
+class Tracking(models.Model):
+ """
+ This is File Tracing Table which contains the status of each individual file created by the user
+ """
+ file_id = models.ForeignKey(File, on_delete=models.CASCADE, null=True)
+ current_id = models.ForeignKey(ExtraInfo, on_delete=models.CASCADE)
+ current_design = models.ForeignKey(HoldsDesignation, null=True, on_delete=models.CASCADE)
+ receiver_id = models.ForeignKey(User,null = True, on_delete=models.CASCADE, related_name='receiver_id')
+ receive_design = models.ForeignKey(Designation, null=True, on_delete=models.CASCADE, related_name='rec_design')
+
+ receive_date = models.DateTimeField(auto_now_add=True)
+ forward_date = models.DateTimeField(auto_now_add=True)
+ remarks = models.CharField(max_length=250, null=True, blank=True)
+ upload_file = models.FileField(blank=True)
+ is_read = models.BooleanField(default = False)
+
+ # additions for API
+ tracking_extra_JSON = models.JSONField(null=True)
+
+ class Meta:
+ db_table = 'Tracking'
diff --git a/FusionIIIT/applications/filetracking/filetracking/sdk/methods.py b/FusionIIIT/applications/filetracking/filetracking/sdk/methods.py
new file mode 100644
index 000000000..c6f9ebc53
--- /dev/null
+++ b/FusionIIIT/applications/filetracking/filetracking/sdk/methods.py
@@ -0,0 +1,423 @@
+from django.contrib.auth.models import User
+from applications.filetracking.models import Tracking, File
+from applications.globals.models import Designation, HoldsDesignation, ExtraInfo
+from applications.filetracking.api.serializers import FileSerializer, FileHeaderSerializer, TrackingSerializer
+from django.core.exceptions import ValidationError
+from typing import Any
+
+
+def create_file(
+ uploader: str,
+ uploader_designation: str,
+ receiver: str,
+ receiver_designation: str,
+ subject: str = "",
+ description: str = "",
+ src_module: str = "filetracking",
+ src_object_id: str = "",
+ file_extra_JSON: dict = {},
+ attached_file: Any = None) -> int:
+ '''
+ This function is used to create a file object corresponding to any object of a module that needs to be tracked
+ '''
+
+ '''
+ Functioning:
+ create base file with params
+ create tracking with params
+ if both complete then return id of file
+ else raise error
+
+ also, delete file object if tracking isnt created
+ '''
+ uploader_user_obj = get_user_object_from_username(uploader)
+ uploader_extrainfo_obj = get_ExtraInfo_object_from_username(uploader)
+ uploader_designation_obj = Designation.objects.get(
+ name=uploader_designation)
+ receiver_obj = get_user_object_from_username(receiver)
+ receiver_designation_obj = Designation.objects.get(
+ name=receiver_designation)
+
+ new_file = File.objects.create(
+ uploader=uploader_extrainfo_obj,
+ subject=subject,
+ description=description,
+ designation=uploader_designation_obj,
+ src_module=src_module,
+ src_object_id=src_object_id,
+ file_extra_JSON=file_extra_JSON,
+ )
+
+
+ if attached_file is not None:
+ new_file.upload_file.save(attached_file.name, attached_file, save=True)
+
+ uploader_holdsdesignation_obj = HoldsDesignation.objects.get(
+ user=uploader_user_obj, designation=uploader_designation_obj)
+
+ new_tracking = Tracking.objects.create(
+ file_id=new_file,
+ current_id=uploader_extrainfo_obj,
+ current_design=uploader_holdsdesignation_obj,
+ receiver_id=receiver_obj,
+ receive_design=receiver_designation_obj,
+ tracking_extra_JSON=file_extra_JSON,
+ remarks=f"File with id:{str(new_file.id)} created by {uploader} and sent to {receiver}"
+ # upload_file = None, dont add file for first tracking
+ )
+ if new_tracking is None:
+ new_file.delete()
+ raise ValidationError('Tracking model data is incorrect')
+ else:
+ return new_file.id
+
+
+def view_file(file_id: int) -> dict:
+ '''
+ This function returns all the details of a given file
+ '''
+ try:
+ requested_file = File.objects.get(id=file_id)
+ serializer = FileSerializer(requested_file)
+ file_details = serializer.data
+ return file_details
+ except File.DoesNotExist:
+ raise NotFound("File Not Found with provided ID")
+
+
+def delete_file(file_id: int) -> bool:
+ '''
+ This function is used to delete a file from being tracked, all the tracking history is deleted as well and returns true if the deletion was successful
+ '''
+ try:
+ File.objects.filter(id=file_id).delete()
+ return True
+ except File.DoesNotExist:
+ return False
+
+# inbox and outbox could be sorted based on most recent linked tracking entry
+
+def view_inbox(username: str, designation: str, src_module: str) -> list:
+ '''
+ This function is used to get all the files in the inbox of a particular user and designation
+ '''
+ user_designation = Designation.objects.get(name=designation)
+ recipient_object = get_user_object_from_username(username)
+ received_files_tracking = Tracking.objects.select_related('file_id').filter(
+ receiver_id=recipient_object,
+ receive_design=user_designation,
+ file_id__src_module=src_module,
+ file_id__is_read=False).order_by('receive_date');
+ received_files = [tracking.file_id for tracking in received_files_tracking]
+
+ # remove duplicate file ids (from sending back and forth)
+ received_files_unique = uniqueList(received_files)
+
+ received_files_serialized = list(FileHeaderSerializer(
+ received_files_unique, many=True).data)
+
+ for file in received_files_serialized:
+ file['sent_by_user'] = get_last_file_sender(file['id']).username
+ file['sent_by_designation'] = get_last_file_sender_designation(file['id']).name
+
+ return received_files_serialized
+
+
+def view_outbox(username: str, designation: str, src_module: str) -> list:
+ '''
+ This function is used to get all the files in the outbox of a particular user and designation
+ '''
+ user_designation = get_designation_obj_from_name(designation=designation)
+ user_object = get_user_object_from_username(username)
+ user_HoldsDesignation_object = HoldsDesignation.objects.get(
+ user=user_object, designation=user_designation)
+ sender_ExtraInfo_object = get_ExtraInfo_object_from_username(username)
+ sent_files_tracking = Tracking.objects.select_related('file_id').filter(
+ current_id=sender_ExtraInfo_object,
+ current_design=user_HoldsDesignation_object,
+ file_id__src_module=src_module,
+ file_id__is_read=False).order_by('-receive_date')
+ sent_files = [tracking.file_id for tracking in sent_files_tracking]
+
+ # remove duplicate file ids (from sending back and forth)
+ sent_files_unique = uniqueList(sent_files)
+
+ sent_files_serialized = FileHeaderSerializer(sent_files_unique, many=True)
+ return sent_files_serialized.data
+
+
+
+def view_archived(username: str, designation: str, src_module: str) -> dict:
+ '''
+ This function is used to get all the files in the archive of a particular user and designation
+ Archived file mean those which the user has ever interacted with, and are now finished or archived
+ '''
+ user_designation = Designation.objects.get(name=designation)
+ user_object = get_user_object_from_username(username)
+ received_archived_tracking = Tracking.objects.select_related('file_id').filter(
+ receiver_id=user_object,
+ receive_design=user_designation,
+ file_id__src_module=src_module,
+ file_id__is_read=True)
+
+ user_HoldsDesignation_object = HoldsDesignation.objects.get(
+ user=user_object, designation=user_designation)
+ sender_ExtraInfo_object = get_ExtraInfo_object_from_username(username)
+ sent_archived_tracking = Tracking.objects.select_related('file_id').filter(
+ current_id=sender_ExtraInfo_object,
+ current_design=user_HoldsDesignation_object,
+ file_id__src_module=src_module,
+ file_id__is_read=True)
+
+ archived_tracking = received_archived_tracking | sent_archived_tracking
+ archived_files = [tracking.file_id for tracking in archived_tracking]
+
+ # remove duplicate file ids (from sending back and forth)
+ archived_files_unique = uniqueList(archived_files)
+
+ archived_files_serialized = FileHeaderSerializer(archived_files_unique, many=True)
+ return archived_files_serialized.data
+
+
+
+def archive_file(file_id: int) -> bool:
+ '''
+ This function is used to archive a file and returns true if the archiving was successful
+ '''
+ try:
+ File.objects.filter(id=file_id).update(is_read=True)
+ return True
+ except File.DoesNotExist:
+ return False
+
+def unarchive_file(file_id: int) -> bool:
+ '''
+ This functions is used to unarchive a file and returns true if the unarchiving was successful
+ '''
+ try:
+ File.objects.filter(id=file_id).update(is_read=False)
+ return True
+ except File.DoesNotExist:
+ return False
+
+
+
+def create_draft(
+ uploader: str,
+ uploader_designation: str,
+ src_module: str = "filetracking",
+ src_object_id: str = "",
+ file_extra_JSON: dict = {},
+ attached_file: Any = None) -> int:
+ '''
+ This function is used to create a draft file object corresponding to any object of a module that needs to be tracked
+ It is similar to create_file but is not sent to anyone
+ Later this file can be sent to someone by forward_file by using draft file_id
+ '''
+ uploader_extrainfo_obj = get_ExtraInfo_object_from_username(uploader)
+ uploader_designation_obj = Designation.objects.get(
+ name=uploader_designation)
+
+ new_file = File.objects.create(
+ uploader=uploader_extrainfo_obj,
+ designation=uploader_designation_obj,
+ src_module=src_module,
+ src_object_id=src_object_id,
+ file_extra_JSON=file_extra_JSON,
+ upload_file=attached_file
+ )
+ return new_file.id
+
+
+def view_drafts(username: str, designation: str, src_module: str) -> dict:
+ '''
+ This function is used to get all the files in the drafts (has not been sent) of a particular user and designation
+ '''
+ user_designation = Designation.objects.get(name=designation)
+ user_ExtraInfo_object = get_ExtraInfo_object_from_username(username)
+ draft_files = File.objects.filter(
+ tracking__isnull=True, uploader=user_ExtraInfo_object, designation=user_designation, src_module=src_module)
+ draft_files_serialized = FileHeaderSerializer(draft_files, many=True)
+ return draft_files_serialized.data
+
+
+
+def forward_file(
+ file_id: int,
+ receiver: str,
+ receiver_designation: str,
+ file_extra_JSON: dict,
+ remarks: str = "",
+ file_attachment: Any = None) -> int:
+ '''
+ This function forwards the file and inserts a new tracking history into the file tracking table
+ Note that only the current owner(with appropriate designation) of the file has the ability to forward files
+ '''
+ # HoldsDesignation and ExtraInfo object are used instead
+ # of Designation and User object because of the legacy code being that way
+
+ current_owner = get_current_file_owner(file_id)
+ current_owner_designation = get_current_file_owner_designation(file_id)
+ current_owner_extra_info = ExtraInfo.objects.get(user=current_owner)
+ current_owner_holds_designation = HoldsDesignation.objects.get(
+ user=current_owner, designation=current_owner_designation)
+ receiver_obj = User.objects.get(username=receiver)
+ receiver_designation_obj = Designation.objects.get(
+ name=receiver_designation)
+ tracking_data = {
+ 'file_id': file_id,
+ 'current_id': current_owner_extra_info.id,
+ 'current_design': current_owner_holds_designation.id,
+ 'receiver_id': receiver_obj.id,
+ 'receive_design': receiver_designation_obj.id,
+ 'tracking_extra_JSON': file_extra_JSON,
+ 'remarks': remarks,
+ }
+ if file_attachment is not None:
+ tracking_data['upload_file'] = file_attachment
+
+ tracking_entry = TrackingSerializer(data=tracking_data)
+ if tracking_entry.is_valid():
+ tracking_entry.save()
+ return tracking_entry.instance.id
+ else:
+ raise ValidationError('forward data is incomplete')
+
+
+def view_history(file_id: int) -> dict:
+ '''
+ This function is used to get the history of a particular file with the given file_id
+ '''
+ Tracking_history = Tracking.objects.filter(
+ file_id=file_id).order_by('-receive_date')
+ Tracking_history_serialized = TrackingSerializer(
+ Tracking_history, many=True)
+ return Tracking_history_serialized.data
+
+
+# HELPER FUNCTIONS
+
+def get_current_file_owner(file_id: int) -> User:
+ '''
+ This functions returns the current owner of the file.
+ The current owner is the latest recipient of the file
+ '''
+ latest_tracking = Tracking.objects.filter(
+ file_id=file_id).order_by('-receive_date').first()
+ latest_recipient = latest_tracking.receiver_id
+ return latest_recipient
+
+
+def get_current_file_owner_designation(file_id: int) -> Designation:
+ '''
+ This function returns the designation of the current owner of the file.
+ The current owner is the latest recipient of the file
+ '''
+ latest_tracking = Tracking.objects.filter(
+ file_id=file_id).order_by('-receive_date').first()
+ latest_recipient_designation = latest_tracking.receive_design
+ return latest_recipient_designation
+
+def get_last_file_sender(file_id: int) -> User:
+ '''
+ This Function returns the last file sender,
+ one who has last forwarded/sent the file
+ '''
+ latest_tracking = Tracking.objects.filter(
+ file_id=file_id).order_by('-receive_date').first()
+ latest_sender_extra_info = latest_tracking.current_id
+ return latest_sender_extra_info.user
+
+def get_last_file_sender_designation(file_id: int) -> Designation:
+ '''
+ This Function returns the last file sender's Designation,
+ one who has last forwarded/sent the file
+ '''
+ latest_tracking = Tracking.objects.filter(
+ file_id=file_id).order_by('receive_date').first()
+ latest_sender_holds_designation = latest_tracking.current_design
+ return latest_sender_holds_designation.designation
+
+def get_designations(username: str) -> list:
+ '''
+ This function is used to return a list of all the designation names of a particular user
+ '''
+ user = User.objects.get(username=username)
+ designations_held = HoldsDesignation.objects.filter(user=user)
+ designation_name = [hold_designation.designation.name for hold_designation in designations_held]
+ return designation_name
+
+
+def get_user_object_from_username(username: str) -> User:
+ user = User.objects.get(username=username)
+ return user
+
+def get_ExtraInfo_object_from_username(username: str) -> ExtraInfo:
+ user = User.objects.get(username=username)
+ extrainfo = ExtraInfo.objects.get(user=user)
+ return extrainfo
+
+def uniqueList(l: list) -> list:
+ '''
+ This function is used to return a list with unique elements
+ O(n) time and space
+ '''
+ seen = set()
+ unique_list = []
+ for item in l:
+ if item not in seen:
+ unique_list.append(item)
+ seen.add(item)
+ return unique_list
+
+def add_uploader_department_to_files_list(files: list) -> list:
+ '''
+ This function is used to add the department of the uploader to the file
+ '''
+ for file in files:
+ uploader_Extrainfo = file['uploader']
+ file['uploader_department'] = (str(uploader_Extrainfo.department)).split(': ')[1]
+
+ return files
+
+def get_designation_obj_from_name(designation: str) -> Designation:
+ des = Designation.objects.get(name = designation)
+ return des
+
+def get_HoldsDesignation_obj(username: str, designation:str) -> HoldsDesignation:
+ user_object = get_user_object_from_username(username=username)
+ user_designation = get_designation_obj_from_name(designation=designation)
+ obj = HoldsDesignation.objects.get(
+ user=user_object, designation=user_designation)
+ return obj
+
+def get_last_recv_tracking_for_user(file_id: int, username: str, designation: str)-> Tracking:
+ '''
+ This returns the last tracking where username+designation recieved file_id
+ '''
+
+ recv_user_obj = get_user_object_from_username(username)
+ recv_design_obj = get_designation_obj_from_name(designation)
+
+ last_tracking = Tracking.objects.filter(file_id=file_id,
+ receiver_id=recv_user_obj,
+ receive_design=recv_design_obj).order_by('-receive_date')[0]
+ return last_tracking
+
+def get_last_forw_tracking_for_user(file_id: int, username: str, designation: str) -> Tracking:
+ '''
+ Returns the last tracking where the specified user forwarded the file.
+ '''
+
+ # Get user and designation objects
+ sender_user_obj = get_ExtraInfo_object_from_username(username)
+ sender_designation_obj = get_HoldsDesignation_obj(username=username, designation=designation)
+
+ # Filter Tracking objects by file_id, sender_id, and sender_designation
+ last_tracking = Tracking.objects.filter(file_id=file_id,
+ current_id=sender_user_obj,
+ current_design=sender_designation_obj).order_by('-forward_date').first()
+ return last_tracking
+
+def get_extra_info_object_from_id(id: int):
+ return ExtraInfo.objects.get(id=id)
diff --git a/FusionIIIT/applications/filetracking/filetracking/tests.py b/FusionIIIT/applications/filetracking/filetracking/tests.py
new file mode 100644
index 000000000..a79ca8be5
--- /dev/null
+++ b/FusionIIIT/applications/filetracking/filetracking/tests.py
@@ -0,0 +1,3 @@
+# from django.test import TestCase
+
+# Create your tests here.
diff --git a/FusionIIIT/applications/filetracking/filetracking/urls.py b/FusionIIIT/applications/filetracking/filetracking/urls.py
new file mode 100644
index 000000000..9236b8c36
--- /dev/null
+++ b/FusionIIIT/applications/filetracking/filetracking/urls.py
@@ -0,0 +1,43 @@
+from django.conf.urls import url, include
+
+from . import views
+from .api import urls
+
+app_name = 'filetracking'
+
+urlpatterns = [
+
+ url(r'^$', views.filetracking, name='filetracking'),
+ url(r'^draftdesign/$', views.draft_design, name='draft_design'),
+ url(r'^drafts/(?P\d+)$', views.drafts_view, name='drafts_view'),
+ url(r'^outbox/(?P\d+)$', views.outbox_view, name='outbox_view'),
+ url(r'^inbox/(?P\d+)$', views.inbox_view, name='inbox_view'),
+ url(r'^outward/$', views.outward, name='outward'),
+ url(r'^inward/$', views.inward, name='inward'),
+ url(r'^confirmdelete/(?P\d+)$',
+ views.confirmdelete, name='confirm_delete'),
+ url(r'^archive/(?P\d+)/$', views.archive_view, name='archive_view'),
+ url(r'^finish/(?P\d+)/$', views.archive_file, name='finish_file'),
+ url(r'^viewfile/(?P\d+)/$', views.view_file, name='view_file_view'),
+ url(r'^forward/(?P\d+)/$', views.forward, name='forward'),
+ url(r'^ajax/$', views.AjaxDropdown1, name='ajax_dropdown1'),
+ url(r'^ajax_dropdown/$', views.AjaxDropdown, name='ajax_dropdown'),
+ url(r'^test/$', views.test, name='test'),
+ url(r'^delete/(?P\d+)$', views.delete, name='delete'),
+ url(r'^forward_inward/(?P\d+)/$',
+ views.forward_inward, name='forward_inward'),
+
+ # correction team 24
+ url(r'^finish_design/$', views.finish_design, name='finish_design'),
+ url(r'^finish_fileview/(?P\d+)$',
+ views.finish_fileview,
+ name='finish_fileview'),
+ url(r'^archive_design/$', views.archive_design, name='archive_design'),
+ url(r'^archive_finish/(?P\d+)/$',
+ views.archive_finish, name='archive_finish'),
+ url(r'^getdesignations/(?P\w+)/$', views.get_designations_view, name="get_user_designations"),
+
+ # REST api urls
+ url(r'^api/', include(urls))
+
+]
diff --git a/FusionIIIT/applications/filetracking/filetracking/utils.py b/FusionIIIT/applications/filetracking/filetracking/utils.py
new file mode 100644
index 000000000..5ebd27374
--- /dev/null
+++ b/FusionIIIT/applications/filetracking/filetracking/utils.py
@@ -0,0 +1,7 @@
+from .models import File, Tracking
+from applications.globals.models import ExtraInfo, HoldsDesignation, Designation
+from django.contrib.auth.models import User
+
+def get_designation(userid):
+ user_designation=HoldsDesignation.objects.select_related('user','working','designation').filter(user=userid)
+ return user_designation
\ No newline at end of file
diff --git a/FusionIIIT/applications/filetracking/filetracking/views.py b/FusionIIIT/applications/filetracking/filetracking/views.py
new file mode 100644
index 000000000..b6d9e3bff
--- /dev/null
+++ b/FusionIIIT/applications/filetracking/filetracking/views.py
@@ -0,0 +1,732 @@
+from django.contrib import messages
+from django.shortcuts import render, get_object_or_404, redirect
+from .models import File, Tracking
+from applications.globals.models import ExtraInfo, HoldsDesignation, Designation
+from django.template.defaulttags import csrf_token
+from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
+from django.contrib.auth.decorators import login_required
+from django.db import IntegrityError
+from django.core import serializers
+from django.contrib.auth.models import User
+from django.http import JsonResponse
+from timeit import default_timer as time
+from notification.views import office_module_notif, file_tracking_notif
+from .utils import *
+from django.utils.dateparse import parse_datetime
+from .sdk.methods import *
+from .decorators import *
+
+@login_required(login_url="/accounts/login/")
+@user_is_student
+def filetracking(request):
+ """
+ The function is used to create files by current user(employee).
+ It adds the employee(uploader) and file datails to a file(table) of filetracking(model)
+ if he intends to create file.
+
+ @param:
+ request - trivial.
+
+ @variables:
+
+
+ uploader - Employee who creates file.
+ subject - Title of the file.
+ description - Description of the file.
+ upload_file - Attachment uploaded while creating file.
+ file - The file object.
+ extrainfo - The Extrainfo object.
+ holdsdesignations - The HoldsDesignation object.
+ context - Holds data needed to make necessary changes in the template.
+ """
+ if request.method == "POST":
+ try:
+ if 'save' in request.POST:
+ uploader = request.user.extrainfo
+ subject = request.POST.get('title')
+ description = request.POST.get('desc')
+ design = request.POST.get('design')
+ designation = Designation.objects.get(id=HoldsDesignation.objects.select_related(
+ 'user', 'working', 'designation').get(id=design).designation_id)
+ upload_file = request.FILES.get('myfile')
+ if upload_file and upload_file.size / 1000 > 10240:
+ messages.error(
+ request, "File should not be greater than 10MB")
+ return redirect("/filetracking")
+
+ File.objects.create(
+ uploader=uploader,
+ description=description,
+ subject=subject,
+ designation=designation,
+ upload_file=upload_file
+ )
+
+ messages.success(request, 'File Draft Saved Successfully')
+
+ if 'send' in request.POST:
+ uploader = request.user.extrainfo
+ subject = request.POST.get('title')
+ description = request.POST.get('desc')
+ design = request.POST.get('design')
+ designation = Designation.objects.get(id=HoldsDesignation.objects.select_related(
+ 'user', 'working', 'designation').get(id=design).designation_id)
+
+ upload_file = request.FILES.get('myfile')
+ if upload_file and upload_file.size / 1000 > 10240:
+ messages.error(
+ request, "File should not be greater than 10MB")
+ return redirect("/filetracking")
+
+ file = File.objects.create(
+ uploader=uploader,
+ description=description,
+ subject=subject,
+ designation=designation,
+ upload_file=upload_file
+ )
+
+ current_id = request.user.extrainfo
+ remarks = request.POST.get('remarks')
+
+ sender = request.POST.get('design')
+ current_design = HoldsDesignation.objects.select_related(
+ 'user', 'working', 'designation').get(id=sender)
+
+ receiver = request.POST.get('receiver')
+ try:
+ receiver_id = User.objects.get(username=receiver)
+ except Exception as e:
+ messages.error(request, 'Enter a valid Username')
+ return redirect('/filetracking/')
+ receive = request.POST.get('recieve')
+ try:
+ receive_design = Designation.objects.get(name=receive)
+ except Exception as e:
+ messages.error(request, 'Enter a valid Designation')
+ return redirect('/filetracking/')
+
+ upload_file = request.FILES.get('myfile')
+
+ Tracking.objects.create(
+ file_id=file,
+ current_id=current_id,
+ current_design=current_design,
+ receive_design=receive_design,
+ receiver_id=receiver_id,
+ remarks=remarks,
+ upload_file=upload_file,
+ )
+ # office_module_notif(request.user, receiver_id)
+ file_tracking_notif(request.user, receiver_id, subject)
+ messages.success(request, 'File sent successfully')
+
+ except IntegrityError:
+ message = "FileID Already Taken.!!"
+ return HttpResponse(message)
+
+ file = File.objects.select_related(
+ 'uploader__user', 'uploader__department', 'designation').all()
+ extrainfo = ExtraInfo.objects.select_related('user', 'department').all()
+ holdsdesignations = HoldsDesignation.objects.select_related(
+ 'user', 'working', 'designation').all()
+ designations = get_designation(request.user)
+
+ context = {
+ 'file': file,
+ 'extrainfo': extrainfo,
+ 'holdsdesignations': holdsdesignations,
+ 'designations': designations,
+ }
+ return render(request, 'filetracking/composefile.html', context)
+
+
+@login_required(login_url="/accounts/login")
+def draft_design(request):
+ """
+ The function is used to get the designation of the user and renders it on draft template.
+
+ @param:
+ request - trivial.
+
+ @variables:
+
+
+ context - Holds data needed to make necessary changes in the template.
+ """
+ designation = get_designation(request.user)
+ context = {
+ 'designation': designation,
+ }
+ return render(request, 'filetracking/draft_design.html', context)
+
+
+@login_required(login_url="/accounts/login")
+def drafts_view(request, id):
+ """
+ This function is used to view all the drafts created by the user ordered by upload date.it collects all the created files from File object.
+
+ @param:
+ request - trivial
+ id - user id
+
+ @parameters
+ draft - file obeject containing all the files created by user
+ context - holds data needed to render the template
+
+
+
+ """
+ user_HoldsDesignation_obj = HoldsDesignation.objects.select_related(
+ 'user', 'working', 'designation').get(pk=id)
+ s = str(user_HoldsDesignation_obj).split(" - ")
+ designation = s[1]
+ draft_files = view_drafts(
+ username=user_HoldsDesignation_obj.user,
+ designation=user_HoldsDesignation_obj.designation,
+ src_module='filetracking'
+ )
+
+ # Correct upload_date type
+ for f in draft_files:
+ f['upload_date'] = parse_datetime(f['upload_date'])
+ f['uploader'] = get_extra_info_object_from_id(f['uploader'])
+
+ draft_files = add_uploader_department_to_files_list(draft_files)
+
+ context = {
+ 'draft_files': draft_files,
+ 'designations': designation,
+ }
+ return render(request, 'filetracking/drafts.html', context)
+
+
+@login_required(login_url="/accounts/login")
+def outbox_view(request, id):
+ """
+ The function is used to get all the files sent by user(employee) to other employees
+ which are filtered from Tracking(table) objects by current user i.e. current_id.
+ It displays files sent by user to other employees of a Tracking(table) of filetracking(model)
+ in the 'Outbox' tab of template.
+
+ @param:
+ request - trivial.
+ id - user id
+
+ @variables:
+ outward_files - File objects filtered by current_id i.e, present working user.
+ context - Holds data needed to make necessary changes in the template.
+
+ """
+ user_HoldsDesignation_obj = HoldsDesignation.objects.select_related(
+ 'user', 'working', 'designation').get(pk=id)
+ s = str(user_HoldsDesignation_obj).split(" - ")
+ designation = s[1]
+
+ outward_files = view_outbox(username=user_HoldsDesignation_obj.user,
+ designation=user_HoldsDesignation_obj.designation,
+ src_module='filetracking')
+
+ for f in outward_files:
+ last_forw_tracking = get_last_forw_tracking_for_user(file_id=f['id'],
+ username=user_HoldsDesignation_obj.user,
+ designation=user_HoldsDesignation_obj.designation)
+ f['sent_to_user'] = last_forw_tracking.receiver_id
+ f['sent_to_design'] = last_forw_tracking.receive_design
+ f['last_sent_date'] = last_forw_tracking.forward_date
+
+ f['upload_date'] = parse_datetime(f['upload_date'])
+ f['uploader'] = get_extra_info_object_from_id(f['uploader'])
+
+ outward_files = add_uploader_department_to_files_list(outward_files)
+
+ context = {
+
+ 'out_files': outward_files,
+ 'viewer_designation': designation,
+ }
+ return render(request, 'filetracking/outbox.html', context)
+
+
+@login_required(login_url="/accounts/login")
+def inbox_view(request, id):
+ """
+ The function is used to fetch the files received by the user form other employees.
+ These files are filtered by receiver id and ordered by receive date.
+
+ @param:
+ request - trivial.
+ id - HoldsDesignation object id
+
+ @variables:
+ inward_files - File object with additional sent by information
+ context - Holds data needed to make necessary changes in the template.
+
+ """
+
+ user_HoldsDesignation_obj = HoldsDesignation.objects.select_related(
+ 'user', 'working', 'designation').get(pk=id)
+ s = str(user_HoldsDesignation_obj).split(" - ")
+ designation = s[1]
+ inward_files = view_inbox(
+ username=user_HoldsDesignation_obj.user,
+ designation=user_HoldsDesignation_obj.designation,
+ src_module='filetracking'
+ )
+
+ # correct upload_date type and add recieve_date
+ for f in inward_files:
+ f['upload_date'] = parse_datetime(f['upload_date'])
+
+ last_recv_tracking = get_last_recv_tracking_for_user(file_id=f['id'],
+ username=user_HoldsDesignation_obj.user,
+ designation=user_HoldsDesignation_obj.designation)
+ f['receive_date'] = last_recv_tracking.receive_date
+ f['uploader'] = get_extra_info_object_from_id(f['uploader'])
+
+ inward_files = add_uploader_department_to_files_list(inward_files)
+
+
+ context = {
+
+ 'in_file': inward_files,
+ 'designations': designation,
+ }
+ return render(request, 'filetracking/inbox.html', context)
+
+
+@login_required(login_url="/accounts/login")
+def outward(request):
+ """
+ This function fetches the different designations of the user and renders it on outward template
+ @param:
+ request - trivial.
+
+ @variables:
+ context - Holds the different designation data of the user
+
+ """
+ designation = get_designation(request.user)
+
+ context = {
+ 'designation': designation,
+ }
+ return render(request, 'filetracking/outward.html', context)
+
+
+@login_required(login_url="/accounts/login")
+def inward(request):
+ """
+ This function fetches the different designations of the user and renders it on inward template
+
+
+ @param:
+ request - trivial.
+
+ @variables:
+ context - Holds the different designation data of the user
+ """
+ designation = get_designation(request.user)
+ context = {
+
+ 'designation': designation,
+ }
+ return render(request, 'filetracking/inward.html', context)
+
+
+@login_required(login_url = "/accounts/login")
+def confirmdelete(request,id):
+ """
+ The function is used to confirm the deletion of a file.
+ @param:
+ request - trivial.
+ id - user id
+
+ @variables:
+ context - Holds data needed to make necessary changes in the template.
+ """
+ file = File.objects.select_related(
+ 'uploader__user', 'uploader__department', 'designation').get(pk=id)
+
+ context = {
+ 'j': file,
+ }
+
+ return render(request, 'filetracking/confirmdelete.html', context)
+
+@login_required(login_url="/accounts/login")
+def view_file(request, id):
+ '''
+ This function is used to view a particular file received by an employee from another.
+ This function also conditionally renders two forms 'forward_file' and 'archive_file'
+ based on if the user has necessary permissions or not.
+ The business permissions are as follows:
+ 1. User can forward file only if they are the last recipient of the file
+ 2. User can archive a file only if they have received it last and they are also the original owner of the file
+
+ To forward the file and to archive the file separate views with POST request are called
+
+ It displays the details file of a File and remarks as well as the attachments of all the users
+ who have been involved till that point of the workflow.
+
+ @param:
+ request - Trivial.
+ id - ID of the file object which the user intends to forward to another employee.
+
+ @variables:
+ file - The File object.
+ track - The Tracking object.
+ designation - the designations of the user
+ '''
+
+ file = get_object_or_404(File, id=id)
+ track = Tracking.objects.select_related('file_id__uploader__user', 'file_id__uploader__department', 'file_id__designation', 'current_id__user', 'current_id__department',
+ 'current_design__user', 'current_design__working', 'current_design__designation', 'receiver_id', 'receive_design').filter(file_id=file).order_by('receive_date')
+ designations = get_designation(request.user)
+
+ forward_enable = False
+ archive_enable = False
+
+ current_owner = get_current_file_owner(file.id)
+ file_uploader = get_user_object_from_username(file.uploader.user.username)
+
+
+ if current_owner == request.user and file.is_read is False:
+ forward_enable = True
+ if current_owner == request.user and file_uploader == request.user and file.is_read is False:
+ archive_enable = True
+
+ context = {
+ 'designations': designations,
+ 'file': file,
+ 'track': track,
+ 'forward_enable': forward_enable,
+ 'archive_enable': archive_enable,
+ }
+ return render(request, 'filetracking/viewfile.html', context)
+
+@login_required(login_url="/accounts/login")
+def archive_file(request, id):
+ '''This function is used to archive a file.
+ It returns unauthorized access if the user is not file uploader
+ and the current owner of the file
+ '''
+ if request.method == "POST":
+ file = get_object_or_404(File, id=id);
+ current_owner = get_current_file_owner(file.id)
+ file_uploader = get_user_object_from_username(file.uploader.user.username)
+ if current_owner == request.user and file_uploader == request.user:
+ file.is_read = True
+ file.save()
+ messages.success(request, 'File Archived')
+ else:
+ messages.error(request, 'Unauthorized access')
+
+ return render(request, 'filetracking/composefile.html')
+
+@login_required(login_url="/accounts/login")
+def forward(request, id):
+ """
+ The function is used to forward files received by user(employee) from other
+ employees which are filtered from Tracking(table) objects by current user
+ i.e. receiver_id to other employees.
+ It also gets track of file created by uploader through all users involved in file
+ along with their remarks and attachments
+ It displays details file of a File(table) and remarks and attachments of user involved
+ in file of Tracking(table) of filetracking(model) in the template.
+
+ @param:
+ request - trivial.
+ id - id of the file object which the user intends to forward to other employee.
+
+ @variables:
+ file - The File object.
+ track - The Tracking object.
+ remarks = Remarks posted by user.
+ receiver = Receiver to be selected by user for forwarding file.
+ receiver_id = Receiver_id who has been selected for forwarding file.
+ upload_file = File attached by user.
+ extrainfo = ExtraInfo object.
+ holdsdesignations = HoldsDesignation objects.
+ context - Holds data needed to make necessary changes in the template.
+ """
+
+ file = get_object_or_404(File, id=id)
+ track = Tracking.objects.select_related('file_id__uploader__user', 'file_id__uploader__department', 'file_id__designation', 'current_id__user', 'current_id__department',
+ 'current_design__user', 'current_design__working', 'current_design__designation', 'receiver_id', 'receive_design').filter(file_id=file).order_by('receive_date')
+
+ if request.method == "POST":
+ if 'finish' in request.POST:
+ file.is_read = True
+ file.save()
+ if 'send' in request.POST:
+ current_id = request.user.extrainfo
+ remarks = request.POST.get('remarks')
+ track.update(is_read=True)
+
+ sender = request.POST.get('sender')
+ current_design = HoldsDesignation.objects.select_related(
+ 'user', 'working', 'designation').get(id=sender)
+
+ receiver = request.POST.get('receiver')
+ try:
+ receiver_id = User.objects.get(username=receiver)
+ except Exception as e:
+ messages.error(request, 'Enter a valid destination')
+ designations = HoldsDesignation.objects.select_related(
+ 'user', 'working', 'designation').filter(user=request.user)
+
+ context = {
+
+ 'designations': designations,
+ 'file': file,
+ 'track': track,
+ }
+ return render(request, 'filetracking/forward.html', context)
+ receive = request.POST.get('recieve')
+ try:
+ receive_design = Designation.objects.get(name=receive)
+ except Exception as e:
+ messages.error(request, 'Enter a valid Designation')
+ designations = get_designation(request.user)
+
+ context = {
+
+ 'designations': designations,
+ 'file': file,
+ 'track': track,
+ }
+ return render(request, 'filetracking/forward.html', context)
+
+ upload_file = request.FILES.get('myfile')
+
+ Tracking.objects.create(
+ file_id=file,
+ current_id=current_id,
+ current_design=current_design,
+ receive_design=receive_design,
+ receiver_id=receiver_id,
+ remarks=remarks,
+ upload_file=upload_file,
+ )
+ messages.success(request, 'File sent successfully')
+
+ designations = get_designation(request.user)
+
+ context = {
+
+ 'designations': designations,
+ 'file': file,
+ 'track': track,
+ }
+
+ return render(request, 'filetracking/forward.html', context)
+
+
+@login_required(login_url="/accounts/login")
+def archive_design(request):
+ designation = HoldsDesignation.objects.select_related(
+ 'user', 'working', 'designation').filter(user=request.user)
+
+ context = {
+ 'designation': designation,
+ }
+ return render(request, 'filetracking/archive_design.html', context)
+
+
+@login_required(login_url="/accounts/login")
+def archive_view(request, id):
+ """
+ The function is used to fetch the files in the user's archive
+ (those which have passed by user and been archived/finished)
+
+ @param:
+ request - trivial.
+ id - HoldsDesignation object id
+
+ @variables:
+ archive_files - File object with additional information
+ context - Holds data needed to make necessary changes in the template.
+
+ """
+ user_HoldsDesignation_obj = HoldsDesignation.objects.select_related(
+ 'user', 'working', 'designation').get(pk=id)
+ s = str(user_HoldsDesignation_obj).split(" - ")
+ designation = s[1]
+
+ archive_files = view_archived(
+ username=user_HoldsDesignation_obj.user,
+ designation=user_HoldsDesignation_obj.designation,
+ src_module='filetracking'
+ )
+
+ # correct upload_date type and add receive_date
+ for f in archive_files:
+ f['upload_date'] = parse_datetime(f['upload_date'])
+ f['designation'] = Designation.objects.get(id=f['designation'])
+ f['uploader'] = get_extra_info_object_from_id(f['uploader'])
+
+ archive_files = add_uploader_department_to_files_list(archive_files)
+
+ context = {
+ 'archive_files': archive_files,
+ 'designations': designation,
+ }
+ return render(request, 'filetracking/archive.html', context)
+
+
+
+@login_required(login_url="/accounts/login")
+def archive_finish(request, id):
+ # file = get_object_or_404(File, ref_id=id)
+ file1 = get_object_or_404(File, id=id)
+ track = Tracking.objects.filter(file_id=file1)
+
+ return render(request, 'filetracking/archive_finish.html', {'file': file1, 'track': track})
+
+
+@login_required(login_url="/accounts/login")
+def finish_design(request):
+
+ designation = HoldsDesignation.objects.select_related(
+ 'user', 'working', 'designation').filter(user=request.user)
+
+ context = {
+ 'designation': designation,
+ }
+ return render(request, 'filetracking/finish_design.html', context)
+
+
+@login_required(login_url="/accounts/login")
+def finish_fileview(request, id):
+
+ out = Tracking.objects.select_related('file_id__uploader__user', 'file_id__uploader__department', 'file_id__designation', 'current_id__user', 'current_id__department',
+ 'current_design__user', 'current_design__working', 'current_design__designation', 'receiver_id', 'receive_design').filter(file_id__uploader=request.user.extrainfo, is_read=False).order_by('-forward_date')
+
+ abcd = HoldsDesignation.objects.select_related(
+ 'user', 'working', 'designation').get(pk=id)
+
+ context = {
+
+ 'out': out,
+ 'abcd': abcd,
+ }
+ return render(request, 'filetracking/finish_fileview.html', context)
+
+
+@login_required(login_url="/accounts/login")
+def finish(request, id):
+ # file = get_object_or_404(File, ref_id=id)
+ file1 = get_object_or_404(File, id=id)
+ track = Tracking.objects.filter(file_id=file1)
+
+ if request.method == "POST":
+ if 'Finished' in request.POST:
+ File.objects.filter(pk=id).update(is_read=True)
+ track.update(is_read=True)
+ messages.success(request, 'File Archived')
+
+ return render(request, 'filetracking/finish.html', {'file': file1, 'track': track, 'fileid': id})
+
+
+def AjaxDropdown1(request):
+
+ """
+ This function returns the designation of receiver on the forward or compose file template.
+
+ @param:
+ request - trivial.
+
+
+ @variables:
+ context - return the httpresponce containing the matched designation of the user
+ """
+ if request.method == 'POST':
+ value = request.POST.get('value')
+
+ hold = Designation.objects.filter(name__startswith=value)
+ holds = serializers.serialize('json', list(hold))
+ context = {
+ 'holds': holds
+ }
+
+ return HttpResponse(JsonResponse(context), content_type='application/json')
+
+
+def AjaxDropdown(request):
+ """
+ This function returns the usernames of receiver on the forward or compose file template.
+
+ @param:
+ request - trivial.
+
+
+ @variables:
+ context - return the httpresponce containing the matched username
+ """
+ if request.method == 'POST':
+ value = request.POST.get('value')
+ users = User.objects.filter(username__startswith=value)
+ users = serializers.serialize('json', list(users))
+
+ context = {
+ 'users': users
+ }
+ return HttpResponse(JsonResponse(context), content_type='application/json')
+
+
+def test(request):
+ return HttpResponse('success')
+
+
+
+@login_required(login_url = "/accounts/login")
+def delete(request,id):
+ """
+ The function is used the delete of a file and it returns to the drafts page.
+
+ @param:
+ request - trivial.
+ id - id of the file that is going to be deleted
+
+ """
+ file = File.objects.get(pk=id)
+ file.delete()
+ return redirect('/filetracking/draftdesign/')
+
+
+
+
+def forward_inward(request,id):
+ """ This function is used forward the files which are available in the inbox of the user .
+
+ @param:
+ request - trivial
+ id - id of the file that is going to forward
+
+ @variables:
+ file - file object
+ track - tracking object of the file
+ context - necessary data to render
+
+ """
+
+ file = get_object_or_404(File, id=id)
+ file.is_read = True
+ track = Tracking.objects.select_related('file_id__uploader__user', 'file_id__uploader__department', 'file_id__designation', 'current_id__user', 'current_id__department',
+ 'current_design__user', 'current_design__working', 'current_design__designation', 'receiver_id', 'receive_design').filter(file_id=file)
+ designations = get_designation(request.user)
+
+ context = {
+
+ 'designations': designations,
+ 'file': file,
+ 'track': track,
+ }
+ return render(request, 'filetracking/forward.html', context)
+
+def get_designations_view(request, username):
+ designations = get_designations(username)
+ print(designations)
+ return JsonResponse(designations, safe=False)
+
diff --git a/FusionIIIT/applications/filetracking/migrations/0002_auto_20240308_1023.py b/FusionIIIT/applications/filetracking/migrations/0002_auto_20240308_1023.py
new file mode 100644
index 000000000..31015f1ec
--- /dev/null
+++ b/FusionIIIT/applications/filetracking/migrations/0002_auto_20240308_1023.py
@@ -0,0 +1,33 @@
+# Generated by Django 3.1.5 on 2024-03-08 10:23
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('filetracking', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='file',
+ name='file_extra_JSON',
+ field=models.JSONField(null=True),
+ ),
+ migrations.AddField(
+ model_name='file',
+ name='src_module',
+ field=models.CharField(default='filetracking', max_length=100),
+ ),
+ migrations.AddField(
+ model_name='file',
+ name='src_object_id',
+ field=models.CharField(max_length=100, null=True),
+ ),
+ migrations.AddField(
+ model_name='tracking',
+ name='tracking_extra_JSON',
+ field=models.JSONField(null=True),
+ ),
+ ]
diff --git a/FusionIIIT/applications/filetracking/models.py b/FusionIIIT/applications/filetracking/models.py
index 5f9581a08..9d78b24c9 100644
--- a/FusionIIIT/applications/filetracking/models.py
+++ b/FusionIIIT/applications/filetracking/models.py
@@ -16,6 +16,11 @@ class File(models.Model):
is_read = models.BooleanField(default = False)
+ # additions for API
+ src_module = models.CharField(max_length=100, default='filetracking')
+ src_object_id = models.CharField(max_length=100,null=True)
+ file_extra_JSON = models.JSONField(null=True)
+
class Meta:
db_table = 'File'
@@ -25,13 +30,11 @@ class Meta:
class Tracking(models.Model):
"""
- This is File Tracing Table which contains the status of each indivisual file created by the user
+ This is File Tracing Table which contains the status of each individual file created by the user
"""
file_id = models.ForeignKey(File, on_delete=models.CASCADE, null=True)
current_id = models.ForeignKey(ExtraInfo, on_delete=models.CASCADE)
current_design = models.ForeignKey(HoldsDesignation, null=True, on_delete=models.CASCADE)
- # receiver_id = models.ForeignKey(ExtraInfo, on_delete=models.CASCADE, related_name='receiver_id')
- # receive_design = models.ForeignKey(HoldsDesignation, null=True, on_delete=models.CASCADE, related_name='rec_design')
receiver_id = models.ForeignKey(User,null = True, on_delete=models.CASCADE, related_name='receiver_id')
receive_design = models.ForeignKey(Designation, null=True, on_delete=models.CASCADE, related_name='rec_design')
@@ -41,5 +44,8 @@ class Tracking(models.Model):
upload_file = models.FileField(blank=True)
is_read = models.BooleanField(default = False)
+ # additions for API
+ tracking_extra_JSON = models.JSONField(null=True)
+
class Meta:
db_table = 'Tracking'
diff --git a/FusionIIIT/applications/filetracking/sdk/methods.py b/FusionIIIT/applications/filetracking/sdk/methods.py
new file mode 100644
index 000000000..97b7c87a1
--- /dev/null
+++ b/FusionIIIT/applications/filetracking/sdk/methods.py
@@ -0,0 +1,424 @@
+from django.contrib.auth.models import User
+from applications.filetracking.models import Tracking, File
+from applications.globals.models import Designation, HoldsDesignation, ExtraInfo
+from applications.filetracking.api.serializers import FileSerializer, FileHeaderSerializer, TrackingSerializer
+from django.core.exceptions import ValidationError
+from typing import Any
+
+
+def create_file(
+ uploader: str,
+ uploader_designation: str,
+ receiver: str,
+ receiver_designation: str,
+ subject: str = "",
+ description: str = "",
+ src_module: str = "filetracking",
+ src_object_id: str = "",
+ file_extra_JSON: dict = {},
+ attached_file: Any = None) -> int:
+ '''
+ This function is used to create a file object corresponding to any object of a module that needs to be tracked
+ '''
+
+ '''
+ Functioning:
+ create base file with params
+ create tracking with params
+ if both complete then return id of file
+ else raise error
+
+ also, delete file object if tracking isnt created
+ '''
+ uploader_user_obj = get_user_object_from_username(uploader)
+ uploader_extrainfo_obj = get_ExtraInfo_object_from_username(uploader)
+ uploader_designation_obj = Designation.objects.get(
+ name=uploader_designation)
+ receiver_obj = get_user_object_from_username(receiver)
+ receiver_designation_obj = Designation.objects.get(
+ name=receiver_designation)
+
+ new_file = File.objects.create(
+ uploader=uploader_extrainfo_obj,
+ subject=subject,
+ description=description,
+ designation=uploader_designation_obj,
+ src_module=src_module,
+ src_object_id=src_object_id,
+ file_extra_JSON=file_extra_JSON,
+ )
+
+
+ if attached_file is not None:
+ new_file.upload_file.save(attached_file.name, attached_file, save=True)
+
+ uploader_holdsdesignation_obj = HoldsDesignation.objects.get(
+ user=uploader_user_obj, designation=uploader_designation_obj)
+
+ new_tracking = Tracking.objects.create(
+ file_id=new_file,
+ current_id=uploader_extrainfo_obj,
+ current_design=uploader_holdsdesignation_obj,
+ receiver_id=receiver_obj,
+ receive_design=receiver_designation_obj,
+ tracking_extra_JSON=file_extra_JSON,
+ remarks=f"File with id:{str(new_file.id)} created by {uploader} and sent to {receiver}"
+ # upload_file = None, dont add file for first tracking
+ )
+ if new_tracking is None:
+ new_file.delete()
+ raise ValidationError('Tracking model data is incorrect')
+ else:
+ return new_file.id
+
+
+def view_file(file_id: int) -> dict:
+ '''
+ This function returns all the details of a given file
+ '''
+ try:
+ requested_file = File.objects.get(id=file_id)
+ serializer = FileSerializer(requested_file)
+ file_details = serializer.data
+ print(file_details)
+ return file_details
+ except File.DoesNotExist:
+ raise NotFound("File Not Found with provided ID")
+
+
+def delete_file(file_id: int) -> bool:
+ '''
+ This function is used to delete a file from being tracked, all the tracking history is deleted as well and returns true if the deletion was successful
+ '''
+ try:
+ File.objects.filter(id=file_id).delete()
+ return True
+ except File.DoesNotExist:
+ return False
+
+# inbox and outbox could be sorted based on most recent linked tracking entry
+
+def view_inbox(username: str, designation: str, src_module: str) -> list:
+ '''
+ This function is used to get all the files in the inbox of a particular user and designation
+ '''
+ user_designation = Designation.objects.get(name=designation)
+ recipient_object = get_user_object_from_username(username)
+ received_files_tracking = Tracking.objects.select_related('file_id').filter(
+ receiver_id=recipient_object,
+ receive_design=user_designation,
+ file_id__src_module=src_module,
+ file_id__is_read=False).order_by('receive_date');
+ received_files = [tracking.file_id for tracking in received_files_tracking]
+
+ # remove duplicate file ids (from sending back and forth)
+ received_files_unique = uniqueList(received_files)
+
+ received_files_serialized = list(FileHeaderSerializer(
+ received_files_unique, many=True).data)
+
+ for file in received_files_serialized:
+ file['sent_by_user'] = get_last_file_sender(file['id']).username
+ file['sent_by_designation'] = get_last_file_sender_designation(file['id']).name
+
+ return received_files_serialized
+
+
+def view_outbox(username: str, designation: str, src_module: str) -> list:
+ '''
+ This function is used to get all the files in the outbox of a particular user and designation
+ '''
+ user_designation = get_designation_obj_from_name(designation=designation)
+ user_object = get_user_object_from_username(username)
+ user_HoldsDesignation_object = HoldsDesignation.objects.get(
+ user=user_object, designation=user_designation)
+ sender_ExtraInfo_object = get_ExtraInfo_object_from_username(username)
+ sent_files_tracking = Tracking.objects.select_related('file_id').filter(
+ current_id=sender_ExtraInfo_object,
+ current_design=user_HoldsDesignation_object,
+ file_id__src_module=src_module,
+ file_id__is_read=False).order_by('-receive_date')
+ sent_files = [tracking.file_id for tracking in sent_files_tracking]
+
+ # remove duplicate file ids (from sending back and forth)
+ sent_files_unique = uniqueList(sent_files)
+
+ sent_files_serialized = FileHeaderSerializer(sent_files_unique, many=True)
+ return sent_files_serialized.data
+
+
+
+def view_archived(username: str, designation: str, src_module: str) -> dict:
+ '''
+ This function is used to get all the files in the archive of a particular user and designation
+ Archived file mean those which the user has ever interacted with, and are now finished or archived
+ '''
+ user_designation = Designation.objects.get(name=designation)
+ user_object = get_user_object_from_username(username)
+ received_archived_tracking = Tracking.objects.select_related('file_id').filter(
+ receiver_id=user_object,
+ receive_design=user_designation,
+ file_id__src_module=src_module,
+ file_id__is_read=True)
+
+ user_HoldsDesignation_object = HoldsDesignation.objects.get(
+ user=user_object, designation=user_designation)
+ sender_ExtraInfo_object = get_ExtraInfo_object_from_username(username)
+ sent_archived_tracking = Tracking.objects.select_related('file_id').filter(
+ current_id=sender_ExtraInfo_object,
+ current_design=user_HoldsDesignation_object,
+ file_id__src_module=src_module,
+ file_id__is_read=True)
+
+ archived_tracking = received_archived_tracking | sent_archived_tracking
+ archived_files = [tracking.file_id for tracking in archived_tracking]
+
+ # remove duplicate file ids (from sending back and forth)
+ archived_files_unique = uniqueList(archived_files)
+
+ archived_files_serialized = FileHeaderSerializer(archived_files_unique, many=True)
+ return archived_files_serialized.data
+
+
+
+def archive_file(file_id: int) -> bool:
+ '''
+ This function is used to archive a file and returns true if the archiving was successful
+ '''
+ try:
+ File.objects.filter(id=file_id).update(is_read=True)
+ return True
+ except File.DoesNotExist:
+ return False
+
+def unarchive_file(file_id: int) -> bool:
+ '''
+ This functions is used to unarchive a file and returns true if the unarchiving was successful
+ '''
+ try:
+ File.objects.filter(id=file_id).update(is_read=False)
+ return True
+ except File.DoesNotExist:
+ return False
+
+
+
+def create_draft(
+ uploader: str,
+ uploader_designation: str,
+ src_module: str = "filetracking",
+ src_object_id: str = "",
+ file_extra_JSON: dict = {},
+ attached_file: Any = None) -> int:
+ '''
+ This function is used to create a draft file object corresponding to any object of a module that needs to be tracked
+ It is similar to create_file but is not sent to anyone
+ Later this file can be sent to someone by forward_file by using draft file_id
+ '''
+ uploader_extrainfo_obj = get_ExtraInfo_object_from_username(uploader)
+ uploader_designation_obj = Designation.objects.get(
+ name=uploader_designation)
+
+ new_file = File.objects.create(
+ uploader=uploader_extrainfo_obj,
+ designation=uploader_designation_obj,
+ src_module=src_module,
+ src_object_id=src_object_id,
+ file_extra_JSON=file_extra_JSON,
+ upload_file=attached_file
+ )
+ return new_file.id
+
+
+def view_drafts(username: str, designation: str, src_module: str) -> dict:
+ '''
+ This function is used to get all the files in the drafts (has not been sent) of a particular user and designation
+ '''
+ user_designation = Designation.objects.get(name=designation)
+ user_ExtraInfo_object = get_ExtraInfo_object_from_username(username)
+ draft_files = File.objects.filter(
+ tracking__isnull=True, uploader=user_ExtraInfo_object, designation=user_designation, src_module=src_module)
+ draft_files_serialized = FileHeaderSerializer(draft_files, many=True)
+ return draft_files_serialized.data
+
+
+
+def forward_file(
+ file_id: int,
+ receiver: str,
+ receiver_designation: str,
+ file_extra_JSON: dict,
+ remarks: str = "",
+ file_attachment: Any = None) -> int:
+ '''
+ This function forwards the file and inserts a new tracking history into the file tracking table
+ Note that only the current owner(with appropriate designation) of the file has the ability to forward files
+ '''
+ # HoldsDesignation and ExtraInfo object are used instead
+ # of Designation and User object because of the legacy code being that way
+
+ current_owner = get_current_file_owner(file_id)
+ current_owner_designation = get_current_file_owner_designation(file_id)
+ current_owner_extra_info = ExtraInfo.objects.get(user=current_owner)
+ current_owner_holds_designation = HoldsDesignation.objects.get(
+ user=current_owner, designation=current_owner_designation)
+ receiver_obj = User.objects.get(username=receiver)
+ receiver_designation_obj = Designation.objects.get(
+ name=receiver_designation)
+ tracking_data = {
+ 'file_id': file_id,
+ 'current_id': current_owner_extra_info.id,
+ 'current_design': current_owner_holds_designation.id,
+ 'receiver_id': receiver_obj.id,
+ 'receive_design': receiver_designation_obj.id,
+ 'tracking_extra_JSON': file_extra_JSON,
+ 'remarks': remarks,
+ }
+ if file_attachment is not None:
+ tracking_data['upload_file'] = file_attachment
+
+ tracking_entry = TrackingSerializer(data=tracking_data)
+ if tracking_entry.is_valid():
+ tracking_entry.save()
+ return tracking_entry.instance.id
+ else:
+ raise ValidationError('forward data is incomplete')
+
+
+def view_history(file_id: int) -> dict:
+ '''
+ This function is used to get the history of a particular file with the given file_id
+ '''
+ Tracking_history = Tracking.objects.filter(
+ file_id=file_id).order_by('-receive_date')
+ Tracking_history_serialized = TrackingSerializer(
+ Tracking_history, many=True)
+ return Tracking_history_serialized.data
+
+
+# HELPER FUNCTIONS
+
+def get_current_file_owner(file_id: int) -> User:
+ '''
+ This functions returns the current owner of the file.
+ The current owner is the latest recipient of the file
+ '''
+ latest_tracking = Tracking.objects.filter(
+ file_id=file_id).order_by('-receive_date').first()
+ latest_recipient = latest_tracking.receiver_id
+ return latest_recipient
+
+
+def get_current_file_owner_designation(file_id: int) -> Designation:
+ '''
+ This function returns the designation of the current owner of the file.
+ The current owner is the latest recipient of the file
+ '''
+ latest_tracking = Tracking.objects.filter(
+ file_id=file_id).order_by('-receive_date').first()
+ latest_recipient_designation = latest_tracking.receive_design
+ return latest_recipient_designation
+
+def get_last_file_sender(file_id: int) -> User:
+ '''
+ This Function returns the last file sender,
+ one who has last forwarded/sent the file
+ '''
+ latest_tracking = Tracking.objects.filter(
+ file_id=file_id).order_by('-receive_date').first()
+ latest_sender_extra_info = latest_tracking.current_id
+ return latest_sender_extra_info.user
+
+def get_last_file_sender_designation(file_id: int) -> Designation:
+ '''
+ This Function returns the last file sender's Designation,
+ one who has last forwarded/sent the file
+ '''
+ latest_tracking = Tracking.objects.filter(
+ file_id=file_id).order_by('receive_date').first()
+ latest_sender_holds_designation = latest_tracking.current_design
+ return latest_sender_holds_designation.designation
+
+def get_designations(username: str) -> list:
+ '''
+ This function is used to return a list of all the designation names of a particular user
+ '''
+ user = User.objects.get(username=username)
+ designations_held = HoldsDesignation.objects.filter(user=user)
+ designation_name = [hold_designation.designation.name for hold_designation in designations_held]
+ return designation_name
+
+
+def get_user_object_from_username(username: str) -> User:
+ user = User.objects.get(username=username)
+ return user
+
+def get_ExtraInfo_object_from_username(username: str) -> ExtraInfo:
+ user = User.objects.get(username=username)
+ extrainfo = ExtraInfo.objects.get(user=user)
+ return extrainfo
+
+def uniqueList(l: list) -> list:
+ '''
+ This function is used to return a list with unique elements
+ O(n) time and space
+ '''
+ seen = set()
+ unique_list = []
+ for item in l:
+ if item not in seen:
+ unique_list.append(item)
+ seen.add(item)
+ return unique_list
+
+def add_uploader_department_to_files_list(files: list) -> list:
+ '''
+ This function is used to add the department of the uploader to the file
+ '''
+ for file in files:
+ uploader_Extrainfo = file['uploader']
+ file['uploader_department'] = (str(uploader_Extrainfo.department)).split(': ')[1]
+
+ return files
+
+def get_designation_obj_from_name(designation: str) -> Designation:
+ des = Designation.objects.get(name = designation)
+ return des
+
+def get_HoldsDesignation_obj(username: str, designation:str) -> HoldsDesignation:
+ user_object = get_user_object_from_username(username=username)
+ user_designation = get_designation_obj_from_name(designation=designation)
+ obj = HoldsDesignation.objects.get(
+ user=user_object, designation=user_designation)
+ return obj
+
+def get_last_recv_tracking_for_user(file_id: int, username: str, designation: str)-> Tracking:
+ '''
+ This returns the last tracking where username+designation recieved file_id
+ '''
+
+ recv_user_obj = get_user_object_from_username(username)
+ recv_design_obj = get_designation_obj_from_name(designation)
+
+ last_tracking = Tracking.objects.filter(file_id=file_id,
+ receiver_id=recv_user_obj,
+ receive_design=recv_design_obj).order_by('-receive_date')[0]
+ return last_tracking
+
+def get_last_forw_tracking_for_user(file_id: int, username: str, designation: str) -> Tracking:
+ '''
+ Returns the last tracking where the specified user forwarded the file.
+ '''
+
+ # Get user and designation objects
+ sender_user_obj = get_ExtraInfo_object_from_username(username)
+ sender_designation_obj = get_HoldsDesignation_obj(username=username, designation=designation)
+
+ # Filter Tracking objects by file_id, sender_id, and sender_designation
+ last_tracking = Tracking.objects.filter(file_id=file_id,
+ current_id=sender_user_obj,
+ current_design=sender_designation_obj).order_by('-forward_date').first()
+ return last_tracking
+
+def get_extra_info_object_from_id(id: int):
+ return ExtraInfo.objects.get(id=id)
diff --git a/FusionIIIT/applications/filetracking/urls.py b/FusionIIIT/applications/filetracking/urls.py
index cb4a7563d..28c8deac1 100644
--- a/FusionIIIT/applications/filetracking/urls.py
+++ b/FusionIIIT/applications/filetracking/urls.py
@@ -1,31 +1,43 @@
-from django.conf.urls import url
+from django.conf.urls import url, include
from . import views
+from .api import urls
app_name = 'filetracking'
urlpatterns = [
url(r'^$', views.filetracking, name='filetracking'),
- url(r'^drafts/$', views.drafts, name='drafts'),
- url(r'^fileview/(?P\d+)$', views.fileview, name='fileview'),
- url(r'^fileview1/(?P\d+)$', views.fileview1, name='fileview1'),
- url(r'^fileview2/(?P\d+)$', views.fileview2, name='fileview2'),
+ url(r'^draftdesign/$', views.draft_design, name='draft_design'),
+ url(r'^drafts/(?P\d+)$', views.drafts_view, name='drafts_view'),
+ url(r'^outbox/(?P\d+)$', views.outbox_view, name='outbox_view'),
+ url(r'^inbox/(?P\d+)$', views.inbox_view, name='inbox_view'),
url(r'^outward/$', views.outward, name='outward'),
url(r'^inward/$', views.inward, name='inward'),
- url(r'^confirmdelete/(?P\d+)$', views.confirmdelete, name='confirm_delete'),
- url(r'^archive/(?P\d+)/$', views.archive, name='archive'),
- url(r'^finish/(?P\d+)/$', views.finish, name='finish'),
+ url(r'^confirmdelete/(?P\d+)$',
+ views.confirmdelete, name='confirm_delete'),
+ url(r'^archive/(?P\d+)/$', views.archive_view, name='archive_view'),
+ url(r'^finish/(?P\d+)/$', views.archive_file, name='finish_file'),
+ url(r'^viewfile/(?P\d+)/$', views.view_file, name='view_file_view'),
url(r'^forward/(?P\d+)/$', views.forward, name='forward'),
url(r'^ajax/$', views.AjaxDropdown1, name='ajax_dropdown1'),
url(r'^ajax_dropdown/$', views.AjaxDropdown, name='ajax_dropdown'),
- url(r'^test/$',views.test, name='test'),
- url(r'^delete/(?P\d+)$',views.delete, name='delete'),
- url(r'^forward_inward/(?P\d+)/$', views.forward_inward, name='forward_inward'),
+ url(r'^test/$', views.test, name='test'),
+ url(r'^delete/(?P\d+)$', views.delete, name='delete'),
+ url(r'^forward_inward/(?P\d+)/$',
+ views.forward_inward, name='forward_inward'),
- ## correction team 24
+ # correction team 24
url(r'^finish_design/$', views.finish_design, name='finish_design'),
- url(r'^finish_fileview/(?P\d+)$', views.finish_fileview, name='finish_fileview'),
+ url(r'^finish_fileview/(?P\d+)$',
+ views.finish_fileview,
+ name='finish_fileview'),
url(r'^archive_design/$', views.archive_design, name='archive_design'),
- url(r'^archive_finish/(?P\d+)/$', views.archive_finish, name='archive_finish'),
+ url(r'^archive_finish/(?P\d+)/$',
+ views.archive_finish, name='archive_finish'),
+ url(r'^getdesignations/(?P\w+)/$', views.get_designations_view, name="get_user_designations"),
+
+ # REST api urls
+ url(r'^api/', include(urls))
+
]
diff --git a/FusionIIIT/applications/filetracking/views.py b/FusionIIIT/applications/filetracking/views.py
index ef5d8f347..b6d9e3bff 100644
--- a/FusionIIIT/applications/filetracking/views.py
+++ b/FusionIIIT/applications/filetracking/views.py
@@ -8,12 +8,16 @@
from django.db import IntegrityError
from django.core import serializers
from django.contrib.auth.models import User
+from django.http import JsonResponse
from timeit import default_timer as time
-from notification.views import office_module_notif,file_tracking_notif
+from notification.views import office_module_notif, file_tracking_notif
from .utils import *
+from django.utils.dateparse import parse_datetime
+from .sdk.methods import *
+from .decorators import *
-
-@login_required(login_url = "/accounts/login/")
+@login_required(login_url="/accounts/login/")
+@user_is_student
def filetracking(request):
"""
The function is used to create files by current user(employee).
@@ -35,18 +39,20 @@ def filetracking(request):
holdsdesignations - The HoldsDesignation object.
context - Holds data needed to make necessary changes in the template.
"""
- if request.method =="POST":
+ if request.method == "POST":
try:
if 'save' in request.POST:
uploader = request.user.extrainfo
subject = request.POST.get('title')
description = request.POST.get('desc')
design = request.POST.get('design')
- designation = Designation.objects.get(id = HoldsDesignation.objects.select_related('user','working','designation').get(id = design).designation_id)
+ designation = Designation.objects.get(id=HoldsDesignation.objects.select_related(
+ 'user', 'working', 'designation').get(id=design).designation_id)
upload_file = request.FILES.get('myfile')
- if(upload_file.size / 1000 > 10240):
- messages.error(request,"File should not be greater than 10MB")
- return redirect("/filetracking")
+ if upload_file and upload_file.size / 1000 > 10240:
+ messages.error(
+ request, "File should not be greater than 10MB")
+ return redirect("/filetracking")
File.objects.create(
uploader=uploader,
@@ -56,18 +62,20 @@ def filetracking(request):
upload_file=upload_file
)
- messages.success(request,'File Draft Saved Successfully')
+ messages.success(request, 'File Draft Saved Successfully')
if 'send' in request.POST:
uploader = request.user.extrainfo
subject = request.POST.get('title')
description = request.POST.get('desc')
design = request.POST.get('design')
- designation = Designation.objects.get(id = HoldsDesignation.objects.select_related('user','working','designation').get(id = design).designation_id)
+ designation = Designation.objects.get(id=HoldsDesignation.objects.select_related(
+ 'user', 'working', 'designation').get(id=design).designation_id)
upload_file = request.FILES.get('myfile')
- if(upload_file.size / 1000 > 10240):
- messages.error(request,"File should not be greater than 10MB")
+ if upload_file and upload_file.size / 1000 > 10240:
+ messages.error(
+ request, "File should not be greater than 10MB")
return redirect("/filetracking")
file = File.objects.create(
@@ -78,12 +86,12 @@ def filetracking(request):
upload_file=upload_file
)
-
current_id = request.user.extrainfo
remarks = request.POST.get('remarks')
sender = request.POST.get('design')
- current_design = HoldsDesignation.objects.select_related('user','working','designation').get(id=sender)
+ current_design = HoldsDesignation.objects.select_related(
+ 'user', 'working', 'designation').get(id=sender)
receiver = request.POST.get('receiver')
try:
@@ -109,19 +117,19 @@ def filetracking(request):
remarks=remarks,
upload_file=upload_file,
)
- #office_module_notif(request.user, receiver_id)
- file_tracking_notif(request.user,receiver_id,subject)
- messages.success(request,'File sent successfully')
+ # office_module_notif(request.user, receiver_id)
+ file_tracking_notif(request.user, receiver_id, subject)
+ messages.success(request, 'File sent successfully')
except IntegrityError:
message = "FileID Already Taken.!!"
return HttpResponse(message)
-
-
- file = File.objects.select_related('uploader__user','uploader__department','designation').all()
- extrainfo = ExtraInfo.objects.select_related('user','department').all()
- holdsdesignations = HoldsDesignation.objects.select_related('user','working','designation').all()
+ file = File.objects.select_related(
+ 'uploader__user', 'uploader__department', 'designation').all()
+ extrainfo = ExtraInfo.objects.select_related('user', 'department').all()
+ holdsdesignations = HoldsDesignation.objects.select_related(
+ 'user', 'working', 'designation').all()
designations = get_designation(request.user)
context = {
@@ -133,8 +141,8 @@ def filetracking(request):
return render(request, 'filetracking/composefile.html', context)
-@login_required(login_url = "/accounts/login")
-def drafts(request):
+@login_required(login_url="/accounts/login")
+def draft_design(request):
"""
The function is used to get the designation of the user and renders it on draft template.
@@ -142,22 +150,21 @@ def drafts(request):
request - trivial.
@variables:
-
-
+
+
context - Holds data needed to make necessary changes in the template.
"""
designation = get_designation(request.user)
context = {
'designation': designation,
}
- return render(request, 'filetracking/drafts.html', context)
+ return render(request, 'filetracking/draft_design.html', context)
-@login_required(login_url = "/accounts/login")
-def fileview(request,id):
-
+@login_required(login_url="/accounts/login")
+def drafts_view(request, id):
"""
- This function is used to veiw all all created files by the user ordered by upload date.it collects all the created files from File object.
+ This function is used to view all the drafts created by the user ordered by upload date.it collects all the created files from File object.
@param:
request - trivial
@@ -166,45 +173,36 @@ def fileview(request,id):
@parameters
draft - file obeject containing all the files created by user
context - holds data needed to render the template
-
-
- """
- # draft = File.objects.select_related('uploader__user','uploader__department','designation').filter(uploader=request.user.extrainfo).order_by('-upload_date')
- # extrainfo = ExtraInfo.objects.select_related('user','department').all()
-
- extrainfo = ExtraInfo.objects.select_related('user','department').all()
-
- ids = File.objects.filter(uploader=request.user.extrainfo).order_by('-upload_date').values_list('id', flat=True)
- draft_files_pk=[]
-
- for i in ids:
- file_tracking_ids = Tracking.objects.filter(file_id=i).values_list('id', flat=True)
- if(len(file_tracking_ids)==0):
- draft_files_pk.append(i)
-
- draft_file_list=[]
- for i in draft_files_pk:
- draft_file_list.append(File.objects.get(pk=i))
+ """
+ user_HoldsDesignation_obj = HoldsDesignation.objects.select_related(
+ 'user', 'working', 'designation').get(pk=id)
+ s = str(user_HoldsDesignation_obj).split(" - ")
+ designation = s[1]
+ draft_files = view_drafts(
+ username=user_HoldsDesignation_obj.user,
+ designation=user_HoldsDesignation_obj.designation,
+ src_module='filetracking'
+ )
+
+ # Correct upload_date type
+ for f in draft_files:
+ f['upload_date'] = parse_datetime(f['upload_date'])
+ f['uploader'] = get_extra_info_object_from_id(f['uploader'])
+
+ draft_files = add_uploader_department_to_files_list(draft_files)
- user_designation = HoldsDesignation.objects.select_related('user','working','designation').get(pk=id)
- s = str(user_designation).split(" - ")
- designations = s[1]
context = {
-
- 'draft': draft_file_list,
- 'extrainfo': extrainfo,
- 'designations': designations,
+ 'draft_files': draft_files,
+ 'designations': designation,
}
- return render(request, 'filetracking/fileview.html', context)
-
-
+ return render(request, 'filetracking/drafts.html', context)
-@login_required(login_url = "/accounts/login")
-def fileview1(request,id):
+@login_required(login_url="/accounts/login")
+def outbox_view(request, id):
"""
The function is used to get all the files sent by user(employee) to other employees
which are filtered from Tracking(table) objects by current user i.e. current_id.
@@ -216,56 +214,88 @@ def fileview1(request,id):
id - user id
@variables:
- out - The Tracking object filtered by current_id i.e, present working user.
+ outward_files - File objects filtered by current_id i.e, present working user.
context - Holds data needed to make necessary changes in the template.
-
+
"""
+ user_HoldsDesignation_obj = HoldsDesignation.objects.select_related(
+ 'user', 'working', 'designation').get(pk=id)
+ s = str(user_HoldsDesignation_obj).split(" - ")
+ designation = s[1]
+
+ outward_files = view_outbox(username=user_HoldsDesignation_obj.user,
+ designation=user_HoldsDesignation_obj.designation,
+ src_module='filetracking')
+
+ for f in outward_files:
+ last_forw_tracking = get_last_forw_tracking_for_user(file_id=f['id'],
+ username=user_HoldsDesignation_obj.user,
+ designation=user_HoldsDesignation_obj.designation)
+ f['sent_to_user'] = last_forw_tracking.receiver_id
+ f['sent_to_design'] = last_forw_tracking.receive_design
+ f['last_sent_date'] = last_forw_tracking.forward_date
- outward_files = Tracking.objects.select_related('file_id__uploader__user','file_id__uploader__department','file_id__designation','current_id__user','current_id__department',
- 'current_design__user','current_design__working','current_design__designation','receiver_id','receive_design').filter(current_id=request.user.extrainfo).order_by('-forward_date')
+ f['upload_date'] = parse_datetime(f['upload_date'])
+ f['uploader'] = get_extra_info_object_from_id(f['uploader'])
- user_designation = HoldsDesignation.objects.select_related('user','working','designation').get(pk=id)
+ outward_files = add_uploader_department_to_files_list(outward_files)
context = {
- 'out': outward_files,
- 'abcd': user_designation,
+ 'out_files': outward_files,
+ 'viewer_designation': designation,
}
- return render(request, 'filetracking/fileview1.html', context)
+ return render(request, 'filetracking/outbox.html', context)
-@login_required(login_url = "/accounts/login")
-def fileview2(request,id):
-
+@login_required(login_url="/accounts/login")
+def inbox_view(request, id):
"""
The function is used to fetch the files received by the user form other employees.
These files are filtered by receiver id and ordered by receive date.
@param:
request - trivial.
- id - user id
+ id - HoldsDesignation object id
@variables:
- inward_file - The Tracking object filtered by receiver_id i.e, present working user.
+ inward_files - File object with additional sent by information
context - Holds data needed to make necessary changes in the template.
"""
- inward_file = Tracking.objects.select_related('file_id__uploader__user','file_id__uploader__department','file_id__designation','current_id__user','current_id__department',
- 'current_design__user','current_design__working','current_design__designation','receiver_id','receive_design').filter(receiver_id=request.user).order_by('-receive_date')
- user_designation = HoldsDesignation.objects.select_related('user','working','designation').get(pk=id)
- s = str(user_designation).split(" - ")
- designations = s[1]
+ user_HoldsDesignation_obj = HoldsDesignation.objects.select_related(
+ 'user', 'working', 'designation').get(pk=id)
+ s = str(user_HoldsDesignation_obj).split(" - ")
+ designation = s[1]
+ inward_files = view_inbox(
+ username=user_HoldsDesignation_obj.user,
+ designation=user_HoldsDesignation_obj.designation,
+ src_module='filetracking'
+ )
+
+ # correct upload_date type and add recieve_date
+ for f in inward_files:
+ f['upload_date'] = parse_datetime(f['upload_date'])
+
+ last_recv_tracking = get_last_recv_tracking_for_user(file_id=f['id'],
+ username=user_HoldsDesignation_obj.user,
+ designation=user_HoldsDesignation_obj.designation)
+ f['receive_date'] = last_recv_tracking.receive_date
+ f['uploader'] = get_extra_info_object_from_id(f['uploader'])
+
+ inward_files = add_uploader_department_to_files_list(inward_files)
+
context = {
- 'in_file': inward_file,
- 'designations': designations,
+ 'in_file': inward_files,
+ 'designations': designation,
}
- return render(request, 'filetracking/fileview2.html', context)
+ return render(request, 'filetracking/inbox.html', context)
-@login_required(login_url = "/accounts/login")
+@login_required(login_url="/accounts/login")
def outward(request):
"""
This function fetches the different designations of the user and renders it on outward template
@@ -274,22 +304,22 @@ def outward(request):
@variables:
context - Holds the different designation data of the user
-
+
"""
designation = get_designation(request.user)
context = {
'designation': designation,
}
- return render( request, 'filetracking/outward.html', context)
+ return render(request, 'filetracking/outward.html', context)
-@login_required(login_url = "/accounts/login")
+@login_required(login_url="/accounts/login")
def inward(request):
"""
This function fetches the different designations of the user and renders it on inward template
-
+
@param:
request - trivial.
@@ -298,7 +328,7 @@ def inward(request):
"""
designation = get_designation(request.user)
context = {
-
+
'designation': designation,
}
return render(request, 'filetracking/inward.html', context)
@@ -306,7 +336,6 @@ def inward(request):
@login_required(login_url = "/accounts/login")
def confirmdelete(request,id):
-
"""
The function is used to confirm the deletion of a file.
@param:
@@ -316,16 +345,86 @@ def confirmdelete(request,id):
@variables:
context - Holds data needed to make necessary changes in the template.
"""
- file = File.objects.select_related('uploader__user','uploader__department','designation').get(pk = id)
+ file = File.objects.select_related(
+ 'uploader__user', 'uploader__department', 'designation').get(pk=id)
context = {
'j': file,
}
- return render(request, 'filetracking/confirmdelete.html',context)
+ return render(request, 'filetracking/confirmdelete.html', context)
+@login_required(login_url="/accounts/login")
+def view_file(request, id):
+ '''
+ This function is used to view a particular file received by an employee from another.
+ This function also conditionally renders two forms 'forward_file' and 'archive_file'
+ based on if the user has necessary permissions or not.
+ The business permissions are as follows:
+ 1. User can forward file only if they are the last recipient of the file
+ 2. User can archive a file only if they have received it last and they are also the original owner of the file
-@login_required(login_url = "/accounts/login")
+ To forward the file and to archive the file separate views with POST request are called
+
+ It displays the details file of a File and remarks as well as the attachments of all the users
+ who have been involved till that point of the workflow.
+
+ @param:
+ request - Trivial.
+ id - ID of the file object which the user intends to forward to another employee.
+
+ @variables:
+ file - The File object.
+ track - The Tracking object.
+ designation - the designations of the user
+ '''
+
+ file = get_object_or_404(File, id=id)
+ track = Tracking.objects.select_related('file_id__uploader__user', 'file_id__uploader__department', 'file_id__designation', 'current_id__user', 'current_id__department',
+ 'current_design__user', 'current_design__working', 'current_design__designation', 'receiver_id', 'receive_design').filter(file_id=file).order_by('receive_date')
+ designations = get_designation(request.user)
+
+ forward_enable = False
+ archive_enable = False
+
+ current_owner = get_current_file_owner(file.id)
+ file_uploader = get_user_object_from_username(file.uploader.user.username)
+
+
+ if current_owner == request.user and file.is_read is False:
+ forward_enable = True
+ if current_owner == request.user and file_uploader == request.user and file.is_read is False:
+ archive_enable = True
+
+ context = {
+ 'designations': designations,
+ 'file': file,
+ 'track': track,
+ 'forward_enable': forward_enable,
+ 'archive_enable': archive_enable,
+ }
+ return render(request, 'filetracking/viewfile.html', context)
+
+@login_required(login_url="/accounts/login")
+def archive_file(request, id):
+ '''This function is used to archive a file.
+ It returns unauthorized access if the user is not file uploader
+ and the current owner of the file
+ '''
+ if request.method == "POST":
+ file = get_object_or_404(File, id=id);
+ current_owner = get_current_file_owner(file.id)
+ file_uploader = get_user_object_from_username(file.uploader.user.username)
+ if current_owner == request.user and file_uploader == request.user:
+ file.is_read = True
+ file.save()
+ messages.success(request, 'File Archived')
+ else:
+ messages.error(request, 'Unauthorized access')
+
+ return render(request, 'filetracking/composefile.html')
+
+@login_required(login_url="/accounts/login")
def forward(request, id):
"""
The function is used to forward files received by user(employee) from other
@@ -351,73 +450,72 @@ def forward(request, id):
holdsdesignations = HoldsDesignation objects.
context - Holds data needed to make necessary changes in the template.
"""
-
- file = get_object_or_404(File, id=id)
- track = Tracking.objects.select_related('file_id__uploader__user','file_id__uploader__department','file_id__designation','current_id__user','current_id__department',
- 'current_design__user','current_design__working','current_design__designation','receiver_id','receive_design').filter(file_id=file)
-
- if request.method == "POST":
- if 'finish' in request.POST:
- file.complete_flag = True
- file.save()
-
- if 'send' in request.POST:
- current_id = request.user.extrainfo
- remarks = request.POST.get('remarks')
- track.update(is_read=True)
- sender = request.POST.get('sender')
- current_design = HoldsDesignation.objects.select_related('user','working','designation').get(id=sender)
-
- receiver = request.POST.get('receiver')
- try:
- receiver_id = User.objects.get(username=receiver)
- except Exception as e:
- messages.error(request, 'Enter a valid destination')
- designations = HoldsDesignation.objects.select_related('user','working','designation').filter(user=request.user)
-
- context = {
-
- 'designations': designations,
- 'file': file,
- 'track': track,
- }
- return render(request, 'filetracking/forward.html', context)
- receive = request.POST.get('recieve')
- try:
- receive_design = Designation.objects.get(name=receive)
- except Exception as e:
- messages.error(request, 'Enter a valid Designation')
- designations = get_designation(request.user)
+ file = get_object_or_404(File, id=id)
+ track = Tracking.objects.select_related('file_id__uploader__user', 'file_id__uploader__department', 'file_id__designation', 'current_id__user', 'current_id__department',
+ 'current_design__user', 'current_design__working', 'current_design__designation', 'receiver_id', 'receive_design').filter(file_id=file).order_by('receive_date')
- context = {
-
- 'designations': designations,
- 'file': file,
- 'track': track,
- }
- return render(request, 'filetracking/forward.html', context)
+ if request.method == "POST":
+ if 'finish' in request.POST:
+ file.is_read = True
+ file.save()
+ if 'send' in request.POST:
+ current_id = request.user.extrainfo
+ remarks = request.POST.get('remarks')
+ track.update(is_read=True)
+
+ sender = request.POST.get('sender')
+ current_design = HoldsDesignation.objects.select_related(
+ 'user', 'working', 'designation').get(id=sender)
+
+ receiver = request.POST.get('receiver')
+ try:
+ receiver_id = User.objects.get(username=receiver)
+ except Exception as e:
+ messages.error(request, 'Enter a valid destination')
+ designations = HoldsDesignation.objects.select_related(
+ 'user', 'working', 'designation').filter(user=request.user)
+
+ context = {
+
+ 'designations': designations,
+ 'file': file,
+ 'track': track,
+ }
+ return render(request, 'filetracking/forward.html', context)
+ receive = request.POST.get('recieve')
+ try:
+ receive_design = Designation.objects.get(name=receive)
+ except Exception as e:
+ messages.error(request, 'Enter a valid Designation')
+ designations = get_designation(request.user)
+
+ context = {
+
+ 'designations': designations,
+ 'file': file,
+ 'track': track,
+ }
+ return render(request, 'filetracking/forward.html', context)
+
+ upload_file = request.FILES.get('myfile')
+
+ Tracking.objects.create(
+ file_id=file,
+ current_id=current_id,
+ current_design=current_design,
+ receive_design=receive_design,
+ receiver_id=receiver_id,
+ remarks=remarks,
+ upload_file=upload_file,
+ )
+ messages.success(request, 'File sent successfully')
-
- upload_file = request.FILES.get('myfile')
-
- Tracking.objects.create(
- file_id=file,
- current_id=current_id,
- current_design=current_design,
- receive_design=receive_design,
- receiver_id=receiver_id,
- remarks=remarks,
- upload_file=upload_file,
- )
- messages.success(request, 'File sent successfully')
-
-
designations = get_designation(request.user)
context = {
-
- 'designations':designations,
+
+ 'designations': designations,
'file': file,
'track': track,
}
@@ -425,83 +523,88 @@ def forward(request, id):
return render(request, 'filetracking/forward.html', context)
-@login_required(login_url = "/accounts/login")
+@login_required(login_url="/accounts/login")
def archive_design(request):
-
- designation = HoldsDesignation.objects.select_related('user','working','designation').filter(user=request.user)
+ designation = HoldsDesignation.objects.select_related(
+ 'user', 'working', 'designation').filter(user=request.user)
context = {
'designation': designation,
}
- return render( request, 'filetracking/archive_design.html', context)
-
-
+ return render(request, 'filetracking/archive_design.html', context)
+@login_required(login_url="/accounts/login")
+def archive_view(request, id):
+ """
+ The function is used to fetch the files in the user's archive
+ (those which have passed by user and been archived/finished)
-@login_required(login_url = "/accounts/login")
-def archive(request , id):
-
- draft = File.objects.select_related('uploader__user','uploader__department','designation').filter(is_read=True).order_by('-upload_date')
-
+ @param:
+ request - trivial.
+ id - HoldsDesignation object id
- extrainfo = ExtraInfo.objects.select_related('user','department').all()
- # designations = Designation.objects.filter(upload_designation=extrainfo.id)
- abcd = HoldsDesignation.objects.select_related('user','working','designation').get(pk=id)
- s = str(abcd).split(" - ")
- designations = s[1]
- #designations = HoldsDesignation.objects.filter(user=request.user)
- # for x in designations:
- # if abcd==x:
- # designations=abcd
+ @variables:
+ archive_files - File object with additional information
+ context - Holds data needed to make necessary changes in the template.
- context = {
+ """
+ user_HoldsDesignation_obj = HoldsDesignation.objects.select_related(
+ 'user', 'working', 'designation').get(pk=id)
+ s = str(user_HoldsDesignation_obj).split(" - ")
+ designation = s[1]
- 'draft': draft,
- 'extrainfo': extrainfo,
- 'designations': designations,
- }
+ archive_files = view_archived(
+ username=user_HoldsDesignation_obj.user,
+ designation=user_HoldsDesignation_obj.designation,
+ src_module='filetracking'
+ )
+ # correct upload_date type and add receive_date
+ for f in archive_files:
+ f['upload_date'] = parse_datetime(f['upload_date'])
+ f['designation'] = Designation.objects.get(id=f['designation'])
+ f['uploader'] = get_extra_info_object_from_id(f['uploader'])
+ archive_files = add_uploader_department_to_files_list(archive_files)
+ context = {
+ 'archive_files': archive_files,
+ 'designations': designation,
+ }
+ return render(request, 'filetracking/archive.html', context)
- return render(request, 'filetracking/archive.html' , context)
-@login_required(login_url = "/accounts/login")
+@login_required(login_url="/accounts/login")
def archive_finish(request, id):
- file1 = get_object_or_404(File, id=id) ##file = get_object_or_404(File, ref_id=id)
+ # file = get_object_or_404(File, ref_id=id)
+ file1 = get_object_or_404(File, id=id)
track = Tracking.objects.filter(file_id=file1)
-
-
return render(request, 'filetracking/archive_finish.html', {'file': file1, 'track': track})
-
-
-@login_required(login_url = "/accounts/login")
+@login_required(login_url="/accounts/login")
def finish_design(request):
- designation = HoldsDesignation.objects.select_related('user','working','designation').filter(user=request.user)
+ designation = HoldsDesignation.objects.select_related(
+ 'user', 'working', 'designation').filter(user=request.user)
context = {
'designation': designation,
}
- return render( request, 'filetracking/finish_design.html', context)
+ return render(request, 'filetracking/finish_design.html', context)
-@login_required(login_url = "/accounts/login")
+@login_required(login_url="/accounts/login")
def finish_fileview(request, id):
- out = Tracking.objects.select_related('file_id__uploader__user','file_id__uploader__department','file_id__designation','current_id__user','current_id__department',
- 'current_design__user','current_design__working','current_design__designation','receiver_id','receive_design').filter(file_id__uploader=request.user.extrainfo, is_read=False).order_by('-forward_date')
-
-
-
-
- abcd = HoldsDesignation.objects.select_related('user','working','designation').get(pk=id)
+ out = Tracking.objects.select_related('file_id__uploader__user', 'file_id__uploader__department', 'file_id__designation', 'current_id__user', 'current_id__department',
+ 'current_design__user', 'current_design__working', 'current_design__designation', 'receiver_id', 'receive_design').filter(file_id__uploader=request.user.extrainfo, is_read=False).order_by('-forward_date')
+ abcd = HoldsDesignation.objects.select_related(
+ 'user', 'working', 'designation').get(pk=id)
context = {
@@ -511,38 +614,29 @@ def finish_fileview(request, id):
return render(request, 'filetracking/finish_fileview.html', context)
-
-
-@login_required(login_url = "/accounts/login")
+@login_required(login_url="/accounts/login")
def finish(request, id):
- file1 = get_object_or_404(File, id=id) ##file = get_object_or_404(File, ref_id=id)
+ # file = get_object_or_404(File, ref_id=id)
+ file1 = get_object_or_404(File, id=id)
track = Tracking.objects.filter(file_id=file1)
-
if request.method == "POST":
- if 'Finished' in request.POST:
- File.objects.filter(pk=id).update(is_read=True)
- track.update(is_read=True)
- messages.success(request,'File Archived')
-
-
-
-
-
-
-
- return render(request, 'filetracking/finish.html', {'file': file1, 'track': track,'fileid':id})
-
+ if 'Finished' in request.POST:
+ File.objects.filter(pk=id).update(is_read=True)
+ track.update(is_read=True)
+ messages.success(request, 'File Archived')
+ return render(request, 'filetracking/finish.html', {'file': file1, 'track': track, 'fileid': id})
def AjaxDropdown1(request):
+
"""
This function returns the designation of receiver on the forward or compose file template.
@param:
request - trivial.
-
+
@variables:
context - return the httpresponce containing the matched designation of the user
@@ -553,20 +647,19 @@ def AjaxDropdown1(request):
hold = Designation.objects.filter(name__startswith=value)
holds = serializers.serialize('json', list(hold))
context = {
- 'holds' : holds
+ 'holds': holds
}
return HttpResponse(JsonResponse(context), content_type='application/json')
def AjaxDropdown(request):
-
"""
This function returns the usernames of receiver on the forward or compose file template.
@param:
request - trivial.
-
+
@variables:
context - return the httpresponce containing the matched username
@@ -589,24 +682,22 @@ def test(request):
@login_required(login_url = "/accounts/login")
def delete(request,id):
-
"""
The function is used the delete of a file and it returns to the drafts page.
@param:
request - trivial.
id - id of the file that is going to be deleted
-
+
"""
- file = File.objects.get(pk = id)
+ file = File.objects.get(pk=id)
file.delete()
- return redirect('/filetracking/drafts/')
+ return redirect('/filetracking/draftdesign/')
def forward_inward(request,id):
-
""" This function is used forward the files which are available in the inbox of the user .
@param:
@@ -617,21 +708,25 @@ def forward_inward(request,id):
file - file object
track - tracking object of the file
context - necessary data to render
-
+
"""
file = get_object_or_404(File, id=id)
file.is_read = True
- track = Tracking.objects.select_related('file_id__uploader__user','file_id__uploader__department','file_id__designation','current_id__user','current_id__department',
- 'current_design__user','current_design__working','current_design__designation','receiver_id','receive_design').filter(file_id=file)
+ track = Tracking.objects.select_related('file_id__uploader__user', 'file_id__uploader__department', 'file_id__designation', 'current_id__user', 'current_id__department',
+ 'current_design__user', 'current_design__working', 'current_design__designation', 'receiver_id', 'receive_design').filter(file_id=file)
designations = get_designation(request.user)
context = {
-
- 'designations':designations,
+
+ 'designations': designations,
'file': file,
'track': track,
}
return render(request, 'filetracking/forward.html', context)
-
+def get_designations_view(request, username):
+ designations = get_designations(username)
+ print(designations)
+ return JsonResponse(designations, safe=False)
+
diff --git a/FusionIIIT/applications/globals/migrations/0002_auto_20240308_1023.py b/FusionIIIT/applications/globals/migrations/0002_auto_20240308_1023.py
new file mode 100644
index 000000000..9fa2bfc59
--- /dev/null
+++ b/FusionIIIT/applications/globals/migrations/0002_auto_20240308_1023.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.1.5 on 2024-03-08 10:23
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('globals', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='extrainfo',
+ name='user_status',
+ field=models.CharField(choices=[('NEW', 'NEW'), ('PRESENT', 'PRESENT')], default='PRESENT', max_length=50),
+ ),
+ ]
diff --git a/FusionIIIT/applications/globals/migrations/0003_auto_20240308_1025.py b/FusionIIIT/applications/globals/migrations/0003_auto_20240308_1025.py
new file mode 100644
index 000000000..2f9f4c3d6
--- /dev/null
+++ b/FusionIIIT/applications/globals/migrations/0003_auto_20240308_1025.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.1.5 on 2024-03-08 10:25
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('globals', '0002_auto_20240308_1023'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='extrainfo',
+ name='user_status',
+ field=models.CharField(choices=[('PRESENT', 'PRESENT'), ('NEW', 'NEW')], default='PRESENT', max_length=50),
+ ),
+ ]
diff --git a/FusionIIIT/applications/globals/urls.py b/FusionIIIT/applications/globals/urls.py
index f8d82ee71..2dea4e77d 100644
--- a/FusionIIIT/applications/globals/urls.py
+++ b/FusionIIIT/applications/globals/urls.py
@@ -23,5 +23,6 @@
# Endpoint to reset all passwords in DEV environment
url(r'^resetallpass/$', views.reset_all_pass, name='resetallpass'),
# API urls
- url(r'^api/', include('applications.globals.api.urls'))
+ url(r'^api/', include('applications.globals.api.urls')),
+ url(r'^update_global_variable/$', views.update_global_variable, name='update_global_var'),
]
diff --git a/FusionIIIT/applications/globals/views.py b/FusionIIIT/applications/globals/views.py
index a7f3886c9..5b023abb5 100644
--- a/FusionIIIT/applications/globals/views.py
+++ b/FusionIIIT/applications/globals/views.py
@@ -740,21 +740,26 @@ def dashboard(request):
}
# a=HoldsDesignation.objects.select_related('user','working','designation').filter(designation = user)
+ print(context)
+ print(type(user.extrainfo.user_type))
if(request.user.get_username() == 'director'):
return render(request, "dashboard/director_dashboard2.html", {})
elif( "dean_rspc" in designation):
return render(request, "dashboard/dashboard.html", context)
- elif user.extrainfo.user_type != 'student':
+ elif user.extrainfo.user_type != "student":
+ print ("inside")
designat = HoldsDesignation.objects.select_related().filter(user=user)
response = {'designat':designat}
context.update(response)
return render(request, "dashboard/dashboard.html", context)
else:
+ print ("inside2")
+
return render(request, "dashboard/dashboard.html", context)
@login_required(login_url=LOGIN_URL)
-def profile(request, username=None):
+def profile(request, username=None):
"""
Generic endpoint for views.
If it's a faculty, redirects to /eis/profile/*
@@ -768,16 +773,76 @@ def profile(request, username=None):
"""
user = get_object_or_404(User, Q(username=username)) if username else request.user
-
editable = request.user == user
+ print("editable",editable)
profile = get_object_or_404(ExtraInfo, Q(user=user))
+ print("profile",profile)
if(str(user.extrainfo.user_type)=='faculty'):
+ print("profile")
return HttpResponseRedirect('/eis/profile/' + (username if username else ''))
if(str(user.extrainfo.department)=='department: Academics'):
+ print("profile2")
return HttpResponseRedirect('/aims')
- current = HoldsDesignation.objects.select_related('user','working','designation').filter(Q(working=user, designation__name="student"))
+
+ array = [
+ "student",
+ "CC convenor",
+ "Mechatronic convenor",
+ "mess_committee",
+ "mess_convener",
+ "alumini",
+ "Electrical_AE",
+ "Electrical_JE",
+ "Civil_AE",
+ "Civil_JE",
+ "co-ordinator",
+ "co co-ordinator",
+ "Convenor",
+ "Convener",
+ "cc1convener",
+ "CC2 convener",
+ "mess_convener_mess2",
+ "mess_committee_mess2"
+]
+
+ # queryset = HoldsDesignation.objects.select_related('user','working','designation').filter(Q(working=user))
+
+ # for obj in queryset:
+ # designation_name = obj.designation.name
+ # print("designation_name",designation_name)
+
+ # design = False
+ # if designation_name in array:
+ # design = True
+ # print("design",design)
+ # print("designation_name",designation_name)
+ # if design:
+ # current = HoldsDesignation.objects.select_relapted('user','working','designation').filter(Q(working=user, designation__name=designation_name))
+ # for obj in current:
+ # obj.designation.name = obj.designation.name.replace(designation_name, 'student')
+
+ designation_name = ""
+ design = False
+
+ current = HoldsDesignation.objects.select_related('user', 'working', 'designation').filter(Q(working=user))
+
+ for obj in current:
+ designation_name = obj.designation.name
+ if designation_name in array:
+ design = True
+ break
+
+ if design:
+ current = HoldsDesignation.objects.filter(working=user, designation__name=designation_name)
+ for obj in current:
+ obj.designation.name = obj.designation.name.replace(designation_name, 'student')
+
+ print(user.extrainfo.user_type)
+ print("current",current)
if current:
+ print("profile3")
student = get_object_or_404(Student, Q(id=profile.id))
+ print("student",student)
if editable and request.method == 'POST':
if 'studentapprovesubmit' in request.POST:
status = PlacementStatus.objects.select_related('notify_id','unique_id__id__user','unique_id__id__department').filter(pk=request.POST['studentapprovesubmit']).update(invitation='ACCEPTED', timestamp=timezone.now())
@@ -979,6 +1044,7 @@ def profile(request, username=None):
return render(request, "globals/student_profile4.html", context)
if 'achievementsubmit' in request.POST or 'deleteach' in request.POST:
return render(request, "globals/student_profile5.html", context)
+ print("context",context)
return render(request, "globals/student_profile.html", context)
else:
return redirect("/")
@@ -1176,4 +1242,15 @@ def search(request):
if len(search_results) == 0:
search_results = []
context = {'sresults':search_results}
- return render(request, "globals/search.html", context)
+ return render(request, "globals/search.html", context),
+
+@login_required(login_url=LOGIN_URL)
+def update_global_variable(request):
+ if request.method == 'POST':
+ selected_option = request.POST.get('dropdown')
+ request.session['currentDesignationSelected'] = selected_option
+ print(selected_option)
+ print(request.session['currentDesignationSelected'])
+ return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
+ # Redirect to home if not a POST request or some issue occurs
+ return HttpResponseRedirect(reverse('home'))
diff --git a/FusionIIIT/applications/iwdModuleV2/migrations/0002_bills_requests.py b/FusionIIIT/applications/iwdModuleV2/migrations/0002_bills_requests.py
new file mode 100644
index 000000000..24909bc10
--- /dev/null
+++ b/FusionIIIT/applications/iwdModuleV2/migrations/0002_bills_requests.py
@@ -0,0 +1,41 @@
+# Generated by Django 3.1.5 on 2024-03-08 10:23
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('iwdModuleV2', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Requests',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=200)),
+ ('description', models.CharField(max_length=200)),
+ ('area', models.CharField(max_length=200)),
+ ('requestCreatedBy', models.CharField(max_length=200)),
+ ('engineerProcessed', models.IntegerField()),
+ ('directorApproval', models.IntegerField()),
+ ('deanProcessed', models.IntegerField()),
+ ('status', models.CharField(max_length=200)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Bills',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=200)),
+ ('work', models.CharField(max_length=200)),
+ ('description', models.CharField(max_length=200)),
+ ('agency', models.CharField(max_length=200)),
+ ('bill_processed', models.IntegerField()),
+ ('bill_settled', models.IntegerField()),
+ ('key', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='iwdModuleV2.projects', unique=True)),
+ ],
+ ),
+ ]
diff --git a/FusionIIIT/applications/iwdModuleV2/models.py b/FusionIIIT/applications/iwdModuleV2/models.py
index a5c40c7b2..e4c09f3cc 100644
--- a/FusionIIIT/applications/iwdModuleV2/models.py
+++ b/FusionIIIT/applications/iwdModuleV2/models.py
@@ -1,5 +1,5 @@
from django.db import models
-
+from datetime import date
# Create your models here.
@@ -160,3 +160,40 @@ class NoOfTechnicalBidTimes(models.Model):
key = models.ForeignKey(Projects, on_delete=models.CASCADE, unique=True)
number = models.IntegerField()
+class Requests(models.Model):
+ # id = models.IntegerField(primary_key=True, max_length=200)
+ name = models.CharField(max_length=200)
+ description = models.CharField(max_length=200)
+ area = models.CharField(max_length=200)
+ requestCreatedBy = models.CharField(max_length=200)
+ engineerProcessed = models.IntegerField()
+ directorApproval = models.IntegerField()
+ deanProcessed = models.IntegerField()
+ status = models.CharField(max_length=200)
+ issuedWorkOrder = models.IntegerField()
+ workCompleted = models.IntegerField()
+
+class WorkOrder(models.Model):
+ request_id = models.IntegerField()
+ name = models.CharField(max_length=200)
+ date = models.DateField(default=date.today)
+ agency = models.CharField(max_length=200)
+ amount = models.IntegerField()
+ deposit = models.IntegerField()
+ alloted_time = models.CharField(max_length=200)
+ start_date = models.DateField()
+ completion_date = models.DateField()
+
+class Inventory(models.Model):
+ name = models.CharField(max_length=200)
+ quantity = models.IntegerField()
+ cost = models.IntegerField()
+
+class Bills(models.Model):
+ key = models.ForeignKey(Projects, on_delete=models.CASCADE, unique=True)
+ name = models.CharField(max_length=200)
+ work = models.CharField(max_length=200)
+ description = models.CharField(max_length=200)
+ agency = models.CharField(max_length=200)
+ bill_processed = models.IntegerField()
+ bill_settled = models.IntegerField()
\ No newline at end of file
diff --git a/FusionIIIT/applications/iwdModuleV2/urls.py b/FusionIIIT/applications/iwdModuleV2/urls.py
index 6ad401098..1530d11c5 100644
--- a/FusionIIIT/applications/iwdModuleV2/urls.py
+++ b/FusionIIIT/applications/iwdModuleV2/urls.py
@@ -36,5 +36,28 @@
url(r'milestoneView/$', views.milestoneView, name='Milestones'),
url(r'addendumView/$', views.addendumView, name='Addendum View'),
url('agreementView/$', views.agreementView, name='Agreement VIew'),
- url(r'corrigendumView/$', views.corrigendumView, name='Corrigendum View')
+ url(r'corrigendumView/$', views.corrigendumView, name='Corrigendum View'),
+ url('requestsView/',views.requestsView, name='Requests view'),
+ url('createdRequestsView/',views.createdRequests, name='Created Requests view'),
+ url('handleEngineerProcessRequests/', views.handleEngineerProcessRequests, name='Engineer-Process-Requests'),
+ url('engineerProcessedRequestsView/',views.engineerProcessedRequests, name='Engineer-Processed-Requests view'),
+ url('handleDeanProcessRequests/', views.handleDeanProcessRequests, name='Dean-Process-Requests'),
+ url('deanProcessedRequestsView/',views.deanProcessedRequests, name='Dean-Processed-Requests view'),
+ url('handleDirectorApprovalRequests/', views.handleDirectorApprovalRequests, name='Director-Approval-Requests'),
+ url('handleDirectorRejectionRequests/', views.handleDirectorRejectionRequests, name='Director-Rejection-Requests'),
+ url('requestsStatus/', views.requestsStatus, name='Requests-Status'),
+ url('fetchDesignations/', views.fetchDesignations, name='Fetch-Designations'),
+ url('fetchRequest/', views.fetchRequest, name='Fetch-Request'),
+ url('issueWorkOrder/', views.issueWorkOrder, name='Issue Work Order'),
+ url('workOrder/', views.workOrder, name='Work Order'),
+ url('inventory/', views.inventory, name='Inventory'),
+ url('addItemsView/', views.addItemsView, name='Add Items View'),
+ url('addItems/', views.addItems, name='Add Items'),
+ url('editInventoryView/', views.editInventoryView, name='Edit Inventory View'),
+ url('editInventory/', views.editInventory, name='Edit Inventory'),
+ url('requestsInProgess/', views.requestsInProgess, name='Requests In Progress'),
+ url('workCompleted/', views.workCompleted, name='Work Completed'),
+ url('requestFromInventory/', views.requestFromInventory, name='Request From Inventory'),
+ # url('billsView/',views.billsView, name='Bills View'),
+
]
diff --git a/FusionIIIT/applications/iwdModuleV2/views.py b/FusionIIIT/applications/iwdModuleV2/views.py
index 7cc9cf67c..25c299199 100644
--- a/FusionIIIT/applications/iwdModuleV2/views.py
+++ b/FusionIIIT/applications/iwdModuleV2/views.py
@@ -1,9 +1,11 @@
from django.shortcuts import render, redirect
-
+from django.urls import reverse
+from django.db.models import Q
from applications.globals.models import *
from .models import *
from django.http import HttpResponseRedirect
-
+from applications.filetracking.sdk.methods import *
+from applications.globals.models import ExtraInfo, HoldsDesignation, Designation
# Create your views here.
@@ -17,17 +19,24 @@
# owing to length and inherent extensiveness of code. Rather than, whosoever read this code is advised to do so
# in conjunction with SRS. After that, everything will become easier.
+# def dashboard(request):
+# eligible = False
+# userObj = request.user
+# userDesignationObjects = HoldsDesignation.objects.filter(user=userObj)
+# for p in userDesignationObjects:
+# if p.designation.name == 'Admin IWD':
+# eligible = True
+# break
+# return render(request, 'iwdModuleV2/dashboard.html', {'eligible': eligible})
+
def dashboard(request):
- eligible = True
+ eligible = ""
userObj = request.user
userDesignationObjects = HoldsDesignation.objects.filter(user=userObj)
for p in userDesignationObjects:
- if p.designation.name == 'Admin IWD':
- eligible = True
- break
+ eligible = p.designation.name
return render(request, 'iwdModuleV2/dashboard.html', {'eligible': eligible})
-
def page1_1(request):
if request.method == 'POST':
formObject = PageOneDetails()
@@ -434,3 +443,434 @@ def extensionFormView(request):
extensionObjects = ExtensionOfTimeDetails.objects.filter(
key=Projects.objects.get(id=request.session['projectId']))
return render(request, 'iwdModuleV2/ExtensionForm.html', {'extension': extensionObjects})
+
+def fetchDesignations(request):
+ print("yesslkednonmedcm")
+ designations = Designation.objects.filter()
+
+ holdsDesignations = []
+
+ for d in designations:
+ if d.name == "Engineer" or d.name == "Dean" or d.name == "director" or d.name == "Accounts Admin":
+ list = HoldsDesignation.objects.filter(designation=d)
+ holdsDesignations.append(list)
+
+ return render(request, 'iwdModuleV2/requestsView.html', {'holdsDesignations' : holdsDesignations})
+
+def requestsView(request):
+ if request.method == 'POST':
+ formObject = Requests()
+ # formObject.key = Projects.objects.get(id=request.session['projectId'])
+ formObject.name = request.POST['name']
+ formObject.description = request.POST['description']
+ formObject.area = request.POST['area']
+ formObject.engineerProcessed = 0
+ formObject.directorApproval = 0
+ formObject.deanProcessed = 0
+ formObject.requestCreatedBy = request.user.username
+ formObject.status = "Pending"
+ formObject.issuedWorkOrder = 0
+ formObject.workCompleted = 0
+ formObject.save()
+ request_object = Requests.objects.get(pk=formObject.pk)
+ d = HoldsDesignation.objects.get(user__username=request.POST['designation'])
+ create_file(uploader=request.user.username,
+ uploader_designation="Engineer",
+ receiver=request.POST['designation'],
+ receiver_designation=d.designation,
+ src_module="IWD",
+ src_object_id= str(request_object.id),
+ file_extra_JSON= {"value": 2},
+ attached_file = None)
+ return redirect('http://127.0.0.1:8000/iwdModuleV2/')
+ return render(request, 'http://127.0.0.1:8000/iwdModuleV2/', {})
+
+def createdRequests(request):
+ obj = []
+
+ inbox_files = view_inbox(
+ username=request.user,
+ designation="Engineer",
+ src_module="IWD"
+ )
+
+ for result in inbox_files:
+ src_object_id = result['src_object_id']
+ request_object = Requests.objects.filter(id=src_object_id).first()
+ if request_object:
+ element = [request_object.id, request_object.name, request_object.area, request_object.description, request_object.requestCreatedBy]
+ obj.append(element)
+
+ designations = Designation.objects.filter()
+
+ holdsDesignations = []
+
+ for d in designations:
+ if d.name == "Engineer" or d.name == "Dean" or d.name == "director" or d.name == "Accounts Admin":
+ list = HoldsDesignation.objects.filter(designation=d)
+ holdsDesignations.append(list)
+
+ return render(request, 'iwdModuleV2/createdRequests.html', {'obj' : obj, 'holdsDesignations' : holdsDesignations})
+
+def handleEngineerProcessRequests(request):
+ if request.method == 'POST':
+
+ request_id = request.POST.get("id", 0)
+
+ d = HoldsDesignation.objects.get(user__username=request.POST['designation'])
+ d1 = HoldsDesignation.objects.get(user__username=request.user)
+
+ create_file(uploader=request.user.username,
+ uploader_designation=d1.designation,
+ receiver=request.POST['designation'],
+ receiver_designation=d.designation,
+ src_module="IWD",
+ src_object_id= str(request_id),
+ file_extra_JSON= {"value": 2},
+ attached_file = None)
+
+ Requests.objects.filter(id=request_id).update(engineerProcessed=1, status="Approved by the engineer")
+
+ inbox_files = view_inbox(
+ username=request.user,
+ designation=d1.designation,
+ src_module="IWD"
+ )
+
+ for p in inbox_files:
+ if p['src_object_id'] == request_id:
+ delete_file(file_id = p['id'])
+ break
+
+ inbox_files = view_inbox(
+ username=request.user,
+ designation=d1.designation,
+ src_module="IWD"
+ )
+
+ obj = []
+ for result in inbox_files:
+ src_object_id = result['src_object_id']
+ request_object = Requests.objects.filter(id=src_object_id).first()
+ if request_object:
+ element = [request_object.id, request_object.name, request_object.area, request_object.description, request_object.requestCreatedBy]
+ obj.append(element)
+
+ return render(request, 'iwdModuleV2/createdRequests.html', {'obj' : obj})
+
+def engineerProcessedRequests(request):
+
+ obj = []
+
+ d = HoldsDesignation.objects.get(user__username=request.user)
+
+ inbox_files = view_inbox(
+ username=request.user,
+ designation=d.designation,
+ src_module="IWD"
+ )
+
+ for result in inbox_files:
+ src_object_id = result['src_object_id']
+ request_object = Requests.objects.filter(id=src_object_id).first()
+ if request_object:
+ element = [request_object.id, request_object.name, request_object.area, request_object.description, request_object.requestCreatedBy]
+ obj.append(element)
+
+ designations = Designation.objects.filter()
+
+ holdsDesignations = []
+
+ for d in designations:
+ if d.name == "Engineer" or d.name == "Dean" or d.name == "director" or d.name == "Accounts Admin":
+ list = HoldsDesignation.objects.filter(designation=d)
+ holdsDesignations.append(list)
+
+ return render(request, 'iwdModuleV2/engineerProcessedRequests.html', {'obj' : obj, 'holdsDesignations' : holdsDesignations})
+
+def handleDeanProcessRequests(request):
+ if request.method == 'POST':
+
+ request_id = request.POST.get("id", 0)
+
+ d = HoldsDesignation.objects.get(user__username=request.POST['designation'])
+ d1 = HoldsDesignation.objects.get(user__username=request.user)
+
+ create_file(uploader=request.user.username,
+ uploader_designation=d1.designation,
+ receiver=request.POST['designation'],
+ receiver_designation=d.designation,
+ src_module="IWD",
+ src_object_id= str(request_id),
+ file_extra_JSON= {"value": 2},
+ attached_file = None)
+
+ Requests.objects.filter(id=request_id).update(deanProcessed=1, status="Approved by the dean")
+
+ inbox_files = view_inbox(
+ username=request.user,
+ designation=d1.designation,
+ src_module="IWD"
+ )
+
+ for p in inbox_files:
+ if p['src_object_id'] == request_id:
+ delete_file(file_id = p['id'])
+ break
+
+ inbox_files = view_inbox(
+ username=request.user,
+ designation=d1.designation,
+ src_module="IWD"
+ )
+
+ obj = []
+ for result in inbox_files:
+ src_object_id = result['src_object_id']
+ request_object = Requests.objects.filter(id=src_object_id).first()
+ if request_object:
+ element = [request_object.id, request_object.name, request_object.area, request_object.description, request_object.requestCreatedBy]
+ obj.append(element)
+
+ return render(request, 'iwdModuleV2/engineerProcessedRequests.html', {'obj' : obj})
+
+def deanProcessedRequests(request):
+ obj = []
+
+ d = HoldsDesignation.objects.get(user__username=request.user)
+
+ inbox_files = view_inbox(
+ username=request.user,
+ designation=d.designation,
+ src_module="IWD"
+ )
+
+ for result in inbox_files:
+ src_object_id = result['src_object_id']
+ request_object = Requests.objects.filter(id=src_object_id).first()
+ if request_object:
+ element = [request_object.id, request_object.name, request_object.area, request_object.description, request_object.requestCreatedBy]
+ obj.append(element)
+
+ designations = Designation.objects.filter()
+
+ holdsDesignations = []
+
+ for d in designations:
+ if d.name == "Engineer" or d.name == "Dean" or d.name == "director" or d.name == "Accounts Admin":
+ list = HoldsDesignation.objects.filter(designation=d)
+ holdsDesignations.append(list)
+
+ return render(request, 'iwdModuleV2/deanProcessedRequests.html', {'obj' : obj, 'holdsDesignations' : holdsDesignations})
+
+def handleDirectorApprovalRequests(request):
+ if request.method == 'POST':
+ request_id = request.POST.get("id", 0)
+
+ d = HoldsDesignation.objects.get(user__username=request.POST['designation'])
+ d1 = HoldsDesignation.objects.get(user__username=request.user)
+
+ create_file(uploader=request.user.username,
+ uploader_designation=d1.designation,
+ receiver=request.POST['designation'],
+ receiver_designation=d.designation,
+ src_module="IWD",
+ src_object_id= str(request_id),
+ file_extra_JSON= {"value": 2},
+ attached_file = None)
+
+ Requests.objects.filter(id=request_id).update(directorApproval=1, status="Approved by the director")
+
+ inbox_files = view_inbox(
+ username=request.user,
+ designation=d1.designation,
+ src_module="IWD"
+ )
+
+ for p in inbox_files:
+ if p['src_object_id'] == request_id:
+ delete_file(file_id = p['id'])
+ break
+
+ inbox_files = view_inbox(
+ username=request.user,
+ designation=d1.designation,
+ src_module="IWD"
+ )
+
+ obj = []
+ for result in inbox_files:
+ src_object_id = result['src_object_id']
+ request_object = Requests.objects.filter(id=src_object_id).first()
+ if request_object:
+ element = [request_object.id, request_object.name, request_object.area, request_object.description, request_object.requestCreatedBy]
+ obj.append(element)
+
+ return render(request, 'iwdModuleV2/deanProcessedRequests.html', {'obj' : obj})
+
+def handleDirectorRejectionRequests(request):
+ if request.method == 'POST':
+ request_id = request.POST.get("id", 0)
+ Requests.objects.filter(id=request_id).update(directorApproval=-1, status="Rejected by the director")
+ obj = []
+ requestsObject = Requests.objects.filter(engineerProcessed = 1, deanProcessed = 1, directorApproval = 0)
+ for x in requestsObject:
+ element = [x.id, x.name, x.area, x.description, x.requestCreatedBy]
+ obj.append(element)
+ return render(request, 'iwdModuleV2/deanProcessedRequests.html', {'obj' : obj})
+
+def issueWorkOrder(request):
+ obj = []
+
+ d = HoldsDesignation.objects.get(user__username=request.user)
+
+ inbox_files = view_inbox(
+ username=request.user,
+ designation=d.designation,
+ src_module="IWD"
+ )
+
+ for result in inbox_files:
+ uploader = result['sent_by_designation']
+ if uploader == 'director':
+ src_object_id = result['src_object_id']
+ request_object = Requests.objects.filter(id=src_object_id).first()
+ if request_object:
+ element = [request_object.id, request_object.name, request_object.area, request_object.description, request_object.requestCreatedBy]
+ obj.append(element)
+
+ return render(request, 'iwdModuleV2/issueWorkOrder.html', {'obj' : obj})
+
+def fetchRequest(request):
+ request_id = request.POST.get("id", 0)
+ req_request = Requests.objects.get(id=request_id)
+ return render(request, 'iwdModuleV2/workOrder.html', {'req' : req_request})
+
+def workOrder(request):
+ if request.method == 'POST':
+ formObject = WorkOrder()
+ formObject.request_id = request.POST['id']
+ formObject.name = request.POST['name']
+ formObject.date = request.POST['date']
+ formObject.agency = request.POST['agency']
+ formObject.amount = request.POST['amount']
+ formObject.deposit = request.POST['deposit']
+ formObject.alloted_time = request.POST['time']
+ formObject.start_date = request.POST['startDate']
+ formObject.completion_date = request.POST['completionDate']
+ formObject.save()
+
+ Requests.objects.filter(id=request.POST['id']).update(status="Work Order issued", issuedWorkOrder=1)
+
+ d = HoldsDesignation.objects.get(user__username=request.user)
+
+ inbox_files = view_inbox(
+ username=request.user,
+ designation=d.designation,
+ src_module="IWD"
+ )
+
+ for result in inbox_files:
+ if result['src_object_id'] == request.POST['id'] and result['sent_by_designation'] == 'director':
+ delete_file(file_id = result['id'])
+ break
+
+ inbox_files = view_inbox(
+ username=request.user,
+ designation=d.designation,
+ src_module="IWD"
+ )
+
+ obj = []
+
+ for result in inbox_files:
+ uploader = result['sent_by_designation']
+ if uploader == 'director':
+ src_object_id = result['src_object_id']
+ request_object = Requests.objects.filter(id=src_object_id).first()
+ if request_object:
+ element = [request_object.id, request_object.name, request_object.area, request_object.description, request_object.requestCreatedBy]
+ obj.append(element)
+
+ return render(request, 'iwdModuleV2/issueWorkOrder.html', {'obj' : obj})
+
+def requestsStatus(request):
+ obj = []
+ requestsObject = Requests.objects.all()
+ for x in requestsObject:
+ element = [x.id, x.name, x.area, x.description, x.requestCreatedBy, x.status]
+ obj.append(element)
+ return render(request, 'iwdModuleV2/requestsStatus.html', {'obj' : obj})
+
+def inventory(request):
+ items = Inventory.objects.filter()
+ obj = []
+ for i in items:
+ element = [i.id, i.name, i.quantity, i.cost]
+ obj.append(element)
+ return render(request, 'iwdModuleV2/inventory.html', {'obj' : obj})
+
+def addItemsView(request):
+ return render(request, 'iwdModuleV2/addItemsView.html')
+
+def addItems(request):
+ if request.method == "POST":
+ formObject = Inventory()
+ formObject.name = request.POST['name']
+ formObject.quantity = request.POST['quantity']
+ formObject.cost = request.POST['cost']
+ formObject.save()
+ return render(request, 'iwdModuleV2/addItemsView.html')
+
+def editInventoryView(request):
+ items = Inventory.objects.filter()
+ obj = []
+ for i in items:
+ element = [i.id, i.name, i.quantity, i.cost]
+ obj.append(element)
+ return render(request, 'iwdModuleV2/editInventory.html', {'obj' : obj})
+
+def editInventory(request):
+ if request.method == "POST":
+ itemId = request.POST['id']
+ itemName = request.POST['name']
+ itemQuantity = request.POST['quantity']
+ itemCost = request.POST['cost']
+ Inventory.objects.filter(id=itemId).update(name=itemName, quantity=itemQuantity, cost=itemCost)
+ items = Inventory.objects.filter()
+ obj = []
+ for i in items:
+ element = [i.id, i.name, i.quantity, i.cost]
+ obj.append(element)
+ return render(request, 'iwdModuleV2/editInventory.html', {'obj' : obj})
+
+def requestsInProgess(request):
+ obj = []
+ requestsObject = Requests.objects.filter(issuedWorkOrder=1)
+ for x in requestsObject:
+ element = [x.id, x.name, x.area, x.description, x.requestCreatedBy, x.workCompleted]
+ obj.append(element)
+ return render(request, 'iwdModuleV2/requestsInProgress.html', {'obj' : obj})
+
+def workCompleted(request):
+ if request.method == 'POST':
+ Requests.objects.filter(id=request.POST['id']).update(workCompleted=1, status="Work Completed")
+ obj = []
+ requestsObject = Requests.objects.filter(issuedWorkOrder=1)
+ for x in requestsObject:
+ element = [x.id, x.name, x.area, x.description, x.requestCreatedBy, x.workCompleted]
+ obj.append(element)
+ return render(request, 'iwdModuleV2/requestsInProgress.html', {'obj' : obj})
+
+def requestFromInventory(request):
+ if request.method == 'POST':
+ requestId = request.POST['id']
+ Req = Requests.objects.filter(id=requestId)
+ Items = Inventory.objects.filter()
+ req = []
+ items = []
+ for i in Req:
+ print(i)
+ print(req)
+ print(items)
+ return render(request, 'iwdModuleV2/requestFromInventory.html', {'req' : req, 'items' : items})
\ No newline at end of file
diff --git a/FusionIIIT/applications/programme_curriculum/migrations/0002_auto_20240308_1023.py b/FusionIIIT/applications/programme_curriculum/migrations/0002_auto_20240308_1023.py
new file mode 100644
index 000000000..fef68f722
--- /dev/null
+++ b/FusionIIIT/applications/programme_curriculum/migrations/0002_auto_20240308_1023.py
@@ -0,0 +1,23 @@
+# Generated by Django 3.1.5 on 2024-03-08 10:23
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('programme_curriculum', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='batch',
+ name='year',
+ field=models.PositiveIntegerField(default=2024),
+ ),
+ migrations.AlterField(
+ model_name='programme',
+ name='programme_begin_year',
+ field=models.PositiveIntegerField(default=2024),
+ ),
+ ]
diff --git a/FusionIIIT/applications/scholarships/migrations/0002_auto_20240308_1023.py b/FusionIIIT/applications/scholarships/migrations/0002_auto_20240308_1023.py
new file mode 100644
index 000000000..997db0247
--- /dev/null
+++ b/FusionIIIT/applications/scholarships/migrations/0002_auto_20240308_1023.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.1.5 on 2024-03-08 10:23
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('scholarships', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='previous_winner',
+ name='year',
+ field=models.IntegerField(default=2024),
+ ),
+ ]
diff --git a/FusionIIIT/templates/academic_procedures/academic.html b/FusionIIIT/templates/academic_procedures/academic.html
old mode 100755
new mode 100644
index 6b04a54fb..35eebf446
--- a/FusionIIIT/templates/academic_procedures/academic.html
+++ b/FusionIIIT/templates/academic_procedures/academic.html
@@ -22,6 +22,39 @@
}
+
+
{% endblock css %}
@@ -30,13 +63,12 @@
{% include 'dashboard/navbar.html' %}
{% endblock %}
-
+
- {% comment %}The left-margin segment!{% endcomment %}
-
+
{% comment %}The left-rail segment starts here!{% endcomment %}
-
+
{% comment %}The user image card starts here!{% endcomment %}
{% block usercard %}
{% include 'globals/usercard.html' %}
@@ -46,8 +78,8 @@
{% comment %}The Tab-Menu starts here!{% endcomment %}
-