Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions Vpassbackend/Controllers/AdminController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,5 +109,45 @@ public async Task<IActionResult> GetUserById(int id)
return Ok(user);
}

[HttpPost("search")]
public async Task<ActionResult<PaginatedResult<UserDto>>> SearchUsers([FromBody] UserSearchDTO filter)
{
var q = _context.Users.Include(u => u.UserRole).AsQueryable();

if (!string.IsNullOrEmpty(filter.SearchTerm))
{
var term = filter.SearchTerm.ToLower();
q = q.Where(u =>
u.FirstName.ToLower().Contains(term) ||
u.LastName.ToLower().Contains(term) ||
u.Email.ToLower().Contains(term) ||
u.UserRole.UserRoleName.ToLower().Contains(term));
}

if (!string.IsNullOrEmpty(filter.Role) && filter.Role != "All Users")
{
q = q.Where(u => u.UserRole.UserRoleName == filter.Role);
}

var total = await q.CountAsync();

var items = await q
.OrderBy(u => u.UserId)
.Skip((filter.PageNumber - 1) * filter.PageSize)
.Take(filter.PageSize)
.Select(u => new UserDto
{
UserId = u.UserId,
Email = u.Email,
Role = u.UserRole.UserRoleName
})
.ToListAsync();

return Ok(new PaginatedResult<UserDto>
{
Data = items,
TotalCount = total
});
}
}
}
49 changes: 49 additions & 0 deletions Vpassbackend/Controllers/CustomersController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -220,5 +220,54 @@ public async Task<IActionResult> DeleteVehicle(int customerId, int vehicleId)
await _context.SaveChangesAsync();
return Ok("Vehicle deleted successfully.");
}

// POST: api/Customers/search
[Authorize(Roles = "SuperAdmin,Admin,ServiceCenterAdmin,Cashier")]
[HttpPost("search")]
public async Task<IActionResult> SearchCustomers([FromBody] SearchDTO filter)
{
var query = _context.Customers.AsQueryable();

if (!string.IsNullOrEmpty(filter.SearchTerm))
{
var term = filter.SearchTerm.ToLower();
query = query.Where(c =>
c.FirstName.ToLower().Contains(term) ||
c.LastName.ToLower().Contains(term) ||
c.Email.ToLower().Contains(term));
}

if (!string.IsNullOrEmpty(filter.Status))
{
query = filter.Status == "Active"
? query.Where(c => c.IsEmailVerified)
: query.Where(c => !c.IsEmailVerified);
}

var totalCount = await query.CountAsync();

var data = await query
.OrderByDescending(c => c.CustomerId)
.Skip((filter.PageNumber - 1) * filter.PageSize)
.Take(filter.PageSize)
.Select(c => new CustomerListItemDTO
{
CustomerId = c.CustomerId,
FirstName = c.FirstName,
LastName = c.LastName,
Email = c.Email,
PhoneNumber = c.PhoneNumber,
Address = c.Address,
LoyaltyPoints = c.LoyaltyPoints,
NIC = c.NIC
})
.ToListAsync();

return Ok(new PaginatedResult<CustomerListItemDTO>
{
Data = data,
TotalCount = totalCount
});
}
}
}
53 changes: 53 additions & 0 deletions Vpassbackend/Controllers/ServiceCentersController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Vpassbackend.Models;
using Vpassbackend.Services;
using System;
using System.Linq;


namespace Vpassbackend.Controllers
Expand Down Expand Up @@ -531,5 +532,57 @@ private bool ServiceCenterServiceExists(int id)
{
return _context.ServiceCenterServices.Any(e => e.ServiceCenterServiceId == id);
}

// POST endpoint to support search and filtering of service centers
[HttpPost("search")]
public async Task<ActionResult<PaginatedResult<ServiceCenterDTO>>> SearchServiceCenters([FromBody] SearchDTO filter)
{
var query = _context.ServiceCenters.AsQueryable();

// Apply keyword search (matches name, email, telephone, or address)
if (!string.IsNullOrWhiteSpace(filter.SearchTerm))
{
var keyword = filter.SearchTerm.ToLower();
query = query.Where(sc =>
(sc.Station_name != null && sc.Station_name.ToLower().Contains(keyword)) ||
(sc.Email != null && sc.Email.ToLower().Contains(keyword)) ||
(sc.Telephone != null && sc.Telephone.ToLower().Contains(keyword)) ||
(sc.Address != null && sc.Address.ToLower().Contains(keyword)));
}

// Optional status filter (e.g., active/inactive)
if (!string.IsNullOrWhiteSpace(filter.Status))
{
query = query.Where(sc => sc.Station_status != null &&
sc.Station_status.ToLower() == filter.Status.ToLower());
}

var total = await query.CountAsync(); // Total count before pagination

// Apply pagination and project to DTO
var data = await query
.OrderBy(sc => sc.Station_id)
.Skip((filter.PageNumber - 1) * filter.PageSize)
.Take(filter.PageSize)
.Select(sc => new ServiceCenterDTO
{
Station_id = sc.Station_id,
OwnerName = sc.OwnerName,
VATNumber = sc.VATNumber,
RegisterationNumber = sc.RegisterationNumber,
Station_name = sc.Station_name,
Email = sc.Email,
Telephone = sc.Telephone,
Address = sc.Address,
Station_status = sc.Station_status
})
.ToListAsync();

return new PaginatedResult<ServiceCenterDTO>
{
Data = data,
TotalCount = total
};
}
}
}
51 changes: 51 additions & 0 deletions Vpassbackend/Controllers/VehiclesController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -412,5 +412,56 @@ private bool ServiceHistoryExists(int serviceHistoryId, int vehicleId)
{
return _context.VehicleServiceHistories.Any(e => e.ServiceHistoryId == serviceHistoryId && e.VehicleId == vehicleId);
}

