Add Pagination in API Customer
All checks were successful
CI/CD Pipeline / Build and Deploy with Docker Compose (push) Successful in 5m23s

This commit is contained in:
Leandro Hernan Rojas 2025-04-06 01:19:47 -03:00
parent 8b8e66086b
commit 3962d889fd
8 changed files with 162 additions and 28 deletions

View File

@ -1,4 +1,5 @@
using Domain.Entities;
using Domain.Generics;
using System;
using System.Collections.Generic;
using System.Linq;
@ -13,7 +14,7 @@ namespace Core.Interfaces
Task<bool> DeleteAsync(int id);
Task<IEnumerable<ECustomer>> GetAllAsync();
Task<ECustomer?> GetByIdAsync(int id);
Task<IEnumerable<ECustomer>> SearchAsync(string? name, string? email, string? document);
Task<PagedResult<ECustomer>> SearchAsync(string? name, string? email, string? document, int page = 1, int pageSize = 50);
Task<bool> UpdateAsync(ECustomer entity);
}
}

View File

@ -1,6 +1,7 @@
using System.Reflection;
using Core.Interfaces;
using Domain.Entities;
using Domain.Generics;
using Models.Helpers;
using Models.Interfaces;
using Models.Models;
@ -45,11 +46,11 @@ namespace Core.Services
throw new NotImplementedException();
}
public async Task<IEnumerable<ECustomer>> SearchAsync(string? name, string? email, string? document)
public async Task<PagedResult<ECustomer>> SearchAsync(string? name, string? email, string? document, int page, int pageSize)
{
try
{
return await _repository.SearchAsync(name, email, document);
return await _repository.SearchAsync(name, email, document, page, pageSize);
}
catch (Exception ex)
{
@ -58,6 +59,9 @@ namespace Core.Services
}
}
public Task<bool> UpdateAsync(ECustomer entity)
{
throw new NotImplementedException();

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Domain.Generics
{
public class PagedRequest
{
public int Page { get; set; } = 1; // Página actual (empieza en 1)
public int PageSize { get; set; } = 10; // Tamaño de página por defecto
}
}

View File

@ -0,0 +1,12 @@
namespace Domain.Generics
{
public class PagedResult<T>
{
public IEnumerable<T> Items { get; set; } = Enumerable.Empty<T>();
public int TotalItems { get; set; }
public int Page { get; set; }
public int PageSize { get; set; }
public int TotalPages => (int)Math.Ceiling((double)TotalItems / PageSize);
}
}

View File

@ -0,0 +1,33 @@
using Domain.Generics;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Models.Helpers
{
public static class PaginationExtensions
{
public static async Task<PagedResult<T>> ToPagedResultAsync<T>(
this IQueryable<T> query,
int page,
int pageSize)
{
var totalItems = await query.CountAsync();
var items = await query
.Skip((page - 1) * pageSize)
.Take(pageSize)
.ToListAsync();
return new PagedResult<T>
{
Items = items,
TotalItems = totalItems,
Page = page,
PageSize = pageSize
};
}
}
}

View File

@ -1,4 +1,5 @@
using Domain.Entities;
using Domain.Generics;
using Models.Models;
using System;
using System.Collections.Generic;
@ -14,7 +15,12 @@ namespace Models.Interfaces
Task<bool> DeleteAsync(int id);
Task<IEnumerable<ECustomer>> GetAllAsync();
Task<ECustomer?> GetByIdAsync(int id);
Task<IEnumerable<ECustomer>> SearchAsync(string? name, string? email, string? document);
Task<PagedResult<ECustomer>> SearchAsync(
string? name,
string? email,
string? document,
int page,
int pageSize);
Task<bool> UpdateAsync(ECustomer entity);
}
}

View File

