diff --git a/app/(dashboard)/salary/employees/[id]/page.tsx b/app/(dashboard)/salary/employees/[id]/page.tsx index 60efec27..9ebb5587 100644 --- a/app/(dashboard)/salary/employees/[id]/page.tsx +++ b/app/(dashboard)/salary/employees/[id]/page.tsx @@ -317,6 +317,7 @@ export default function EmployeeDetailPage({ params }: { params: Promise<{ id: s
+

{t('form_employment_degree_hint')}

diff --git a/components/salary/NewEmployeeDialog.tsx b/components/salary/NewEmployeeDialog.tsx index 2ec3a7d7..6de7048f 100644 --- a/components/salary/NewEmployeeDialog.tsx +++ b/components/salary/NewEmployeeDialog.tsx @@ -294,6 +294,7 @@ function NewEmployeeForm({ onCreated, onCancel }: { onCreated: () => void; onCan +

Under 100 % räknas grundlönen som månadslön × sysselsättningsgrad.

diff --git a/components/salary/run/RunEmployeesTable.tsx b/components/salary/run/RunEmployeesTable.tsx index 4c0a24e5..14901c2e 100644 --- a/components/salary/run/RunEmployeesTable.tsx +++ b/components/salary/run/RunEmployeesTable.tsx @@ -142,6 +142,22 @@ export function RunEmployeesTable({ const netValue = sre.net_salary + (sre.tax_withheld - taxValue) const editableSalary = isDraft && canWrite && sre.salary_type === 'monthly' const primaryNumber = isDraft ? sre.monthly_salary : sre.gross_salary + // In a draft the number on the row is the full-time monthly salary + // the engine multiplies by the employee's sysselsättningsgrad. Below + // 100 % that product is not obvious from the input alone (a 10 % + // employee typed 45 310 to get a 4 531 kr gross), so spell it out + // right under the number instead of only in Beräkningsdetaljer. + const degree = Number(sre.employment_degree) + const showDegreeHint = + isDraft && sre.salary_type === 'monthly' && Number.isFinite(degree) && degree < 100 + const degreeHint = showDegreeHint ? ( + + {t('degree_hint', { + degree: degree.toLocaleString('sv-SE'), + amount: formatCurrency(roundOre((sre.monthly_salary || 0) * (degree / 100))), + })} + + ) : null return (
e.stopPropagation()} - onBlur={e => onSalaryEdit(sre.employee_id, e.target.value, sre.monthly_salary)} - disabled={actionLoading === `salary-${sre.employee_id}`} - aria-label={t('salary_input_aria', { name })} - className="h-8 w-28 text-right tabular-nums shrink-0" - /> +
+ e.stopPropagation()} + onBlur={e => onSalaryEdit(sre.employee_id, e.target.value, sre.monthly_salary)} + disabled={actionLoading === `salary-${sre.employee_id}`} + aria-label={t('salary_input_aria', { name })} + className="h-8 w-28 text-right tabular-nums" + /> + {degreeHint} +
) : ( - - {formatCurrency(primaryNumber)} - +
+ + {formatCurrency(primaryNumber)} + + {degreeHint} +
)} {/* Payslip PDF */} diff --git a/messages/en.json b/messages/en.json index 8073f000..2716860c 100644 --- a/messages/en.json +++ b/messages/en.json @@ -6703,6 +6703,7 @@ "view_pdf": "View PDF", "view_payslip_title": "View payslip", "salary_input_aria": "Monthly salary for {name}", + "degree_hint": "× {degree} % = {amount}", "remove_sr": "Remove", "remove_employee_aria": "Remove {name} from the payroll run", "remove_employee_title": "Remove from the payroll run", @@ -6937,6 +6938,7 @@ "form_employment_start": "Employment start date", "form_employment_end": "End date", "form_employment_degree": "Degree of employment (%)", + "form_employment_degree_hint": "Below 100 % the base salary is monthly salary × degree of employment.", "form_hours_per_week": "Hours per week", "form_workdays_per_week": "Workdays per week", "form_work_schedule_hint": "The work schedule drives daily rates for absence and hourly-rate derivation (40 h / 5 days = default).", diff --git a/messages/sv.json b/messages/sv.json index 941e1781..ac649465 100644 --- a/messages/sv.json +++ b/messages/sv.json @@ -6703,6 +6703,7 @@ "view_pdf": "Visa PDF", "view_payslip_title": "Visa lönespecifikation", "salary_input_aria": "Månadslön för {name}", + "degree_hint": "× {degree} % = {amount}", "remove_sr": "Ta bort", "remove_employee_aria": "Ta bort {name} från lönekörningen", "remove_employee_title": "Ta bort från lönekörningen", @@ -6937,6 +6938,7 @@ "form_employment_start": "Anställningsdatum", "form_employment_end": "Slutdatum", "form_employment_degree": "Sysselsättningsgrad (%)", + "form_employment_degree_hint": "Under 100 % räknas grundlönen som månadslön × sysselsättningsgrad.", "form_hours_per_week": "Timmar per vecka", "form_workdays_per_week": "Arbetsdagar per vecka", "form_work_schedule_hint": "Arbetsschemat styr dagslön vid frånvaro och timlöneberäkning (40 h/5 dagar = standard).",