From c1d9014fe1cb125bccacf7bc72a9cf389ff99208 Mon Sep 17 00:00:00 2001 From: Konrad du Plessis Date: Fri, 24 Apr 2026 09:49:26 +0200 Subject: [PATCH] ux(labels): shorter adjustment type labels (display-only rename) Path A rename - DB values untouched, only TYPE_CHOICES display labels change: 'New Loan' -> shown as 'Loan' 'Advance Payment' -> shown as 'Advance' 'Advance Repayment' -> shown as 'Advance Repaid' Templates that render the type as visible text switched from {{ adj.type }} to {{ adj.get_type_display }}. Data attributes and CSS class slugs keep the raw DB value (identifiers, not labels). Zero data migration. Zero changes to ADDITIVE_TYPES / DEDUCTIVE_TYPES constants, hardcoded string comparisons, CSS class names, test fixtures, or any other code that references the canonical DB value. Every historic PayrollAdjustment row keeps type='New Loan' / 'Advance Payment' / 'Advance Repayment' as stored. Django's makemigrations generated a no-op AlterField migration to record the choices-metadata change. Tests: 69/69. Co-Authored-By: Claude Opus 4.7 (1M context) --- ...r_payrolladjustment_type_display_labels.py | 18 ++++++++++++++++ core/models.py | 21 ++++++++++++------- core/templates/core/_adjustment_row.html | 2 +- core/templates/core/payroll_dashboard.html | 4 ++-- core/templates/core/work_log_payroll.html | 2 +- 5 files changed, 36 insertions(+), 11 deletions(-) create mode 100644 core/migrations/0012_alter_payrolladjustment_type_display_labels.py diff --git a/core/migrations/0012_alter_payrolladjustment_type_display_labels.py b/core/migrations/0012_alter_payrolladjustment_type_display_labels.py new file mode 100644 index 0000000..e5bac45 --- /dev/null +++ b/core/migrations/0012_alter_payrolladjustment_type_display_labels.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2.7 on 2026-04-24 07:45 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0011_worker_tax_number'), + ] + + operations = [ + migrations.AlterField( + model_name='payrolladjustment', + name='type', + field=models.CharField(choices=[('Bonus', 'Bonus'), ('Overtime', 'Overtime'), ('Deduction', 'Deduction'), ('Loan Repayment', 'Loan Repayment'), ('New Loan', 'Loan'), ('Advance Payment', 'Advance'), ('Advance Repayment', 'Advance Repaid')], max_length=50), + ), + ] diff --git a/core/models.py b/core/models.py index 1171b17..dc4e30f 100644 --- a/core/models.py +++ b/core/models.py @@ -187,14 +187,21 @@ class Loan(models.Model): return f"{self.worker.name} - {label} - {self.date}" class PayrollAdjustment(models.Model): + # === PayrollAdjustment TYPE_CHOICES - canonical DB value | display label === + # Path A rename (24 Apr 2026): DB values are PRESERVED as-is. Only the + # second tuple element (the human label) changes for three types, so + # users see shorter labels in tables while every historic row, formula, + # constant, test fixture, CSS class, and data-attribute KEEP WORKING + # UNCHANGED because they all key off the DB value on the left. + # See CLAUDE.md "UI-vs-DB naming drift" section for the full rule. TYPE_CHOICES = [ - ('Bonus', 'Bonus'), - ('Overtime', 'Overtime'), - ('Deduction', 'Deduction'), - ('Loan Repayment', 'Loan Repayment'), - ('New Loan', 'New Loan'), - ('Advance Payment', 'Advance Payment'), - ('Advance Repayment', 'Advance Repayment'), + ('Bonus', 'Bonus'), + ('Overtime', 'Overtime'), + ('Deduction', 'Deduction'), + ('Loan Repayment', 'Loan Repayment'), + ('New Loan', 'Loan'), + ('Advance Payment', 'Advance'), + ('Advance Repayment', 'Advance Repaid'), ] worker = models.ForeignKey(Worker, on_delete=models.CASCADE, related_name='adjustments') diff --git a/core/templates/core/_adjustment_row.html b/core/templates/core/_adjustment_row.html index 0703a91..4e767d3 100644 --- a/core/templates/core/_adjustment_row.html +++ b/core/templates/core/_adjustment_row.html @@ -34,7 +34,7 @@ Row actions differ by paid status: {# --- Type badge (colour comes from the .badge-type- CSS class) --- #} - {{ adj.type }} + {{ adj.get_type_display }} {# --- Amount (sign reflects additive vs deductive) --- #} diff --git a/core/templates/core/payroll_dashboard.html b/core/templates/core/payroll_dashboard.html index ca5f79c..523e1d8 100644 --- a/core/templates/core/payroll_dashboard.html +++ b/core/templates/core/payroll_dashboard.html @@ -367,7 +367,7 @@ data-adj-project="{{ adj.project_id|default:'' }}" data-adj-worker="{{ adj.worker.name }}"> {% if adj.type == 'Bonus' or adj.type == 'Overtime' or adj.type == 'New Loan' or adj.type == 'Advance Payment' %}+{% else %}-{% endif %}R{{ adj.amount|floatformat:2 }} - {{ adj.type }} + {{ adj.get_type_display }} {% if adj.project %}({{ adj.project.name }}){% endif %} {% endfor %} @@ -451,7 +451,7 @@ {% for adj in record.adjustments.all %} - {{ adj.type }}: R {{ adj.amount|floatformat:2 }} + {{ adj.get_type_display }}: R {{ adj.amount|floatformat:2 }} {% empty %} - diff --git a/core/templates/core/work_log_payroll.html b/core/templates/core/work_log_payroll.html index 9710a58..b7dd2b6 100644 --- a/core/templates/core/work_log_payroll.html +++ b/core/templates/core/work_log_payroll.html @@ -128,7 +128,7 @@ {% for adj in adjustments %} - {{ adj.type }} + {{ adj.get_type_display }} {{ adj.worker.name }} R {{ adj.amount|money }}