@ -1,4 +1,5 @@
using Domain.Entities;
using Domain.Generics;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Models.Helpers;
@ -36,48 +37,92 @@ namespace Models.Repositories
return customer != null ? EntityMapper.MapEntity<PhSCustomer, ECustomer>(customer) : null;
}
public async Task<IEnumerable<ECustomer>> SearchAsync(string? name, string? email, string? document)
public async Task<PagedResult<ECustomer>> SearchAsync(
string? name, string? email, string? document,
int page = 1, int pageSize = 50)
{
var query = _context.PhSCustomers
.Include(c => c.Accounttypes)
.Include(c => c.PhSCustomerDocuments)
.Include(c => c.PhSCustomerAddresses)
.Take(100)
.AsQueryable();
if (!string.IsNullOrWhiteSpace(name))
{
var loweredName = name.ToLower();
var lowered = name.ToLower();
query = query.Where(c =>
c.Name.ToLower().Contains(loweredName) ||
c.BusinessName.ToLower().Contains(loweredName));
}
if (!string.IsNullOrWhiteSpace(email))
{
var loweredEmail = email.ToLower();
query = query.Where(c =>
c.PhSCustomerAddresses.Any(a =>
a.Email.ToLower().Contains(loweredEmail)));
c.Name.ToLower().Contains(lowered) ||
c.BusinessName.ToLower().Contains(lowered));
}
if (!string.IsNullOrWhiteSpace(document) && document != "?")
{
query = query.Where(c =>
c.PhSCustomerDocuments.Any(a =>
EF.Functions.Like(a.DocumentNumber, $"%{document}%")));
c.PhSCustomerDocuments.Any(d =>
EF.Functions.Like(d.DocumentNumber, $"%{document}%")));
}
var customers = await query.ToListAsync();
Console.WriteLine($"VALOR RECIBIDO DE 'name': {name}");
Console.WriteLine($"VALOR RECIBIDO DE 'email': {email}");
Console.WriteLine($"VALOR RECIBIDO DE 'document': {document}");
return customers.Select(EntityMapper.MapEntity<PhSCustomer, ECustomer>);
if (!string.IsNullOrWhiteSpace(email))
{
var lowered = email.ToLower();
query = query.Where(c =>
c.PhSCustomerAddresses.Any(a =>
a.Email.ToLower().Contains(lowered)));
}
var pagedEntities = await query.ToPagedResultAsync(page, pageSize);
return new PagedResult<ECustomer>
{
Items = pagedEntities.Items.Select(EntityMapper.MapEntity<PhSCustomer, ECustomer>),
TotalItems = pagedEntities.TotalItems,
Page = pagedEntities.Page,
PageSize = pagedEntities.PageSize
};
}
//public async Task<IEnumerable<ECustomer>> SearchAsync(string? name, string? email, string? document)
//{
// var query = _context.PhSCustomers
// .Include(c => c.Accounttypes)
// .Include(c => c.PhSCustomerDocuments)
// .Include(c => c.PhSCustomerAddresses)
// .Take(100)
// .AsQueryable();
// if (!string.IsNullOrWhiteSpace(name))
// {
// var loweredName = name.ToLower();
// query = query.Where(c =>
// c.Name.ToLower().Contains(loweredName) ||
// c.BusinessName.ToLower().Contains(loweredName));
// }
// if (!string.IsNullOrWhiteSpace(email))
// {
// var loweredEmail = email.ToLower();
// query = query.Where(c =>
// c.PhSCustomerAddresses.Any(a =>
// a.Email.ToLower().Contains(loweredEmail)));
// }
// if (!string.IsNullOrWhiteSpace(document) && document != "?")
// {
// query = query.Where(c =>
// c.PhSCustomerDocuments.Any(a =>
// EF.Functions.Like(a.DocumentNumber, $"%{document}%")));
// }
// var customers = await query.ToListAsync();
// Console.WriteLine($"VALOR RECIBIDO DE 'name': {name}");
// Console.WriteLine($"VALOR RECIBIDO DE 'email': {email}");
// Console.WriteLine($"VALOR RECIBIDO DE 'document': {document}");
// return customers.Select(EntityMapper.MapEntity<PhSCustomer, ECustomer>);
//}
public async Task<ECustomer> AddAsync(ECustomer entity)
{
var customer = EntityMapper.MapEntity<ECustomer, PhSCustomer>(entity);

View File

@ -14,7 +14,7 @@ namespace phronCare.API.Controllers.Sales
{
_customerService = customerService ?? throw new ArgumentNullException(nameof(customerService));
}
[HttpGet("GetAll")]
[HttpGet("all")]
public async Task<IActionResult> GetAll()
{
try
@ -28,11 +28,16 @@ namespace phronCare.API.Controllers.Sales
}
}
[HttpGet("search")]
public async Task<IActionResult> Search([FromQuery] string? name, [FromQuery] string? email, [FromQuery] string? document)
public async Task<IActionResult> Search(
[FromQuery] string? name,
[FromQuery] string? email,
[FromQuery] string? document,
[FromQuery] int page = 1,
[FromQuery] int pageSize = 50)
{
try
{
var result = await _customerService.SearchAsync(name, email, document);
var result = await _customerService.SearchAsync(name, email, document, page, pageSize);
return Ok(result);
}
catch (Exception ex)
@ -41,6 +46,20 @@ namespace phronCare.API.Controllers.Sales
return StatusCode(500, $"{methodName} Message: {ex.Message}");
}
}
//[HttpGet("search")]
//public async Task<IActionResult> Search([FromQuery] string? name, [FromQuery] string? email, [FromQuery] string? document)
//{
// try
// {
// var result = await _customerService.SearchAsync(name, email, document);
// return Ok(result);
// }
// catch (Exception ex)
// {
// var methodName = MethodBase.GetCurrentMethod()?.Name ?? "UnknownMethod";
// return StatusCode(500, $"{methodName} Message: {ex.Message}");
// }
//}
}
}