diff --git a/.all-contributorsrc b/.all-contributorsrc new file mode 100644 index 0000000..0855b9d --- /dev/null +++ b/.all-contributorsrc @@ -0,0 +1,26 @@ +{ + "files": [ + "README.md" + ], + "imageSize": 100, + "commit": false, + "commitType": "docs", + "commitConvention": "angular", + "contributors": [ + { + "login": "joisemp", + "name": "Joise MP", + "avatar_url": "https://avatars.githubusercontent.com/u/69669027?v=4", + "profile": "https://github.com/joisemp", + "contributions": [ + "code" + ] + } + ], + "contributorsPerLine": 7, + "skipCi": true, + "repoType": "github", + "repoHost": "https://github.com", + "projectName": "inventory-management-system", + "projectOwner": "joisemp" +} diff --git a/README.md b/README.md index 99108c6..7eb1feb 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,25 @@ # inventory-management-system + +[![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors-) + Inventory management system for labs + +## Contributors ✨ + +Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): + + + + + + + + + + +
Joise MP
Joise MP

💻
+ + + + + diff --git a/core/migrations/0002_userprofile_dept_delete_department.py b/core/migrations/0002_userprofile_dept_delete_department.py deleted file mode 100644 index 3336c4f..0000000 --- a/core/migrations/0002_userprofile_dept_delete_department.py +++ /dev/null @@ -1,24 +0,0 @@ -# Generated by Django 4.2 on 2024-06-20 06:08 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('org', '0002_department'), - ('lab', '0002_alter_lab_dept'), - ('core', '0001_initial'), - ] - - operations = [ - migrations.AddField( - model_name='userprofile', - name='dept', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='org.department'), - ), - migrations.DeleteModel( - name='Department', - ), - ] diff --git a/core/migrations/0003_alter_userprofile_user.py b/core/migrations/0003_alter_userprofile_user.py deleted file mode 100644 index 7432ba0..0000000 --- a/core/migrations/0003_alter_userprofile_user.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 4.2 on 2024-08-05 15:39 - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('core', '0002_userprofile_dept_delete_department'), - ] - - operations = [ - migrations.AlterField( - model_name='userprofile', - name='user', - field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, related_name='profile', serialize=False, to=settings.AUTH_USER_MODEL), - ), - ] diff --git a/core/templates/core/add-user-form.html b/core/templates/core/add-user-form.html deleted file mode 100644 index 60452fd..0000000 --- a/core/templates/core/add-user-form.html +++ /dev/null @@ -1,36 +0,0 @@ -{% extends 'base.html' %} -{% load static %} -{% block style %} - -{% endblock style %} - - -{% block content %} -
-
-
-

Add Staff