[HttpPost("search")]
public async Task<ActionResult<PaginatedResult<CustomerVehicleDTO>>> SearchVehicles([FromBody] SearchDTO filter)
{
var query = _context.Vehicles.Include(v => v.Customer).AsQueryable();

if (!string.IsNullOrEmpty(filter.SearchTerm))
{
var term = filter.SearchTerm.ToLower();
query = query.Where(v =>
v.Brand.ToLower().Contains(term) ||
v.Model.ToLower().Contains(term) ||
v.Customer.FirstName.ToLower().Contains(term) ||
v.Customer.LastName.ToLower().Contains(term));
}

// Example filter on status - e.g. active/inactive
if (!string.IsNullOrEmpty(filter.Status))
{
// Assuming there's an `IsActive` property on Vehicle or Customer
if (filter.Status == "Active")
query = query.Where(v => v.Year.HasValue && v.Year.Value >= DateTime.Now.Year - 10);
else
query = query.Where(v => !v.Year.HasValue || v.Year.Value < DateTime.Now.Year - 10);
}

var totalCount = await query.CountAsync();

var items = await query
.OrderBy(v => v.VehicleId)
.Skip((filter.PageNumber - 1) * filter.PageSize)
.Take(filter.PageSize)
.Select(v => new CustomerVehicleDTO
{
VehicleId = v.VehicleId,
CustomerId = v.CustomerId,
Client = v.Customer.FirstName + " " + v.Customer.LastName,
Brand = v.Brand,
Model = v.Model,
Fuel = v.Fuel,
Year = v.Year,
RegistrationNumber = v.RegistrationNumber
})
.ToListAsync();

return Ok(new PaginatedResult<CustomerVehicleDTO>
{
Data = items,
TotalCount = totalCount
});
}
}
}
14 changes: 14 additions & 0 deletions Vpassbackend/DTOs/CustomerListItemDTO.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace Vpassbackend.DTOs
{
public class CustomerListItemDTO
{
public int CustomerId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string PhoneNumber { get; set; }
public string Address { get; set; }
public int LoyaltyPoints { get; set; }
public string NIC { get; set; }
}
}
14 changes: 14 additions & 0 deletions Vpassbackend/DTOs/CustomerVehicleDTO.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace Vpassbackend.DTOs
{
public class CustomerVehicleDTO
{
public int VehicleId { get; set; }
public int CustomerId { get; set; }
public string Client { get; set; }
public string Brand { get; set; }
public string Model { get; set; }
public string Fuel { get; set; }
public int? Year { get; set; }
public string RegistrationNumber { get; set; }
}
}
9 changes: 9 additions & 0 deletions Vpassbackend/DTOs/PaginatedResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Vpassbackend.DTOs
{
// Generic wrapper to return paginated results for any entity type
public class PaginatedResult<T>
{
public List<T> Data { get; set; } = new(); // Current page data
public int TotalCount { get; set; } // Total items across all pages
}
}
10 changes: 10 additions & 0 deletions Vpassbackend/DTOs/SearchDTO.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Vpassbackend.DTOs
{
public class SearchDTO
{
public string? SearchTerm { get; set; } // General keyword search (name, email, etc.)
public string? Status { get; set; } // "active", "inactive"
public int PageNumber { get; set; } = 1; // For pagination
public int PageSize { get; set; } = 10; // For pagination
}
}
10 changes: 10 additions & 0 deletions Vpassbackend/DTOs/UserSearchDTO.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Vpassbackend.DTOs
{
public class UserSearchDTO
{
public string? SearchTerm { get; set; }
public string? Role { get; set; }
public int PageNumber { get; set; } = 1;
public int PageSize { get; set; } = 10;
}
}