horilla-opensource / horilla

Horilla is a free and open source HR software.
https://www.horilla.com/
GNU Lesser General Public License v2.1
161 stars 109 forks source link

Feature Request - Add holidays into work records screen #173

Closed BhuviTheDataGuy closed 4 months ago

BhuviTheDataGuy commented 4 months ago

The work record screen is great and gives visibility into one screen. But end of the month if I want to process the attendance data I need one one holistic table/CSV file/screen to show Present or Absent and holidays.

May 1st is a holiday, so some indication would make sense. image

horilla-opensource commented 4 months ago

Hi @BhuviTheDataGuy , Sure, will add that into the work record screen.

With Regards, Team Horilla

BhuviTheDataGuy commented 4 months ago

Add on to this: Would be great if you provide the export option to Excel sheets of this view. Many companies maintain this structure in excel.

horilla-opensource commented 4 months ago

Yes, we'll add the export option also.

horilla-opensource commented 4 months ago

Hi @BhuviTheDataGuy , The updates have been added to the latest commit for exporting the work records and also display company leave/ holidays.

Please check and let us know if you face any issues. With Regards, Team Horilla

BhuviTheDataGuy commented 4 months ago

After the upgrade Im getting this error

relation "leave_leavegeneralsetting" does not exist LINE 1: SELECT 1 AS "a" FROM "leave_leavegeneralsetting" LIMIT 1

horilla-opensource commented 4 months ago

Did you run the migration commands?

BhuviTheDataGuy commented 4 months ago

Something wrong

May be due to this - https://github.com/horilla-opensource/horilla/issues/170 ?

Traceback (most recent call last):
  File "/opt/horilla/manage.py", line 22, in <module>
    main()
  File "/opt/horilla/manage.py", line 18, in main
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python3.10/dist-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python3.10/dist-packages/django/core/management/__init__.py", line 436, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python3.10/dist-packages/django/core/management/base.py", line 412, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/local/lib/python3.10/dist-packages/django/core/management/base.py", line 453, in execute
    self.check()
  File "/usr/local/lib/python3.10/dist-packages/django/core/management/base.py", line 485, in check
    all_issues = checks.run_checks(
  File "/usr/local/lib/python3.10/dist-packages/django/core/checks/registry.py", line 88, in run_checks
    new_errors = check(app_configs=app_configs, databases=databases)
  File "/usr/local/lib/python3.10/dist-packages/django/core/checks/urls.py", line 14, in check_url_config
    return check_resolver(resolver)
  File "/usr/local/lib/python3.10/dist-packages/django/core/checks/urls.py", line 24, in check_resolver
    return check_method()
  File "/usr/local/lib/python3.10/dist-packages/django/urls/resolvers.py", line 494, in check
    for pattern in self.url_patterns:
  File "/usr/local/lib/python3.10/dist-packages/django/utils/functional.py", line 57, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/usr/local/lib/python3.10/dist-packages/django/urls/resolvers.py", line 715, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
  File "/usr/local/lib/python3.10/dist-packages/django/utils/functional.py", line 57, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/usr/local/lib/python3.10/dist-packages/django/urls/resolvers.py", line 708, in urlconf_module
    return import_module(self.urlconf_name)
  File "/usr/lib/python3.10/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/opt/horilla/horilla/urls.py", line 47, in <module>
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
AttributeError: module 'horilla.settings' has no attribute 'MEDIA_ROOT'
horilla-opensource commented 4 months ago

Yes, sorry to mention that. We have made changes in the urls.py which could have overwritten the contents you have made earlier in the urls.py for the S3 bucket configuration. You can just comment out the if loop inside the horilla/urls.py which we have done earlier in the #170 and it should work fine.

With Regards, Team Horilla

BhuviTheDataGuy commented 4 months ago
root@ip-10-10-28-15:/opt/horilla# python3 manage.py migrate
Operations to perform:
  Apply all migrations: admin, asset, attendance, auth, base, contenttypes, django_apscheduler, django_ses, employee, helpdesk, horilla_audit, horilla_documents, leave, notifications, offboarding, onboarding, payroll, pms, recruitment, sessions
Running migrations:
  No migrations to apply.
horilla-opensource commented 4 months ago

Hi @BhuviTheDataGuy , I think its an issue with the migration not being applied correctly. Can you check inside the leave module, the last migration file (leave/migrations). Within that file you can find the content similar to the one below:

migrations.CreateModel(
            name='LeaveGeneralSetting',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('created_at', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Created At')),
                ('is_active', models.BooleanField(default=True, verbose_name='Is Active')),
                ('compensatory_leave', models.BooleanField(default=True)),
                ('company_id', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='base.company')),
                ('created_by', models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='Created By')),
            ],
            options={
                'abstract': False,
            },
        ),

