first comit
This commit is contained in:
0
hrm/__init__.py
Executable file
0
hrm/__init__.py
Executable file
BIN
hrm/__pycache__/__init__.cpython-310.pyc
Executable file
BIN
hrm/__pycache__/__init__.cpython-310.pyc
Executable file
Binary file not shown.
BIN
hrm/__pycache__/admin.cpython-310.pyc
Normal file
BIN
hrm/__pycache__/admin.cpython-310.pyc
Normal file
Binary file not shown.
BIN
hrm/__pycache__/apps.cpython-310.pyc
Normal file
BIN
hrm/__pycache__/apps.cpython-310.pyc
Normal file
Binary file not shown.
BIN
hrm/__pycache__/models.cpython-310.pyc
Normal file
BIN
hrm/__pycache__/models.cpython-310.pyc
Normal file
Binary file not shown.
BIN
hrm/__pycache__/urls.cpython-310.pyc
Normal file
BIN
hrm/__pycache__/urls.cpython-310.pyc
Normal file
Binary file not shown.
BIN
hrm/__pycache__/views.cpython-310.pyc
Normal file
BIN
hrm/__pycache__/views.cpython-310.pyc
Normal file
Binary file not shown.
22
hrm/admin.py
Executable file
22
hrm/admin.py
Executable file
@@ -0,0 +1,22 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
from hrm.models import *
|
||||
|
||||
class employeeAdmin(admin.ModelAdmin):
|
||||
list_display = ['employee', 'job_title', 'department', 'company']
|
||||
|
||||
class departmentAdmin(admin.ModelAdmin):
|
||||
list_display = ['name', 'manager']
|
||||
|
||||
class companyAdmin(admin.ModelAdmin):
|
||||
list_display = ['name']
|
||||
|
||||
class absenceAdmin(admin.ModelAdmin):
|
||||
list_display = ['days_taken', 'date_from', 'date_to']
|
||||
|
||||
admin.site.register(employee, employeeAdmin)
|
||||
admin.site.register(department, departmentAdmin)
|
||||
admin.site.register(company,companyAdmin)
|
||||
admin.site.register(absence_days, absenceAdmin)
|
||||
admin.site.register(homepage_links)
|
||||
6
hrm/apps.py
Executable file
6
hrm/apps.py
Executable file
@@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class HrmConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'hrm'
|
||||
65
hrm/migrations/0001_initial.py
Normal file
65
hrm/migrations/0001_initial.py
Normal file
@@ -0,0 +1,65 @@
|
||||
# Generated by Django 5.0.2 on 2024-02-19 15:39
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='pay_structure',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(blank=True, max_length=300, null=True)),
|
||||
('rate', models.CharField(blank=True, max_length=300, null=True)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='department',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(blank=True, max_length=300, null=True)),
|
||||
('manager', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='manager', to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='employee',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('preferred_name', models.CharField(blank=True, max_length=150, null=True)),
|
||||
('job_title', models.CharField(blank=True, max_length=100, null=True)),
|
||||
('contact_number', models.CharField(blank=True, max_length=15, null=True)),
|
||||
('address_street', models.CharField(blank=True, max_length=300, null=True)),
|
||||
('address_city', models.CharField(blank=True, max_length=300, null=True)),
|
||||
('address_country', models.CharField(blank=True, default='United Kingdom', max_length=300, null=True)),
|
||||
('address_postcode', models.CharField(blank=True, max_length=300, null=True)),
|
||||
('emergency_contact_name', models.CharField(blank=True, max_length=300, null=True)),
|
||||
('emergency_contact_relationship', models.CharField(blank=True, max_length=300, null=True)),
|
||||
('emergency_contact_address_street', models.CharField(blank=True, max_length=300, null=True)),
|
||||
('emergency_contact_address_city', models.CharField(blank=True, max_length=300, null=True)),
|
||||
('emergency_contact_address_country', models.CharField(blank=True, default='United Kingdom', max_length=300, null=True)),
|
||||
('emergency_contact_address_postcode', models.CharField(blank=True, max_length=300, null=True)),
|
||||
('emergency_contact_phone_number', models.CharField(blank=True, max_length=15, null=True)),
|
||||
('emergency_contact_alternative_number', models.CharField(blank=True, max_length=15, null=True)),
|
||||
('holiday_days_allocated', models.IntegerField(default=28)),
|
||||
('holiday_days_remaining', models.IntegerField(default=28)),
|
||||
('salary', models.CharField(blank=True, max_length=100, null=True)),
|
||||
('contract_start_date', models.DateField(auto_now_add=True)),
|
||||
('contract_end_date', models.DateField(blank=True, null=True)),
|
||||
('employee_company', models.CharField(blank=True, max_length=150, null=True)),
|
||||
('employee_vat_number', models.CharField(blank=True, max_length=150, null=True)),
|
||||
('department', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='department', to=settings.AUTH_USER_MODEL)),
|
||||
('employee', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='employee', to=settings.AUTH_USER_MODEL)),
|
||||
('line_manager', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='line_manager', to=settings.AUTH_USER_MODEL)),
|
||||
('pay_structure', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='pay_structure', to='hrm.pay_structure')),
|
||||
],
|
||||
),
|
||||
]
|
||||
19
hrm/migrations/0002_alter_employee_department.py
Normal file
19
hrm/migrations/0002_alter_employee_department.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# Generated by Django 5.0.2 on 2024-02-19 15:41
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('hrm', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='employee',
|
||||
name='department',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='department', to='hrm.department'),
|
||||
),
|
||||
]
|
||||
18
hrm/migrations/0003_alter_pay_structure_rate.py
Normal file
18
hrm/migrations/0003_alter_pay_structure_rate.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.0.2 on 2024-02-19 15:45
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('hrm', '0002_alter_employee_department'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='pay_structure',
|
||||
name='rate',
|
||||
field=models.CharField(blank=True, choices=[('Once', 'One Off'), ('Day', 'Daily'), ('Week', 'Monthly'), ('Month', 'Monthly')], max_length=300, null=True),
|
||||
),
|
||||
]
|
||||
18
hrm/migrations/0004_alter_employee_contract_start_date.py
Normal file
18
hrm/migrations/0004_alter_employee_contract_start_date.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.0.2 on 2024-02-19 15:45
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('hrm', '0003_alter_pay_structure_rate'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='employee',
|
||||
name='contract_start_date',
|
||||
field=models.DateField(blank=True, null=True),
|
||||
),
|
||||
]
|
||||
19
hrm/migrations/0005_employee_signature.py
Normal file
19
hrm/migrations/0005_employee_signature.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# Generated by Django 5.0.2 on 2024-02-19 15:48
|
||||
|
||||
import jsignature.fields
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('hrm', '0004_alter_employee_contract_start_date'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='employee',
|
||||
name='signature',
|
||||
field=jsignature.fields.JSignatureField(blank=True, null=True),
|
||||
),
|
||||
]
|
||||
26
hrm/migrations/0006_company_employee_company.py
Normal file
26
hrm/migrations/0006_company_employee_company.py
Normal file
@@ -0,0 +1,26 @@
|
||||
# Generated by Django 5.0.2 on 2024-02-19 18:17
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('hrm', '0005_employee_signature'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='company',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(blank=True, max_length=300, null=True)),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='employee',
|
||||
name='company',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='company', to='hrm.company'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,43 @@
|
||||
# Generated by Django 5.0.2 on 2024-02-19 18:28
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('hrm', '0006_company_employee_company'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='company',
|
||||
name='address_city',
|
||||
field=models.CharField(blank=True, max_length=300, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='company',
|
||||
name='address_country',
|
||||
field=models.CharField(blank=True, default='United Kingdom', max_length=300, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='company',
|
||||
name='address_postcode',
|
||||
field=models.CharField(blank=True, max_length=300, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='company',
|
||||
name='address_street',
|
||||
field=models.CharField(blank=True, max_length=300, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='company',
|
||||
name='contact_number',
|
||||
field=models.CharField(blank=True, max_length=15, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='company',
|
||||
name='vat_number',
|
||||
field=models.CharField(blank=True, max_length=300, null=True),
|
||||
),
|
||||
]
|
||||
22
hrm/migrations/0008_alter_company_options_employee_email.py
Normal file
22
hrm/migrations/0008_alter_company_options_employee_email.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# Generated by Django 5.0.2 on 2024-02-21 10:29
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('hrm', '0007_company_address_city_company_address_country_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='company',
|
||||
options={'verbose_name_plural': 'Companies'},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='employee',
|
||||
name='email',
|
||||
field=models.EmailField(blank=True, max_length=254, null=True),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,26 @@
|
||||
# Generated by Django 5.0.2 on 2024-02-21 13:55
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('hrm', '0008_alter_company_options_employee_email'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='employee',
|
||||
name='pay_structure',
|
||||
field=models.CharField(blank=True, choices=[('Once', 'One Off'), ('Day', 'Daily'), ('Week', 'Monthly'), ('Month', 'Monthly'), ('Invoice', 'Invoice')], max_length=300, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='employee',
|
||||
name='pay_rate',
|
||||
field=models.CharField(blank=True, max_length=100, null=True),
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='pay_structure',
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,24 @@
|
||||
# Generated by Django 5.0.2 on 2024-02-21 14:13
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('auth', '0012_alter_user_first_name_max_length'),
|
||||
('hrm', '0009_alter_employee_pay_structure_employee_pay_rate_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='employee',
|
||||
name='groups',
|
||||
field=models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='employee_set', related_query_name='employee', to='auth.group', verbose_name='groups'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='employee',
|
||||
name='pay_structure',
|
||||
field=models.CharField(blank=True, choices=[('Once', 'One Off'), ('Daily', 'Daily'), ('Weekly', 'Weekly'), ('Monthly', 'Monthly'), ('Invoice', 'Invoice')], max_length=300, null=True),
|
||||
),
|
||||
]
|
||||
18
hrm/migrations/0011_employee_sick_days_taken.py
Normal file
18
hrm/migrations/0011_employee_sick_days_taken.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.0.2 on 2024-02-21 18:02
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('hrm', '0010_employee_groups_alter_employee_pay_structure'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='employee',
|
||||
name='sick_days_taken',
|
||||
field=models.IntegerField(default=0),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,31 @@
|
||||
# Generated by Django 5.0.2 on 2024-02-21 18:14
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('hrm', '0011_employee_sick_days_taken'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name='employee',
|
||||
old_name='sick_days_taken',
|
||||
new_name='days_absent',
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='absence_days',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('days_taken', models.IntegerField(default=0)),
|
||||
('date_from', models.DateField(blank=True, null=True)),
|
||||
('date_to', models.DateField(blank=True, null=True)),
|
||||
('authorised', models.BooleanField(default=False)),
|
||||
('authorised_by', models.OneToOneField(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='authorised_by', to='hrm.employee')),
|
||||
('taken_by', models.OneToOneField(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='taken_by', to='hrm.employee')),
|
||||
],
|
||||
),
|
||||
]
|
||||
27
hrm/migrations/0013_alter_absence_days_options_and_more.py
Normal file
27
hrm/migrations/0013_alter_absence_days_options_and_more.py
Normal file
@@ -0,0 +1,27 @@
|
||||
# Generated by Django 5.0.2 on 2024-02-21 18:27
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('hrm', '0012_rename_sick_days_taken_employee_days_absent_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='absence_days',
|
||||
options={'verbose_name_plural': 'Absence Days'},
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name='employee',
|
||||
old_name='days_absent',
|
||||
new_name='days_absent_authorised',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='employee',
|
||||
name='days_absent_unauthorised',
|
||||
field=models.IntegerField(default=0),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,31 @@
|
||||
# Generated by Django 5.0.2 on 2024-02-21 18:32
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('hrm', '0013_alter_absence_days_options_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='absence_days',
|
||||
name='authorised_by',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='absence_days',
|
||||
name='taken_by',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='absence_days',
|
||||
name='authorised_by',
|
||||
field=models.ManyToManyField(blank=True, default=None, null=True, related_name='authorised_by', to='hrm.employee'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='absence_days',
|
||||
name='taken_by',
|
||||
field=models.ManyToManyField(blank=True, default=None, null=True, related_name='taken_by', to='hrm.employee'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,32 @@
|
||||
# Generated by Django 5.0.2 on 2024-02-21 18:34
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('hrm', '0014_remove_absence_days_authorised_by_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='absence_days',
|
||||
name='authorised_by',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='absence_days',
|
||||
name='taken_by',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='absence_days',
|
||||
name='authorised_by',
|
||||
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='authorised_by', to='hrm.employee'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='absence_days',
|
||||
name='taken_by',
|
||||
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='taken_by', to='hrm.employee'),
|
||||
),
|
||||
]
|
||||
18
hrm/migrations/0016_company_departments.py
Normal file
18
hrm/migrations/0016_company_departments.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.0.2 on 2024-02-22 09:58
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('hrm', '0015_remove_absence_days_authorised_by_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='company',
|
||||
name='departments',
|
||||
field=models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='department_set', related_query_name='departments', to='hrm.department', verbose_name='departments'),
|
||||
),
|
||||
]
|
||||
18
hrm/migrations/0017_alter_company_name.py
Normal file
18
hrm/migrations/0017_alter_company_name.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.0.2 on 2024-02-22 10:22
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('hrm', '0016_company_departments'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='company',
|
||||
name='name',
|
||||
field=models.CharField(blank=True, max_length=300, null=True, unique=True),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,23 @@
|
||||
# Generated by Django 5.0.2 on 2024-02-22 11:43
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('hrm', '0017_alter_company_name'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='absence_days',
|
||||
name='is_holiday',
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='absence_days',
|
||||
name='is_request',
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
]
|
||||
19
hrm/migrations/0019_company_year_start_date.py
Normal file
19
hrm/migrations/0019_company_year_start_date.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# Generated by Django 5.0.2 on 2024-02-22 11:49
|
||||
|
||||
import datetime
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('hrm', '0018_absence_days_is_holiday_absence_days_is_request_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='company',
|
||||
name='year_start_date',
|
||||
field=models.DateField(default=datetime.date(1971, 1, 1)),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,22 @@
|
||||
# Generated by Django 5.0.2 on 2024-02-22 11:56
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('hrm', '0019_company_year_start_date'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='absence_days',
|
||||
name='is_holiday',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='absence_days',
|
||||
name='reason',
|
||||
field=models.CharField(blank=True, choices=[('hol', 'Holiday'), ('sick', 'Sick'), ('mat', 'Maternity'), ('pat', 'Paternity'), ('other', 'Other')], max_length=50, null=True),
|
||||
),
|
||||
]
|
||||
21
hrm/migrations/0021_homepage_links.py
Normal file
21
hrm/migrations/0021_homepage_links.py
Normal file
@@ -0,0 +1,21 @@
|
||||
# Generated by Django 5.0.2 on 2024-02-22 15:21
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('hrm', '0020_remove_absence_days_is_holiday_absence_days_reason'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='homepage_links',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(blank=True, default=None, help_text='This is the text that will appear on the homepage.', max_length=100, null=True)),
|
||||
('link', models.URLField()),
|
||||
],
|
||||
),
|
||||
]
|
||||
18
hrm/migrations/0022_homepage_links_enabled.py
Normal file
18
hrm/migrations/0022_homepage_links_enabled.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.0.2 on 2024-02-22 15:45
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('hrm', '0021_homepage_links'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='homepage_links',
|
||||
name='enabled',
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
]
|
||||
18
hrm/migrations/0023_alter_homepage_links_link.py
Normal file
18
hrm/migrations/0023_alter_homepage_links_link.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.0.2 on 2024-02-22 15:56
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('hrm', '0022_homepage_links_enabled'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='homepage_links',
|
||||
name='link',
|
||||
field=models.CharField(blank=True, max_length=200, null=True),
|
||||
),
|
||||
]
|
||||
18
hrm/migrations/0024_alter_company_departments.py
Normal file
18
hrm/migrations/0024_alter_company_departments.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.0.2 on 2024-02-22 18:51
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('hrm', '0023_alter_homepage_links_link'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='company',
|
||||
name='departments',
|
||||
field=models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='company_set', related_query_name='company', to='hrm.department', verbose_name='departments'),
|
||||
),
|
||||
]
|
||||
0
hrm/migrations/__init__.py
Executable file
0
hrm/migrations/__init__.py
Executable file
BIN
hrm/migrations/__pycache__/0001_initial.cpython-310.pyc
Normal file
BIN
hrm/migrations/__pycache__/0001_initial.cpython-310.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
hrm/migrations/__pycache__/0021_homepage_links.cpython-310.pyc
Normal file
BIN
hrm/migrations/__pycache__/0021_homepage_links.cpython-310.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
hrm/migrations/__pycache__/__init__.cpython-310.pyc
Normal file
BIN
hrm/migrations/__pycache__/__init__.cpython-310.pyc
Normal file
Binary file not shown.
247
hrm/models.py
Executable file
247
hrm/models.py
Executable file
@@ -0,0 +1,247 @@
|
||||
from django.db import models
|
||||
from jsignature.fields import JSignatureField
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import Group
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.dispatch import receiver
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
pay_choices = {
|
||||
"Once": "One Off",
|
||||
"Daily": "Daily",
|
||||
"Weekly": "Weekly",
|
||||
"Monthly": "Monthly",
|
||||
"Invoice": "Invoice"
|
||||
}
|
||||
|
||||
absence_reason = {
|
||||
"hol": "Holiday",
|
||||
"sick": "Sick",
|
||||
"mat": "Maternity",
|
||||
"pat": "Paternity",
|
||||
"other": "Other"
|
||||
}
|
||||
def getGroups(self):
|
||||
grps = self.groups.all()
|
||||
groups = []
|
||||
for g in grps:
|
||||
groups.append({'name': g.name})
|
||||
return groups
|
||||
default_date = datetime.strptime("1971-01-01", '%Y-%m-%d').date()
|
||||
|
||||
class department(models.Model):
|
||||
name = models.CharField(max_length=300, blank=True, null=True, )
|
||||
manager = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL,
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
related_name='manager'
|
||||
)
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class company(models.Model):
|
||||
name = models.CharField(max_length=300, blank=True, null=True, unique=True)
|
||||
vat_number = models.CharField(max_length=300, blank=True, null=True, )
|
||||
contact_number = models.CharField(max_length=15, blank=True, null=True, )
|
||||
address_street = models.CharField(max_length=300, blank=True, null=True, )
|
||||
address_city = models.CharField(max_length=300, blank=True, null=True, )
|
||||
address_country = models.CharField(max_length=300, blank=True, null=True, default='United Kingdom')
|
||||
address_postcode = models.CharField(max_length=300, blank=True, null=True, )
|
||||
departments = models.ManyToManyField(
|
||||
department,
|
||||
verbose_name=_("departments"),
|
||||
blank=True,
|
||||
help_text=_(
|
||||
"The groups this user belongs to. A user will get all permissions "
|
||||
"granted to each of their groups."
|
||||
),
|
||||
related_name="company_set",
|
||||
related_query_name="company",
|
||||
)
|
||||
year_start_date = models.DateField(default=default_date)
|
||||
def __str__(self):
|
||||
return self.name
|
||||
class Meta:
|
||||
verbose_name_plural = "Companies"
|
||||
|
||||
class employee(models.Model):
|
||||
employee = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL,
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
related_name='employee'
|
||||
)
|
||||
company = models.ForeignKey(
|
||||
company,
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
related_name='company'
|
||||
)
|
||||
email = models.EmailField(blank=True, null=True)
|
||||
preferred_name = models.CharField(max_length=150, blank=True, null=True, )
|
||||
job_title = models.CharField(max_length=100, blank=True, null=True, )
|
||||
department = models.ForeignKey(
|
||||
department,
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
related_name='department'
|
||||
)
|
||||
line_manager = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL,
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
related_name='line_manager'
|
||||
)
|
||||
contact_number = models.CharField(max_length=15, blank=True, null=True, )
|
||||
address_street = models.CharField(max_length=300, blank=True, null=True, )
|
||||
address_city = models.CharField(max_length=300, blank=True, null=True, )
|
||||
address_country = models.CharField(max_length=300, blank=True, null=True, default='United Kingdom')
|
||||
address_postcode = models.CharField(max_length=300, blank=True, null=True, )
|
||||
emergency_contact_name = models.CharField(max_length=300, blank=True, null=True, )
|
||||
emergency_contact_relationship = models.CharField(max_length=300, blank=True, null=True, )
|
||||
emergency_contact_address_street = models.CharField(max_length=300, blank=True, null=True, )
|
||||
emergency_contact_address_city = models.CharField(max_length=300, blank=True, null=True, )
|
||||
emergency_contact_address_country = models.CharField(max_length=300, blank=True, null=True, default='United Kingdom')
|
||||
emergency_contact_address_postcode = models.CharField(max_length=300, blank=True, null=True, )
|
||||
emergency_contact_phone_number = models.CharField(max_length=15, blank=True, null=True, )
|
||||
emergency_contact_alternative_number = models.CharField(max_length=15, blank=True, null=True, )
|
||||
holiday_days_allocated = models.IntegerField(default=28)
|
||||
holiday_days_remaining = models.IntegerField(default=28)
|
||||
pay_structure = models.CharField(max_length=300, blank=True, null=True, choices=pay_choices)
|
||||
pay_rate = models.CharField(max_length=100, blank=True, null=True,)
|
||||
salary = models.CharField(max_length=100, blank=True, null=True,)
|
||||
contract_start_date = models.DateField(blank=True, null=True)
|
||||
contract_end_date = models.DateField(blank=True, null=True)
|
||||
employee_company = models.CharField(max_length=150, blank=True, null=True, )
|
||||
employee_vat_number = models.CharField(max_length=150, blank=True, null=True, )
|
||||
signature = JSignatureField(blank=True, null=True,)
|
||||
groups = models.ManyToManyField(
|
||||
Group,
|
||||
verbose_name=_("groups"),
|
||||
blank=True,
|
||||
help_text=_(
|
||||
"The groups this user belongs to. A user will get all permissions "
|
||||
"granted to each of their groups."
|
||||
),
|
||||
related_name="employee_set",
|
||||
related_query_name="employee",
|
||||
)
|
||||
days_absent_authorised = models.IntegerField(default=0)
|
||||
days_absent_unauthorised = models.IntegerField(default=0)
|
||||
|
||||
def __str__(self):
|
||||
name = f"{self.employee.first_name} {self.employee.last_name}"
|
||||
return name
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
"id": self.pk,
|
||||
"employee": {"first_name": self.employee.first_name, "last_name": self.employee.last_name, "email": self.employee.email},
|
||||
"company": self.company.name,
|
||||
"email": self.email,
|
||||
"preferred_name": self.preferred_name,
|
||||
"job_title": self.job_title,
|
||||
"department": self.department,
|
||||
"line_manager": {"first_name": self.line_manager.first_name, "last_name": self.line_manager.last_name, "email": self.line_manager.email},
|
||||
"contact_number": self.contact_number,
|
||||
"address_street": self.address_street,
|
||||
"address_city": self.address_city,
|
||||
"address_country": self.address_country,
|
||||
"address_postcode": self.address_postcode,
|
||||
"emergency_contact_name": self.emergency_contact_name,
|
||||
"emergency_contact_relationship": self.emergency_contact_relationship,
|
||||
"emergency_contact_address_street": self.emergency_contact_address_street,
|
||||
"emergency_contact_address_city": self.emergency_contact_address_city,
|
||||
"emergency_contact_address_country": self.emergency_contact_address_country,
|
||||
"emergency_contact_address_postcode": self.emergency_contact_address_postcode,
|
||||
"emergency_contact_phone_number": self.emergency_contact_phone_number,
|
||||
"emergency_contact_alternative_number": self.emergency_contact_alternative_number,
|
||||
"holiday_days_allocated": self.holiday_days_allocated,
|
||||
"holiday_days_remaining": self.holiday_days_remaining,
|
||||
"pay_structure": self.pay_structure,
|
||||
"pay_rate": self.pay_rate,
|
||||
"salary": self.salary,
|
||||
"contract_start_date": self.contract_start_date,
|
||||
"contract_end_date": self.contract_end_date,
|
||||
"employee_company": self.employee_company,
|
||||
"employee_vat_number": self.employee_vat_number,
|
||||
"signature": self.signature,
|
||||
"groups": getGroups(self)
|
||||
}
|
||||
|
||||
class absence_days(models.Model):
|
||||
days_taken = models.IntegerField(default=0)
|
||||
date_from = models.DateField(blank=True, null=True)
|
||||
date_to = models.DateField(blank=True, null=True)
|
||||
reason = models.CharField(max_length=50, blank=True, null=True, choices=absence_reason)
|
||||
is_request = models.BooleanField(default=False)
|
||||
authorised = models.BooleanField(default=False)
|
||||
authorised_by = models.ForeignKey(
|
||||
employee,
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
blank=True,
|
||||
default=None,
|
||||
related_name='authorised_by'
|
||||
)
|
||||
taken_by = models.ForeignKey(
|
||||
employee,
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
blank=True,
|
||||
default=None,
|
||||
related_name='taken_by'
|
||||
)
|
||||
class Meta:
|
||||
verbose_name_plural= 'Absence Days'
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
"days_taken": self.days_taken,
|
||||
"date_from": str(self.date_from),
|
||||
"date_to": str(self.date_to),
|
||||
"reason": self.reason,
|
||||
"is_request": self.is_request,
|
||||
"authorised": self.authorised,
|
||||
"authorised_by": {"first_name": self.employee.authorised_by.first_name, "last_name": self.employee.authorised_by.last_name, "email": self.employee.authorised_by.email},
|
||||
"taken_by": {"first_name": self.employee.taken_by.first_name, "last_name": self.employee.taken_by.last_name, "email": self.employee.taken_by.email}
|
||||
}
|
||||
|
||||
class homepage_links(models.Model):
|
||||
name = models.CharField(
|
||||
max_length=100,
|
||||
default=None,
|
||||
null=True,
|
||||
blank=True,
|
||||
help_text=(
|
||||
"This is the text that will appear on the homepage."
|
||||
)
|
||||
)
|
||||
link = models.CharField(max_length=200, blank=True, null=True)
|
||||
enabled = models.BooleanField(default=False)
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
"name": self.name,
|
||||
"link": self.link,
|
||||
"enabled": self.enabled
|
||||
}
|
||||
|
||||
|
||||
|
||||
@receiver(models.signals.post_save, sender=absence_days)
|
||||
def update_totals(sender, instance, **kwargs):
|
||||
date_last_year = datetime.now() - timedelta(days=365)
|
||||
taa = sender.objects.filter(taken_by=instance.taken_by, is_request=False, authorised=True, date_from__range=[date_last_year, datetime.now()])
|
||||
tua = sender.objects.filter(taken_by=instance.taken_by, is_request=False, authorised=False, date_from__range=[date_last_year, datetime.now()])
|
||||
total_authorised_absences = 0
|
||||
total_unauthorised_absences = 0
|
||||
for days in taa:
|
||||
total_authorised_absences += days.days_taken
|
||||
for days in tua:
|
||||
total_unauthorised_absences += days.days_taken
|
||||
e = employee.objects.get(id=instance.taken_by.id)
|
||||
e.days_absent_authorised = total_authorised_absences
|
||||
e.days_absent_unauthorised = total_unauthorised_absences
|
||||
e.save()
|
||||
3
hrm/tests.py
Executable file
3
hrm/tests.py
Executable file
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
9
hrm/urls.py
Executable file
9
hrm/urls.py
Executable file
@@ -0,0 +1,9 @@
|
||||
from django.contrib import admin
|
||||
from django.urls import path, include
|
||||
from hrm import views
|
||||
|
||||
urlpatterns = [
|
||||
path('', views.index, name='index'),
|
||||
path('profile', views.profile, name='profile'),
|
||||
path('request_holiday', views.request_holiday, name='request_holiday'),
|
||||
]
|
||||
104
hrm/views.py
Executable file
104
hrm/views.py
Executable file
@@ -0,0 +1,104 @@
|
||||
from django.shortcuts import render, get_object_or_404, redirect
|
||||
from django.http import HttpResponseRedirect, HttpResponse, JsonResponse
|
||||
from django.urls import reverse
|
||||
from hrm.models import *
|
||||
from custom_user.models import User
|
||||
from django.contrib.auth.decorators import login_required
|
||||
import json
|
||||
import calendar
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from api.views import sendMail
|
||||
|
||||
#@login_required
|
||||
def index(request):
|
||||
try:
|
||||
user = User.objects.get(id=request.user.id)
|
||||
employee_object = employee.objects.get(employee=user)
|
||||
context = {
|
||||
"employee": employee_object,#
|
||||
"links": homepage_links.objects.all(),
|
||||
"segment": "index"
|
||||
}
|
||||
return render(request, 'hrm/index.html', context)
|
||||
except Exception as e:
|
||||
print(repr(e))
|
||||
context = {
|
||||
"segment": "index"
|
||||
}
|
||||
return redirect(reverse('404'))
|
||||
|
||||
|
||||
#@login_required
|
||||
def profile(request):
|
||||
user = User.objects.get(id=request.user.id)
|
||||
try:
|
||||
employee_object = employee.objects.get(employee=user)
|
||||
print(f"employee = {employee_object}")
|
||||
context = {
|
||||
"employee": employee_object,
|
||||
"segment": "profile"
|
||||
}
|
||||
return render( request, 'hrm/profile.html', context)
|
||||
except Exception as e:
|
||||
print(repr(e))
|
||||
return redirect(reverse('404'))
|
||||
|
||||
|
||||
|
||||
|
||||
workdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
|
||||
def weekday_count(start, end):
|
||||
start_date = datetime.strptime(start, '%Y-%m-%d')
|
||||
end_date = datetime.strptime(end, '%Y-%m-%d')
|
||||
days = 0
|
||||
for i in range((end_date - start_date).days):
|
||||
day = calendar.day_name[(start_date + timedelta(days=i+1)).weekday()]
|
||||
if day in workdays:
|
||||
days += 1
|
||||
return days
|
||||
|
||||
def request_holiday(request):
|
||||
if request.method == 'GET':
|
||||
emp = employee.objects.get(employee=User.objects.get(id=request.user.id))
|
||||
today = datetime.today().strftime('%Y-%m-%d')
|
||||
context ={
|
||||
"segment": "holiday",
|
||||
"today": today,
|
||||
"employee": emp,
|
||||
}
|
||||
return render(request, 'hrm/holiday_request.html', context)
|
||||
elif request.method == 'POST':
|
||||
try:
|
||||
data = json.loads(request.POST.get('data' , ''))
|
||||
days = weekday_count(data['from'], data['to'])
|
||||
emp = employee.objects.get(id=data['employee.id'])
|
||||
requested_days = absence_days.objects.create(
|
||||
days_taken = days,
|
||||
date_from = data['from'],
|
||||
date_to = data['to'],
|
||||
reason = 'hol',
|
||||
is_request=True,
|
||||
taken_by = emp
|
||||
)
|
||||
email_message = """
|
||||
Hello, {{ employee.employee.first_name }}, <br><br>
|
||||
{{ absence_days.requested_by.employee.first_name }} has submitted a new holiday request. <br>
|
||||
Click here to manage this request. <br><br>
|
||||
Thanks,
|
||||
"""
|
||||
sendMail('Holiday Request', email_message, emp.line_manager.email, emp.to_dict(), requested_days.to_dict(), None)
|
||||
message = f"Holiday dates: {data['from']}-{data['to']} <br> has been sent to {emp.line_manager.first_name} {emp.line_manager.last_name} for approval."
|
||||
messageTitle = "Success!"
|
||||
messageStatus = 'text-bg-success'
|
||||
response = JsonResponse({'messageTitle':messageTitle, 'message': message, 'messageStatus':messageStatus})
|
||||
return response
|
||||
except Exception as e:
|
||||
#logger.error(repr(e))
|
||||
print(repr(e))
|
||||
messageTitle = "Oops!"
|
||||
messageStatus = 'text-bg-danger'
|
||||
message = str(e)
|
||||
response = JsonResponse({'messageTitle':messageTitle, 'message': message, 'messageStatus':messageStatus})
|
||||
return response
|
||||
|
||||
Reference in New Issue
Block a user