-
- {% csrf_token %} -
- - -
-
- - -
-
- - -
- - -
- -
-
-
-
-
-{% endblock content %} diff --git a/core/views.py b/core/views.py deleted file mode 100644 index b8b1412..0000000 --- a/core/views.py +++ /dev/null @@ -1,368 +0,0 @@ -from django.urls import reverse, reverse_lazy - -from lab.models import Lab -from core.utils import generate_password, get_lab_item_report_data, get_lab_report_data, get_lab_system_report_data, get_report_data -from django.views import generic -from django.contrib.auth import views -from django.contrib.auth import login -from django.shortcuts import redirect, render -from core.models import User, UserProfile -from org.models import Org -from core.account_activation_email import send_account_activation_mail -from core.token_generator import account_activation_token -from django.utils.http import urlsafe_base64_decode -from django.http import HttpResponse, HttpResponseForbidden -from django.utils.encoding import force_str -from core.forms import LabStaffCreationForm, CustomAuthenticationForm, CustomOrgRegisterForm -from lab.mixins import RedirectLoggedInUserMixin - -from django.template.loader import render_to_string -from xhtml2pdf import pisa - - - -class LandingPageView(RedirectLoggedInUserMixin, generic.TemplateView): - template_name = 'landing_page.html' - - -class UserRegisterView(generic.CreateView): - form_class = CustomOrgRegisterForm - template_name = 'core/register-user.html' - - def form_valid(self, form): - user = form.save(commit=False) - user.is_active = False - user.save() - first_name = form.cleaned_data.get('first_name') - last_name = form.cleaned_data.get('last_name') - org_name = form.cleaned_data.get('org_name') - org_address = form.cleaned_data.get('org_address') - org_email = form.cleaned_data.get('org_email') - org_website_url = form.cleaned_data.get('org_website_url') - - org = Org.objects.create( - org_name=org_name, - contact = org_email, - website_url = org_website_url, - address = org_address - ) - - UserProfile.objects.create( - user = user, - org = org, - first_name = first_name, - last_name = last_name, - is_org_admin = True - ) - - send_account_activation_mail(self.request, user, email = user.email) - return super(UserRegisterView, self).form_valid(form) - - def get_success_url(self): - return reverse('core:login') - - -class LoginView(views.LoginView): - form_class = CustomAuthenticationForm - template_name = 'core/login.html' - - def form_valid(self, form): - login(self.request, form.get_user()) - return redirect('landing-page') - - -class LogoutView(views.LogoutView): - template_name = 'core/logout.html' - - -class ChangePasswordView(views.PasswordChangeView): - template_name = 'core/change-password.html' - success_url = reverse_lazy('landing-page') - - -class ResetPasswordView(views.PasswordResetView): - email_template_name = 'core/password_reset/password_reset_email.html' - html_email_template_name = 'core/password_reset/password_reset_email.html' - subject_template_name = 'core/password_reset/password_reset_subject.txt' - success_url = reverse_lazy('core:done-password-reset') - template_name = 'core/password_reset/password_reset_form.html' - - -class DonePasswordResetView(views.PasswordResetDoneView): - template_name = 'core/password_reset/password_reset_done.html' - - -class ConfirmPasswordResetView(views.PasswordResetConfirmView): - success_url = reverse_lazy('core:complete-password-reset') - template_name = 'core/password_reset/password_reset_confirm.html' - - -class CompletePasswordResetView(views.PasswordResetCompleteView): - template_name = 'core/password_reset/password_reset_complete.html' - -""" -class AddUserView(generic.CreateView): - fields = ['email', 'first_name', 'last_name'] - model = User - template_name = 'core/add-user-form.html' - - def form_valid(self, form): - email = form.cleaned_data.get('email') - password = str(generate_password()) - first_name = form.cleaned_data.get('first_name') - last_name = form.cleaned_data.get('last_name') - - user = User.objects.create( - email=email, - password=password, - ) - - return redirect('lab:lab-list') -""" - -class LabStaffCreateView(generic.FormView): - model = User - template_name = 'core/lab-staff-create.html' - form_class = LabStaffCreationForm - - def form_valid(self, form): - email = form.cleaned_data.get('email') - password = str(generate_password()) - first_name = form.cleaned_data.get('first_name') - last_name = form.cleaned_data.get('last_name') - org_id = self.kwargs["org_id"] - org = Org.objects.get(pk=org_id) - - user = User.objects.create( - email=email, - password=password, - ) - - user_profile = UserProfile.objects.create( - first_name = first_name, - last_name = last_name, - user = user, - org = org, - is_lab_staff = True - ) - - return super().form_valid(form) - - def get_success_url(self): - org_id = self.kwargs["org_id"] - dept_id = self.kwargs["dept_id"] - return reverse('org:lab:lab-create', kwargs={'org_id':org_id, 'dept_id':dept_id}) - - -class DeptIncargeCreateView(generic.FormView): - model = User - form_class = LabStaffCreationForm - - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) - context["org_id"] = self.kwargs["org_id"] - return context - - def form_valid(self, form): - email = form.cleaned_data.get('email') - password = str(generate_password()) - first_name = form.cleaned_data.get('first_name') - last_name = form.cleaned_data.get('last_name') - org = Org.objects.get(pk=self.kwargs["org_id"]) - - user = User.objects.create( - email=email, - password=password, - ) - - UserProfile.objects.create( - first_name = first_name, - last_name = last_name, - user = user, - org = org, - is_dept_incharge = True - ) - - return super().form_valid(form) - - def get_success_url(self): - org_id = self.kwargs["org_id"] - return reverse('dept-create', kwargs={'org_id':org_id}) - - -class ActivateAccountView(generic.View): - def get(self, request, uidb64, token): - try: - uid = force_str(urlsafe_base64_decode(uidb64)) - user = User.objects.get(pk=uid) - except (TypeError, ValueError, OverflowError, User.DoesNotExist): - user = None - - if user is not None and account_activation_token.check_token(user, token): - user.is_active = True - user.save() - return render(request, 'core/account-verified.html') - else: - return render(request, 'core/account-verified.html') - - -class GenerateReportView(generic.View): - def get(self, request, org_id): - if not request.user.is_authenticated: - return HttpResponseForbidden() - - userprofile = UserProfile.objects.get(user=request.user) - org = userprofile.org - - report = get_report_data(org) - - print(report) - - # Combine report data - report_data = { - 'organization_name': org.org_name, - 'lab_count':len(report), - 'lab_report': report - } - - - # Render HTML template - template_name = 'core/report.html' # Replace with your actual template name - html = render_to_string(template_name, report_data) - - # Configure xhtml2pdf options (optional) - pdf_options = { - 'page-size': 'A4', # Set desired page size - 'encoding': 'utf-8', # Set encoding for text content - } - - # Generate PDF - response = HttpResponse(content_type='application/pdf') - response['Content-Disposition'] = f'attachment; filename=report_{org.org_name}.pdf' - - result = pisa.CreatePDF(html, dest=response, options=pdf_options) - if result.err: - return HttpResponse('Error: {}'.format(result.err)) # Handle errors - - return response - - - -class GenerateLabReportView(generic.View): - def get(self, request, org_id, dept_id, lab_id): - if not request.user.is_authenticated: - return HttpResponseForbidden() - - userprofile = UserProfile.objects.get(user=request.user) - org = userprofile.org - lab = Lab.objects.get(pk = lab_id) - - report = get_lab_report_data(lab) - - - # Combine report data - report_data = { - 'organization_name': org.org_name, - 'lab': report - } - - - # Render HTML template - template_name = 'core/lab-report.html' # Replace with your actual template name - html = render_to_string(template_name, report_data) - - # Configure xhtml2pdf options (optional) - pdf_options = { - 'page-size': 'A4', # Set desired page size - 'encoding': 'utf-8', # Set encoding for text content - } - - # Generate PDF - response = HttpResponse(content_type='application/pdf') - response['Content-Disposition'] = f'attachment; filename=report_{org.org_name}.pdf' - - result = pisa.CreatePDF(html, dest=response, options=pdf_options) - if result.err: - return HttpResponse('Error: {}'.format(result.err)) # Handle errors - - return response - - -class GenerateLabItemReportView(generic.View): - def get(self, request, org_id, dept_id, lab_id): - if not request.user.is_authenticated: - return HttpResponseForbidden() - - userprofile = UserProfile.objects.get(user=request.user) - org = userprofile.org - lab = Lab.objects.get(pk = lab_id) - - report = get_lab_item_report_data(lab) - - - # Combine report data - report_data = { - 'organization_name': org.org_name, - 'lab': report - } - - - # Render HTML template - template_name = 'core/lab-report.html' # Replace with your actual template name - html = render_to_string(template_name, report_data) - - # Configure xhtml2pdf options (optional) - pdf_options = { - 'page-size': 'A4', # Set desired page size - 'encoding': 'utf-8', # Set encoding for text content - } - - # Generate PDF - response = HttpResponse(content_type='application/pdf') - response['Content-Disposition'] = f'attachment; filename=report_{org.org_name}.pdf' - - result = pisa.CreatePDF(html, dest=response, options=pdf_options) - if result.err: - return HttpResponse('Error: {}'.format(result.err)) # Handle errors - - return response - - -class GenerateLabSystemReportView(generic.View): - def get(self, request, org_id, dept_id, lab_id): - if not request.user.is_authenticated: - return HttpResponseForbidden() - - userprofile = UserProfile.objects.get(user=request.user) - org = userprofile.org - lab = Lab.objects.get(pk = lab_id) - - report = get_lab_system_report_data(lab) - - - # Combine report data - report_data = { - 'organization_name': org.org_name, - 'lab': report - } - - - # Render HTML template - template_name = 'core/lab-report.html' # Replace with your actual template name - html = render_to_string(template_name, report_data) - - # Configure xhtml2pdf options (optional) - pdf_options = { - 'page-size': 'A4', # Set desired page size - 'encoding': 'utf-8', # Set encoding for text content - } - - # Generate PDF - response = HttpResponse(content_type='application/pdf') - response['Content-Disposition'] = f'attachment; filename=report_{org.org_name}.pdf' - - result = pisa.CreatePDF(html, dest=response, options=pdf_options) - if result.err: - return HttpResponse('Error: {}'.format(result.err)) # Handle errors - - return response \ No newline at end of file diff --git a/lab/migrations/0002_alter_lab_dept.py b/lab/migrations/0002_alter_lab_dept.py deleted file mode 100644 index 480f3f9..0000000 --- a/lab/migrations/0002_alter_lab_dept.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 4.2 on 2024-06-20 06:08 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('org', '0002_department'), - ('lab', '0001_initial'), - ] - - operations = [ - migrations.AlterField( - model_name='lab', - name='dept', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='org.department'), - ), - ] diff --git a/lab/migrations/0003_remove_system_cpu_cabin_remove_system_hdd_and_more.py b/lab/migrations/0003_remove_system_cpu_cabin_remove_system_hdd_and_more.py deleted file mode 100644 index 2841492..0000000 --- a/lab/migrations/0003_remove_system_cpu_cabin_remove_system_hdd_and_more.py +++ /dev/null @@ -1,65 +0,0 @@ -# Generated by Django 4.2 on 2024-06-30 07:07 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('lab', '0002_alter_lab_dept'), - ] - - operations = [ - migrations.RemoveField( - model_name='system', - name='cpu_cabin', - ), - migrations.RemoveField( - model_name='system', - name='hdd', - ), - migrations.RemoveField( - model_name='system', - name='keyboard', - ), - migrations.RemoveField( - model_name='system', - name='monitor', - ), - migrations.RemoveField( - model_name='system', - name='mouse', - ), - migrations.RemoveField( - model_name='system', - name='os', - ), - migrations.RemoveField( - model_name='system', - name='processor', - ), - migrations.RemoveField( - model_name='system', - name='ram', - ), - migrations.AddField( - model_name='system', - name='last_updated', - field=models.DateTimeField(auto_now=True), - ), - migrations.CreateModel( - name='SystemComponent', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('component_type', models.CharField(choices=[('mouse', 'Mouse'), ('keyboard', 'Keyboard'), ('processor', 'Processor'), ('ram', 'RAM'), ('storage', 'HDD/SSD'), ('os', 'Operating System'), ('monitor', 'Monitor'), ('cpu_cabin', 'CPU Cabin')], max_length=255)), - ('item', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lab.item')), - ('system', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lab.system')), - ], - ), - migrations.AddField( - model_name='system', - name='components', - field=models.ManyToManyField(related_name='systems', through='lab.SystemComponent', to='lab.item'), - ), - ] diff --git a/lab/migrations/0004_alter_system_status.py b/lab/migrations/0004_alter_system_status.py deleted file mode 100644 index cfb21ff..0000000 --- a/lab/migrations/0004_alter_system_status.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.2 on 2024-06-30 07:16 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('lab', '0003_remove_system_cpu_cabin_remove_system_hdd_and_more'), - ] - - operations = [ - migrations.AlterField( - model_name='system', - name='status', - field=models.CharField(choices=[('working', 'Working'), ('not_working', 'Not working'), ('item_missing', 'Item missing')], default='item_missing', max_length=255), - ), - ] diff --git a/lab/migrations/0005_alter_system_status.py b/lab/migrations/0005_alter_system_status.py deleted file mode 100644 index 246cafb..0000000 --- a/lab/migrations/0005_alter_system_status.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.2 on 2024-06-30 07:16 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('lab', '0004_alter_system_status'), - ] - - operations = [ - migrations.AlterField( - model_name='system', - name='status', - field=models.CharField(choices=[('working', 'Working'), ('not_working', 'Not working'), ('item_missing', 'Item missing')], max_length=255), - ), - ] diff --git a/lab/migrations/0006_systemcomponent_serial_no_and_more.py b/lab/migrations/0006_systemcomponent_serial_no_and_more.py deleted file mode 100644 index e74e1a2..0000000 --- a/lab/migrations/0006_systemcomponent_serial_no_and_more.py +++ /dev/null @@ -1,25 +0,0 @@ -# Generated by Django 4.2 on 2024-07-09 17:11 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('lab', '0005_alter_system_status'), - ] - - operations = [ - migrations.AddField( - model_name='systemcomponent', - name='serial_no', - field=models.CharField(default=1, max_length=255), - preserve_default=False, - ), - migrations.AlterField( - model_name='systemcomponent', - name='system', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='lab.system'), - ), - ] diff --git a/lab/migrations/0007_remove_system_components.py b/lab/migrations/0007_remove_system_components.py deleted file mode 100644 index b880f2b..0000000 --- a/lab/migrations/0007_remove_system_components.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 4.2 on 2024-07-12 06:15 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('lab', '0006_systemcomponent_serial_no_and_more'), - ] - - operations = [ - migrations.RemoveField( - model_name='system', - name='components', - ), - ] diff --git a/lab/migrations/0008_alter_systemcomponent_component_type.py b/lab/migrations/0008_alter_systemcomponent_component_type.py deleted file mode 100644 index e8b7131..0000000 --- a/lab/migrations/0008_alter_systemcomponent_component_type.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.2 on 2024-07-27 06:44 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('lab', '0007_remove_system_components'), - ] - - operations = [ - migrations.AlterField( - model_name='systemcomponent', - name='component_type', - field=models.CharField(choices=[('Mouse', 'Mouse'), ('Keyboard', 'Keyboard'), ('Processor', 'Processor'), ('RAM', 'RAM'), ('Storage', 'Storage'), ('OS', 'OS'), ('Monitor', 'Monitor'), ('CPU Cabin', 'CPU Cabin')], max_length=255), - ), - ] diff --git a/lab/migrations/0009_itemrecord_remove_item_date_of_purchase_and_more.py b/lab/migrations/0009_itemrecord_remove_item_date_of_purchase_and_more.py deleted file mode 100644 index a95bd96..0000000 --- a/lab/migrations/0009_itemrecord_remove_item_date_of_purchase_and_more.py +++ /dev/null @@ -1,40 +0,0 @@ -# Generated by Django 4.2 on 2024-07-30 07:53 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('lab', '0008_alter_systemcomponent_component_type'), - ] - - operations = [ - migrations.CreateModel( - name='ItemRecord', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('qty', models.IntegerField()), - ('date', models.DateField(auto_now_add=True)), - ('remarks', models.TextField()), - ], - ), - migrations.RemoveField( - model_name='item', - name='date_of_purchase', - ), - migrations.DeleteModel( - name='LabRecord', - ), - migrations.AddField( - model_name='itemrecord', - name='item', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lab.item'), - ), - migrations.AddField( - model_name='itemrecord', - name='lab', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lab.lab'), - ), - ] diff --git a/lab/migrations/0010_itemremovalrecord_delete_itemrecord.py b/lab/migrations/0010_itemremovalrecord_delete_itemrecord.py deleted file mode 100644 index 394ad7b..0000000 --- a/lab/migrations/0010_itemremovalrecord_delete_itemrecord.py +++ /dev/null @@ -1,29 +0,0 @@ -# Generated by Django 4.2 on 2024-07-30 08:04 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('lab', '0009_itemrecord_remove_item_date_of_purchase_and_more'), - ] - - operations = [ - migrations.CreateModel( - name='ItemRemovalRecord', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('reason', models.CharField(choices=[('Depreciation', 'Depreciation'), ('Consumption', 'Consumption')], max_length=255)), - ('qty', models.IntegerField()), - ('date', models.DateField(auto_now_add=True)), - ('remarks', models.TextField()), - ('item', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lab.item')), - ('lab', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lab.lab')), - ], - ), - migrations.DeleteModel( - name='ItemRecord', - ), - ] diff --git a/lab/migrations/0011_alter_systemcomponent_system.py b/lab/migrations/0011_alter_systemcomponent_system.py deleted file mode 100644 index 4eb4ae0..0000000 --- a/lab/migrations/0011_alter_systemcomponent_system.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 4.2 on 2024-07-30 16:37 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('lab', '0010_itemremovalrecord_delete_itemrecord'), - ] - - operations = [ - migrations.AlterField( - model_name='systemcomponent', - name='system', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='lab.system'), - ), - ] diff --git a/lab/migrations/0012_alter_labsettings_lab.py b/lab/migrations/0012_alter_labsettings_lab.py deleted file mode 100644 index c8fc332..0000000 --- a/lab/migrations/0012_alter_labsettings_lab.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 4.2 on 2024-08-05 10:10 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('lab', '0011_alter_systemcomponent_system'), - ] - - operations = [ - migrations.AlterField( - model_name='labsettings', - name='lab', - field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='settings', to='lab.lab'), - ), - ] diff --git a/lab/migrations/0013_alter_lab_user.py b/lab/migrations/0013_alter_lab_user.py deleted file mode 100644 index 4649f0c..0000000 --- a/lab/migrations/0013_alter_lab_user.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 4.2 on 2024-08-05 10:14 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('core', '0002_userprofile_dept_delete_department'), - ('lab', '0012_alter_labsettings_lab'), - ] - - operations = [ - migrations.AlterField( - model_name='lab', - name='user', - field=models.ManyToManyField(related_name='assistants', to='core.userprofile'), - ), - ] diff --git a/lab/migrations/0014_alter_lab_user.py b/lab/migrations/0014_alter_lab_user.py deleted file mode 100644 index 0586e4d..0000000 --- a/lab/migrations/0014_alter_lab_user.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 4.2 on 2024-08-05 10:16 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('core', '0002_userprofile_dept_delete_department'), - ('lab', '0013_alter_lab_user'), - ] - - operations = [ - migrations.AlterField( - model_name='lab', - name='user', - field=models.ManyToManyField(related_name='labs', to='core.userprofile'), - ), - ] diff --git a/org/migrations/0002_department.py b/org/migrations/0002_department.py deleted file mode 100644 index 46bffca..0000000 --- a/org/migrations/0002_department.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 4.2 on 2024-06-20 06:08 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('org', '0001_initial'), - ] - - operations = [ - migrations.CreateModel( - name='Department', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=255)), - ('created_on', models.DateTimeField(auto_now_add=True)), - ('org', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='org.org')), - ], - ), - ] diff --git a/org/migrations/0003_department_head.py b/org/migrations/0003_department_head.py deleted file mode 100644 index 703523d..0000000 --- a/org/migrations/0003_department_head.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 4.2 on 2024-08-07 17:27 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('core', '0003_alter_userprofile_user'), - ('org', '0002_department'), - ] - - operations = [ - migrations.AddField( - model_name='department', - name='head', - field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, to='core.userprofile'), - ), - ] diff --git a/org/urls.py b/org/urls.py deleted file mode 100644 index ea96229..0000000 --- a/org/urls.py +++ /dev/null @@ -1,16 +0,0 @@ -from django.urls import path, include -from org import views -from core import views as core_views - -app_name = 'org' - -urlpatterns = [ - path('/', views.OrgDetailView.as_view(), name='org-dashboard'), - path('/people/', views.OrgPeopleListView.as_view(), name='org-people-list'), - path('/dept/create/', views.DepartmentCreateView.as_view(), name='dept-create'), - path('/dept/create/add-user/', core_views.DeptIncargeCreateView.as_view(), name='dept-incharge-create'), - path('/generate-report/', core_views.GenerateReportView.as_view(), name='generate-report'), - - path('/dept//lab/', include('lab.urls', namespace='lab')), -] - diff --git a/requirements.txt b/requirements.txt index ed456ed..e008c2c 100644 Binary files a/requirements.txt and b/requirements.txt differ diff --git a/core/__init__.py b/src/apps/__init__.py similarity index 100% rename from core/__init__.py rename to src/apps/__init__.py diff --git a/core/migrations/__init__.py b/src/apps/core/__init__.py similarity index 100% rename from core/migrations/__init__.py rename to src/apps/core/__init__.py diff --git a/core/account_activation_email.py b/src/apps/core/account_activation_email.py similarity index 100% rename from core/account_activation_email.py rename to src/apps/core/account_activation_email.py diff --git a/core/admin.py b/src/apps/core/admin.py similarity index 100% rename from core/admin.py rename to src/apps/core/admin.py diff --git a/core/apps.py b/src/apps/core/apps.py similarity index 84% rename from core/apps.py rename to src/apps/core/apps.py index 8115ae6..4143768 100644 --- a/core/apps.py +++ b/src/apps/core/apps.py @@ -3,4 +3,4 @@ class CoreConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' - name = 'core' + name = 'apps.core' diff --git a/core/forms.py b/src/apps/core/forms.py similarity index 78% rename from core/forms.py rename to src/apps/core/forms.py index 785069f..9cbdc7d 100644 --- a/core/forms.py +++ b/src/apps/core/forms.py @@ -74,4 +74,18 @@ def clean_email(self): email = self.cleaned_data['email'] if User.objects.filter(email=email).exists(): raise forms.ValidationError('This email address is already in use.') - return email \ No newline at end of file + return email + + +class AddOrgUserForm(forms.ModelForm): + def __init__(self, *args, **kwargs): + super(AddOrgUserForm, self).__init__(*args, **kwargs) + self.fields['email'].widget.attrs.update({'class': 'form-control'}) + self.fields['first_name'].widget.attrs.update({'class': 'form-control'}) + self.fields['last_name'].widget.attrs.update({'class': 'form-control'}) + # if some_condition: + # self.fields['extra_field'] = forms.EmailField() + + class Meta: + model = User + fields = ["first_name","last_name", "email",] \ No newline at end of file diff --git a/core/migrations/0001_initial.py b/src/apps/core/migrations/0001_initial.py similarity index 76% rename from core/migrations/0001_initial.py rename to src/apps/core/migrations/0001_initial.py index 0e382d6..7faf5ed 100644 --- a/core/migrations/0001_initial.py +++ b/src/apps/core/migrations/0001_initial.py @@ -1,6 +1,6 @@ -# Generated by Django 4.2 on 2024-06-10 16:21 +# Generated by Django 4.2 on 2024-08-13 19:04 -import core.user_manager +import apps.core.user_manager from django.conf import settings from django.db import migrations, models import django.db.models.deletion @@ -12,7 +12,6 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('org', '0001_initial'), ('auth', '0012_alter_user_first_name_max_length'), ] @@ -39,29 +38,18 @@ class Migration(migrations.Migration): 'abstract': False, }, managers=[ - ('objects', core.user_manager.UserManager()), + ('objects', apps.core.user_manager.UserManager()), ], ), migrations.CreateModel( name='UserProfile', fields=[ - ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL)), + ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, related_name='profile', serialize=False, to=settings.AUTH_USER_MODEL)), ('first_name', models.CharField(max_length=255)), ('last_name', models.CharField(max_length=255)), ('is_org_admin', models.BooleanField(default=False, verbose_name='is admin')), ('is_dept_incharge', models.BooleanField(default=False, verbose_name='is department incharge')), ('is_lab_staff', models.BooleanField(default=False, verbose_name='is lab staff')), - ('org', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='org.org')), - ], - ), - migrations.CreateModel( - name='Department', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=255)), - ('created_on', models.DateTimeField(auto_now_add=True)), - ('org', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='org.org')), - ('incharge', models.OneToOneField(on_delete=django.db.models.deletion.DO_NOTHING, to='core.userprofile')), ], ), ] diff --git a/core/migrations/0004_alter_userprofile_dept.py b/src/apps/core/migrations/0002_initial.py similarity index 50% rename from core/migrations/0004_alter_userprofile_dept.py rename to src/apps/core/migrations/0002_initial.py index 45d31e7..b63790e 100644 --- a/core/migrations/0004_alter_userprofile_dept.py +++ b/src/apps/core/migrations/0002_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 4.2 on 2024-08-07 17:59 +# Generated by Django 4.2 on 2024-08-13 19:04 from django.db import migrations, models import django.db.models.deletion @@ -6,15 +6,22 @@ class Migration(migrations.Migration): + initial = True + dependencies = [ - ('org', '0003_department_head'), - ('core', '0003_alter_userprofile_user'), + ('org', '0001_initial'), + ('core', '0001_initial'), ] operations = [ - migrations.AlterField( + migrations.AddField( model_name='userprofile', name='dept', field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='org.department'), ), + migrations.AddField( + model_name='userprofile', + name='org', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='org.org'), + ), ] diff --git a/lab/__init__.py b/src/apps/core/migrations/__init__.py similarity index 100% rename from lab/__init__.py rename to src/apps/core/migrations/__init__.py diff --git a/core/models.py b/src/apps/core/models.py similarity index 96% rename from core/models.py rename to src/apps/core/models.py index 26af15a..bb74931 100644 --- a/core/models.py +++ b/src/apps/core/models.py @@ -2,7 +2,7 @@ from django.contrib.auth.models import AbstractUser from django.utils.translation import gettext_lazy as _ from . user_manager import UserManager -from org.models import Org, Department +from apps.org.models import Org, Department class User(AbstractUser): diff --git a/core/static/core/account-verified/style.css b/src/apps/core/static/core/account-verified/style.css similarity index 100% rename from core/static/core/account-verified/style.css rename to src/apps/core/static/core/account-verified/style.css diff --git a/core/static/core/account-verified/style.scss b/src/apps/core/static/core/account-verified/style.scss similarity index 100% rename from core/static/core/account-verified/style.scss rename to src/apps/core/static/core/account-verified/style.scss diff --git a/core/static/core/change-password/style.css b/src/apps/core/static/core/change-password/style.css similarity index 100% rename from core/static/core/change-password/style.css rename to src/apps/core/static/core/change-password/style.css diff --git a/core/static/core/change-password/style.scss b/src/apps/core/static/core/change-password/style.scss similarity index 100% rename from core/static/core/change-password/style.scss rename to src/apps/core/static/core/change-password/style.scss diff --git a/core/static/core/login/style.css b/src/apps/core/static/core/login/style.css similarity index 100% rename from core/static/core/login/style.css rename to src/apps/core/static/core/login/style.css diff --git a/core/static/core/login/style.scss b/src/apps/core/static/core/login/style.scss similarity index 100% rename from core/static/core/login/style.scss rename to src/apps/core/static/core/login/style.scss diff --git a/core/static/core/password-reset-completed/style.css b/src/apps/core/static/core/password-reset-completed/style.css similarity index 100% rename from core/static/core/password-reset-completed/style.css rename to src/apps/core/static/core/password-reset-completed/style.css diff --git a/core/static/core/password-reset-completed/style.scss b/src/apps/core/static/core/password-reset-completed/style.scss similarity index 100% rename from core/static/core/password-reset-completed/style.scss rename to src/apps/core/static/core/password-reset-completed/style.scss diff --git a/core/static/core/password-reset-confirm/style.css b/src/apps/core/static/core/password-reset-confirm/style.css similarity index 100% rename from core/static/core/password-reset-confirm/style.css rename to src/apps/core/static/core/password-reset-confirm/style.css diff --git a/core/static/core/password-reset-confirm/style.scss b/src/apps/core/static/core/password-reset-confirm/style.scss similarity index 100% rename from core/static/core/password-reset-confirm/style.scss rename to src/apps/core/static/core/password-reset-confirm/style.scss diff --git a/core/static/core/password-reset-done/style.css b/src/apps/core/static/core/password-reset-done/style.css similarity index 100% rename from core/static/core/password-reset-done/style.css rename to src/apps/core/static/core/password-reset-done/style.css diff --git a/core/static/core/password-reset-done/style.scss b/src/apps/core/static/core/password-reset-done/style.scss similarity index 100% rename from core/static/core/password-reset-done/style.scss rename to src/apps/core/static/core/password-reset-done/style.scss diff --git a/core/static/core/password-reset-form/style.css b/src/apps/core/static/core/password-reset-form/style.css similarity index 100% rename from core/static/core/password-reset-form/style.css rename to src/apps/core/static/core/password-reset-form/style.css diff --git a/core/static/core/password-reset-form/style.scss b/src/apps/core/static/core/password-reset-form/style.scss similarity index 100% rename from core/static/core/password-reset-form/style.scss rename to src/apps/core/static/core/password-reset-form/style.scss diff --git a/core/templates/core/account-activate-email.html b/src/apps/core/templates/core/account-activate-email.html similarity index 100% rename from core/templates/core/account-activate-email.html rename to src/apps/core/templates/core/account-activate-email.html diff --git a/core/templates/core/account-verified.html b/src/apps/core/templates/core/account-verified.html similarity index 100% rename from core/templates/core/account-verified.html rename to src/apps/core/templates/core/account-verified.html diff --git a/src/apps/core/templates/core/add-user.html b/src/apps/core/templates/core/add-user.html new file mode 100644 index 0000000..0c90f1b --- /dev/null +++ b/src/apps/core/templates/core/add-user.html @@ -0,0 +1,22 @@ +{% extends 'base.html' %} + + + +{% block subnav %} + +{% endblock subnav %} + + +{% block content %} +
+
+ {% csrf_token %} + {{form}} + +
+
+{% endblock content %} \ No newline at end of file diff --git a/core/templates/core/change-password.html b/src/apps/core/templates/core/change-password.html similarity index 100% rename from core/templates/core/change-password.html rename to src/apps/core/templates/core/change-password.html diff --git a/core/templates/core/dept-create.html b/src/apps/core/templates/core/dept-create.html similarity index 100% rename from core/templates/core/dept-create.html rename to src/apps/core/templates/core/dept-create.html diff --git a/core/templates/core/lab-report.html b/src/apps/core/templates/core/lab-report.html similarity index 100% rename from core/templates/core/lab-report.html rename to src/apps/core/templates/core/lab-report.html diff --git a/core/templates/core/lab-staff-create.html b/src/apps/core/templates/core/lab-staff-create.html similarity index 100% rename from core/templates/core/lab-staff-create.html rename to src/apps/core/templates/core/lab-staff-create.html diff --git a/core/templates/core/login.html b/src/apps/core/templates/core/login.html similarity index 100% rename from core/templates/core/login.html rename to src/apps/core/templates/core/login.html diff --git a/core/templates/core/logout.html b/src/apps/core/templates/core/logout.html similarity index 100% rename from core/templates/core/logout.html rename to src/apps/core/templates/core/logout.html diff --git a/core/templates/core/org-dashboard.html b/src/apps/core/templates/core/org-dashboard.html similarity index 91% rename from core/templates/core/org-dashboard.html rename to src/apps/core/templates/core/org-dashboard.html index 554ac39..b6038ee 100644 --- a/core/templates/core/org-dashboard.html +++ b/src/apps/core/templates/core/org-dashboard.html @@ -55,7 +55,7 @@

Departments

@@ -73,6 +73,7 @@

Departments

Department Name + Department Head Created on Action @@ -81,6 +82,7 @@

Departments

{% for department in departments %} {{department.name}} + {{department.head}} {{department.created_on.date}} Manage diff --git a/core/templates/core/org-people-list.html b/src/apps/core/templates/core/org-people-list.html similarity index 84% rename from core/templates/core/org-people-list.html rename to src/apps/core/templates/core/org-people-list.html index 6417715..d835968 100644 --- a/core/templates/core/org-people-list.html +++ b/src/apps/core/templates/core/org-people-list.html @@ -49,7 +49,7 @@

People

- Add Admin + Add User @@ -64,7 +64,8 @@

People

Full Name Role - Email + Email + Action @@ -82,14 +83,19 @@

People

{% if person.is_org_admin %} Organisation Admin {% elif person.is_dept_incharge %} - Departement Incharge + {{person.dept.name}} Department Incharge {% elif person.is_lab_staff %} Lab Staff + {% else %} + None {% endif %} {{person.user.email}} + + Delete + {% endfor %} diff --git a/core/templates/core/password_reset/password_reset_complete.html b/src/apps/core/templates/core/password_reset/password_reset_complete.html similarity index 100% rename from core/templates/core/password_reset/password_reset_complete.html rename to src/apps/core/templates/core/password_reset/password_reset_complete.html diff --git a/core/templates/core/password_reset/password_reset_confirm.html b/src/apps/core/templates/core/password_reset/password_reset_confirm.html similarity index 100% rename from core/templates/core/password_reset/password_reset_confirm.html rename to src/apps/core/templates/core/password_reset/password_reset_confirm.html diff --git a/core/templates/core/password_reset/password_reset_done.html b/src/apps/core/templates/core/password_reset/password_reset_done.html similarity index 100% rename from core/templates/core/password_reset/password_reset_done.html rename to src/apps/core/templates/core/password_reset/password_reset_done.html diff --git a/core/templates/core/password_reset/password_reset_email.html b/src/apps/core/templates/core/password_reset/password_reset_email.html similarity index 100% rename from core/templates/core/password_reset/password_reset_email.html rename to src/apps/core/templates/core/password_reset/password_reset_email.html diff --git a/core/templates/core/password_reset/password_reset_form.html b/src/apps/core/templates/core/password_reset/password_reset_form.html similarity index 100% rename from core/templates/core/password_reset/password_reset_form.html rename to src/apps/core/templates/core/password_reset/password_reset_form.html diff --git a/core/templates/core/password_reset/password_reset_subject.txt b/src/apps/core/templates/core/password_reset/password_reset_subject.txt similarity index 100% rename from core/templates/core/password_reset/password_reset_subject.txt rename to src/apps/core/templates/core/password_reset/password_reset_subject.txt diff --git a/core/templates/core/register-user.html b/src/apps/core/templates/core/register-user.html similarity index 100% rename from core/templates/core/register-user.html rename to src/apps/core/templates/core/register-user.html diff --git a/core/templates/core/report.html b/src/apps/core/templates/core/report.html similarity index 100% rename from core/templates/core/report.html rename to src/apps/core/templates/core/report.html diff --git a/core/tests.py b/src/apps/core/tests.py similarity index 100% rename from core/tests.py rename to src/apps/core/tests.py diff --git a/core/token_generator.py b/src/apps/core/token_generator.py similarity index 100% rename from core/token_generator.py rename to src/apps/core/token_generator.py diff --git a/core/urls.py b/src/apps/core/urls.py similarity index 81% rename from core/urls.py rename to src/apps/core/urls.py index 27d74bf..41273b2 100644 --- a/core/urls.py +++ b/src/apps/core/urls.py @@ -1,5 +1,5 @@ from django.urls import path -from .import views +from apps.core import views app_name = 'core' @@ -15,6 +15,8 @@ views.ConfirmPasswordResetView.as_view(), name='confirm-password-reset'), path('complete-password-reset/', views.CompletePasswordResetView.as_view(), name='complete-password-reset'), - # path('add-user/', views.AddUserView.as_view(), name='add-user'), path('activate///', views.ActivateAccountView.as_view(), name='activate'), + + path('people/add/', views.OrgUserAddView.as_view(), name='add-user'), + path('people//delete/', views.UserDeleteView.as_view(), name='delete_user'), ] \ No newline at end of file diff --git a/core/user_manager.py b/src/apps/core/user_manager.py similarity index 100% rename from core/user_manager.py rename to src/apps/core/user_manager.py diff --git a/core/utils.py b/src/apps/core/utils.py similarity index 96% rename from core/utils.py rename to src/apps/core/utils.py index 37f5f15..dbe4ba8 100644 --- a/core/utils.py +++ b/src/apps/core/utils.py @@ -2,7 +2,7 @@ import string from django.db.models import CharField -from lab.models import Brand, Category, Item, Lab, System +from apps.lab.models import Brand, Category, Item, Lab, System def generate_password(length=10): alphabet = string.ascii_letters + string.digits + string.punctuation diff --git a/src/apps/core/views.py b/src/apps/core/views.py new file mode 100644 index 0000000..a1c81ed --- /dev/null +++ b/src/apps/core/views.py @@ -0,0 +1,342 @@ +from django.urls import reverse, reverse_lazy +from apps.core.utils import generate_password +from django.views import generic +from django.contrib.auth import views +from django.contrib.auth import login +from django.shortcuts import redirect, render +from apps.core.models import User, UserProfile +from apps.org.models import Org +from apps.core.account_activation_email import send_account_activation_mail +from apps.core.token_generator import account_activation_token +from django.utils.http import urlsafe_base64_decode +from django.http import HttpResponsePermanentRedirect +from django.utils.encoding import force_str +from apps.core.forms import LabStaffCreationForm, CustomAuthenticationForm, CustomOrgRegisterForm, AddOrgUserForm +from apps.lab.mixins import RedirectLoggedInUserMixin + +# from xhtml2pdf import pisa + + + +class LandingPageView(RedirectLoggedInUserMixin, generic.TemplateView): + template_name = 'landing_page.html' + + +class UserRegisterView(generic.CreateView): + form_class = CustomOrgRegisterForm + template_name = 'core/register-user.html' + + def form_valid(self, form): + user = form.save(commit=False) + user.is_active = False + user.save() + first_name = form.cleaned_data.get('first_name') + last_name = form.cleaned_data.get('last_name') + org_name = form.cleaned_data.get('org_name') + org_address = form.cleaned_data.get('org_address') + org_email = form.cleaned_data.get('org_email') + org_website_url = form.cleaned_data.get('org_website_url') + + org = Org.objects.create( + org_name=org_name, + contact = org_email, + website_url = org_website_url, + address = org_address + ) + + UserProfile.objects.create( + user = user, + org = org, + first_name = first_name, + last_name = last_name, + is_org_admin = True + ) + + send_account_activation_mail(self.request, user, email = user.email) + return super(UserRegisterView, self).form_valid(form) + + def get_success_url(self): + return reverse('core:login') + + +class OrgUserAddView(generic.CreateView): + model = User + template_name = 'core/add-user.html' + form_class = AddOrgUserForm + + def form_valid(self, form): + user = form.save(commit=False) + user.set_password(str(generate_password())) + user.save() + UserProfile.objects.create( + user = user, + first_name = user.first_name, + last_name = user.last_name, + org = self.request.user.profile.org + ) + return super().form_valid(form) + + def get_success_url(self): + org_id = self.request.user.profile.org.pk + return reverse('org:org-people-list', kwargs={'org_id':org_id}) + + + +class UserDeleteView(generic.DeleteView): + model = User + + def get(self, request, *args, **kwargs): + user = User.objects.get(pk = self.kwargs["user_id"]) + user.delete() + return HttpResponsePermanentRedirect(reverse('org:org-people-list', kwargs={'org_id':self.request.user.profile.org.pk})) + + +class LoginView(views.LoginView): + form_class = CustomAuthenticationForm + template_name = 'core/login.html' + + def form_valid(self, form): + login(self.request, form.get_user()) + return redirect('landing-page') + + +class LogoutView(views.LogoutView): + template_name = 'core/logout.html' + + +class ChangePasswordView(views.PasswordChangeView): + template_name = 'core/change-password.html' + success_url = reverse_lazy('landing-page') + + +class ResetPasswordView(views.PasswordResetView): + email_template_name = 'core/password_reset/password_reset_email.html' + html_email_template_name = 'core/password_reset/password_reset_email.html' + subject_template_name = 'core/password_reset/password_reset_subject.txt' + success_url = reverse_lazy('core:done-password-reset') + template_name = 'core/password_reset/password_reset_form.html' + + +class DonePasswordResetView(views.PasswordResetDoneView): + template_name = 'core/password_reset/password_reset_done.html' + + +class ConfirmPasswordResetView(views.PasswordResetConfirmView): + success_url = reverse_lazy('core:complete-password-reset') + template_name = 'core/password_reset/password_reset_confirm.html' + + +class CompletePasswordResetView(views.PasswordResetCompleteView): + template_name = 'core/password_reset/password_reset_complete.html' + + +class LabStaffCreateView(generic.FormView): + model = User + template_name = 'core/lab-staff-create.html' + form_class = LabStaffCreationForm + + def form_valid(self, form): + email = form.cleaned_data.get('email') + password = str(generate_password()) + first_name = form.cleaned_data.get('first_name') + last_name = form.cleaned_data.get('last_name') + org_id = self.kwargs["org_id"] + org = Org.objects.get(pk=org_id) + + user = User.objects.create( + email=email, + password=password, + ) + + user_profile = UserProfile.objects.create( + first_name = first_name, + last_name = last_name, + user = user, + org = org, + is_lab_staff = True + ) + + return super().form_valid(form) + + def get_success_url(self): + org_id = self.kwargs["org_id"] + dept_id = self.kwargs["dept_id"] + return reverse('org:lab:lab-create', kwargs={'org_id':org_id, 'dept_id':dept_id}) + + +class ActivateAccountView(generic.View): + def get(self, request, uidb64, token): + try: + uid = force_str(urlsafe_base64_decode(uidb64)) + user = User.objects.get(pk=uid) + except (TypeError, ValueError, OverflowError, User.DoesNotExist): + user = None + + if user is not None and account_activation_token.check_token(user, token): + user.is_active = True + user.save() + return render(request, 'core/account-verified.html') + else: + return render(request, 'core/account-verified.html') + + +# class GenerateReportView(generic.View): +# def get(self, request, org_id): +# if not request.user.is_authenticated: +# return HttpResponseForbidden() + +# userprofile = UserProfile.objects.get(user=request.user) +# org = userprofile.org + +# report = get_report_data(org) + +# print(report) + +# # Combine report data +# report_data = { +# 'organization_name': org.org_name, +# 'lab_count':len(report), +# 'lab_report': report +# } + + +# # Render HTML template +# template_name = 'core/report.html' # Replace with your actual template name +# html = render_to_string(template_name, report_data) + +# # Configure xhtml2pdf options (optional) +# pdf_options = { +# 'page-size': 'A4', # Set desired page size +# 'encoding': 'utf-8', # Set encoding for text content +# } + +# # Generate PDF +# response = HttpResponse(content_type='application/pdf') +# response['Content-Disposition'] = f'attachment; filename=report_{org.org_name}.pdf' + +# result = pisa.CreatePDF(html, dest=response, options=pdf_options) +# if result.err: +# return HttpResponse('Error: {}'.format(result.err)) # Handle errors + +# return response + + + +# class GenerateLabReportView(generic.View): +# def get(self, request, org_id, dept_id, lab_id): +# if not request.user.is_authenticated: +# return HttpResponseForbidden() + +# userprofile = UserProfile.objects.get(user=request.user) +# org = userprofile.org +# lab = Lab.objects.get(pk = lab_id) + +# report = get_lab_report_data(lab) + + +# # Combine report data +# report_data = { +# 'organization_name': org.org_name, +# 'lab': report +# } + + +# # Render HTML template +# template_name = 'core/lab-report.html' # Replace with your actual template name +# html = render_to_string(template_name, report_data) + +# # Configure xhtml2pdf options (optional) +# pdf_options = { +# 'page-size': 'A4', # Set desired page size +# 'encoding': 'utf-8', # Set encoding for text content +# } + +# # Generate PDF +# response = HttpResponse(content_type='application/pdf') +# response['Content-Disposition'] = f'attachment; filename=report_{org.org_name}.pdf' + +# result = pisa.CreatePDF(html, dest=response, options=pdf_options) +# if result.err: +# return HttpResponse('Error: {}'.format(result.err)) # Handle errors + +# return response + + +# class GenerateLabItemReportView(generic.View): +# def get(self, request, org_id, dept_id, lab_id): +# if not request.user.is_authenticated: +# return HttpResponseForbidden() + +# userprofile = UserProfile.objects.get(user=request.user) +# org = userprofile.org +# lab = Lab.objects.get(pk = lab_id) + +# report = get_lab_item_report_data(lab) + + +# # Combine report data +# report_data = { +# 'organization_name': org.org_name, +# 'lab': report +# } + + +# # Render HTML template +# template_name = 'core/lab-report.html' # Replace with your actual template name +# html = render_to_string(template_name, report_data) + +# # Configure xhtml2pdf options (optional) +# pdf_options = { +# 'page-size': 'A4', # Set desired page size +# 'encoding': 'utf-8', # Set encoding for text content +# } + +# # Generate PDF +# response = HttpResponse(content_type='application/pdf') +# response['Content-Disposition'] = f'attachment; filename=report_{org.org_name}.pdf' + +# result = pisa.CreatePDF(html, dest=response, options=pdf_options) +# if result.err: +# return HttpResponse('Error: {}'.format(result.err)) # Handle errors + +# return response + + +# class GenerateLabSystemReportView(generic.View): +# def get(self, request, org_id, dept_id, lab_id): +# if not request.user.is_authenticated: +# return HttpResponseForbidden() + +# userprofile = UserProfile.objects.get(user=request.user) +# org = userprofile.org +# lab = Lab.objects.get(pk = lab_id) + +# report = get_lab_system_report_data(lab) + + +# # Combine report data +# report_data = { +# 'organization_name': org.org_name, +# 'lab': report +# } + + +# # Render HTML template +# template_name = 'core/lab-report.html' # Replace with your actual template name +# html = render_to_string(template_name, report_data) + +# # Configure xhtml2pdf options (optional) +# pdf_options = { +# 'page-size': 'A4', # Set desired page size +# 'encoding': 'utf-8', # Set encoding for text content +# } + +# # Generate PDF +# response = HttpResponse(content_type='application/pdf') +# response['Content-Disposition'] = f'attachment; filename=report_{org.org_name}.pdf' + +# result = pisa.CreatePDF(html, dest=response, options=pdf_options) +# if result.err: +# return HttpResponse('Error: {}'.format(result.err)) # Handle errors + +# return response \ No newline at end of file diff --git a/lab/migrations/__init__.py b/src/apps/lab/__init__.py similarity index 100% rename from lab/migrations/__init__.py rename to src/apps/lab/__init__.py diff --git a/lab/admin.py b/src/apps/lab/admin.py similarity index 100% rename from lab/admin.py rename to src/apps/lab/admin.py diff --git a/lab/apps.py b/src/apps/lab/apps.py similarity index 84% rename from lab/apps.py rename to src/apps/lab/apps.py index f835608..b959275 100644 --- a/lab/apps.py +++ b/src/apps/lab/apps.py @@ -3,4 +3,4 @@ class LabConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' - name = 'lab' + name = 'apps.lab' diff --git a/lab/forms.py b/src/apps/lab/forms.py similarity index 96% rename from lab/forms.py rename to src/apps/lab/forms.py index 978df39..66f1cf9 100644 --- a/lab/forms.py +++ b/src/apps/lab/forms.py @@ -1,7 +1,7 @@ from django import forms from django.urls import reverse -from lab.models import Lab, LabSettings, Category, Item, ItemRemovalRecord, System -from core.models import UserProfile +from apps.lab.models import Lab, LabSettings, Category, Item, ItemRemovalRecord, System +from apps.core.models import UserProfile from django.forms import ModelForm from django.contrib.auth import get_user_model from django.forms import ModelMultipleChoiceField, CheckboxSelectMultiple diff --git a/lab/migrations/0001_initial.py b/src/apps/lab/migrations/0001_initial.py similarity index 72% rename from lab/migrations/0001_initial.py rename to src/apps/lab/migrations/0001_initial.py index 9d7a0d3..55b71db 100644 --- a/lab/migrations/0001_initial.py +++ b/src/apps/lab/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 4.2 on 2024-06-10 16:21 +# Generated by Django 4.2 on 2024-08-13 19:05 from django.db import migrations, models import django.db.models.deletion @@ -9,8 +9,8 @@ class Migration(migrations.Migration): initial = True dependencies = [ + ('core', '0002_initial'), ('org', '0001_initial'), - ('core', '0001_initial'), ] operations = [ @@ -42,7 +42,6 @@ class Migration(migrations.Migration): ('removed_qty', models.IntegerField(default=0)), ('unit_of_measure', models.CharField(blank=True, max_length=255, null=True)), ('created_on', models.DateTimeField(auto_now_add=True)), - ('date_of_purchase', models.DateField()), ('brand', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='lab.brand')), ('category', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='lab.category')), ], @@ -54,9 +53,9 @@ class Migration(migrations.Migration): ('lab_name', models.CharField(max_length=255)), ('room_no', models.IntegerField(unique=True)), ('created_on', models.DateTimeField(auto_now_add=True)), - ('dept', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.department')), + ('dept', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='org.department')), ('org', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='org.org')), - ('user', models.ManyToManyField(to='core.userprofile')), + ('user', models.ManyToManyField(related_name='labs', to='core.userprofile')), ], ), migrations.CreateModel( @@ -67,15 +66,18 @@ class Migration(migrations.Migration): ('sys_name', models.CharField(max_length=255, verbose_name='System Name')), ('status', models.CharField(choices=[('working', 'Working'), ('not_working', 'Not working'), ('item_missing', 'Item missing')], max_length=255)), ('created_on', models.DateTimeField(auto_now_add=True)), - ('cpu_cabin', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='cpu_cabin', to='lab.item', verbose_name='CPU Cabin')), - ('hdd', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='hdd', to='lab.item', verbose_name='Hard Disk Drive')), - ('keyboard', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='keyboard', to='lab.item', verbose_name='Keyboard')), + ('last_updated', models.DateTimeField(auto_now=True)), ('lab', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lab.lab')), - ('monitor', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='monitor', to='lab.item', verbose_name='Monitor')), - ('mouse', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='mouse', to='lab.item', verbose_name='Mouse')), - ('os', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='os', to='lab.item', verbose_name='Operating System')), - ('processor', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='processor', to='lab.item', verbose_name='Processor')), - ('ram', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='ram', to='lab.item', verbose_name='RAM')), + ], + ), + migrations.CreateModel( + name='SystemComponent', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('serial_no', models.CharField(max_length=255)), + ('component_type', models.CharField(choices=[('Mouse', 'Mouse'), ('Keyboard', 'Keyboard'), ('Processor', 'Processor'), ('RAM', 'RAM'), ('Storage', 'Storage'), ('OS', 'OS'), ('Monitor', 'Monitor'), ('CPU Cabin', 'CPU Cabin')], max_length=255)), + ('item', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lab.item')), + ('system', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='lab.system')), ], ), migrations.CreateModel( @@ -86,15 +88,18 @@ class Migration(migrations.Migration): ('sys_tab', models.BooleanField(default=False)), ('categories_tab', models.BooleanField(default=False)), ('brands_tab', models.BooleanField(default=False)), - ('lab', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='lab.lab')), + ('lab', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='settings', to='lab.lab')), ], ), migrations.CreateModel( - name='LabRecord', + name='ItemRemovalRecord', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('log_text', models.CharField(max_length=500)), - ('user_desc', models.TextField(blank=True, null=True)), + ('reason', models.CharField(choices=[('Depreciation', 'Depreciation'), ('Consumption', 'Consumption')], max_length=255)), + ('qty', models.IntegerField()), + ('date', models.DateField(auto_now_add=True)), + ('remarks', models.TextField()), + ('item', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lab.item')), ('lab', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lab.lab')), ], ), diff --git a/main/__init__.py b/src/apps/lab/migrations/__init__.py similarity index 100% rename from main/__init__.py rename to src/apps/lab/migrations/__init__.py diff --git a/lab/mixins.py b/src/apps/lab/mixins.py similarity index 88% rename from lab/mixins.py rename to src/apps/lab/mixins.py index 4dfd85e..2833add 100644 --- a/lab/mixins.py +++ b/src/apps/lab/mixins.py @@ -2,7 +2,7 @@ from django.http import HttpResponsePermanentRedirect from django.urls import reverse from . models import Lab -from core.models import UserProfile, Department, Org +from apps.core.models import UserProfile, Department, Org from django.http import Http404 diff --git a/lab/models.py b/src/apps/lab/models.py similarity index 97% rename from lab/models.py rename to src/apps/lab/models.py index 35d3bb5..aafcca1 100644 --- a/lab/models.py +++ b/src/apps/lab/models.py @@ -1,6 +1,6 @@ from django.db import models -from core.models import UserProfile -from org.models import Org, Department +from apps.core.models import UserProfile +from apps.org.models import Org, Department class Lab(models.Model): diff --git a/lab/static/lab/add-item/style.css b/src/apps/lab/static/lab/add-item/style.css similarity index 100% rename from lab/static/lab/add-item/style.css rename to src/apps/lab/static/lab/add-item/style.css diff --git a/lab/static/lab/add-item/style.scss b/src/apps/lab/static/lab/add-item/style.scss similarity index 100% rename from lab/static/lab/add-item/style.scss rename to src/apps/lab/static/lab/add-item/style.scss diff --git a/lab/static/lab/group-detail/style.css b/src/apps/lab/static/lab/group-detail/style.css similarity index 100% rename from lab/static/lab/group-detail/style.css rename to src/apps/lab/static/lab/group-detail/style.css diff --git a/lab/static/lab/group-detail/style.scss b/src/apps/lab/static/lab/group-detail/style.scss similarity index 100% rename from lab/static/lab/group-detail/style.scss rename to src/apps/lab/static/lab/group-detail/style.scss diff --git a/lab/static/lab/group-list/style.css b/src/apps/lab/static/lab/group-list/style.css similarity index 100% rename from lab/static/lab/group-list/style.css rename to src/apps/lab/static/lab/group-list/style.css diff --git a/lab/static/lab/group-list/style.scss b/src/apps/lab/static/lab/group-list/style.scss similarity index 100% rename from lab/static/lab/group-list/style.scss rename to src/apps/lab/static/lab/group-list/style.scss diff --git a/lab/static/lab/item-list/style.css b/src/apps/lab/static/lab/item-list/style.css similarity index 100% rename from lab/static/lab/item-list/style.css rename to src/apps/lab/static/lab/item-list/style.css diff --git a/lab/static/lab/item-list/style.scss b/src/apps/lab/static/lab/item-list/style.scss similarity index 100% rename from lab/static/lab/item-list/style.scss rename to src/apps/lab/static/lab/item-list/style.scss diff --git a/lab/static/lab/lab-create/style.css b/src/apps/lab/static/lab/lab-create/style.css similarity index 100% rename from lab/static/lab/lab-create/style.css rename to src/apps/lab/static/lab/lab-create/style.css diff --git a/lab/static/lab/lab-create/style.scss b/src/apps/lab/static/lab/lab-create/style.scss similarity index 100% rename from lab/static/lab/lab-create/style.scss rename to src/apps/lab/static/lab/lab-create/style.scss diff --git a/lab/static/lab/lab-list/style.css b/src/apps/lab/static/lab/lab-list/style.css similarity index 100% rename from lab/static/lab/lab-list/style.css rename to src/apps/lab/static/lab/lab-list/style.css diff --git a/lab/static/lab/lab-list/style.scss b/src/apps/lab/static/lab/lab-list/style.scss similarity index 100% rename from lab/static/lab/lab-list/style.scss rename to src/apps/lab/static/lab/lab-list/style.scss diff --git a/lab/templates/lab/add-item.html b/src/apps/lab/templates/lab/add-item.html similarity index 100% rename from lab/templates/lab/add-item.html rename to src/apps/lab/templates/lab/add-item.html diff --git a/lab/templates/lab/additionals/item-options.html b/src/apps/lab/templates/lab/additionals/item-options.html similarity index 100% rename from lab/templates/lab/additionals/item-options.html rename to src/apps/lab/templates/lab/additionals/item-options.html diff --git a/lab/templates/lab/brand-list.html b/src/apps/lab/templates/lab/brand-list.html similarity index 100% rename from lab/templates/lab/brand-list.html rename to src/apps/lab/templates/lab/brand-list.html diff --git a/lab/templates/lab/category-list.html b/src/apps/lab/templates/lab/category-list.html similarity index 100% rename from lab/templates/lab/category-list.html rename to src/apps/lab/templates/lab/category-list.html diff --git a/lab/templates/lab/create-category.html b/src/apps/lab/templates/lab/create-category.html similarity index 100% rename from lab/templates/lab/create-category.html rename to src/apps/lab/templates/lab/create-category.html diff --git a/lab/templates/lab/item-list.html b/src/apps/lab/templates/lab/item-list.html similarity index 100% rename from lab/templates/lab/item-list.html rename to src/apps/lab/templates/lab/item-list.html diff --git a/lab/templates/lab/item-removal-record.html b/src/apps/lab/templates/lab/item-removal-record.html similarity index 100% rename from lab/templates/lab/item-removal-record.html rename to src/apps/lab/templates/lab/item-removal-record.html diff --git a/lab/templates/lab/item-update.html b/src/apps/lab/templates/lab/item-update.html similarity index 100% rename from lab/templates/lab/item-update.html rename to src/apps/lab/templates/lab/item-update.html diff --git a/lab/templates/lab/lab-create.html b/src/apps/lab/templates/lab/lab-create.html similarity index 100% rename from lab/templates/lab/lab-create.html rename to src/apps/lab/templates/lab/lab-create.html diff --git a/lab/templates/lab/lab-update.html b/src/apps/lab/templates/lab/lab-update.html similarity index 100% rename from lab/templates/lab/lab-update.html rename to src/apps/lab/templates/lab/lab-update.html diff --git a/lab/templates/lab/lab_settings.html b/src/apps/lab/templates/lab/lab_settings.html similarity index 100% rename from lab/templates/lab/lab_settings.html rename to src/apps/lab/templates/lab/lab_settings.html diff --git a/lab/templates/lab/labs-list.html b/src/apps/lab/templates/lab/labs-list.html similarity index 100% rename from lab/templates/lab/labs-list.html rename to src/apps/lab/templates/lab/labs-list.html diff --git a/lab/templates/lab/system-create.html b/src/apps/lab/templates/lab/system-create.html similarity index 100% rename from lab/templates/lab/system-create.html rename to src/apps/lab/templates/lab/system-create.html diff --git a/lab/templates/lab/system-detail.html b/src/apps/lab/templates/lab/system-detail.html similarity index 100% rename from lab/templates/lab/system-detail.html rename to src/apps/lab/templates/lab/system-detail.html diff --git a/lab/templates/lab/system-list.html b/src/apps/lab/templates/lab/system-list.html similarity index 100% rename from lab/templates/lab/system-list.html rename to src/apps/lab/templates/lab/system-list.html diff --git a/lab/templates/lab/system-update.html b/src/apps/lab/templates/lab/system-update.html similarity index 100% rename from lab/templates/lab/system-update.html rename to src/apps/lab/templates/lab/system-update.html diff --git a/lab/tests.py b/src/apps/lab/tests.py similarity index 100% rename from lab/tests.py rename to src/apps/lab/tests.py diff --git a/lab/urls.py b/src/apps/lab/urls.py similarity index 81% rename from lab/urls.py rename to src/apps/lab/urls.py index d92a031..cbcbf25 100644 --- a/lab/urls.py +++ b/src/apps/lab/urls.py @@ -1,7 +1,6 @@ from django.urls import path, include from . import views -from core.views import LabStaffCreateView, GenerateLabReportView, GenerateLabItemReportView, GenerateLabSystemReportView -from purchases import views as purchase_views +from apps.core.views import LabStaffCreateView app_name = 'lab' @@ -12,11 +11,11 @@ path('/update/', views.UpdateLabView.as_view(), name='lab-update'), path('/delete/', views.DeleteLabView.as_view(), name='lab-delete'), path('/settings/', views.LabSettingsView.as_view(), name='lab-settings'), - path('/generate-report/', GenerateLabReportView.as_view(), name='generate-lab-report'), + # path('/generate-report/', GenerateLabReportView.as_view(), name='generate-lab-report'), path('/items/add-item/', views.CreateItemView.as_view(), name='add-item'), path('/items/', views.ItemListView.as_view(), name='item-list'), - path('/items/generate-report/', GenerateLabItemReportView.as_view(), name='item-report'), + # path('/items/generate-report/', GenerateLabItemReportView.as_view(), name='item-report'), path('/items//update/', views.ItemUpdateView.as_view(), name='item-update'), path('/items//delete/', views.ItemDeleteView.as_view(), name='item-delete'), path('/items//remove/', views.RecordItemRemovalView.as_view(), name='item-remove'), @@ -27,7 +26,7 @@ path('/systems//load_items/', views.LoadItemsView.as_view(), name='load_items'), path('/systems//add-system-component/', views.SystemComponentCreateView.as_view(), name='add_component'), path('/systems//delete-system-component//', views.SystemComponentDeleteView.as_view(), name='delete_component'), - path('/systems/generate-report/', GenerateLabSystemReportView.as_view(), name='system-report'), + # path('/systems/generate-report/', GenerateLabSystemReportView.as_view(), name='system-report'), path('/systems//update/', views.SystemUpdateView.as_view(), name='update-system'), path('/systems//delete/', views.SystemDeleteView.as_view(), name='system-delete'), @@ -39,6 +38,6 @@ path('/brands/create/', views.BrandCreateView.as_view(), name='brand-create'), path('/brands/delete//', views.BrandDeleteView.as_view(), name='brand-delete'), - path('/purchases/', include('purchases.urls', namespace='purchases')), + path('/purchases/', include('apps.purchases.urls', namespace='purchases')), ] diff --git a/lab/utils.py b/src/apps/lab/utils.py similarity index 100% rename from lab/utils.py rename to src/apps/lab/utils.py diff --git a/lab/views.py b/src/apps/lab/views.py similarity index 98% rename from lab/views.py rename to src/apps/lab/views.py index a004c1d..abf1b2f 100644 --- a/lab/views.py +++ b/src/apps/lab/views.py @@ -1,17 +1,16 @@ from django.http import HttpResponsePermanentRedirect from django.shortcuts import get_object_or_404, redirect, render -from django.urls import reverse, reverse_lazy +from django.urls import reverse from django.views import generic, View -from lab.mixins import LabAccessMixin, DeptAdminOnlyAccessMixin +from apps.lab.mixins import LabAccessMixin, DeptAdminOnlyAccessMixin from . models import Item, Lab, Category, SystemComponent, System, Brand, LabSettings, ItemRemovalRecord -from core.models import Department +from apps.core.models import Department from .forms import LabCreateForm, BrandCreateForm, LabSettingsForm, AddSystemComponetForm, ItemRemovalForm, SystemUpdateForm -from org.models import Org +from apps.org.models import Org from django.contrib.auth.mixins import LoginRequiredMixin from django.db import transaction -from django.db.models import ForeignKey, ManyToManyField -from core.models import UserProfile +from apps.core.models import UserProfile from .utils import generate_unique_code diff --git a/main/settings/__init__.py b/src/apps/org/__init__.py similarity index 100% rename from main/settings/__init__.py rename to src/apps/org/__init__.py diff --git a/org/admin.py b/src/apps/org/admin.py similarity index 67% rename from org/admin.py rename to src/apps/org/admin.py index 21fb80d..8bf17a1 100644 --- a/org/admin.py +++ b/src/apps/org/admin.py @@ -1,5 +1,5 @@ from django.contrib import admin -from org.models import Department, Org +from apps.org.models import Department, Org admin.site.register(Org) admin.site.register(Department) diff --git a/org/apps.py b/src/apps/org/apps.py similarity index 84% rename from org/apps.py rename to src/apps/org/apps.py index 4d3b1a0..026b7e7 100644 --- a/org/apps.py +++ b/src/apps/org/apps.py @@ -3,4 +3,4 @@ class OrgConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' - name = 'org' + name = 'apps.org' diff --git a/org/migrations/0001_initial.py b/src/apps/org/migrations/0001_initial.py similarity index 52% rename from org/migrations/0001_initial.py rename to src/apps/org/migrations/0001_initial.py index 8b61af3..229aafc 100644 --- a/org/migrations/0001_initial.py +++ b/src/apps/org/migrations/0001_initial.py @@ -1,6 +1,7 @@ -# Generated by Django 4.2 on 2024-06-10 16:21 +# Generated by Django 4.2 on 2024-08-13 19:04 from django.db import migrations, models +import django.db.models.deletion class Migration(migrations.Migration): @@ -8,6 +9,7 @@ class Migration(migrations.Migration): initial = True dependencies = [ + ('core', '0001_initial'), ] operations = [ @@ -23,4 +25,14 @@ class Migration(migrations.Migration): ('created_on', models.DateTimeField(auto_now_add=True)), ], ), + migrations.CreateModel( + name='Department', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255)), + ('created_on', models.DateTimeField(auto_now_add=True)), + ('head', models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, to='core.userprofile')), + ('org', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='org.org')), + ], + ), ] diff --git a/org/__init__.py b/src/apps/org/migrations/__init__.py similarity index 100% rename from org/__init__.py rename to src/apps/org/migrations/__init__.py diff --git a/org/models.py b/src/apps/org/models.py similarity index 100% rename from org/models.py rename to src/apps/org/models.py diff --git a/org/tests.py b/src/apps/org/tests.py similarity index 100% rename from org/tests.py rename to src/apps/org/tests.py diff --git a/src/apps/org/urls.py b/src/apps/org/urls.py new file mode 100644 index 0000000..21a8b35 --- /dev/null +++ b/src/apps/org/urls.py @@ -0,0 +1,14 @@ +from django.urls import path, include +from apps.org import views + +app_name = 'org' + +urlpatterns = [ + path('/', views.OrgDetailView.as_view(), name='org-dashboard'), + path('/people/', views.OrgPeopleListView.as_view(), name='org-people-list'), + path('/dept/create/', views.DepartmentCreateView.as_view(), name='dept-create'), + # path('/generate-report/', core_views.GenerateReportView.as_view(), name='generate-report'), + + path('/dept//lab/', include('apps.lab.urls', namespace='lab')), +] + diff --git a/org/views.py b/src/apps/org/views.py similarity index 95% rename from org/views.py rename to src/apps/org/views.py index a9adc26..8fcde08 100644 --- a/org/views.py +++ b/src/apps/org/views.py @@ -1,8 +1,8 @@ from django.shortcuts import render from django.views import generic from django.urls import reverse -from purchases.models import Org, Department -from core.models import UserProfile +from apps.purchases.models import Org, Department +from apps.core.models import UserProfile class OrgDetailView(generic.DetailView): diff --git a/org/migrations/__init__.py b/src/apps/purchases/__init__.py similarity index 100% rename from org/migrations/__init__.py rename to src/apps/purchases/__init__.py diff --git a/purchases/admin.py b/src/apps/purchases/admin.py similarity index 100% rename from purchases/admin.py rename to src/apps/purchases/admin.py diff --git a/purchases/apps.py b/src/apps/purchases/apps.py similarity index 81% rename from purchases/apps.py rename to src/apps/purchases/apps.py index 89928f6..c353ca9 100644 --- a/purchases/apps.py +++ b/src/apps/purchases/apps.py @@ -3,4 +3,4 @@ class PurchasesConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' - name = 'purchases' + name = 'apps.purchases' diff --git a/purchases/forms.py b/src/apps/purchases/forms.py similarity index 96% rename from purchases/forms.py rename to src/apps/purchases/forms.py index eb8fe4d..8b3b9ab 100644 --- a/purchases/forms.py +++ b/src/apps/purchases/forms.py @@ -1,5 +1,5 @@ from django import forms -from purchases.models import Purchase +from apps.purchases.models import Purchase class PurchaseCreateForm(forms.ModelForm): class Meta: diff --git a/purchases/migrations/0001_initial.py b/src/apps/purchases/migrations/0001_initial.py similarity index 93% rename from purchases/migrations/0001_initial.py rename to src/apps/purchases/migrations/0001_initial.py index 7e625a1..b75c09c 100644 --- a/purchases/migrations/0001_initial.py +++ b/src/apps/purchases/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 4.2 on 2024-08-04 17:38 +# Generated by Django 4.2 on 2024-08-13 19:07 from django.db import migrations, models import django.db.models.deletion @@ -9,8 +9,8 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('org', '0002_department'), - ('lab', '0011_alter_systemcomponent_system'), + ('org', '0001_initial'), + ('lab', '0001_initial'), ] operations = [ diff --git a/purchases/__init__.py b/src/apps/purchases/migrations/__init__.py similarity index 100% rename from purchases/__init__.py rename to src/apps/purchases/migrations/__init__.py diff --git a/purchases/models.py b/src/apps/purchases/models.py similarity index 92% rename from purchases/models.py rename to src/apps/purchases/models.py index 5827569..18af243 100644 --- a/purchases/models.py +++ b/src/apps/purchases/models.py @@ -1,6 +1,6 @@ from django.db import models -from lab.models import Item, Lab -from org.models import Org, Department +from apps.lab.models import Item, Lab +from apps.org.models import Org, Department class Vendor(models.Model): diff --git a/purchases/templates/purchases/create-purchase.html b/src/apps/purchases/templates/purchases/create-purchase.html similarity index 100% rename from purchases/templates/purchases/create-purchase.html rename to src/apps/purchases/templates/purchases/create-purchase.html diff --git a/purchases/templates/purchases/purchase-detail.html b/src/apps/purchases/templates/purchases/purchase-detail.html similarity index 100% rename from purchases/templates/purchases/purchase-detail.html rename to src/apps/purchases/templates/purchases/purchase-detail.html diff --git a/purchases/templates/purchases/purchase-list.html b/src/apps/purchases/templates/purchases/purchase-list.html similarity index 100% rename from purchases/templates/purchases/purchase-list.html rename to src/apps/purchases/templates/purchases/purchase-list.html diff --git a/purchases/templates/purchases/purchase-update.html b/src/apps/purchases/templates/purchases/purchase-update.html similarity index 100% rename from purchases/templates/purchases/purchase-update.html rename to src/apps/purchases/templates/purchases/purchase-update.html diff --git a/purchases/tests.py b/src/apps/purchases/tests.py similarity index 100% rename from purchases/tests.py rename to src/apps/purchases/tests.py diff --git a/purchases/urls.py b/src/apps/purchases/urls.py similarity index 93% rename from purchases/urls.py rename to src/apps/purchases/urls.py index 0d9ff05..3ab33f4 100644 --- a/purchases/urls.py +++ b/src/apps/purchases/urls.py @@ -1,5 +1,5 @@ from django.urls import path -from purchases import views +from apps.purchases import views app_name = 'purchases' diff --git a/purchases/views.py b/src/apps/purchases/views.py similarity index 96% rename from purchases/views.py rename to src/apps/purchases/views.py index 1b93505..350cb3e 100644 --- a/purchases/views.py +++ b/src/apps/purchases/views.py @@ -2,9 +2,9 @@ from django.shortcuts import render, get_object_or_404 from django.urls import reverse from django.views import generic -from org.models import Department -from lab.models import Lab, Item -from purchases.models import Purchase +from apps.org.models import Department +from apps.lab.models import Lab, Item +from apps.purchases.models import Purchase from . forms import PurchaseCreateForm, PurchaseUpdateForm diff --git a/purchases/migrations/__init__.py b/src/config/__init__.py similarity index 100% rename from purchases/migrations/__init__.py rename to src/config/__init__.py diff --git a/main/asgi.py b/src/config/asgi.py similarity index 74% rename from main/asgi.py rename to src/config/asgi.py index 954266b..787b362 100644 --- a/main/asgi.py +++ b/src/config/asgi.py @@ -1,5 +1,5 @@ """ -ASGI config for main project. +ASGI config for config project. It exposes the ASGI callable as a module-level variable named ``application``. @@ -11,6 +11,6 @@ from django.core.asgi import get_asgi_application -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'main.settings.dev') +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') application = get_asgi_application() diff --git a/src/config/settings/__init__.py b/src/config/settings/__init__.py new file mode 100644 index 0000000..80733c7 --- /dev/null +++ b/src/config/settings/__init__.py @@ -0,0 +1 @@ +from . dev import * diff --git a/main/settings/base.py b/src/config/settings/base.py similarity index 91% rename from main/settings/base.py rename to src/config/settings/base.py index 7b718b0..c6d00cd 100644 --- a/main/settings/base.py +++ b/src/config/settings/base.py @@ -15,10 +15,10 @@ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', - 'core.apps.CoreConfig', - 'lab.apps.LabConfig', - 'org.apps.OrgConfig', - 'purchases.apps.PurchasesConfig', + 'apps.core', + 'apps.lab', + 'apps.org', + 'apps.purchases', ] MIDDLEWARE = [ @@ -31,7 +31,7 @@ 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] -ROOT_URLCONF = 'main.urls' +ROOT_URLCONF = 'config.urls' TEMPLATES = [ { @@ -49,7 +49,7 @@ }, ] -WSGI_APPLICATION = 'main.wsgi.application' +WSGI_APPLICATION = 'config.wsgi.application' # Password validation diff --git a/main/settings/dev.py b/src/config/settings/dev.py similarity index 100% rename from main/settings/dev.py rename to src/config/settings/dev.py diff --git a/main/settings/pro.py b/src/config/settings/pro.py similarity index 100% rename from main/settings/pro.py rename to src/config/settings/pro.py diff --git a/main/urls.py b/src/config/urls.py similarity index 74% rename from main/urls.py rename to src/config/urls.py index 77f350d..5fbe876 100644 --- a/main/urls.py +++ b/src/config/urls.py @@ -2,13 +2,13 @@ from django.urls import path, include from django.conf import settings from django.conf.urls.static import static -from core.views import LandingPageView +from apps.core.views import LandingPageView urlpatterns = [ path('admin/', admin.site.urls), path('', LandingPageView.as_view(), name='landing-page'), - path('core/', include('core.urls', namespace='core')), - path('org/', include('org.urls', namespace='org')), + path('core/', include('apps.core.urls', namespace='core')), + path('org/', include('apps.org.urls', namespace='org')), ] if settings.DEBUG: diff --git a/main/wsgi.py b/src/config/wsgi.py similarity index 82% rename from main/wsgi.py rename to src/config/wsgi.py index 2246815..6b9ab03 100644 --- a/main/wsgi.py +++ b/src/config/wsgi.py @@ -11,6 +11,6 @@ from django.core.wsgi import get_wsgi_application -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'main.settings.dev') +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') application = get_wsgi_application() diff --git a/manage.py b/src/manage.py similarity index 89% rename from manage.py rename to src/manage.py index 9c7ff8c..94fa320 100755 --- a/manage.py +++ b/src/manage.py @@ -8,7 +8,7 @@ def main(): """Run administrative tasks.""" dotenv.load_dotenv() - os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'main.settings.dev') + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') try: from django.core.management import execute_from_command_line except ImportError as exc: diff --git a/static/Components/_buttons.scss b/src/static/Components/_buttons.scss similarity index 100% rename from static/Components/_buttons.scss rename to src/static/Components/_buttons.scss diff --git a/static/Components/_components-base.scss b/src/static/Components/_components-base.scss similarity index 100% rename from static/Components/_components-base.scss rename to src/static/Components/_components-base.scss diff --git a/static/Components/_navbar.scss b/src/static/Components/_navbar.scss similarity index 100% rename from static/Components/_navbar.scss rename to src/static/Components/_navbar.scss diff --git a/static/Components/_sub-nav.scss b/src/static/Components/_sub-nav.scss similarity index 100% rename from static/Components/_sub-nav.scss rename to src/static/Components/_sub-nav.scss diff --git a/static/Components/_table.scss b/src/static/Components/_table.scss similarity index 100% rename from static/Components/_table.scss rename to src/static/Components/_table.scss diff --git a/static/base/bootstrap/css/bootstrap.min.css b/src/static/base/bootstrap/css/bootstrap.min.css similarity index 100% rename from static/base/bootstrap/css/bootstrap.min.css rename to src/static/base/bootstrap/css/bootstrap.min.css diff --git a/static/base/bootstrap/js/bootstrap.bundle.min.js b/src/static/base/bootstrap/js/bootstrap.bundle.min.js similarity index 100% rename from static/base/bootstrap/js/bootstrap.bundle.min.js rename to src/static/base/bootstrap/js/bootstrap.bundle.min.js diff --git a/static/base/font-awesome/css/all.min.css b/src/static/base/font-awesome/css/all.min.css similarity index 100% rename from static/base/font-awesome/css/all.min.css rename to src/static/base/font-awesome/css/all.min.css diff --git a/static/base/font-awesome/css/fontawesome.min.css b/src/static/base/font-awesome/css/fontawesome.min.css similarity index 100% rename from static/base/font-awesome/css/fontawesome.min.css rename to src/static/base/font-awesome/css/fontawesome.min.css diff --git a/static/base/font-awesome/webfonts/fa-brands-400.ttf b/src/static/base/font-awesome/webfonts/fa-brands-400.ttf similarity index 100% rename from static/base/font-awesome/webfonts/fa-brands-400.ttf rename to src/static/base/font-awesome/webfonts/fa-brands-400.ttf diff --git a/static/base/font-awesome/webfonts/fa-brands-400.woff2 b/src/static/base/font-awesome/webfonts/fa-brands-400.woff2 similarity index 100% rename from static/base/font-awesome/webfonts/fa-brands-400.woff2 rename to src/static/base/font-awesome/webfonts/fa-brands-400.woff2 diff --git a/static/base/font-awesome/webfonts/fa-regular-400.ttf b/src/static/base/font-awesome/webfonts/fa-regular-400.ttf similarity index 100% rename from static/base/font-awesome/webfonts/fa-regular-400.ttf rename to src/static/base/font-awesome/webfonts/fa-regular-400.ttf diff --git a/static/base/font-awesome/webfonts/fa-regular-400.woff2 b/src/static/base/font-awesome/webfonts/fa-regular-400.woff2 similarity index 100% rename from static/base/font-awesome/webfonts/fa-regular-400.woff2 rename to src/static/base/font-awesome/webfonts/fa-regular-400.woff2 diff --git a/static/base/font-awesome/webfonts/fa-solid-900.ttf b/src/static/base/font-awesome/webfonts/fa-solid-900.ttf similarity index 100% rename from static/base/font-awesome/webfonts/fa-solid-900.ttf rename to src/static/base/font-awesome/webfonts/fa-solid-900.ttf diff --git a/static/base/font-awesome/webfonts/fa-solid-900.woff2 b/src/static/base/font-awesome/webfonts/fa-solid-900.woff2 similarity index 100% rename from static/base/font-awesome/webfonts/fa-solid-900.woff2 rename to src/static/base/font-awesome/webfonts/fa-solid-900.woff2 diff --git a/static/base/font-awesome/webfonts/fa-v4compatibility.ttf b/src/static/base/font-awesome/webfonts/fa-v4compatibility.ttf similarity index 100% rename from static/base/font-awesome/webfonts/fa-v4compatibility.ttf rename to src/static/base/font-awesome/webfonts/fa-v4compatibility.ttf diff --git a/static/base/font-awesome/webfonts/fa-v4compatibility.woff2 b/src/static/base/font-awesome/webfonts/fa-v4compatibility.woff2 similarity index 100% rename from static/base/font-awesome/webfonts/fa-v4compatibility.woff2 rename to src/static/base/font-awesome/webfonts/fa-v4compatibility.woff2 diff --git a/static/base/htmx/htmx.min.js b/src/static/base/htmx/htmx.min.js similarity index 100% rename from static/base/htmx/htmx.min.js rename to src/static/base/htmx/htmx.min.js diff --git a/static/base/img/bg.png b/src/static/base/img/bg.png similarity index 100% rename from static/base/img/bg.png rename to src/static/base/img/bg.png diff --git a/static/base/img/logo.svg b/src/static/base/img/logo.svg similarity index 100% rename from static/base/img/logo.svg rename to src/static/base/img/logo.svg diff --git a/static/base/img/logo1.svg b/src/static/base/img/logo1.svg similarity index 100% rename from static/base/img/logo1.svg rename to src/static/base/img/logo1.svg diff --git a/static/base/img/sfslogo.svg b/src/static/base/img/sfslogo.svg similarity index 100% rename from static/base/img/sfslogo.svg rename to src/static/base/img/sfslogo.svg diff --git a/static/base/sass/_colors.scss b/src/static/base/sass/_colors.scss similarity index 100% rename from static/base/sass/_colors.scss rename to src/static/base/sass/_colors.scss diff --git a/static/base/sass/_typography.scss b/src/static/base/sass/_typography.scss similarity index 100% rename from static/base/sass/_typography.scss rename to src/static/base/sass/_typography.scss diff --git a/static/base/styles/base.css b/src/static/base/styles/base.css similarity index 100% rename from static/base/styles/base.css rename to src/static/base/styles/base.css diff --git a/static/base/styles/base.scss b/src/static/base/styles/base.scss similarity index 100% rename from static/base/styles/base.scss rename to src/static/base/styles/base.scss diff --git a/static/form/style.css b/src/static/form/style.css similarity index 100% rename from static/form/style.css rename to src/static/form/style.css diff --git a/static/form/style.scss b/src/static/form/style.scss similarity index 100% rename from static/form/style.scss rename to src/static/form/style.scss diff --git a/static/org-dashboard/style.css b/src/static/org-dashboard/style.css similarity index 100% rename from static/org-dashboard/style.css rename to src/static/org-dashboard/style.css diff --git a/static/org-dashboard/style.scss b/src/static/org-dashboard/style.scss similarity index 100% rename from static/org-dashboard/style.scss rename to src/static/org-dashboard/style.scss diff --git a/static/register/style.css b/src/static/register/style.css similarity index 100% rename from static/register/style.css rename to src/static/register/style.css diff --git a/static/register/style.scss b/src/static/register/style.scss similarity index 100% rename from static/register/style.scss rename to src/static/register/style.scss diff --git a/templates/base.html b/src/templates/base.html similarity index 100% rename from templates/base.html rename to src/templates/base.html diff --git a/templates/landing_page.html b/src/templates/landing_page.html similarity index 100% rename from templates/landing_page.html rename to src/templates/landing_page.html diff --git a/templates/navbar.html b/src/templates/navbar.html similarity index 100% rename from templates/navbar.html rename to src/templates/navbar.html