Enhances employee details with comprehensive salary and HR data
Adds detailed salary rates, commission structures, and HR-related records Introduces new data models and view components for: - Salary rates and supplements - Commissions and rate configurations - Employee HR tracking (certifications, courses, absence) Implements dynamic rate synchronization between drawer and card views
This commit is contained in:
parent
2e6207bb0b
commit
f71f00099a
15 changed files with 1589 additions and 137 deletions
|
|
@ -1,44 +1,183 @@
|
|||
@model PlanTempus.Application.Features.Employees.Components.EmployeeDetailHRViewModel
|
||||
|
||||
<swp-detail-grid>
|
||||
<swp-card>
|
||||
<swp-section-label>@Model.LabelDocuments</swp-section-label>
|
||||
<swp-document-list>
|
||||
<swp-document-item>
|
||||
<i class="ph ph-file-pdf"></i>
|
||||
<swp-document-name>@Model.LabelContract</swp-document-name>
|
||||
<swp-document-date>15. aug 2019</swp-document-date>
|
||||
</swp-document-item>
|
||||
<swp-document-item>
|
||||
<i class="ph ph-file-pdf"></i>
|
||||
<swp-document-name>Lønaftale 2024</swp-document-name>
|
||||
<swp-document-date>1. jan 2024</swp-document-date>
|
||||
</swp-document-item>
|
||||
</swp-document-list>
|
||||
</swp-card>
|
||||
<!-- Left column -->
|
||||
<div>
|
||||
<!-- Contract & Documents -->
|
||||
<swp-card>
|
||||
<swp-section-label>@Model.LabelContractDocuments</swp-section-label>
|
||||
|
||||
<swp-edit-section>
|
||||
<swp-edit-row>
|
||||
<swp-edit-label>@Model.LabelContractType</swp-edit-label>
|
||||
<swp-edit-select>
|
||||
<select>
|
||||
@foreach (var option in Model.ContractTypeOptions)
|
||||
{
|
||||
<option selected="@(option == Model.ContractType)">@option</option>
|
||||
}
|
||||
</select>
|
||||
</swp-edit-select>
|
||||
</swp-edit-row>
|
||||
<swp-edit-row>
|
||||
<swp-edit-label>@Model.LabelTerminationNotice</swp-edit-label>
|
||||
<swp-edit-select>
|
||||
<select>
|
||||
@foreach (var option in Model.TerminationNoticeOptions)
|
||||
{
|
||||
<option selected="@(option == Model.TerminationNotice)">@option</option>
|
||||
}
|
||||
</select>
|
||||
</swp-edit-select>
|
||||
</swp-edit-row>
|
||||
<swp-edit-row>
|
||||
<swp-edit-label>@Model.LabelContractExpiry</swp-edit-label>
|
||||
<swp-edit-value>@Model.ContractExpiry</swp-edit-value>
|
||||
</swp-edit-row>
|
||||
</swp-edit-section>
|
||||
|
||||
<swp-document-list style="margin-top: var(--spacing-6);">
|
||||
@foreach (var doc in Model.Documents)
|
||||
{
|
||||
<swp-document-item>
|
||||
<i class="ph ph-file-pdf"></i>
|
||||
<swp-document-info>
|
||||
<swp-document-name>@doc.Name</swp-document-name>
|
||||
<swp-document-meta>@doc.UploadDate</swp-document-meta>
|
||||
</swp-document-info>
|
||||
<swp-document-actions>
|
||||
<swp-btn class="secondary sm">Vis</swp-btn>
|
||||
</swp-document-actions>
|
||||
</swp-document-item>
|
||||
}
|
||||
</swp-document-list>
|
||||
|
||||
<swp-add-button>+ @Model.LabelUploadDocument</swp-add-button>
|
||||
</swp-card>
|
||||
|
||||
<!-- Planned absence -->
|
||||
<swp-card>
|
||||
<swp-section-label>@Model.LabelPlannedAbsence</swp-section-label>
|
||||
<swp-simple-list>
|
||||
@foreach (var absence in Model.PlannedAbsences)
|
||||
{
|
||||
<swp-simple-item>
|
||||
<swp-simple-item-text>@absence.Dates</swp-simple-item-text>
|
||||
<swp-status-badge class="@absence.TypeClass">@absence.Type</swp-status-badge>
|
||||
</swp-simple-item>
|
||||
}
|
||||
</swp-simple-list>
|
||||
<swp-add-button>+ @Model.LabelAddAbsence</swp-add-button>
|
||||
</swp-card>
|
||||
</div>
|
||||
|
||||
<!-- Right column -->
|
||||
<div>
|
||||
<!-- Certifications -->
|
||||
<swp-card>
|
||||
<swp-section-label>@Model.LabelCertifications</swp-section-label>
|
||||
<swp-document-list>
|
||||
@foreach (var cert in Model.Certifications)
|
||||
{
|
||||
<swp-document-item>
|
||||
<i class="ph ph-certificate"></i>
|
||||
<swp-document-info>
|
||||
<swp-document-name>@cert.Name</swp-document-name>
|
||||
<swp-document-meta>@cert.ExpiryDate</swp-document-meta>
|
||||
</swp-document-info>
|
||||
<swp-document-actions>
|
||||
<swp-status-badge class="@cert.StatusClass">@cert.Status</swp-status-badge>
|
||||
</swp-document-actions>
|
||||
</swp-document-item>
|
||||
}
|
||||
</swp-document-list>
|
||||
<swp-add-button>+ @Model.LabelAddCertification</swp-add-button>
|
||||
</swp-card>
|
||||
|
||||
<!-- Courses -->
|
||||
<swp-card>
|
||||
<swp-section-label>@Model.LabelCourses</swp-section-label>
|
||||
|
||||
<swp-subsection>
|
||||
<swp-subsection-title>@Model.LabelCompletedCourses</swp-subsection-title>
|
||||
<swp-document-list>
|
||||
@foreach (var course in Model.CompletedCourses)
|
||||
{
|
||||
<swp-document-item>
|
||||
<swp-document-info>
|
||||
<swp-document-name>@course.Name</swp-document-name>
|
||||
<swp-document-meta>@course.Provider · @course.Date</swp-document-meta>
|
||||
</swp-document-info>
|
||||
</swp-document-item>
|
||||
}
|
||||
</swp-document-list>
|
||||
</swp-subsection>
|
||||
|
||||
<swp-subsection>
|
||||
<swp-subsection-title>@Model.LabelPlannedCourses</swp-subsection-title>
|
||||
<swp-document-list>
|
||||
@foreach (var course in Model.PlannedCourses)
|
||||
{
|
||||
<swp-document-item>
|
||||
<swp-document-info>
|
||||
<swp-document-name>@course.Name</swp-document-name>
|
||||
<swp-document-meta>@course.Provider · @course.Date</swp-document-meta>
|
||||
</swp-document-info>
|
||||
@if (!string.IsNullOrEmpty(course.Status))
|
||||
{
|
||||
<swp-document-actions>
|
||||
<swp-status-badge class="enrolled">@course.Status</swp-status-badge>
|
||||
</swp-document-actions>
|
||||
}
|
||||
</swp-document-item>
|
||||
}
|
||||
</swp-document-list>
|
||||
</swp-subsection>
|
||||
|
||||
<swp-add-button>+ @Model.LabelAddCourse</swp-add-button>
|
||||
</swp-card>
|
||||
</div>
|
||||
</swp-detail-grid>
|
||||
|
||||
<!-- Vacation & Absence section -->
|
||||
<swp-detail-grid style="margin-top: var(--spacing-8);">
|
||||
<swp-card>
|
||||
<swp-section-label>@Model.LabelVacation</swp-section-label>
|
||||
<swp-section-label>@Model.LabelVacationBalance</swp-section-label>
|
||||
<swp-edit-section>
|
||||
<swp-edit-row>
|
||||
<swp-edit-label>Optjent ferie</swp-edit-label>
|
||||
<swp-edit-value>25 dage</swp-edit-value>
|
||||
<swp-edit-label>@Model.LabelVacationEarned</swp-edit-label>
|
||||
<swp-edit-value>@Model.VacationEarned</swp-edit-value>
|
||||
</swp-edit-row>
|
||||
<swp-edit-row>
|
||||
<swp-edit-label>Afholdt ferie</swp-edit-label>
|
||||
<swp-edit-value>12 dage</swp-edit-value>
|
||||
<swp-edit-label>@Model.LabelVacationUsed</swp-edit-label>
|
||||
<swp-edit-value>@Model.VacationUsed</swp-edit-value>
|
||||
</swp-edit-row>
|
||||
<swp-edit-row>
|
||||
<swp-edit-label>Resterende</swp-edit-label>
|
||||
<swp-edit-value>13 dage</swp-edit-value>
|
||||
<swp-edit-label>@Model.LabelVacationRemaining</swp-edit-label>
|
||||
<swp-edit-value style="font-weight: 600; color: var(--color-teal);">@Model.VacationRemaining</swp-edit-value>
|
||||
</swp-edit-row>
|
||||
</swp-edit-section>
|
||||
</swp-card>
|
||||
|
||||
<swp-card>
|
||||
<swp-section-label>@Model.LabelNotes</swp-section-label>
|
||||
<swp-notes-area contenteditable="true">
|
||||
Ingen noter tilføjet endnu...
|
||||
</swp-notes-area>
|
||||
<swp-section-label>@Model.LabelAbsenceSickness</swp-section-label>
|
||||
<swp-edit-section>
|
||||
<swp-edit-row>
|
||||
<swp-edit-label>@Model.LabelSickDays2025</swp-edit-label>
|
||||
<swp-edit-value>@Model.SickDays2025</swp-edit-value>
|
||||
</swp-edit-row>
|
||||
<swp-edit-row>
|
||||
<swp-edit-label>@Model.LabelSickDays2024</swp-edit-label>
|
||||
<swp-edit-value>@Model.SickDays2024</swp-edit-value>
|
||||
</swp-edit-row>
|
||||
<swp-edit-row>
|
||||
<swp-edit-label>@Model.LabelChildSickDays2025</swp-edit-label>
|
||||
<swp-edit-value>@Model.ChildSickDays2025</swp-edit-value>
|
||||
</swp-edit-row>
|
||||
<swp-edit-row>
|
||||
<swp-edit-label>@Model.LabelMaternityLeave</swp-edit-label>
|
||||
<swp-edit-value>@Model.MaternityLeave</swp-edit-value>
|
||||
</swp-edit-row>
|
||||
</swp-edit-section>
|
||||
</swp-card>
|
||||
</swp-detail-grid>
|
||||
|
|
|
|||
|
|
@ -14,13 +14,95 @@ public class EmployeeDetailHRViewComponent : ViewComponent
|
|||
|
||||
public IViewComponentResult Invoke(string key)
|
||||
{
|
||||
var employee = EmployeeDetailCatalog.Get(key);
|
||||
|
||||
var model = new EmployeeDetailHRViewModel
|
||||
{
|
||||
LabelDocuments = _localization.Get("employees.detail.hr.documents"),
|
||||
LabelContract = _localization.Get("employees.detail.hr.contract"),
|
||||
LabelVacation = _localization.Get("employees.detail.hr.vacation"),
|
||||
LabelSickLeave = _localization.Get("employees.detail.hr.sickleave"),
|
||||
LabelNotes = _localization.Get("employees.detail.hr.notes")
|
||||
// Contract data
|
||||
ContractType = employee.ContractType,
|
||||
TerminationNotice = employee.TerminationNotice,
|
||||
ContractExpiry = employee.ContractExpiry,
|
||||
|
||||
// Vacation data
|
||||
VacationEarned = employee.VacationEarned,
|
||||
VacationUsed = employee.VacationUsed,
|
||||
VacationRemaining = employee.VacationRemaining,
|
||||
|
||||
// Absence data
|
||||
SickDays2025 = employee.SickDays2025,
|
||||
SickDays2024 = employee.SickDays2024,
|
||||
ChildSickDays2025 = employee.ChildSickDays2025,
|
||||
MaternityLeave = employee.MaternityLeave,
|
||||
|
||||
// Labels - Contract & Documents
|
||||
LabelContractDocuments = _localization.Get("employees.detail.hr.contractdocuments"),
|
||||
LabelContractType = _localization.Get("employees.detail.hr.contracttype"),
|
||||
LabelTerminationNotice = _localization.Get("employees.detail.hr.terminationnotice"),
|
||||
LabelContractExpiry = _localization.Get("employees.detail.hr.contractexpiry"),
|
||||
LabelUploadDocument = _localization.Get("employees.detail.hr.uploaddocument"),
|
||||
|
||||
// Labels - Certifications
|
||||
LabelCertifications = _localization.Get("employees.detail.hr.certifications"),
|
||||
LabelAddCertification = _localization.Get("employees.detail.hr.addcertification"),
|
||||
|
||||
// Labels - Courses
|
||||
LabelCourses = _localization.Get("employees.detail.hr.courses"),
|
||||
LabelCompletedCourses = _localization.Get("employees.detail.hr.completedcourses"),
|
||||
LabelPlannedCourses = _localization.Get("employees.detail.hr.plannedcourses"),
|
||||
LabelAddCourse = _localization.Get("employees.detail.hr.addcourse"),
|
||||
|
||||
// Labels - Vacation
|
||||
LabelVacationBalance = _localization.Get("employees.detail.hr.vacationbalance"),
|
||||
LabelVacationEarned = _localization.Get("employees.detail.hr.vacationearned"),
|
||||
LabelVacationUsed = _localization.Get("employees.detail.hr.vacationused"),
|
||||
LabelVacationRemaining = _localization.Get("employees.detail.hr.vacationremaining"),
|
||||
|
||||
// Labels - Absence
|
||||
LabelAbsenceSickness = _localization.Get("employees.detail.hr.absencesickness"),
|
||||
LabelSickDays2025 = _localization.Get("employees.detail.hr.sickdays2025"),
|
||||
LabelSickDays2024 = _localization.Get("employees.detail.hr.sickdays2024"),
|
||||
LabelChildSickDays2025 = _localization.Get("employees.detail.hr.childsickdays2025"),
|
||||
LabelMaternityLeave = _localization.Get("employees.detail.hr.maternityleave"),
|
||||
|
||||
// Labels - Planned absence
|
||||
LabelPlannedAbsence = _localization.Get("employees.detail.hr.plannedabsence"),
|
||||
LabelAddAbsence = _localization.Get("employees.detail.hr.addabsence"),
|
||||
|
||||
// Contract type options
|
||||
ContractTypeOptions = new List<string> { "Fastansættelse", "Tidsbegrænset", "Freelance", "Elev/Lærling" },
|
||||
TerminationNoticeOptions = new List<string> { "14 dage", "1 måned", "3 måneder" },
|
||||
|
||||
// Mock data - Documents
|
||||
Documents = new List<DocumentRecord>
|
||||
{
|
||||
new("Ansættelseskontrakt.pdf", "Uploadet 1. aug 2019"),
|
||||
new("Tillæg - Lønforhøjelse 2023.pdf", "Uploadet 15. jan 2023")
|
||||
},
|
||||
|
||||
// Mock data - Certifications
|
||||
Certifications = new List<CertificationRecord>
|
||||
{
|
||||
new("Balayage Specialist", "Udløber: 15. juni 2026", "Gyldig", "valid"),
|
||||
new("Farvecertificering (Wella)", "Udløber: 1. marts 2025", "Udløber snart", "expiring")
|
||||
},
|
||||
|
||||
// Mock data - Courses
|
||||
CompletedCourses = new List<CourseRecord>
|
||||
{
|
||||
new("Avanceret balayage teknikker", "Wella Academy", "Marts 2024"),
|
||||
new("Kundeservice & mersalg", "SalonUp", "November 2023")
|
||||
},
|
||||
PlannedCourses = new List<CourseRecord>
|
||||
{
|
||||
new("Olaplex certificering", "Olaplex DK", "15. februar 2026", "Tilmeldt")
|
||||
},
|
||||
|
||||
// Mock data - Planned absence
|
||||
PlannedAbsences = new List<PlannedAbsenceRecord>
|
||||
{
|
||||
new("23. dec – 2. jan 2026", "Ferie", "ferie"),
|
||||
new("14. feb 2025", "Fri", "fri")
|
||||
}
|
||||
};
|
||||
|
||||
return View(model);
|
||||
|
|
@ -29,9 +111,64 @@ public class EmployeeDetailHRViewComponent : ViewComponent
|
|||
|
||||
public class EmployeeDetailHRViewModel
|
||||
{
|
||||
public required string LabelDocuments { get; init; }
|
||||
public required string LabelContract { get; init; }
|
||||
public required string LabelVacation { get; init; }
|
||||
public required string LabelSickLeave { get; init; }
|
||||
public required string LabelNotes { get; init; }
|
||||
// Contract data
|
||||
public required string ContractType { get; init; }
|
||||
public required string TerminationNotice { get; init; }
|
||||
public required string ContractExpiry { get; init; }
|
||||
|
||||
// Vacation data
|
||||
public required string VacationEarned { get; init; }
|
||||
public required string VacationUsed { get; init; }
|
||||
public required string VacationRemaining { get; init; }
|
||||
|
||||
// Absence data
|
||||
public required string SickDays2025 { get; init; }
|
||||
public required string SickDays2024 { get; init; }
|
||||
public required string ChildSickDays2025 { get; init; }
|
||||
public required string MaternityLeave { get; init; }
|
||||
|
||||
// Labels - Contract & Documents
|
||||
public required string LabelContractDocuments { get; init; }
|
||||
public required string LabelContractType { get; init; }
|
||||
public required string LabelTerminationNotice { get; init; }
|
||||
public required string LabelContractExpiry { get; init; }
|
||||
public required string LabelUploadDocument { get; init; }
|
||||
|
||||
// Labels - Certifications
|
||||
public required string LabelCertifications { get; init; }
|
||||
public required string LabelAddCertification { get; init; }
|
||||
|
||||
// Labels - Courses
|
||||
public required string LabelCourses { get; init; }
|
||||
public required string LabelCompletedCourses { get; init; }
|
||||
public required string LabelPlannedCourses { get; init; }
|
||||
public required string LabelAddCourse { get; init; }
|
||||
|
||||
// Labels - Vacation
|
||||
public required string LabelVacationBalance { get; init; }
|
||||
public required string LabelVacationEarned { get; init; }
|
||||
public required string LabelVacationUsed { get; init; }
|
||||
public required string LabelVacationRemaining { get; init; }
|
||||
|
||||
// Labels - Absence
|
||||
public required string LabelAbsenceSickness { get; init; }
|
||||
public required string LabelSickDays2025 { get; init; }
|
||||
public required string LabelSickDays2024 { get; init; }
|
||||
public required string LabelChildSickDays2025 { get; init; }
|
||||
public required string LabelMaternityLeave { get; init; }
|
||||
|
||||
// Labels - Planned absence
|
||||
public required string LabelPlannedAbsence { get; init; }
|
||||
public required string LabelAddAbsence { get; init; }
|
||||
|
||||
// Contract type options
|
||||
public List<string> ContractTypeOptions { get; init; } = new();
|
||||
public List<string> TerminationNoticeOptions { get; init; } = new();
|
||||
|
||||
// Data collections
|
||||
public List<DocumentRecord> Documents { get; init; } = new();
|
||||
public List<CertificationRecord> Certifications { get; init; } = new();
|
||||
public List<CourseRecord> CompletedCourses { get; init; } = new();
|
||||
public List<CourseRecord> PlannedCourses { get; init; } = new();
|
||||
public List<PlannedAbsenceRecord> PlannedAbsences { get; init; } = new();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue