A modern HR management web application built with ASP.NET Core 8, Entity Framework Core 9, and SQL Server. It supports both Admin and Employee roles, with responsive design, structured logging, and comprehensive unit tests.
- Admin Panel: Manage employees, departments, holidays, payroll, and time logs
- Employee Portal: Clock in/out, view logs, and monthly salary summaries
- Role-based Access: Admin and Employee roles with separate permissions
- Payroll System: Automated salary calculations with overtime rates (holidays 1.5x, Sundays 1.75x)
- Export Options: PDF, Excel, and CSV payroll reports
- Modern UI: Responsive Bootstrap 5 design with mobile-friendly navigation
- Structured Logging: Serilog integration with console and file sinks
- Unit Tests: 30+ tests covering services and controllers
┌─────────────────────────────────────────────────────────────┐
│ HrApplication (Web) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ Controllers │──│ Views │ │ Services │ │
│ │ (MVC) │ │ (Razor) │ │ (PayrollService) │ │
│ └──────┬──────┘ └─────────────┘ └──────────┬──────────┘ │
│ │ │ │
│ └──────────────┬───────────────────────┘ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ Repository Pattern │ │
│ │ (IEntitiesRepository)│ │
│ └──────────┬──────────┘ │
└─────────────────────────┼───────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ HrApplication.Model (Data Layer) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ Entities │ │ DbContext │ │ Migrations │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ HrApplication.Tests (xUnit) │
│ ┌─────────────────────┐ ┌─────────────────────────────┐ │
│ │ PayrollServiceTests │ │ DepartmentControllerTests │ │
│ │ (21 tests) │ │ (9 tests) │ │
│ └─────────────────────┘ └─────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
| Layer | Technologies |
|---|---|
| Backend | ASP.NET Core 8, C# 12 |
| ORM | Entity Framework Core 9 |
| Database | SQL Server / Azure SQL |
| Authentication | ASP.NET Core Identity |
| Logging | Serilog (Console + File sinks) |
| Frontend | Razor Views, Bootstrap 5, Bootstrap Icons |
| Testing | xUnit, Moq, FluentAssertions |
| PDF/Excel | iTextSharp, ClosedXML |
hr-application/
├── HrApplication/ # Main ASP.NET Core web project
│ ├── Controllers/ # MVC Controllers
│ │ ├── Admin/ # Admin-only controllers
│ │ └── ... # Public controllers
│ ├── Services/ # Business logic layer
│ │ ├── IPayrollService.cs # Service interface
│ │ └── PayrollService.cs # Salary calculations
│ ├── Models/ # ViewModels
│ ├── Views/ # Razor views
│ └── Program.cs # App startup & DI
│
├── HrApplication.Model/ # Data access layer
│ ├── Entities/ # Domain entities
│ ├── Context/ # EF Core DbContext
│ ├── Concrete/ # Repository implementation
│ └── Migrations/ # EF Core migrations
│
└── HrApplication.Tests/ # Unit tests
├── Services/ # Service tests
└── Controllers/ # Controller tests
Generic repository for data access abstraction:
public interface IEntitiesRepository<T> where T : class
{
T Get(int? id);
IQueryable<T> GetAll();
void Add(T entity);
void Update(T entity);
void Remove(T entity);
}Business logic centralized in services:
public interface IPayrollService
{
PayrollCalculationResult CalculateSalary(
double totalHours,
double holidayHours,
double sundayHours,
decimal hourlyRate);
}All services registered in Program.cs:
builder.Services.AddScoped<IPayrollService, PayrollService>();
builder.Services.AddScoped(typeof(IEntitiesRepository<>), typeof(EntitiesRepository<>));- .NET 8 SDK
- SQL Server (LocalDB, SQL Express, or Azure SQL)
-
Clone the repository:
git clone https://github.com/yourusername/hr-application.git cd hr-application -
Configure the database:
For local development, use User Secrets:
cd HrApplication dotnet user-secrets set "ConnectionStrings:DefaultConnection" "Server=(localdb)\\mssqllocaldb;Database=HrApp;Trusted_Connection=True;"
-
Restore packages:
dotnet restore
-
Apply migrations:
cd HrApplication.Model dotnet ef database update --startup-project ../HrApplication -
Run the application:
cd ../HrApplication dotnet run -
Run tests:
cd ../HrApplication.Tests dotnet test
The PayrollService handles all salary calculations with configurable rates:
| Rate Type | Multiplier | Description |
|---|---|---|
| Normal | 1.0x | Standard hourly rate |
| Holiday | 1.5x | 50% overtime for holidays |
| Sunday | 1.75x | 75% overtime for Sundays |
| Tax | 20% | Deducted from gross salary |
Example:
100 hours total (80 normal + 8 holiday + 12 Sunday) @ 100 LEK/hour
├── Normal Pay: 80 × 100 = 8,000 LEK
├── Holiday Pay: 8 × 100 × 1.5 = 1,200 LEK
├── Sunday Pay: 12 × 100 × 1.75 = 2,100 LEK
├── Gross: 11,300 LEK
├── Tax (20%): 2,260 LEK
└── Net: 9,040 LEK
Structured logging with Serilog:
- Console: Real-time output during development
- File: Rolling daily logs in
Logs/hr-app-{date}.log - Log Levels: Microsoft/EF Core warnings suppressed to reduce noise
[14:32:05 INF] Starting HR Application
[14:32:06 INF] HR Application started successfully
[14:32:10 INF] HTTP GET /Dashboard responded 200 in 45.2ms
30 unit tests covering:
-
PayrollServiceTests (21 tests)
- Tax rate and multiplier validation
- Salary calculations with various inputs
- Edge cases (zero hours, overtime exceeding total)
- Rounding behavior
-
DepartmentControllerTests (9 tests)
- CRUD operations
- Validation handling
- Authorization checks
Run tests:
dotnet test --verbosity normalMIT License - see LICENSE for details.