Remove this section from that file and rerun the migrations command again. This should fix the issue.

With Regards, Team Horilla

BhuviTheDataGuy commented 4 months ago

Approving a leave leads to this error

ProgrammingError at /leave/request-approve/10
column leave_leavetype.is_compensatory_leave does not exist
LINE 1: ...pany_leave", "leave_leavetype"."exclude_holiday", "leave_lea...
horilla-opensource commented 4 months ago

Is this error coming up after running the migrations command ?

BhuviTheDataGuy commented 4 months ago

No,

everything was working but any leave approval button throws this error

horilla-opensource commented 4 months ago

Sorry for the inconvenience. As a walkaround, can you check with the last two migrations file in the leave module and check for the below line :

migrations.AddField(
            model_name='leavetype',
            name='is_compensatory_leave',
            field=models.BooleanField(default=False),
        ),

Remove this line and rerun the migrations command. This should fix the issue. We'll sort out the reason for this issue meanwhile.

With Regards, Team Horilla

BhuviTheDataGuy commented 4 months ago

I dont see these lines.

2 files inside the leave/migrations/ 0001_initial.py 0002_leavegeneralsetting.py

Or give the table name, and column name with the data type. I'll manually add this into the table

horilla-opensource commented 4 months ago

Inside the last migrations file can you add these lines inside the operations like in the screenshot:

migrations.AddField(
            model_name='leavetype',
            name='is_compensatory_leave',
            field=models.BooleanField(default=False),
        ),
Screenshot 2024-05-09 at 7 21 29 PM
BhuviTheDataGuy commented 4 months ago

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion

class Migration(migrations.Migration):

    dependencies = [
        ('base', '0002_initial'),
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
        ('leave', '0001_initial'),
    ]

    operations = [
        migrations.CreateModel(
            name='LeaveGeneralSetting',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('created_at', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Created At')),
                ('is_active', models.BooleanField(default=True, verbose_name='Is Active')),
                ('compensatory_leave', models.BooleanField(default=True)),
                ('company_id', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='base.company')),
                ('created_by', models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='Created By')),
            ],
            options={
                'abstract': False,
            },
        ),
        migrations.AddField(
            model_name='leavetype',
            name='is_compensatory_leave',
            field=models.BooleanField(default=False),
        ),
    ]

root@ip-10-10-28-15:/opt/horilla# python3 manage.py makemigrations No changes detected

BhuviTheDataGuy commented 4 months ago

The employee profile view also gives the same error image

horilla-opensource commented 4 months ago

Hi @BhuviTheDataGuy , Can you share the last migration file contents which includes the leave model data's (maybe last two or three migration file contents) ?

With Regards, Team Horilla

BhuviTheDataGuy commented 4 months ago

I dont what is last migration file,

but inside the horilla/leave/migrations/ I have 2 files, the 2nd file is shared in previous command

# Generated by Django 4.2.11 on 2024-05-09 11:24

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
import simple_history.models

