feat: add Worker.pay_type discriminator + is_salaried property
This commit is contained in:
parent
4dadb7cf23
commit
3c471691f3
18
core/migrations/0016_worker_pay_type.py
Normal file
18
core/migrations/0016_worker_pay_type.py
Normal file
@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.2.7 on 2026-05-15 17:06
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('core', '0015_absence_project'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='worker',
|
||||
name='pay_type',
|
||||
field=models.CharField(choices=[('daily', 'Daily-rated'), ('fixed', 'Fixed salary')], default='daily', help_text='Daily-rated workers are logged per day. Fixed-salary staff (managers) are paid a set monthly amount and are never added to a work log.', max_length=10),
|
||||
),
|
||||
]
|
||||
@ -72,6 +72,22 @@ class Worker(models.Model):
|
||||
notes = models.TextField(blank=True)
|
||||
active = models.BooleanField(default=True)
|
||||
|
||||
# === PAY TYPE ===
|
||||
# 'daily' = normal field worker, paid per logged work day (daily_rate).
|
||||
# 'fixed' = manager / salaried staff: paid a fixed monthly amount via a
|
||||
# 'Salary' PayrollAdjustment, never logged on a WorkLog. See
|
||||
# CLAUDE.md "Manager / Salaried pay" + the Path-A naming note.
|
||||
PAY_TYPE_CHOICES = [
|
||||
('daily', 'Daily-rated'),
|
||||
('fixed', 'Fixed salary'),
|
||||
]
|
||||
pay_type = models.CharField(
|
||||
max_length=10, choices=PAY_TYPE_CHOICES, default='daily',
|
||||
help_text='Daily-rated workers are logged per day. Fixed-salary '
|
||||
'staff (managers) are paid a set monthly amount and are '
|
||||
'never added to a work log.',
|
||||
)
|
||||
|
||||
# === SIZING ===
|
||||
# Clothing and boot sizes for PPE (personal protective equipment) ordering
|
||||
shoe_size = models.CharField(max_length=20, blank=True)
|
||||
@ -94,6 +110,11 @@ class Worker(models.Model):
|
||||
# monthly salary divided by 20 working days
|
||||
return (self.monthly_salary / Decimal('20.00')).quantize(Decimal('0.01'))
|
||||
|
||||
@property
|
||||
def is_salaried(self):
|
||||
# True for managers / fixed-salary staff (pay_type='fixed').
|
||||
return self.pay_type == 'fixed'
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
@ -3364,3 +3364,22 @@ class DashboardPaidThisMonthTests(TestCase):
|
||||
"""No payments in the current month → zero (not None)."""
|
||||
resp = self.client.get('/')
|
||||
self.assertEqual(resp.context['paid_this_month'], Decimal('0.00'))
|
||||
|
||||
|
||||
class ManagerSalariedPayModelTests(TestCase):
|
||||
"""Worker.pay_type discriminator + is_salaried convenience property."""
|
||||
|
||||
def test_pay_type_defaults_to_daily(self):
|
||||
w = Worker.objects.create(
|
||||
name='Daily Dan', id_number='PT-D1', monthly_salary=Decimal('6000.00'),
|
||||
)
|
||||
self.assertEqual(w.pay_type, 'daily')
|
||||
self.assertFalse(w.is_salaried)
|
||||
|
||||
def test_pay_type_fixed_is_salaried(self):
|
||||
m = Worker.objects.create(
|
||||
name='Manager Fitz', id_number='PT-M1',
|
||||
monthly_salary=Decimal('40000.00'), pay_type='fixed',
|
||||
)
|
||||
self.assertEqual(m.pay_type, 'fixed')
|
||||
self.assertTrue(m.is_salaried)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user