489 lines
16 KiB
Python
489 lines
16 KiB
Python
"""
|
|
Tests for Salary and Document Management
|
|
"""
|
|
from django.test import TestCase, Client
|
|
from django.contrib.auth import get_user_model
|
|
from django.utils import timezone
|
|
from datetime import date, timedelta
|
|
from decimal import Decimal
|
|
|
|
from core.models import Tenant
|
|
from hr.models import (
|
|
Employee, Department, SalaryInformation, SalaryAdjustment,
|
|
DocumentRequest, DocumentTemplate
|
|
)
|
|
|
|
User = get_user_model()
|
|
|
|
|
|
class SalaryInformationTestCase(TestCase):
|
|
"""Test cases for SalaryInformation model"""
|
|
|
|
def setUp(self):
|
|
"""Set up test data"""
|
|
self.tenant = Tenant.objects.create(
|
|
name="Test Hospital",
|
|
subdomain="test",
|
|
is_active=True
|
|
)
|
|
|
|
self.user = User.objects.create_user(
|
|
username='testuser',
|
|
email='test@example.com',
|
|
password='testpass123',
|
|
tenant=self.tenant
|
|
)
|
|
|
|
self.department = Department.objects.create(
|
|
name="Test Department",
|
|
code="TEST",
|
|
tenant=self.tenant
|
|
)
|
|
|
|
self.employee = Employee.objects.create(
|
|
user=self.user,
|
|
employee_id="EMP001",
|
|
department=self.department,
|
|
job_title="Test Position",
|
|
hire_date=date.today(),
|
|
tenant=self.tenant
|
|
)
|
|
|
|
def test_salary_creation(self):
|
|
"""Test creating a salary record"""
|
|
salary = SalaryInformation.objects.create(
|
|
employee=self.employee,
|
|
basic_salary=Decimal('5000.00'),
|
|
housing_allowance=Decimal('2000.00'),
|
|
transportation_allowance=Decimal('500.00'),
|
|
food_allowance=Decimal('300.00'),
|
|
currency='SAR',
|
|
payment_frequency='MONTHLY',
|
|
effective_date=date.today(),
|
|
tenant=self.tenant,
|
|
created_by=self.user
|
|
)
|
|
|
|
self.assertEqual(salary.employee, self.employee)
|
|
self.assertEqual(salary.basic_salary, Decimal('5000.00'))
|
|
self.assertEqual(salary.total_salary, Decimal('7800.00'))
|
|
self.assertTrue(salary.is_active)
|
|
|
|
def test_salary_total_calculation(self):
|
|
"""Test automatic total salary calculation"""
|
|
salary = SalaryInformation.objects.create(
|
|
employee=self.employee,
|
|
basic_salary=Decimal('10000.00'),
|
|
housing_allowance=Decimal('3000.00'),
|
|
transportation_allowance=Decimal('1000.00'),
|
|
food_allowance=Decimal('500.00'),
|
|
currency='SAR',
|
|
payment_frequency='MONTHLY',
|
|
effective_date=date.today(),
|
|
tenant=self.tenant,
|
|
created_by=self.user
|
|
)
|
|
|
|
expected_total = Decimal('14500.00')
|
|
self.assertEqual(salary.total_salary, expected_total)
|
|
|
|
def test_iban_validation(self):
|
|
"""Test IBAN validation for Saudi format"""
|
|
salary = SalaryInformation(
|
|
employee=self.employee,
|
|
basic_salary=Decimal('5000.00'),
|
|
currency='SAR',
|
|
payment_frequency='MONTHLY',
|
|
effective_date=date.today(),
|
|
iban='SA0380000000608010167519', # Valid Saudi IBAN
|
|
tenant=self.tenant,
|
|
created_by=self.user
|
|
)
|
|
|
|
# Should not raise validation error
|
|
salary.full_clean()
|
|
salary.save()
|
|
self.assertEqual(len(salary.iban), 24)
|
|
|
|
|
|
class SalaryAdjustmentTestCase(TestCase):
|
|
"""Test cases for SalaryAdjustment model"""
|
|
|
|
def setUp(self):
|
|
"""Set up test data"""
|
|
self.tenant = Tenant.objects.create(
|
|
name="Test Hospital",
|
|
subdomain="test",
|
|
is_active=True
|
|
)
|
|
|
|
self.user = User.objects.create_user(
|
|
username='testuser',
|
|
email='test@example.com',
|
|
password='testpass123',
|
|
tenant=self.tenant
|
|
)
|
|
|
|
self.department = Department.objects.create(
|
|
name="Test Department",
|
|
code="TEST",
|
|
tenant=self.tenant
|
|
)
|
|
|
|
self.employee = Employee.objects.create(
|
|
user=self.user,
|
|
employee_id="EMP001",
|
|
department=self.department,
|
|
job_title="Test Position",
|
|
hire_date=date.today(),
|
|
tenant=self.tenant
|
|
)
|
|
|
|
self.previous_salary = SalaryInformation.objects.create(
|
|
employee=self.employee,
|
|
basic_salary=Decimal('5000.00'),
|
|
currency='SAR',
|
|
payment_frequency='MONTHLY',
|
|
effective_date=date.today() - timedelta(days=365),
|
|
tenant=self.tenant,
|
|
created_by=self.user
|
|
)
|
|
|
|
self.new_salary = SalaryInformation.objects.create(
|
|
employee=self.employee,
|
|
basic_salary=Decimal('6000.00'),
|
|
currency='SAR',
|
|
payment_frequency='MONTHLY',
|
|
effective_date=date.today(),
|
|
tenant=self.tenant,
|
|
created_by=self.user
|
|
)
|
|
|
|
def test_adjustment_creation(self):
|
|
"""Test creating a salary adjustment"""
|
|
adjustment = SalaryAdjustment.objects.create(
|
|
employee=self.employee,
|
|
previous_salary=self.previous_salary,
|
|
new_salary=self.new_salary,
|
|
adjustment_type='ANNUAL_INCREMENT',
|
|
adjustment_date=date.today(),
|
|
reason='Annual performance review',
|
|
tenant=self.tenant
|
|
)
|
|
|
|
self.assertEqual(adjustment.employee, self.employee)
|
|
self.assertEqual(adjustment.adjustment_type, 'ANNUAL_INCREMENT')
|
|
|
|
def test_adjustment_calculations(self):
|
|
"""Test automatic calculation of amount and percentage change"""
|
|
adjustment = SalaryAdjustment.objects.create(
|
|
employee=self.employee,
|
|
previous_salary=self.previous_salary,
|
|
new_salary=self.new_salary,
|
|
adjustment_type='ANNUAL_INCREMENT',
|
|
adjustment_date=date.today(),
|
|
reason='Annual performance review',
|
|
tenant=self.tenant
|
|
)
|
|
|
|
expected_amount_change = Decimal('1000.00')
|
|
expected_percentage = Decimal('20.00')
|
|
|
|
self.assertEqual(adjustment.amount_change, expected_amount_change)
|
|
self.assertEqual(adjustment.percentage_change, expected_percentage)
|
|
|
|
|
|
class DocumentRequestTestCase(TestCase):
|
|
"""Test cases for DocumentRequest model"""
|
|
|
|
def setUp(self):
|
|
"""Set up test data"""
|
|
self.tenant = Tenant.objects.create(
|
|
name="Test Hospital",
|
|
subdomain="test",
|
|
is_active=True
|
|
)
|
|
|
|
self.user = User.objects.create_user(
|
|
username='testuser',
|
|
email='test@example.com',
|
|
password='testpass123',
|
|
tenant=self.tenant
|
|
)
|
|
|
|
self.department = Department.objects.create(
|
|
name="Test Department",
|
|
code="TEST",
|
|
tenant=self.tenant
|
|
)
|
|
|
|
self.employee = Employee.objects.create(
|
|
user=self.user,
|
|
employee_id="EMP001",
|
|
department=self.department,
|
|
job_title="Test Position",
|
|
hire_date=date.today(),
|
|
tenant=self.tenant
|
|
)
|
|
|
|
def test_document_request_creation(self):
|
|
"""Test creating a document request"""
|
|
doc_request = DocumentRequest.objects.create(
|
|
employee=self.employee,
|
|
document_type='SALARY_CERTIFICATE',
|
|
language='ENGLISH',
|
|
purpose='Bank loan application',
|
|
delivery_method='EMAIL',
|
|
delivery_email='test@example.com',
|
|
tenant=self.tenant
|
|
)
|
|
|
|
self.assertEqual(doc_request.employee, self.employee)
|
|
self.assertEqual(doc_request.document_type, 'SALARY_CERTIFICATE')
|
|
self.assertEqual(doc_request.status, 'DRAFT')
|
|
self.assertIsNotNone(doc_request.document_number)
|
|
|
|
def test_document_number_generation(self):
|
|
"""Test automatic document number generation"""
|
|
doc_request = DocumentRequest.objects.create(
|
|
employee=self.employee,
|
|
document_type='EMPLOYMENT_CERTIFICATE',
|
|
language='ARABIC',
|
|
purpose='Embassy application',
|
|
delivery_method='PICKUP',
|
|
tenant=self.tenant
|
|
)
|
|
|
|
# Document number format: DOC-YYYYMMDD-XXXX
|
|
self.assertTrue(doc_request.document_number.startswith('DOC-'))
|
|
self.assertEqual(len(doc_request.document_number), 17)
|
|
|
|
def test_urgency_detection(self):
|
|
"""Test urgency detection based on required_by_date"""
|
|
# Urgent request (required in 2 days)
|
|
urgent_request = DocumentRequest.objects.create(
|
|
employee=self.employee,
|
|
document_type='SALARY_CERTIFICATE',
|
|
language='ENGLISH',
|
|
purpose='Urgent bank matter',
|
|
delivery_method='EMAIL',
|
|
delivery_email='test@example.com',
|
|
required_by_date=date.today() + timedelta(days=2),
|
|
tenant=self.tenant
|
|
)
|
|
|
|
self.assertTrue(urgent_request.is_urgent)
|
|
|
|
def test_overdue_detection(self):
|
|
"""Test overdue detection"""
|
|
# Overdue request
|
|
overdue_request = DocumentRequest.objects.create(
|
|
employee=self.employee,
|
|
document_type='SALARY_CERTIFICATE',
|
|
language='ENGLISH',
|
|
purpose='Test purpose',
|
|
delivery_method='EMAIL',
|
|
delivery_email='test@example.com',
|
|
required_by_date=date.today() - timedelta(days=1),
|
|
status='PENDING',
|
|
tenant=self.tenant
|
|
)
|
|
|
|
self.assertTrue(overdue_request.is_overdue)
|
|
|
|
|
|
class DocumentTemplateTestCase(TestCase):
|
|
"""Test cases for DocumentTemplate model"""
|
|
|
|
def setUp(self):
|
|
"""Set up test data"""
|
|
self.tenant = Tenant.objects.create(
|
|
name="Test Hospital",
|
|
subdomain="test",
|
|
is_active=True
|
|
)
|
|
|
|
def test_template_creation(self):
|
|
"""Test creating a document template"""
|
|
template = DocumentTemplate.objects.create(
|
|
name="Salary Certificate Template",
|
|
description="Standard salary certificate",
|
|
document_type='SALARY_CERTIFICATE',
|
|
language='ENGLISH',
|
|
template_content="This is to certify that {{employee_name}} works at our hospital.",
|
|
is_active=True,
|
|
tenant=self.tenant
|
|
)
|
|
|
|
self.assertEqual(template.name, "Salary Certificate Template")
|
|
self.assertEqual(template.document_type, 'SALARY_CERTIFICATE')
|
|
self.assertTrue(template.is_active)
|
|
|
|
def test_default_template(self):
|
|
"""Test default template functionality"""
|
|
template = DocumentTemplate.objects.create(
|
|
name="Default Salary Certificate",
|
|
document_type='SALARY_CERTIFICATE',
|
|
language='ENGLISH',
|
|
template_content="Default template content",
|
|
is_default=True,
|
|
is_active=True,
|
|
tenant=self.tenant
|
|
)
|
|
|
|
self.assertTrue(template.is_default)
|
|
|
|
|
|
class SalaryViewsTestCase(TestCase):
|
|
"""Test cases for salary views"""
|
|
|
|
def setUp(self):
|
|
"""Set up test data"""
|
|
self.client = Client()
|
|
self.tenant = Tenant.objects.create(
|
|
name="Test Hospital",
|
|
subdomain="test",
|
|
is_active=True
|
|
)
|
|
|
|
self.user = User.objects.create_user(
|
|
username='testuser',
|
|
email='test@example.com',
|
|
password='testpass123',
|
|
tenant=self.tenant,
|
|
is_staff=True
|
|
)
|
|
|
|
self.department = Department.objects.create(
|
|
name="Test Department",
|
|
code="TEST",
|
|
tenant=self.tenant
|
|
)
|
|
|
|
self.employee = Employee.objects.create(
|
|
user=self.user,
|
|
employee_id="EMP001",
|
|
department=self.department,
|
|
job_title="Test Position",
|
|
hire_date=date.today(),
|
|
tenant=self.tenant
|
|
)
|
|
|
|
self.client.login(username='testuser', password='testpass123')
|
|
|
|
def test_salary_list_view(self):
|
|
"""Test salary list view"""
|
|
response = self.client.get('/hr/salary/')
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
def test_salary_create_view(self):
|
|
"""Test salary create view"""
|
|
response = self.client.get('/hr/salary/create/')
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
|
|
class DocumentViewsTestCase(TestCase):
|
|
"""Test cases for document views"""
|
|
|
|
def setUp(self):
|
|
"""Set up test data"""
|
|
self.client = Client()
|
|
self.tenant = Tenant.objects.create(
|
|
name="Test Hospital",
|
|
subdomain="test",
|
|
is_active=True
|
|
)
|
|
|
|
self.user = User.objects.create_user(
|
|
username='testuser',
|
|
email='test@example.com',
|
|
password='testpass123',
|
|
tenant=self.tenant,
|
|
is_staff=True
|
|
)
|
|
|
|
self.department = Department.objects.create(
|
|
name="Test Department",
|
|
code="TEST",
|
|
tenant=self.tenant
|
|
)
|
|
|
|
self.employee = Employee.objects.create(
|
|
user=self.user,
|
|
employee_id="EMP001",
|
|
department=self.department,
|
|
job_title="Test Position",
|
|
hire_date=date.today(),
|
|
tenant=self.tenant
|
|
)
|
|
|
|
self.client.login(username='testuser', password='testpass123')
|
|
|
|
def test_document_request_list_view(self):
|
|
"""Test document request list view"""
|
|
response = self.client.get('/hr/documents/')
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
def test_document_request_create_view(self):
|
|
"""Test document request create view"""
|
|
response = self.client.get('/hr/documents/create/')
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
|
|
class APITestCase(TestCase):
|
|
"""Test cases for API endpoints"""
|
|
|
|
def setUp(self):
|
|
"""Set up test data"""
|
|
self.client = Client()
|
|
self.tenant = Tenant.objects.create(
|
|
name="Test Hospital",
|
|
subdomain="test",
|
|
is_active=True
|
|
)
|
|
|
|
self.user = User.objects.create_user(
|
|
username='testuser',
|
|
email='test@example.com',
|
|
password='testpass123',
|
|
tenant=self.tenant,
|
|
is_staff=True
|
|
)
|
|
|
|
self.department = Department.objects.create(
|
|
name="Test Department",
|
|
code="TEST",
|
|
tenant=self.tenant
|
|
)
|
|
|
|
self.employee = Employee.objects.create(
|
|
user=self.user,
|
|
employee_id="EMP001",
|
|
department=self.department,
|
|
job_title="Test Position",
|
|
hire_date=date.today(),
|
|
tenant=self.tenant
|
|
)
|
|
|
|
self.salary = SalaryInformation.objects.create(
|
|
employee=self.employee,
|
|
basic_salary=Decimal('5000.00'),
|
|
currency='SAR',
|
|
payment_frequency='MONTHLY',
|
|
effective_date=date.today(),
|
|
tenant=self.tenant,
|
|
created_by=self.user
|
|
)
|
|
|
|
self.client.login(username='testuser', password='testpass123')
|
|
|
|
def test_salary_api_list(self):
|
|
"""Test salary information API list endpoint"""
|
|
response = self.client.get('/hr/api/salary-information/')
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
def test_document_request_api_list(self):
|
|
"""Test document request API list endpoint"""
|
|
response = self.client.get('/hr/api/document-requests/')
|
|
self.assertEqual(response.status_code, 200)
|