class Migration(migrations.Migration):

    initial = True

    dependencies = [
        ('base', '0001_initial'),
        ('attendance', '0001_initial'),
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
        ('horilla_audit', '0001_initial'),
        ('employee', '0001_initial'),
    ]

    operations = [
        migrations.CreateModel(
            name='AvailableLeave',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('created_at', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Created At')),
                ('is_active', models.BooleanField(default=True, verbose_name='Is Active')),
                ('available_days', models.FloatField(default=0, verbose_name='Available Days')),
                ('carryforward_days', models.FloatField(default=0, verbose_name='Carryforward Days')),
                ('total_leave_days', models.FloatField(default=0, verbose_name='Total Leave Days')),
                ('assigned_date', models.DateField(default=django.utils.timezone.now, verbose_name='Assigned Date')),
                ('reset_date', models.DateField(blank=True, null=True, verbose_name='Leave Reset Date')),
                ('expired_date', models.DateField(blank=True, null=True, verbose_name='CarryForward Expired Date')),
                ('created_by', models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='Created By')),
                ('employee_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='available_leave', to='employee.employee', verbose_name='Employee')),
            ],
        ),
        migrations.CreateModel(
            name='CompensatoryLeaveRequest',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('created_at', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Created At')),
                ('is_active', models.BooleanField(default=True, verbose_name='Is Active')),
                ('requested_days', models.FloatField(blank=True, null=True)),
                ('requested_date', models.DateField(default=django.utils.timezone.now)),
                ('description', models.TextField(max_length=255)),
                ('status', models.CharField(choices=[('requested', 'Requested'), ('approved', 'Approved'), ('rejected', 'Rejected')], default='requested', max_length=30)),
                ('reject_reason', models.TextField(blank=True, max_length=255)),
                ('attendance_id', models.ManyToManyField(to='attendance.attendance', verbose_name='Attendance')),
                ('created_by', models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='Created By')),
                ('employee_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='employee.employee', verbose_name='Employee')),
            ],
            options={
                'ordering': ['-id'],
            },
        ),
        migrations.AddField(
            model_name='leavetype',
            name='is_compensatory_leave',
            field=models.BooleanField(default=False),
        ),
        migrations.CreateModel(
            name='LeaveAllocationRequest',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('created_at', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Created At')),
                ('is_active', models.BooleanField(default=True, verbose_name='Is Active')),
                ('requested_days', models.FloatField(blank=True, null=True)),
                ('requested_date', models.DateField(default=django.utils.timezone.now)),
                ('description', models.TextField(max_length=255)),
                ('attachment', models.FileField(blank=True, null=True, upload_to='leave/leave_attachment')),
                ('status', models.CharField(choices=[('requested', 'Requested'), ('approved', 'Approved'), ('rejected', 'Rejected')], default='requested', max_length=30)),
                ('reject_reason', models.TextField(blank=True, max_length=255)),
                ('created_by', models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='Created By')),
                ('employee_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='employee.employee', verbose_name='Employee')),
            ],
            options={
                'ordering': ['-id'],
            },
        ),
        migrations.CreateModel(
            name='LeaveRequest',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('created_at', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Created At')),
                ('is_active', models.BooleanField(default=True, verbose_name='Is Active')),
                ('start_date', models.DateField(verbose_name='Start Date')),
                ('start_date_breakdown', models.CharField(choices=[('full_day', 'Full Day'), ('first_half', 'First Half'), ('second_half', 'Second Half')], default='full_day', max_length=30, verbose_name='Start Date Breakdown')),
                ('end_date', models.DateField(blank=True, null=True, verbose_name='End Date')),
                ('end_date_breakdown', models.CharField(choices=[('full_day', 'Full Day'), ('first_half', 'First Half'), ('second_half', 'Second Half')], default='full_day', max_length=30, verbose_name='End Date Breakdown')),
                ('requested_days', models.FloatField(blank=True, null=True, verbose_name='Requested Days')),
                ('leave_clashes_count', models.IntegerField(default=0, verbose_name='Leave Clashes Count')),
                ('description', models.TextField(max_length=255, verbose_name='Description')),
                ('attachment', models.FileField(blank=True, null=True, upload_to='leave/leave_attachment', verbose_name='Attachment')),
                ('status', models.CharField(choices=[('requested', 'Requested'), ('approved', 'Approved'), ('cancelled', 'Cancelled'), ('rejected', 'Rejected')], default='requested', max_length=30, verbose_name='Status')),
                ('requested_date', models.DateField(default=django.utils.timezone.now, verbose_name='Created Date')),
                ('approved_available_days', models.FloatField(default=0)),
                ('approved_carryforward_days', models.FloatField(default=0)),
                ('reject_reason', models.TextField(blank=True, max_length=255, verbose_name='Reject Reason')),
                ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='leave_request_created', to='employee.employee', verbose_name='Created By')),
                ('employee_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='employee.employee', verbose_name='Employee')),
            ],
            options={
                'ordering': ['-id'],
            },
        ),
        migrations.CreateModel(
            name='LeaverequestFile',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('file', models.FileField(upload_to='leave/request_files')),
            ],
        ),
        migrations.CreateModel(
            name='RestrictLeave',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('created_at', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Created At')),
                ('is_active', models.BooleanField(default=True, verbose_name='Is Active')),
                ('title', models.CharField(max_length=20)),
                ('start_date', models.DateField(verbose_name='Start Date')),
                ('end_date', models.DateField(verbose_name='End Date')),
                ('description', models.TextField(max_length=255, null=True, verbose_name='Description')),
                ('created_by', models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='Created By')),
                ('department', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='base.department', verbose_name='Department')),
                ('job_position', models.ManyToManyField(blank=True, help_text='If no job positions are specifically selected, the system will consider all job positions under the selected department.', to='base.jobposition', verbose_name='Job Position')),
            ],
            options={
                'abstract': False,
            },
        ),
        migrations.CreateModel(
            name='LeaveType',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('created_at', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Created At')),
                ('is_active', models.BooleanField(default=True, verbose_name='Is Active')),
                ('icon', models.ImageField(blank=True, null=True, upload_to='leave/leave_icon')),
                ('name', models.CharField(max_length=30)),
                ('color', models.CharField(max_length=30, null=True)),
                ('payment', models.CharField(choices=[('paid', 'Paid'), ('unpaid', 'Unpaid')], default='unpaid', max_length=30)),
                ('count', models.IntegerField(default=1, null=True)),
                ('period_in', models.CharField(choices=[('day', 'Day'), ('month', 'Month'), ('year', 'Year')], default='day', max_length=30)),
                ('total_days', models.IntegerField(default=1, null=True)),
                ('reset', models.BooleanField(default=False)),
                ('is_encashable', models.BooleanField(default=False, verbose_name='Is encashable')),
                ('reset_based', models.CharField(blank=True, choices=[('yearly', 'Yearly'), ('monthly', 'Monthly'), ('weekly', 'Weekly')], max_length=30, null=True)),
                ('reset_month', models.CharField(blank=True, choices=[('1', 'Jan'), ('2', 'Feb'), ('3', 'Mar'), ('4', 'Apr'), ('5', 'May'), ('6', 'Jun'), ('7', 'Jul'), ('8', 'Aug'), ('9', 'Sep'), ('10', 'Oct'), ('11', 'Nov'), ('12', 'Dec')], max_length=30)),
                ('reset_day', models.CharField(blank=True, choices=[('last day', 'Last Day'), ('1', '1st'), ('2', '2nd'), ('3', '3rd'), ('4', '4th'), ('5', '5th'), ('6', '6th'), ('7', '7th'), ('8', '8th'), ('9', '9th'), ('10', '10th'), ('11', '11th'), ('12', '12th'), ('13', '13th'), ('14', '14th'), ('15', '15th'), ('16', '16th'), ('17', '17th'), ('18', '18th'), ('19', '19th'), ('20', '20th'), ('21', '21th'), ('22', '22th'), ('23', '23th'), ('24', '24th'), ('25', '25th'), ('26', '26th'), ('27', '27th'), ('28', '28th'), ('29', '29th'), ('30', '30th'), ('31', '31th')], max_length=30, null=True)),
                ('reset_weekend', models.CharField(blank=True, choices=[('0', 'Monday'), ('1', 'Tuesday'), ('2', 'Wednesday'), ('3', 'Thursday'), ('4', 'Friday'), ('5', 'Saturday'), ('6', 'Sunday')], max_length=10, null=True)),
                ('carryforward_type', models.CharField(choices=[('no carryforward', 'No Carry Forward'), ('carryforward', 'Carry Forward'), ('carryforward expire', 'Carry Forward with Expire')], default='no carryforward', max_length=30)),
                ('carryforward_max', models.FloatField(blank=True, null=True)),
                ('carryforward_expire_in', models.IntegerField(blank=True, null=True)),
                ('carryforward_expire_period', models.CharField(blank=True, choices=[('day', 'Day'), ('month', 'Month'), ('year', 'Year')], max_length=30, null=True)),
                ('require_approval', models.CharField(blank=True, choices=[('yes', 'Yes'), ('no', 'No')], default='yes', max_length=30, null=True)),
                ('require_attachment', models.CharField(blank=True, choices=[('yes', 'Yes'), ('no', 'No')], default='no', max_length=30, null=True, verbose_name='Require Attachment')),
                ('exclude_company_leave', models.CharField(choices=[('yes', 'Yes'), ('no', 'No')], default='no', max_length=30)),
                ('exclude_holiday', models.CharField(choices=[('yes', 'Yes'), ('no', 'No')], default='no', max_length=30)),
                ('is_compensatory_leave', models.BooleanField(default=False)),
                ('company_id', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.PROTECT, to='base.company')),
                ('created_by', models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='Created By')),
            ],
            options={
                'ordering': ['-id'],
            },
        ),
        migrations.CreateModel(
            name='LeaveRequestConditionApproval',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('sequence', models.IntegerField()),
                ('is_approved', models.BooleanField(default=False)),
                ('is_rejected', models.BooleanField(default=False)),
                ('leave_request_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='leave.leaverequest')),
                ('manager_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='employee.employee')),
            ],
        ),
        migrations.CreateModel(
            name='LeaverequestComment',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('created_at', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Created At')),
                ('is_active', models.BooleanField(default=True, verbose_name='Is Active')),
                ('comment', models.TextField(max_length=255, null=True, verbose_name='Comment')),
                ('created_by', models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='Created By')),
                ('employee_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='employee.employee')),
                ('files', models.ManyToManyField(blank=True, to='leave.leaverequestfile')),
                ('request_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='leave.leaverequest')),
            ],
            options={
                'abstract': False,
            },
        ),
        migrations.AddField(
            model_name='leaverequest',
            name='leave_type_id',
            field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='leave.leavetype', verbose_name='Leave Type'),
        ),
       # migrations.CreateModel(
       #     name='LeaveGeneralSetting',
       #     fields=[
       #         ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
       #         ('created_at', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Created At')),
       #         ('is_active', models.BooleanField(default=True, verbose_name='Is Active')),
       #         ('compensatory_leave', models.BooleanField(default=True)),
       #         ('company_id', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='base.company')),
       #         ('created_by', models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='Created By')),
       #     ],
       #     options={
       #         'abstract': False,
       #     },
       # ),
        migrations.CreateModel(
            name='LeaveallocationrequestComment',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('created_at', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Created At')),
                ('is_active', models.BooleanField(default=True, verbose_name='Is Active')),
                ('comment', models.TextField(max_length=255, null=True, verbose_name='Comment')),
                ('created_by', models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='Created By')),
                ('employee_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='employee.employee')),
                ('files', models.ManyToManyField(blank=True, to='leave.leaverequestfile')),
                ('request_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='leave.leaveallocationrequest')),
            ],
            options={
                'abstract': False,
            },
        ),
        migrations.AddField(
            model_name='leaveallocationrequest',
            name='leave_type_id',
            field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='leave.leavetype', verbose_name='Leave type'),
        ),
        migrations.CreateModel(
            name='Holiday',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('created_at', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Created At')),
                ('is_active', models.BooleanField(default=True, verbose_name='Is Active')),
                ('name', models.CharField(max_length=30, verbose_name='Name')),
                ('start_date', models.DateField(verbose_name='Start Date')),
                ('end_date', models.DateField(blank=True, null=True, verbose_name='End Date')),
                ('recurring', models.BooleanField(default=False, verbose_name='Recurring')),
                ('company_id', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.PROTECT, to='base.company')),
                ('created_by', models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='Created By')),
            ],
            options={
                'abstract': False,
            },
        ),
        migrations.CreateModel(
            name='HistoricalLeaveRequest',
            fields=[
                ('id', models.BigIntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
                ('created_at', models.DateTimeField(blank=True, editable=False, null=True, verbose_name='Created At')),
                ('is_active', models.BooleanField(default=True, verbose_name='Is Active')),
                ('history_title', models.CharField(blank=True, max_length=20, null=True)),
                ('history_description', models.TextField(null=True)),
                ('history_highlight', models.BooleanField(default=False, null=True)),
                ('start_date', models.DateField(verbose_name='Start Date')),
                ('start_date_breakdown', models.CharField(choices=[('full_day', 'Full Day'), ('first_half', 'First Half'), ('second_half', 'Second Half')], default='full_day', max_length=30, verbose_name='Start Date Breakdown')),
                ('end_date', models.DateField(blank=True, null=True, verbose_name='End Date')),
                ('end_date_breakdown', models.CharField(choices=[('full_day', 'Full Day'), ('first_half', 'First Half'), ('second_half', 'Second Half')], default='full_day', max_length=30, verbose_name='End Date Breakdown')),
                ('requested_days', models.FloatField(blank=True, null=True, verbose_name='Requested Days')),
                ('leave_clashes_count', models.IntegerField(default=0, verbose_name='Leave Clashes Count')),
                ('description', models.TextField(max_length=255, verbose_name='Description')),
                ('attachment', models.TextField(blank=True, max_length=100, null=True, verbose_name='Attachment')),
                ('status', models.CharField(choices=[('requested', 'Requested'), ('approved', 'Approved'), ('cancelled', 'Cancelled'), ('rejected', 'Rejected')], default='requested', max_length=30, verbose_name='Status')),
                ('requested_date', models.DateField(default=django.utils.timezone.now, verbose_name='Created Date')),
                ('approved_available_days', models.FloatField(default=0)),
                ('approved_carryforward_days', models.FloatField(default=0)),
                ('reject_reason', models.TextField(blank=True, max_length=255, verbose_name='Reject Reason')),
                ('history_id', models.AutoField(primary_key=True, serialize=False)),
                ('history_date', models.DateTimeField(db_index=True)),
                ('history_change_reason', models.CharField(max_length=100, null=True)),
                ('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
                ('created_by', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='employee.employee', verbose_name='Created By')),
                ('employee_id', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='employee.employee', verbose_name='Employee')),
                ('history_relation', models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.DO_NOTHING, related_name='history_set', to='leave.leaverequest')),
                ('history_tags', models.ManyToManyField(to='horilla_audit.audittag')),
                ('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
                ('leave_type_id', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='leave.leavetype', verbose_name='Leave Type')),
            ],
            options={
                'verbose_name': 'historical leave request',
                'verbose_name_plural': 'historical leave requests',
                'ordering': ('-history_date', '-history_id'),
                'get_latest_by': ('history_date', 'history_id'),
            },
            bases=(simple_history.models.HistoricalChanges, models.Model),
        ),
        migrations.CreateModel(
            name='HistoricalLeaveAllocationRequest',
            fields=[
                ('id', models.BigIntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
                ('created_at', models.DateTimeField(blank=True, editable=False, null=True, verbose_name='Created At')),
                ('is_active', models.BooleanField(default=True, verbose_name='Is Active')),
                ('history_title', models.CharField(blank=True, max_length=20, null=True)),
                ('history_description', models.TextField(null=True)),
                ('history_highlight', models.BooleanField(default=False, null=True)),
                ('requested_days', models.FloatField(blank=True, null=True)),
                ('requested_date', models.DateField(default=django.utils.timezone.now)),
                ('description', models.TextField(max_length=255)),
                ('attachment', models.TextField(blank=True, max_length=100, null=True)),
                ('status', models.CharField(choices=[('requested', 'Requested'), ('approved', 'Approved'), ('rejected', 'Rejected')], default='requested', max_length=30)),
                ('reject_reason', models.TextField(blank=True, max_length=255)),
                ('history_id', models.AutoField(primary_key=True, serialize=False)),
                ('history_date', models.DateTimeField(db_index=True)),
                ('history_change_reason', models.CharField(max_length=100, null=True)),
                ('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
                ('created_by', models.ForeignKey(blank=True, db_constraint=False, editable=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Created By')),
                ('employee_id', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='employee.employee', verbose_name='Employee')),
                ('history_relation', models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.DO_NOTHING, related_name='history_set', to='leave.leaveallocationrequest')),
                ('history_tags', models.ManyToManyField(to='horilla_audit.audittag')),
                ('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
                ('leave_type_id', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='leave.leavetype', verbose_name='Leave type')),
            ],
            options={
                'verbose_name': 'historical leave allocation request',
                'verbose_name_plural': 'historical leave allocation requests',
                'ordering': ('-history_date', '-history_id'),
                'get_latest_by': ('history_date', 'history_id'),
            },
            bases=(simple_history.models.HistoricalChanges, models.Model),
        ),
        migrations.CreateModel(
            name='HistoricalCompensatoryLeaveRequest',
            fields=[
                ('id', models.BigIntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
                ('created_at', models.DateTimeField(blank=True, editable=False, null=True, verbose_name='Created At')),
                ('is_active', models.BooleanField(default=True, verbose_name='Is Active')),
                ('history_title', models.CharField(blank=True, max_length=20, null=True)),
                ('history_description', models.TextField(null=True)),
                ('history_highlight', models.BooleanField(default=False, null=True)),
                ('requested_days', models.FloatField(blank=True, null=True)),
                ('requested_date', models.DateField(default=django.utils.timezone.now)),
                ('description', models.TextField(max_length=255)),
                ('status', models.CharField(choices=[('requested', 'Requested'), ('approved', 'Approved'), ('rejected', 'Rejected')], default='requested', max_length=30)),
                ('reject_reason', models.TextField(blank=True, max_length=255)),
                ('history_id', models.AutoField(primary_key=True, serialize=False)),
                ('history_date', models.DateTimeField(db_index=True)),
                ('history_change_reason', models.CharField(max_length=100, null=True)),
                ('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
                ('created_by', models.ForeignKey(blank=True, db_constraint=False, editable=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Created By')),
                ('employee_id', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='employee.employee', verbose_name='Employee')),
                ('history_relation', models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.DO_NOTHING, related_name='history_set', to='leave.compensatoryleaverequest')),
                ('history_tags', models.ManyToManyField(to='horilla_audit.audittag')),
                ('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
                ('leave_type_id', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='leave.leavetype', verbose_name='Leave type')),
            ],
            options={
                'verbose_name': 'historical compensatory leave request',
                'verbose_name_plural': 'historical compensatory leave requests',
                'ordering': ('-history_date', '-history_id'),
                'get_latest_by': ('history_date', 'history_id'),
            },
            bases=(simple_history.models.HistoricalChanges, models.Model),
        ),
        migrations.CreateModel(
            name='HistoricalAvailableLeave',
            fields=[
                ('id', models.BigIntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
                ('created_at', models.DateTimeField(blank=True, editable=False, null=True, verbose_name='Created At')),
                ('is_active', models.BooleanField(default=True, verbose_name='Is Active')),
                ('history_title', models.CharField(blank=True, max_length=20, null=True)),
                ('history_description', models.TextField(null=True)),
                ('history_highlight', models.BooleanField(default=False, null=True)),
                ('available_days', models.FloatField(default=0, verbose_name='Available Days')),
                ('carryforward_days', models.FloatField(default=0, verbose_name='Carryforward Days')),
                ('total_leave_days', models.FloatField(default=0, verbose_name='Total Leave Days')),
                ('assigned_date', models.DateField(default=django.utils.timezone.now, verbose_name='Assigned Date')),
                ('reset_date', models.DateField(blank=True, null=True, verbose_name='Leave Reset Date')),
                ('expired_date', models.DateField(blank=True, null=True, verbose_name='CarryForward Expired Date')),
                ('history_id', models.AutoField(primary_key=True, serialize=False)),
                ('history_date', models.DateTimeField(db_index=True)),
                ('history_change_reason', models.CharField(max_length=100, null=True)),
                ('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
                ('created_by', models.ForeignKey(blank=True, db_constraint=False, editable=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Created By')),
                ('employee_id', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='employee.employee', verbose_name='Employee')),
                ('history_relation', models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.DO_NOTHING, related_name='history_set', to='leave.availableleave')),
                ('history_tags', models.ManyToManyField(to='horilla_audit.audittag')),
                ('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
                ('leave_type_id', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='leave.leavetype', verbose_name='Leave type')),
            ],
            options={
                'verbose_name': 'historical available leave',
                'verbose_name_plural': 'historical available leaves',
                'ordering': ('-history_date', '-history_id'),
                'get_latest_by': ('history_date', 'history_id'),
            },
            bases=(simple_history.models.HistoricalChanges, models.Model),
        ),
        migrations.CreateModel(
            name='CompensatoryLeaverequestComment',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('created_at', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Created At')),
                ('is_active', models.BooleanField(default=True, verbose_name='Is Active')),
                ('comment', models.TextField(max_length=255, null=True, verbose_name='Comment')),
                ('created_by', models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='Created By')),
                ('employee_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='employee.employee')),
                ('files', models.ManyToManyField(blank=True, to='leave.leaverequestfile')),
                ('request_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='leave.compensatoryleaverequest')),
            ],
            options={
                'abstract': False,
            },
        ),
        migrations.AddField(
            model_name='compensatoryleaverequest',
            name='leave_type_id',
            field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='leave.leavetype', verbose_name='Leave type'),
        ),
        migrations.AddField(
            model_name='availableleave',
            name='leave_type_id',
            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='employee_available_leave', to='leave.leavetype', verbose_name='Leave type'),
        ),
        migrations.CreateModel(
            name='CompanyLeave',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('created_at', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Created At')),
                ('is_active', models.BooleanField(default=True, verbose_name='Is Active')),
                ('based_on_week', models.CharField(blank=True, choices=[('0', 'First Week'), ('1', 'Second Week'), ('2', 'Third Week'), ('3', 'Fourth Week'), ('4', 'Fifth Week')], max_length=100, null=True)),
                ('based_on_week_day', models.CharField(choices=[('0', 'Monday'), ('1', 'Tuesday'), ('2', 'Wednesday'), ('3', 'Thursday'), ('4', 'Friday'), ('5', 'Saturday'), ('6', 'Sunday')], max_length=100)),
                ('company_id', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.PROTECT, to='base.company')),
                ('created_by', models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='Created By')),
            ],
            options={
                'unique_together': {('based_on_week', 'based_on_week_day')},
            },
        ),
        migrations.AlterUniqueTogether(
            name='availableleave',
            unique_together={('leave_type_id', 'employee_id')},
        ),
    ]
BhuviTheDataGuy commented 4 months ago

Now getting the error while deleting the attendance request

ProgrammingError at /attendance/attendance-delete/41/
relation "leave_compensatoryleaverequest_attendance_id" does not exist
LINE 1: DELETE FROM "leave_compensatoryleaverequest_attendance_id" W...
BhuviTheDataGuy commented 4 months ago

Thanks @horilla-opensource for help us on this,

the fix was, to comment on all the lines that belong to the Compensatory model. There were 3 models. After that running the migration will solve this.