Add Products
All checks were successful
CI/CD Pipeline / Build and Deploy with Docker Compose (push) Successful in 16m35s
All checks were successful
CI/CD Pipeline / Build and Deploy with Docker Compose (push) Successful in 16m35s
This commit is contained in:
parent
ebbfe90d1e
commit
1be33c37b5
10
Core/Interfaces/Stock/ILSMLookUpDom.cs
Normal file
10
Core/Interfaces/Stock/ILSMLookUpDom.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
using Domain.Entities;
|
||||||
|
|
||||||
|
namespace Core.Interfaces
|
||||||
|
{
|
||||||
|
public interface ILSMLookUpDom
|
||||||
|
{
|
||||||
|
Task<IEnumerable<ELookUpItem>> ProductDivisionsListAsync(string filter, int limit = 10);
|
||||||
|
Task<IEnumerable<ELookUpItem>> UnitsOfMeasureListAsync(string filter, int limit = 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
15
Core/Interfaces/Stock/ILSProductDivisionDom.cs
Normal file
15
Core/Interfaces/Stock/ILSProductDivisionDom.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using Domain.Entities;
|
||||||
|
using Domain.Generics;
|
||||||
|
|
||||||
|
namespace Core.Interfaces.Stock
|
||||||
|
{
|
||||||
|
public interface ILSProductDivisionDom
|
||||||
|
{
|
||||||
|
Task<PagedResult<ELSProductDivision>> GetAllAsync(int page = 1, int pageSize = 50);
|
||||||
|
Task<ELSProductDivision?> GetByIdAsync(int id);
|
||||||
|
Task<PagedResult<ELSProductDivision>> SearchAsync(string? term, int page = 1, int pageSize = 50);
|
||||||
|
Task<ELSProductDivision> CreateAsync(ELSProductDivision entity);
|
||||||
|
Task<bool> UpdateAsync(ELSProductDivision entity);
|
||||||
|
Task<bool> DeleteAsync(int id);
|
||||||
|
}
|
||||||
|
}
|
||||||
15
Core/Interfaces/Stock/ILSProductDom.cs
Normal file
15
Core/Interfaces/Stock/ILSProductDom.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using Domain.Entities;
|
||||||
|
using Domain.Generics;
|
||||||
|
|
||||||
|
namespace Core.Interfaces
|
||||||
|
{
|
||||||
|
public interface ILSProductDom
|
||||||
|
{
|
||||||
|
Task<PagedResult<ELSProduct>> SearchAsync(LSProductSearchParams searchParams);
|
||||||
|
Task<ELSProduct?> GetByIdAsync(int id);
|
||||||
|
Task<ELSProduct> CreateAsync(ELSProduct entity);
|
||||||
|
Task<bool> UpdateAsync(ELSProduct entity);
|
||||||
|
Task<bool> DeleteAsync(int id);
|
||||||
|
Task<byte[]> ExportToExcelAsync(LSProductSearchParams searchParams);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,15 +0,0 @@
|
|||||||
using Domain.Entities;
|
|
||||||
using Domain.Generics;
|
|
||||||
|
|
||||||
namespace Core.Interfaces.Stock
|
|
||||||
{
|
|
||||||
public interface IProductDivisionDom
|
|
||||||
{
|
|
||||||
Task<PagedResult<EProductDivision>> GetAllAsync(int page = 1, int pageSize = 50);
|
|
||||||
Task<EProductDivision?> GetByIdAsync(int id);
|
|
||||||
Task<PagedResult<EProductDivision>> SearchAsync(string? term, int page = 1, int pageSize = 50);
|
|
||||||
Task<EProductDivision> CreateAsync(EProductDivision entity);
|
|
||||||
Task<bool> UpdateAsync(EProductDivision entity);
|
|
||||||
Task<bool> DeleteAsync(int id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
26
Core/Services/Stock/LSMLookUpService.cs
Normal file
26
Core/Services/Stock/LSMLookUpService.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using Core.Interfaces;
|
||||||
|
using Domain.Entities;
|
||||||
|
using Models.Interfaces;
|
||||||
|
|
||||||
|
namespace Core.Services
|
||||||
|
{
|
||||||
|
public class LSMLookUpService : ILSMLookUpDom
|
||||||
|
{
|
||||||
|
#region Declaraciones y Constructor
|
||||||
|
private readonly IPhLSMLookUpRepository _repository;
|
||||||
|
|
||||||
|
public LSMLookUpService(IPhLSMLookUpRepository repository)
|
||||||
|
{
|
||||||
|
_repository = repository ?? throw new ArgumentNullException(nameof(repository));
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Métodos de clase
|
||||||
|
public Task<IEnumerable<ELookUpItem>> ProductDivisionsListAsync(string filter, int limit = 10)
|
||||||
|
=> _repository.ProductDivisionsAsync(filter, limit);
|
||||||
|
|
||||||
|
public Task<IEnumerable<ELookUpItem>> UnitsOfMeasureListAsync(string filter, int limit = 10)
|
||||||
|
=> _repository.UnitsOfMeasureAsync(filter, limit);
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,18 +7,18 @@ using System.Reflection;
|
|||||||
|
|
||||||
namespace Core.Services.Stock
|
namespace Core.Services.Stock
|
||||||
{
|
{
|
||||||
public class ProductDivisionService : IProductDivisionDom
|
public class LSProductDivisionService : ILSProductDivisionDom
|
||||||
{
|
{
|
||||||
#region Declaraciones y Constructor
|
#region Declaraciones y Constructor
|
||||||
private readonly IPhLSMProductDivisionRepository _repository;
|
private readonly IPhLSMProductDivisionRepository _repository;
|
||||||
public ProductDivisionService(IPhLSMProductDivisionRepository repository)
|
public LSProductDivisionService(IPhLSMProductDivisionRepository repository)
|
||||||
{
|
{
|
||||||
_repository = repository ?? throw new ArgumentNullException(nameof(repository));
|
_repository = repository ?? throw new ArgumentNullException(nameof(repository));
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Métodos de clase
|
#region Métodos de clase
|
||||||
public async Task<PagedResult<EProductDivision>> GetAllAsync(int page = 1, int pageSize = 50)
|
public async Task<PagedResult<ELSProductDivision>> GetAllAsync(int page = 1, int pageSize = 50)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -31,7 +31,7 @@ namespace Core.Services.Stock
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<EProductDivision?> GetByIdAsync(int id)
|
public async Task<ELSProductDivision?> GetByIdAsync(int id)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -44,7 +44,7 @@ namespace Core.Services.Stock
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<PagedResult<EProductDivision>> SearchAsync(string? term, int page = 1, int pageSize = 50)
|
public async Task<PagedResult<ELSProductDivision>> SearchAsync(string? term, int page = 1, int pageSize = 50)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -57,7 +57,7 @@ namespace Core.Services.Stock
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<EProductDivision> CreateAsync(EProductDivision entity)
|
public async Task<ELSProductDivision> CreateAsync(ELSProductDivision entity)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -70,7 +70,7 @@ namespace Core.Services.Stock
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> UpdateAsync(EProductDivision entity)
|
public async Task<bool> UpdateAsync(ELSProductDivision entity)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
81
Core/Services/Stock/LSProductService.cs
Normal file
81
Core/Services/Stock/LSProductService.cs
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
using Core.Interfaces;
|
||||||
|
using Domain.Entities;
|
||||||
|
using Domain.Generics;
|
||||||
|
using Models.Interfaces;
|
||||||
|
using System.Reflection;
|
||||||
|
using Transversal.Services;
|
||||||
|
|
||||||
|
namespace Core.Services
|
||||||
|
{
|
||||||
|
public class LSProductService : ILSProductDom
|
||||||
|
{
|
||||||
|
private readonly IPhLSMProductRepository _repository;
|
||||||
|
|
||||||
|
public LSProductService(IPhLSMProductRepository repository)
|
||||||
|
{
|
||||||
|
_repository = repository ?? throw new ArgumentNullException(nameof(repository));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<PagedResult<ELSProduct>> SearchAsync(LSProductSearchParams searchParams)
|
||||||
|
{
|
||||||
|
return await _repository.SearchAsync(searchParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ELSProduct?> GetByIdAsync(int id)
|
||||||
|
{
|
||||||
|
return await _repository.GetByIdAsync(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ELSProduct> CreateAsync(ELSProduct entity)
|
||||||
|
{
|
||||||
|
return await _repository.CreateAsync(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> UpdateAsync(ELSProduct entity)
|
||||||
|
{
|
||||||
|
return await _repository.UpdateAsync(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> DeleteAsync(int id)
|
||||||
|
{
|
||||||
|
return await _repository.DeleteAsync(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<byte[]> ExportToExcelAsync(LSProductSearchParams searchParams)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = await _repository.SearchAsync(searchParams);
|
||||||
|
if (result?.Items == null || !result.Items.Any())
|
||||||
|
throw new Exception("No se encontraron productos para exportar.");
|
||||||
|
|
||||||
|
var exportador = new XLSXExportBase();
|
||||||
|
|
||||||
|
var exportData = result.Items.Select(p => new
|
||||||
|
{
|
||||||
|
p.Id,
|
||||||
|
p.FactoryCode,
|
||||||
|
p.ExternalCode,
|
||||||
|
p.Name,
|
||||||
|
p.Descripcion,
|
||||||
|
Tipo = p.ProductType == 1 ? "Implantable" :
|
||||||
|
p.ProductType == 2 ? "Instrumental" :
|
||||||
|
p.ProductType == 3 ? "Inyectable" : "Otro",
|
||||||
|
Trazabilidad = p.TraceabilityType == 1 ? "No aplica" :
|
||||||
|
p.TraceabilityType == 2 ? "Por cantidad" :
|
||||||
|
p.TraceabilityType == 3 ? "Por lote y vencimiento" : "Otro",
|
||||||
|
PlusProcess = p.PlusProcess ? "Sí" : "No",
|
||||||
|
División = p.Division?.Name ?? "-",
|
||||||
|
Unidad = p.Unit?.Name ?? "-"
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
return exportador.ExportExcel(exportData);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
var method = MethodBase.GetCurrentMethod()?.Name ?? "ExportToExcel";
|
||||||
|
throw new Exception($"Error en {method}: {ex.Message}", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
59
Domain/Entities/ELSProduct.cs
Normal file
59
Domain/Entities/ELSProduct.cs
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
namespace Domain.Entities
|
||||||
|
{
|
||||||
|
public partial class ELSProduct
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Identificador único del producto médico o industrial
|
||||||
|
/// </summary>
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Código de producto definido por la fábrica o fabricante. Puede variar según proveedor, presentación o país de origen.
|
||||||
|
/// </summary>
|
||||||
|
public string FactoryCode { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Nombre técnico o estandarizado del producto (ej: ficha técnica, fabricante)
|
||||||
|
/// </summary>
|
||||||
|
public string? Name { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Descripción comercial o práctica del producto (impresión logística, uso cotidiano)
|
||||||
|
/// </summary>
|
||||||
|
public string Descripcion { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tipo de producto: 1=Implantable, 2=Instrumental, 3=Inyectable, etc.
|
||||||
|
/// </summary>
|
||||||
|
public int ProductType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tipo de trazabilidad: 1=No aplica, 2=Por cantidad, 3=Por lote y vencimiento
|
||||||
|
/// </summary>
|
||||||
|
public int TraceabilityType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indica si el producto requiere un proceso adicional previo a su uso (ej: esterilización, calibración, limpieza, inspección, etc.)
|
||||||
|
/// </summary>
|
||||||
|
public bool PlusProcess { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Código externo estándar del producto (ej: GTIN, código de proveedor, catálogo EAN, etc.)
|
||||||
|
/// </summary>
|
||||||
|
public string? ExternalCode { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// División o familia técnica del producto (ej: columna, trauma, descartables, etc.)
|
||||||
|
/// </summary>
|
||||||
|
public int? DivisionId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unidad de medida base del producto (ej: unidad, mililitro, metro)
|
||||||
|
/// </summary>
|
||||||
|
public int UnitId { get; set; }
|
||||||
|
|
||||||
|
public virtual ELSProductDivision? Division { get; set; }
|
||||||
|
|
||||||
|
public virtual ELSUnitOfMeasure Unit { get; set; } = null!;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
namespace Domain.Entities
|
namespace Domain.Entities
|
||||||
{
|
{
|
||||||
public class EProductDivision
|
public class ELSProductDivision
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Identificador único de la división de productos
|
/// Identificador único de la división de productos
|
||||||
23
Domain/Entities/ELSUnitOfMeasure.cs
Normal file
23
Domain/Entities/ELSUnitOfMeasure.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
namespace Domain.Entities
|
||||||
|
{
|
||||||
|
public class ELSUnitOfMeasure
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Código abreviado de unidad de medida (ej: UN, ML, MT)
|
||||||
|
/// </summary>
|
||||||
|
public string Code { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Nombre descriptivo de la unidad de medida
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Descripción extendida o notas adicionales sobre la unidad
|
||||||
|
/// </summary>
|
||||||
|
public string? Description { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
41
Domain/Generics/LSProductSearchParams.cs
Normal file
41
Domain/Generics/LSProductSearchParams.cs
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
namespace Domain.Generics
|
||||||
|
{
|
||||||
|
public class LSProductSearchParams : PagedRequest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Código interno o externo del producto (factory_code o external_code)
|
||||||
|
/// </summary>
|
||||||
|
public string? Code { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Nombre técnico o descripción comercial (name o descripcion)
|
||||||
|
/// </summary>
|
||||||
|
public string? Description { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tipo de producto: 1=Implantable, 2=Instrumental, 3=Inyectable
|
||||||
|
/// </summary>
|
||||||
|
public int? ProductType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tipo de trazabilidad: 1=No aplica, 2=Por cantidad, 3=Por lote y vencimiento
|
||||||
|
/// </summary>
|
||||||
|
public int? TraceabilityType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// División técnica del producto (FK a ProductDivision)
|
||||||
|
/// </summary>
|
||||||
|
public int? DivisionId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unidad de medida base del producto (FK a UnitOfMeasure)
|
||||||
|
/// </summary>
|
||||||
|
public int? UnitId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indica si el producto requiere un proceso adicional como esterilización
|
||||||
|
/// </summary>
|
||||||
|
public bool? PlusProcess { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
10
Models/Interfaces/IPhLSMLookUpRepository.cs
Normal file
10
Models/Interfaces/IPhLSMLookUpRepository.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
using Domain.Entities;
|
||||||
|
|
||||||
|
namespace Models.Interfaces
|
||||||
|
{
|
||||||
|
public interface IPhLSMLookUpRepository
|
||||||
|
{
|
||||||
|
Task<IEnumerable<ELookUpItem>> ProductDivisionsAsync(string filter, int limit = 10);
|
||||||
|
Task<IEnumerable<ELookUpItem>> UnitsOfMeasureAsync(string filter, int limit = 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,11 +5,11 @@ namespace Models.Interfaces
|
|||||||
{
|
{
|
||||||
public interface IPhLSMProductDivisionRepository
|
public interface IPhLSMProductDivisionRepository
|
||||||
{
|
{
|
||||||
Task<EProductDivision> CreateAsync(EProductDivision entity);
|
Task<ELSProductDivision> CreateAsync(ELSProductDivision entity);
|
||||||
Task<bool> DeleteAsync(int id);
|
Task<bool> DeleteAsync(int id);
|
||||||
Task<PagedResult<EProductDivision>> GetAllAsync(int page = 1, int pageSize = 50);
|
Task<PagedResult<ELSProductDivision>> GetAllAsync(int page = 1, int pageSize = 50);
|
||||||
Task<EProductDivision?> GetByIdAsync(int id);
|
Task<ELSProductDivision?> GetByIdAsync(int id);
|
||||||
Task<PagedResult<EProductDivision>> SearchAsync(string? term, int page = 1, int pageSize = 50);
|
Task<PagedResult<ELSProductDivision>> SearchAsync(string? term, int page = 1, int pageSize = 50);
|
||||||
Task<bool> UpdateAsync(EProductDivision entity);
|
Task<bool> UpdateAsync(ELSProductDivision entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
15
Models/Interfaces/IPhLSMProductRepository.cs
Normal file
15
Models/Interfaces/IPhLSMProductRepository.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using Domain.Entities;
|
||||||
|
using Domain.Generics;
|
||||||
|
using Models.Models;
|
||||||
|
|
||||||
|
namespace Models.Interfaces
|
||||||
|
{
|
||||||
|
public interface IPhLSMProductRepository
|
||||||
|
{
|
||||||
|
Task<PagedResult<ELSProduct>> SearchAsync(LSProductSearchParams searchParams);
|
||||||
|
Task<ELSProduct?> GetByIdAsync(int id);
|
||||||
|
Task<ELSProduct> CreateAsync(ELSProduct entity);
|
||||||
|
Task<bool> UpdateAsync(ELSProduct entity);
|
||||||
|
Task<bool> DeleteAsync(int id);
|
||||||
|
}
|
||||||
|
}
|
||||||
39
Models/Repositories/Stock/PhLSMLookUpRepository.cs
Normal file
39
Models/Repositories/Stock/PhLSMLookUpRepository.cs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Domain.Entities;
|
||||||
|
using Models.Interfaces;
|
||||||
|
using Models.Models;
|
||||||
|
|
||||||
|
namespace Models.Repositories
|
||||||
|
{
|
||||||
|
public class PhLSMLookUpRepository(PhronCareOperationsHubContext context) : IPhLSMLookUpRepository
|
||||||
|
{
|
||||||
|
private readonly PhronCareOperationsHubContext _context = context;
|
||||||
|
|
||||||
|
public async Task<IEnumerable<ELookUpItem>> ProductDivisionsAsync(string filter, int limit = 10)
|
||||||
|
=> await _context.PhLsmProductDivisions
|
||||||
|
.Where(d =>
|
||||||
|
d.Code.Contains(filter) ||
|
||||||
|
d.Name.Contains(filter) ||
|
||||||
|
d.Description.Contains(filter))
|
||||||
|
.OrderBy(d => d.Code)
|
||||||
|
.Select(d => new ELookUpItem
|
||||||
|
{
|
||||||
|
Id = d.Id,
|
||||||
|
Nombre = d.Code + " | " + d.Name
|
||||||
|
})
|
||||||
|
.Take(limit)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
public async Task<IEnumerable<ELookUpItem>> UnitsOfMeasureAsync(string filter, int limit = 10)
|
||||||
|
=> await _context.PhLsmUnitOfMeasures
|
||||||
|
.Where(u => u.Code.Contains(filter) || u.Name.Contains(filter))
|
||||||
|
.OrderBy(u => u.Code)
|
||||||
|
.Select(u => new ELookUpItem
|
||||||
|
{
|
||||||
|
Id = u.Id,
|
||||||
|
Nombre = u.Code + " | " + u.Name
|
||||||
|
})
|
||||||
|
.Take(limit)
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -11,28 +11,28 @@ namespace Models.Repositories.Stock
|
|||||||
{
|
{
|
||||||
private readonly PhronCareOperationsHubContext _context = context;
|
private readonly PhronCareOperationsHubContext _context = context;
|
||||||
|
|
||||||
public async Task<PagedResult<EProductDivision>> GetAllAsync(int page = 1, int pageSize = 50)
|
public async Task<PagedResult<ELSProductDivision>> GetAllAsync(int page = 1, int pageSize = 50)
|
||||||
{
|
{
|
||||||
var query = _context.PhLsmProductDivisions.AsQueryable();
|
var query = _context.PhLsmProductDivisions.AsQueryable();
|
||||||
|
|
||||||
var pagedEntities = await query.ToPagedResultAsync(page, pageSize);
|
var pagedEntities = await query.ToPagedResultAsync(page, pageSize);
|
||||||
|
|
||||||
return new PagedResult<EProductDivision>
|
return new PagedResult<ELSProductDivision>
|
||||||
{
|
{
|
||||||
Items = pagedEntities.Items.Select(EntityMapper.MapEntity<PhLsmProductDivision, EProductDivision>),
|
Items = pagedEntities.Items.Select(EntityMapper.MapEntity<PhLsmProductDivision, ELSProductDivision>),
|
||||||
TotalItems = pagedEntities.TotalItems,
|
TotalItems = pagedEntities.TotalItems,
|
||||||
Page = pagedEntities.Page,
|
Page = pagedEntities.Page,
|
||||||
PageSize = pagedEntities.PageSize
|
PageSize = pagedEntities.PageSize
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<EProductDivision?> GetByIdAsync(int id)
|
public async Task<ELSProductDivision?> GetByIdAsync(int id)
|
||||||
{
|
{
|
||||||
var entity = await _context.PhLsmProductDivisions.FirstOrDefaultAsync(x => x.Id == id);
|
var entity = await _context.PhLsmProductDivisions.FirstOrDefaultAsync(x => x.Id == id);
|
||||||
return entity is null ? null : EntityMapper.MapEntity<PhLsmProductDivision, EProductDivision>(entity);
|
return entity is null ? null : EntityMapper.MapEntity<PhLsmProductDivision, ELSProductDivision>(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<PagedResult<EProductDivision>> SearchAsync(string? term, int page = 1, int pageSize = 50)
|
public async Task<PagedResult<ELSProductDivision>> SearchAsync(string? term, int page = 1, int pageSize = 50)
|
||||||
{
|
{
|
||||||
var query = _context.PhLsmProductDivisions.AsQueryable();
|
var query = _context.PhLsmProductDivisions.AsQueryable();
|
||||||
|
|
||||||
@ -47,26 +47,26 @@ namespace Models.Repositories.Stock
|
|||||||
}
|
}
|
||||||
var pagedEntities = await query.ToPagedResultAsync(page, pageSize);
|
var pagedEntities = await query.ToPagedResultAsync(page, pageSize);
|
||||||
|
|
||||||
return new PagedResult<EProductDivision>
|
return new PagedResult<ELSProductDivision>
|
||||||
{
|
{
|
||||||
Items = pagedEntities.Items.Select(EntityMapper.MapEntity<PhLsmProductDivision, EProductDivision>),
|
Items = pagedEntities.Items.Select(EntityMapper.MapEntity<PhLsmProductDivision, ELSProductDivision>),
|
||||||
TotalItems = pagedEntities.TotalItems,
|
TotalItems = pagedEntities.TotalItems,
|
||||||
Page = pagedEntities.Page,
|
Page = pagedEntities.Page,
|
||||||
PageSize = pagedEntities.PageSize
|
PageSize = pagedEntities.PageSize
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<EProductDivision> CreateAsync(EProductDivision entity)
|
public async Task<ELSProductDivision> CreateAsync(ELSProductDivision entity)
|
||||||
{
|
{
|
||||||
if (entity == null)
|
if (entity == null)
|
||||||
throw new ArgumentNullException(nameof(entity));
|
throw new ArgumentNullException(nameof(entity));
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var mapped = EntityMapper.MapEntity<EProductDivision, PhLsmProductDivision>(entity);
|
var mapped = EntityMapper.MapEntity<ELSProductDivision, PhLsmProductDivision>(entity);
|
||||||
_context.PhLsmProductDivisions.Add(mapped);
|
_context.PhLsmProductDivisions.Add(mapped);
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
return EntityMapper.MapEntity<PhLsmProductDivision, EProductDivision>(mapped);
|
return EntityMapper.MapEntity<PhLsmProductDivision, ELSProductDivision>(mapped);
|
||||||
}
|
}
|
||||||
catch (DbUpdateException dbEx)
|
catch (DbUpdateException dbEx)
|
||||||
{
|
{
|
||||||
@ -78,7 +78,7 @@ namespace Models.Repositories.Stock
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> UpdateAsync(EProductDivision entity)
|
public async Task<bool> UpdateAsync(ELSProductDivision entity)
|
||||||
{
|
{
|
||||||
if (entity == null)
|
if (entity == null)
|
||||||
throw new ArgumentNullException(nameof(entity));
|
throw new ArgumentNullException(nameof(entity));
|
||||||
|
|||||||
101
Models/Repositories/Stock/PhLSMProductRepository.cs
Normal file
101
Models/Repositories/Stock/PhLSMProductRepository.cs
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
using Domain.Entities;
|
||||||
|
using Domain.Generics;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Models.Helpers;
|
||||||
|
using Models.Interfaces;
|
||||||
|
using Models.Models;
|
||||||
|
|
||||||
|
namespace Models.Repositories
|
||||||
|
{
|
||||||
|
public class PhLSMProductRepository(PhronCareOperationsHubContext context) : IPhLSMProductRepository
|
||||||
|
{
|
||||||
|
private readonly PhronCareOperationsHubContext _context = context;
|
||||||
|
|
||||||
|
public async Task<PagedResult<ELSProduct>> SearchAsync(LSProductSearchParams searchParams)
|
||||||
|
{
|
||||||
|
var query = _context.PhLsmProducts
|
||||||
|
.Include(p => p.Division)
|
||||||
|
.Include(p => p.Unit)
|
||||||
|
.AsQueryable();
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(searchParams.Code))
|
||||||
|
{
|
||||||
|
var lowered = searchParams.Code.ToLower();
|
||||||
|
query = query.Where(p =>
|
||||||
|
(!string.IsNullOrEmpty(p.FactoryCode) && p.FactoryCode.ToLower().Contains(lowered)) ||
|
||||||
|
(!string.IsNullOrEmpty(p.ExternalCode) && p.ExternalCode.ToLower().Contains(lowered)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(searchParams.Description))
|
||||||
|
{
|
||||||
|
var lowered = searchParams.Description.ToLower();
|
||||||
|
query = query.Where(p =>
|
||||||
|
(!string.IsNullOrEmpty(p.Name) && p.Name.ToLower().Contains(lowered)) ||
|
||||||
|
(!string.IsNullOrEmpty(p.Descripcion) && p.Descripcion.ToLower().Contains(lowered)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (searchParams.ProductType.HasValue)
|
||||||
|
query = query.Where(p => p.ProductType == searchParams.ProductType);
|
||||||
|
|
||||||
|
if (searchParams.TraceabilityType.HasValue)
|
||||||
|
query = query.Where(p => p.TraceabilityType == searchParams.TraceabilityType);
|
||||||
|
|
||||||
|
if (searchParams.DivisionId.HasValue)
|
||||||
|
query = query.Where(p => p.DivisionId == searchParams.DivisionId);
|
||||||
|
|
||||||
|
if (searchParams.UnitId.HasValue)
|
||||||
|
query = query.Where(p => p.UnitId == searchParams.UnitId);
|
||||||
|
|
||||||
|
if (searchParams.PlusProcess.HasValue)
|
||||||
|
query = query.Where(p => p.PlusProcess == searchParams.PlusProcess);
|
||||||
|
|
||||||
|
var paged = await query.ToPagedResultAsync(searchParams.Page, searchParams.PageSize);
|
||||||
|
|
||||||
|
return new PagedResult<ELSProduct>
|
||||||
|
{
|
||||||
|
Items = paged.Items.Select(EntityMapper.MapEntity<PhLsmProduct, ELSProduct>),
|
||||||
|
TotalItems = paged.TotalItems,
|
||||||
|
Page = paged.Page,
|
||||||
|
PageSize = paged.PageSize
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ELSProduct?> GetByIdAsync(int id)
|
||||||
|
{
|
||||||
|
var entity = await _context.PhLsmProducts
|
||||||
|
.Include(p => p.Division)
|
||||||
|
.Include(p => p.Unit)
|
||||||
|
.FirstOrDefaultAsync(p => p.Id == id);
|
||||||
|
|
||||||
|
return entity != null ? EntityMapper.MapEntity<PhLsmProduct, ELSProduct>(entity) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ELSProduct> CreateAsync(ELSProduct entity)
|
||||||
|
{
|
||||||
|
var mapped = EntityMapper.MapEntity<ELSProduct, PhLsmProduct>(entity);
|
||||||
|
_context.PhLsmProducts.Add(mapped);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
return EntityMapper.MapEntity<PhLsmProduct, ELSProduct>(mapped);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> UpdateAsync(ELSProduct entity)
|
||||||
|
{
|
||||||
|
var existing = await _context.PhLsmProducts.FindAsync(entity.Id);
|
||||||
|
if (existing == null) return false;
|
||||||
|
|
||||||
|
EntityMapper.MapEntityToExisting(entity, existing);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> DeleteAsync(int id)
|
||||||
|
{
|
||||||
|
var entity = await _context.PhLsmProducts.FindAsync(id);
|
||||||
|
if (entity == null) return false;
|
||||||
|
|
||||||
|
_context.PhLsmProducts.Remove(entity);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
22
phronCare.API/Controllers/Stock/LSMLookUpController.cs
Normal file
22
phronCare.API/Controllers/Stock/LSMLookUpController.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using Core.Interfaces;
|
||||||
|
using Domain.Entities;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace phronCare.API.Controllers.Stock
|
||||||
|
{
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
public class LSMLookUpController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly ILSMLookUpDom _lookup;
|
||||||
|
public LSMLookUpController(ILSMLookUpDom lookup) => _lookup = lookup;
|
||||||
|
|
||||||
|
[HttpGet("productdivisions")]
|
||||||
|
public Task<IEnumerable<ELookUpItem>> ProductDivisions([FromQuery] string q = "")
|
||||||
|
=> _lookup.ProductDivisionsListAsync(q);
|
||||||
|
|
||||||
|
[HttpGet("units")]
|
||||||
|
public Task<IEnumerable<ELookUpItem>> Units([FromQuery] string q = "")
|
||||||
|
=> _lookup.UnitsOfMeasureListAsync(q);
|
||||||
|
}
|
||||||
|
}
|
||||||
68
phronCare.API/Controllers/Stock/LSProductController.cs
Normal file
68
phronCare.API/Controllers/Stock/LSProductController.cs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
using Core.Interfaces;
|
||||||
|
using Domain.Entities;
|
||||||
|
using Domain.Generics;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace API.Controllers.Stock
|
||||||
|
{
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
public class LSProductController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly ILSProductDom _service;
|
||||||
|
|
||||||
|
public LSProductController(ILSProductDom service)
|
||||||
|
{
|
||||||
|
_service = service;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("search")]
|
||||||
|
public async Task<ActionResult<PagedResult<ELSProduct>>> Search([FromBody] LSProductSearchParams searchParams)
|
||||||
|
{
|
||||||
|
var result = await _service.SearchAsync(searchParams);
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{id}")]
|
||||||
|
public async Task<ActionResult<ELSProduct>> GetById(int id)
|
||||||
|
{
|
||||||
|
var product = await _service.GetByIdAsync(id);
|
||||||
|
if (product == null)
|
||||||
|
return NotFound($"No se encontró el producto con ID {id}.");
|
||||||
|
return Ok(product);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("create")]
|
||||||
|
public async Task<ActionResult<ELSProduct>> Create([FromBody] ELSProduct model)
|
||||||
|
{
|
||||||
|
var created = await _service.CreateAsync(model);
|
||||||
|
return CreatedAtAction(nameof(GetById), new { id = created.Id }, created);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPut("update")]
|
||||||
|
public async Task<IActionResult> Update([FromBody] ELSProduct model)
|
||||||
|
{
|
||||||
|
var success = await _service.UpdateAsync(model);
|
||||||
|
if (!success)
|
||||||
|
return NotFound("No se pudo actualizar el producto.");
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpDelete("{id}")]
|
||||||
|
public async Task<IActionResult> Delete(int id)
|
||||||
|
{
|
||||||
|
var success = await _service.DeleteAsync(id);
|
||||||
|
if (!success)
|
||||||
|
return NotFound("No se pudo eliminar el producto.");
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("exportfiltered")]
|
||||||
|
public async Task<IActionResult> ExportFiltered([FromBody] LSProductSearchParams searchParams)
|
||||||
|
{
|
||||||
|
var content = await _service.ExportToExcelAsync(searchParams);
|
||||||
|
var fileName = $"productos_{DateTime.Now:yyyyMMddHHmm}.xlsx";
|
||||||
|
return File(content, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -8,9 +8,9 @@ namespace phronCare.API.Controllers.Stock
|
|||||||
[ApiController]
|
[ApiController]
|
||||||
public class ProductDivisionController : ControllerBase
|
public class ProductDivisionController : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly IProductDivisionDom _service;
|
private readonly ILSProductDivisionDom _service;
|
||||||
|
|
||||||
public ProductDivisionController(IProductDivisionDom service)
|
public ProductDivisionController(ILSProductDivisionDom service)
|
||||||
{
|
{
|
||||||
_service = service ?? throw new ArgumentNullException(nameof(service));
|
_service = service ?? throw new ArgumentNullException(nameof(service));
|
||||||
}
|
}
|
||||||
@ -54,7 +54,7 @@ namespace phronCare.API.Controllers.Stock
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("Create")]
|
[HttpPost("Create")]
|
||||||
public async Task<IActionResult> Create([FromBody] EProductDivision division)
|
public async Task<IActionResult> Create([FromBody] ELSProductDivision division)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -68,7 +68,7 @@ namespace phronCare.API.Controllers.Stock
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpPut("Update")]
|
[HttpPut("Update")]
|
||||||
public async Task<IActionResult> Update([FromBody] EProductDivision division)
|
public async Task<IActionResult> Update([FromBody] ELSProductDivision division)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@ -257,7 +257,12 @@ static void RepositorysAndServices(WebApplicationBuilder builder)
|
|||||||
client.BaseAddress = new Uri("https://api.bcra.gob.ar/");
|
client.BaseAddress = new Uri("https://api.bcra.gob.ar/");
|
||||||
});
|
});
|
||||||
//Core de Divisiones de Productos
|
//Core de Divisiones de Productos
|
||||||
builder.Services.AddScoped<IProductDivisionDom, ProductDivisionService>();
|
builder.Services.AddScoped<ILSProductDivisionDom, LSProductDivisionService>();
|
||||||
builder.Services.AddScoped<IPhLSMProductDivisionRepository, PhLSMProductDivisionRepository>();
|
builder.Services.AddScoped<IPhLSMProductDivisionRepository, PhLSMProductDivisionRepository>();
|
||||||
|
|
||||||
|
builder.Services.AddScoped<ILSProductDom, LSProductService>();
|
||||||
|
builder.Services.AddScoped<IPhLSMProductRepository, PhLSMProductRepository>();
|
||||||
|
|
||||||
|
builder.Services.AddScoped<IPhLSMLookUpRepository, PhLSMLookUpRepository>();
|
||||||
|
builder.Services.AddScoped<ILSMLookUpDom, LSMLookUpService>();
|
||||||
}
|
}
|
||||||
@ -960,6 +960,184 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ContainingType": "phronCare.API.Controllers.Stock.LSMLookUpController",
|
||||||
|
"Method": "ProductDivisions",
|
||||||
|
"RelativePath": "api/LSMLookUp/productdivisions",
|
||||||
|
"HttpMethod": "GET",
|
||||||
|
"IsController": true,
|
||||||
|
"Order": 0,
|
||||||
|
"Parameters": [
|
||||||
|
{
|
||||||
|
"Name": "q",
|
||||||
|
"Type": "System.String",
|
||||||
|
"IsRequired": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ReturnTypes": [
|
||||||
|
{
|
||||||
|
"Type": "System.Collections.Generic.IEnumerable\u00601[[Domain.Entities.ELookUpItem, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]",
|
||||||
|
"MediaTypes": [
|
||||||
|
"text/plain",
|
||||||
|
"application/json",
|
||||||
|
"text/json"
|
||||||
|
],
|
||||||
|
"StatusCode": 200
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ContainingType": "phronCare.API.Controllers.Stock.LSMLookUpController",
|
||||||
|
"Method": "Units",
|
||||||
|
"RelativePath": "api/LSMLookUp/units",
|
||||||
|
"HttpMethod": "GET",
|
||||||
|
"IsController": true,
|
||||||
|
"Order": 0,
|
||||||
|
"Parameters": [
|
||||||
|
{
|
||||||
|
"Name": "q",
|
||||||
|
"Type": "System.String",
|
||||||
|
"IsRequired": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ReturnTypes": [
|
||||||
|
{
|
||||||
|
"Type": "System.Collections.Generic.IEnumerable\u00601[[Domain.Entities.ELookUpItem, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]",
|
||||||
|
"MediaTypes": [
|
||||||
|
"text/plain",
|
||||||
|
"application/json",
|
||||||
|
"text/json"
|
||||||
|
],
|
||||||
|
"StatusCode": 200
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ContainingType": "API.Controllers.Stock.LSProductController",
|
||||||
|
"Method": "GetById",
|
||||||
|
"RelativePath": "api/LSProduct/{id}",
|
||||||
|
"HttpMethod": "GET",
|
||||||
|
"IsController": true,
|
||||||
|
"Order": 0,
|
||||||
|
"Parameters": [
|
||||||
|
{
|
||||||
|
"Name": "id",
|
||||||
|
"Type": "System.Int32",
|
||||||
|
"IsRequired": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ReturnTypes": [
|
||||||
|
{
|
||||||
|
"Type": "Domain.Entities.ELSProduct",
|
||||||
|
"MediaTypes": [
|
||||||
|
"text/plain",
|
||||||
|
"application/json",
|
||||||
|
"text/json"
|
||||||
|
],
|
||||||
|
"StatusCode": 200
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ContainingType": "API.Controllers.Stock.LSProductController",
|
||||||
|
"Method": "Delete",
|
||||||
|
"RelativePath": "api/LSProduct/{id}",
|
||||||
|
"HttpMethod": "DELETE",
|
||||||
|
"IsController": true,
|
||||||
|
"Order": 0,
|
||||||
|
"Parameters": [
|
||||||
|
{
|
||||||
|
"Name": "id",
|
||||||
|
"Type": "System.Int32",
|
||||||
|
"IsRequired": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ReturnTypes": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ContainingType": "API.Controllers.Stock.LSProductController",
|
||||||
|
"Method": "Create",
|
||||||
|
"RelativePath": "api/LSProduct/create",
|
||||||
|
"HttpMethod": "POST",
|
||||||
|
"IsController": true,
|
||||||
|
"Order": 0,
|
||||||
|
"Parameters": [
|
||||||
|
{
|
||||||
|
"Name": "model",
|
||||||
|
"Type": "Domain.Entities.ELSProduct",
|
||||||
|
"IsRequired": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ReturnTypes": [
|
||||||
|
{
|
||||||
|
"Type": "Domain.Entities.ELSProduct",
|
||||||
|
"MediaTypes": [
|
||||||
|
"text/plain",
|
||||||
|
"application/json",
|
||||||
|
"text/json"
|
||||||
|
],
|
||||||
|
"StatusCode": 200
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ContainingType": "API.Controllers.Stock.LSProductController",
|
||||||
|
"Method": "ExportFiltered",
|
||||||
|
"RelativePath": "api/LSProduct/exportfiltered",
|
||||||
|
"HttpMethod": "POST",
|
||||||
|
"IsController": true,
|
||||||
|
"Order": 0,
|
||||||
|
"Parameters": [
|
||||||
|
{
|
||||||
|
"Name": "searchParams",
|
||||||
|
"Type": "Domain.Generics.LSProductSearchParams",
|
||||||
|
"IsRequired": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ReturnTypes": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ContainingType": "API.Controllers.Stock.LSProductController",
|
||||||
|
"Method": "Search",
|
||||||
|
"RelativePath": "api/LSProduct/search",
|
||||||
|
"HttpMethod": "POST",
|
||||||
|
"IsController": true,
|
||||||
|
"Order": 0,
|
||||||
|
"Parameters": [
|
||||||
|
{
|
||||||
|
"Name": "searchParams",
|
||||||
|
"Type": "Domain.Generics.LSProductSearchParams",
|
||||||
|
"IsRequired": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ReturnTypes": [
|
||||||
|
{
|
||||||
|
"Type": "Domain.Generics.PagedResult\u00601[[Domain.Entities.ELSProduct, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]",
|
||||||
|
"MediaTypes": [
|
||||||
|
"text/plain",
|
||||||
|
"application/json",
|
||||||
|
"text/json"
|
||||||
|
],
|
||||||
|
"StatusCode": 200
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ContainingType": "API.Controllers.Stock.LSProductController",
|
||||||
|
"Method": "Update",
|
||||||
|
"RelativePath": "api/LSProduct/update",
|
||||||
|
"HttpMethod": "PUT",
|
||||||
|
"IsController": true,
|
||||||
|
"Order": 0,
|
||||||
|
"Parameters": [
|
||||||
|
{
|
||||||
|
"Name": "model",
|
||||||
|
"Type": "Domain.Entities.ELSProduct",
|
||||||
|
"IsRequired": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ReturnTypes": []
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ContainingType": "phronCare.API.Controllers.Sales.PatientController",
|
"ContainingType": "phronCare.API.Controllers.Sales.PatientController",
|
||||||
"Method": "GetById",
|
"Method": "GetById",
|
||||||
@ -1459,7 +1637,7 @@
|
|||||||
"Parameters": [
|
"Parameters": [
|
||||||
{
|
{
|
||||||
"Name": "division",
|
"Name": "division",
|
||||||
"Type": "Domain.Entities.EProductDivision",
|
"Type": "Domain.Entities.ELSProductDivision",
|
||||||
"IsRequired": true
|
"IsRequired": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -1554,7 +1732,7 @@
|
|||||||
"Parameters": [
|
"Parameters": [
|
||||||
{
|
{
|
||||||
"Name": "division",
|
"Name": "division",
|
||||||
"Type": "Domain.Entities.EProductDivision",
|
"Type": "Domain.Entities.ELSProductDivision",
|
||||||
"IsRequired": true
|
"IsRequired": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
255
phronCare.UIBlazor/Pages/Stock/LSProduct.razor
Normal file
255
phronCare.UIBlazor/Pages/Stock/LSProduct.razor
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
@page "/stock/products"
|
||||||
|
@using Blazored.Typeahead
|
||||||
|
@using phronCare.UIBlazor.Services.Stock
|
||||||
|
@using phronCare.UIBlazor.Services.Lookups
|
||||||
|
@using Domain.Entities
|
||||||
|
@using Domain.Generics
|
||||||
|
@inject IToastService toastService
|
||||||
|
@inject NavigationManager Navigation
|
||||||
|
@inject LSProductService productService
|
||||||
|
@inject IStockLookUpService lookUpService
|
||||||
|
|
||||||
|
<div class="card" style="zoom:80%">
|
||||||
|
<div class="card-header d-flex justify-content-center align-items-center" style="zoom:80%;">
|
||||||
|
<h3 class="card-title m-0">Catálogo de Productos Médicos</h3>
|
||||||
|
</div>
|
||||||
|
<div class="card-body px-4">
|
||||||
|
<!-- FILTROS -->
|
||||||
|
<div class="mb-3 row g-2 align-items-end">
|
||||||
|
<div class="col-md-1">
|
||||||
|
<label for="code">Código</label>
|
||||||
|
<input id="code" class="form-control form-control-sm" style="height: 38px;" placeholder="Código interno o externo" @bind="SearchParams.Code" />
|
||||||
|
</div>
|
||||||
|
<div class="col-sm">
|
||||||
|
<label for="description">Nombre o descripción</label>
|
||||||
|
<input id="description" class="form-control form-control-sm" style="height: 38px;" placeholder="Nombre o descripción" @bind="SearchParams.Description" />
|
||||||
|
</div>
|
||||||
|
<div class="col-sm">
|
||||||
|
<label for="division">División</label>
|
||||||
|
<BlazoredTypeahead id="division" TItem="ELookUpItem" TValue="ELookUpItem"
|
||||||
|
SearchMethod="@(filter => lookUpService.GetProductDivisionsAsync(filter).ContinueWith(t => t.Result.AsEnumerable()))"
|
||||||
|
Value="_selectedDivision" ValueChanged="OnDivisionSelected"
|
||||||
|
ValueExpression="@(() => _selectedDivision)"
|
||||||
|
Placeholder="Buscar división..." TextProperty="Nombre" MaximumSuggestions="5"
|
||||||
|
class="form-control form-control-sm" style="height: 38px;">
|
||||||
|
<ResultTemplate Context="item">@item.Nombre</ResultTemplate>
|
||||||
|
<SelectedTemplate Context="item">@item.Nombre</SelectedTemplate>
|
||||||
|
</BlazoredTypeahead>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-2">
|
||||||
|
<label for="unitmeasure">Unidad</label>
|
||||||
|
<BlazoredTypeahead id="unitmeasure" TItem="ELookUpItem" TValue="ELookUpItem"
|
||||||
|
SearchMethod="@(filter => lookUpService.GetUnitsOfMeasureAsync(filter).ContinueWith(t => t.Result.AsEnumerable()))"
|
||||||
|
Value="_selectedUnit" ValueChanged="OnUnitSelected"
|
||||||
|
ValueExpression="@(() => _selectedUnit)"
|
||||||
|
Placeholder="Buscar unidad..." TextProperty="Nombre" MaximumSuggestions="5"
|
||||||
|
class="form-control form-control-sm" style="height: 38px;">
|
||||||
|
<ResultTemplate Context="item">@item.Nombre</ResultTemplate>
|
||||||
|
<SelectedTemplate Context="item">@item.Nombre</SelectedTemplate>
|
||||||
|
</BlazoredTypeahead>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-2">
|
||||||
|
<label for="type">Tipo</label>
|
||||||
|
|
||||||
|
<InputSelect id="type" class="form-select form-control-sm" style="height: 38px;" @bind-Value="SearchParams.ProductType">
|
||||||
|
<option value="">Tipo</option>
|
||||||
|
<option value="1">Implantable</option>
|
||||||
|
<option value="2">Instrumental</option>
|
||||||
|
<option value="3">Inyectable</option>
|
||||||
|
</InputSelect>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm">
|
||||||
|
<label for="traceability">División</label>
|
||||||
|
|
||||||
|
<InputSelect id="traceability" class="form-select form-control-sm" style="height: 38px;" @bind-Value="SearchParams.TraceabilityType">
|
||||||
|
<option value="">Trazabilidad</option>
|
||||||
|
<option value="1">No aplica</option>
|
||||||
|
<option value="2">Por cantidad</option>
|
||||||
|
<option value="3">Por lote y vencimiento</option>
|
||||||
|
</InputSelect>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm">
|
||||||
|
<div class="form-check form-switch">
|
||||||
|
<input type="checkbox" class="form-check-input me-2" id="plusProcess" @bind="SearchParams.PlusProcess" />
|
||||||
|
<label class="form-check-label" for="plusProcess">Esterilizable</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- BOONES DE BUSQUEDA -->
|
||||||
|
<div class="mb-3 d-flex justify-content-end gap-2">
|
||||||
|
<button class="btn btn-primary rounded-pill" @onclick="Buscar">
|
||||||
|
<i class="fas fa-binoculars me-1"></i> Buscar
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-success rounded-pill" disabled="1" @onclick="Nuevo">
|
||||||
|
<i class="fas fa-plus me-1"></i> Nuevo
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-success rounded-pill" @onclick="ExportarExcel">
|
||||||
|
<i class="fas fa-file-excel me-1"></i> Excel
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-secondary rounded-pill" @onclick="Cancelar">
|
||||||
|
<i class="fas fa-arrow-left me-1"></i> Volver
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<div style="zoom:90%;">
|
||||||
|
@if (TablaProductos != null && TablaProductos.Any())
|
||||||
|
{
|
||||||
|
<PhTable Columns="TableColumns"
|
||||||
|
Data="TablaProductos"
|
||||||
|
SelectionField="Id"
|
||||||
|
RowsPerPage="SearchParams.PageSize"
|
||||||
|
RenderButtons="true"
|
||||||
|
Buttons="botones"
|
||||||
|
ShowPageButtons="false"
|
||||||
|
ShowQuickSearch="false"
|
||||||
|
RenderSelect="false" />
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<p>No hay resultados.</p>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-footer d-flex justify-content-center align-items-end" style="zoom:80%;">
|
||||||
|
<div class="d-flex align-items-center gap-3">
|
||||||
|
<button class="btn btn-secondary rounded-pill" @onclick="PrimeraPagina" disabled="@(SearchParams.Page == 1)">« Primera</button>
|
||||||
|
<button class="btn btn-secondary rounded-pill" @onclick="AnteriorPagina" disabled="@(!PuedeRetroceder)">‹ Anterior</button>
|
||||||
|
<span class="mx-2">Página <strong>@SearchParams.Page</strong> de <strong>@TotalPaginas</strong></span>
|
||||||
|
<button class="btn btn-secondary rounded-pill" @onclick="SiguientePagina" disabled="@(!PuedeAvanzar)">Siguiente ›</button>
|
||||||
|
<button class="btn btn-secondary rounded-pill" @onclick="UltimaPagina" disabled="@(SearchParams.Page == TotalPaginas)">Última »</button>
|
||||||
|
<input type="number" class="form-control form-control-sm rounded ms-3" style="width: 80px;" min="1" max="@TotalPaginas" @bind="PaginaDeseada" />
|
||||||
|
<button class="btn btn-outline-primary btn-sm rounded-pill ms-2" @onclick="IrAPagina">Ir</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
private LSProductSearchParams SearchParams = new() { Page = 1, PageSize = 10 };
|
||||||
|
private List<Dictionary<string, object>> TablaProductos = new();
|
||||||
|
private PagedResult<ELSProduct>? PagedResult;
|
||||||
|
private int PaginaDeseada = 1;
|
||||||
|
private ELookUpItem? _selectedDivision;
|
||||||
|
private ELookUpItem? _selectedUnit;
|
||||||
|
List<PhTable.ButtonOptions> botones = new();
|
||||||
|
|
||||||
|
private List<string> TableColumns = new()
|
||||||
|
{
|
||||||
|
"Id", "Código Fábrica", "Código Externo", "Nombre", "Descripción", "División", "Unidad", "Tipo", "Trazabilidad", "Esteriliza"
|
||||||
|
};
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
botones = new List<PhTable.ButtonOptions>
|
||||||
|
{
|
||||||
|
new PhTable.ButtonOptions
|
||||||
|
{
|
||||||
|
Caption = "Editar",
|
||||||
|
ElementClass = "btn btn-primary btn-sm",
|
||||||
|
UrlAction = "/stock/productform/",
|
||||||
|
OnClickAction = async (id) =>
|
||||||
|
{
|
||||||
|
if (int.TryParse(id, out var pid))
|
||||||
|
Navigation.NavigateTo($"/stock/productform/{pid}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// await Buscar();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Buscar()
|
||||||
|
{
|
||||||
|
SearchParams.PageSize = 13;
|
||||||
|
SearchParams.Page = 1;
|
||||||
|
await CargarPaginaActual();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task CargarPaginaActual()
|
||||||
|
{
|
||||||
|
SearchParams.DivisionId = _selectedDivision?.Id;
|
||||||
|
SearchParams.UnitId = _selectedUnit?.Id;
|
||||||
|
PagedResult = await productService.SearchAsync(SearchParams);
|
||||||
|
TablaProductos = PagedResult?.Items.Select(p => new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "Id", p.Id },
|
||||||
|
{ "Código Fábrica", p.FactoryCode },
|
||||||
|
{ "Código Externo", p.ExternalCode },
|
||||||
|
{ "Nombre", p.Name },
|
||||||
|
{ "Descripción", p.Descripcion },
|
||||||
|
{ "División", p.Division?.Name ?? "" },
|
||||||
|
{ "Unidad", p.Unit?.Name ?? "" },
|
||||||
|
{ "Tipo", ObtenerTipoProducto(p.ProductType) },
|
||||||
|
{ "Trazabilidad", ObtenerTipoTrazabilidad(p.TraceabilityType) },
|
||||||
|
{ "Esteriliza", p.PlusProcess ? "Sí" : "No" }
|
||||||
|
}).ToList() ?? [];
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDivisionSelected(ELookUpItem item) => _selectedDivision = item;
|
||||||
|
private void OnUnitSelected(ELookUpItem item) => _selectedUnit = item;
|
||||||
|
|
||||||
|
private string ObtenerTipoProducto(int? tipo) => tipo switch
|
||||||
|
{
|
||||||
|
1 => "Implantable",
|
||||||
|
2 => "Instrumental",
|
||||||
|
3 => "Inyectable",
|
||||||
|
_ => ""
|
||||||
|
};
|
||||||
|
|
||||||
|
private string ObtenerTipoTrazabilidad(int? tipo) => tipo switch
|
||||||
|
{
|
||||||
|
1 => "No aplica",
|
||||||
|
2 => "Por cantidad",
|
||||||
|
3 => "Por lote/vencimiento",
|
||||||
|
_ => ""
|
||||||
|
};
|
||||||
|
|
||||||
|
private async Task PrimeraPagina() { SearchParams.Page = 1; await CargarPaginaActual(); }
|
||||||
|
private async Task UltimaPagina() { SearchParams.Page = TotalPaginas; await CargarPaginaActual(); }
|
||||||
|
private async Task SiguientePagina() => await CambiarPagina(1);
|
||||||
|
private async Task AnteriorPagina() => await CambiarPagina(-1);
|
||||||
|
private async Task CambiarPagina(int delta)
|
||||||
|
{
|
||||||
|
var nueva = SearchParams.Page + delta;
|
||||||
|
if (nueva >= 1 && nueva <= TotalPaginas)
|
||||||
|
{
|
||||||
|
SearchParams.Page = nueva;
|
||||||
|
await CargarPaginaActual();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task IrAPagina()
|
||||||
|
{
|
||||||
|
if (PaginaDeseada >= 1 && PaginaDeseada <= TotalPaginas)
|
||||||
|
{
|
||||||
|
SearchParams.Page = PaginaDeseada;
|
||||||
|
await CargarPaginaActual();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
toastService.ShowWarning("Página fuera de rango.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ExportarExcel()
|
||||||
|
{
|
||||||
|
SearchParams.Page = 1;
|
||||||
|
SearchParams.PageSize = int.MaxValue; // Exportar todos los resultados
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await productService.ExportFilteredAsync(SearchParams);
|
||||||
|
toastService.ShowSuccess("Exportación completada.");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
toastService.ShowError($"Error: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Nuevo() => Navigation.NavigateTo("/stock/productform/");
|
||||||
|
private void Cancelar() => Navigation.NavigateTo("/DashboardPanel");
|
||||||
|
|
||||||
|
private int TotalPaginas => PagedResult is null ? 1 : (int)Math.Ceiling(PagedResult.TotalItems / (double)SearchParams.PageSize);
|
||||||
|
private bool PuedeRetroceder => SearchParams.Page > 1;
|
||||||
|
private bool PuedeAvanzar => PagedResult != null && SearchParams.Page < TotalPaginas;
|
||||||
|
}
|
||||||
@ -71,7 +71,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private PagedResult<EProductDivision>? Resultado;
|
private PagedResult<ELSProductDivision>? Resultado;
|
||||||
private List<Dictionary<string, object>> Tabla = new();
|
private List<Dictionary<string, object>> Tabla = new();
|
||||||
private List<string> Columnas = new() { "Id", "Codigo", "Nombre", "Descripción" };
|
private List<string> Columnas = new() { "Id", "Codigo", "Nombre", "Descripción" };
|
||||||
private ProductDivisionSearchParams SearchParams = new() { PageSize = 10 };
|
private ProductDivisionSearchParams SearchParams = new() { PageSize = 10 };
|
||||||
|
|||||||
@ -50,7 +50,7 @@
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public int? Id { get; set; }
|
public int? Id { get; set; }
|
||||||
|
|
||||||
private EProductDivision model = new();
|
private ELSProductDivision model = new();
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -46,6 +46,7 @@ await builder.Build().RunAsync();
|
|||||||
static void InjectDependencies(WebAssemblyHostBuilder builder)
|
static void InjectDependencies(WebAssemblyHostBuilder builder)
|
||||||
{
|
{
|
||||||
builder.Services.AddScoped<ISalesLookupService, SalesLookupService>();
|
builder.Services.AddScoped<ISalesLookupService, SalesLookupService>();
|
||||||
|
builder.Services.AddScoped<IStockLookUpService, StockLookUpService>();
|
||||||
builder.Services.AddScoped<IExchangeRateService, ExchangeRateService>();
|
builder.Services.AddScoped<IExchangeRateService, ExchangeRateService>();
|
||||||
|
|
||||||
builder.Services.AddScoped<ExchangeRateService>();
|
builder.Services.AddScoped<ExchangeRateService>();
|
||||||
@ -64,4 +65,6 @@ static void InjectDependencies(WebAssemblyHostBuilder builder)
|
|||||||
builder.Services.AddScoped<ProductCategoryService>();
|
builder.Services.AddScoped<ProductCategoryService>();
|
||||||
builder.Services.AddScoped<PatientService>();
|
builder.Services.AddScoped<PatientService>();
|
||||||
builder.Services.AddScoped<ProductDivisionService>();
|
builder.Services.AddScoped<ProductDivisionService>();
|
||||||
|
builder.Services.AddScoped<LSProductService>();
|
||||||
|
|
||||||
}
|
}
|
||||||
10
phronCare.UIBlazor/Services/Lookups/IStockLookUpService.cs
Normal file
10
phronCare.UIBlazor/Services/Lookups/IStockLookUpService.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
using Domain.Entities;
|
||||||
|
|
||||||
|
namespace phronCare.UIBlazor.Services.Lookups
|
||||||
|
{
|
||||||
|
public interface IStockLookUpService
|
||||||
|
{
|
||||||
|
Task<List<ELookUpItem>> GetProductDivisionsAsync(string filter = "");
|
||||||
|
Task<List<ELookUpItem>> GetUnitsOfMeasureAsync(string filter = "");
|
||||||
|
}
|
||||||
|
}
|
||||||
28
phronCare.UIBlazor/Services/Lookups/StockLookUpService.cs
Normal file
28
phronCare.UIBlazor/Services/Lookups/StockLookUpService.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
using Domain.Entities;
|
||||||
|
using phronCare.UIBlazor.Services.Lookups;
|
||||||
|
using System.Net.Http.Json;
|
||||||
|
|
||||||
|
public class StockLookUpService: IStockLookUpService
|
||||||
|
{
|
||||||
|
private readonly HttpClient _http;
|
||||||
|
|
||||||
|
public StockLookUpService(HttpClient http)
|
||||||
|
{
|
||||||
|
_http = http;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<ELookUpItem>> GetProductDivisionsAsync(string filter = "")
|
||||||
|
{
|
||||||
|
string url = string.IsNullOrWhiteSpace(filter)
|
||||||
|
? "/api/LSMLookUp/productdivisions"
|
||||||
|
: $"/api/LSMLookUp/productdivisions?q={Uri.EscapeDataString(filter)}";
|
||||||
|
|
||||||
|
var result = await _http.GetFromJsonAsync<List<ELookUpItem>>(url);
|
||||||
|
return result ?? new List<ELookUpItem>();
|
||||||
|
}
|
||||||
|
public async Task<List<ELookUpItem>> GetUnitsOfMeasureAsync(string filter = "")
|
||||||
|
{
|
||||||
|
var result = await _http.GetFromJsonAsync<List<ELookUpItem>>($"/api/LSMLookUp/units?q={filter}");
|
||||||
|
return result ?? [];
|
||||||
|
}
|
||||||
|
}
|
||||||
77
phronCare.UIBlazor/Services/Stock/LSProductService.cs
Normal file
77
phronCare.UIBlazor/Services/Stock/LSProductService.cs
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
using Domain.Entities;
|
||||||
|
using Domain.Generics;
|
||||||
|
using Microsoft.JSInterop;
|
||||||
|
using System.Net.Http.Json;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
|
namespace phronCare.UIBlazor.Services.Stock
|
||||||
|
{
|
||||||
|
public class LSProductService
|
||||||
|
{
|
||||||
|
private readonly HttpClient _http;
|
||||||
|
private readonly IJSRuntime _js;
|
||||||
|
|
||||||
|
public LSProductService(HttpClient http, IJSRuntime js)
|
||||||
|
{
|
||||||
|
_http = http;
|
||||||
|
_js = js;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<PagedResult<ELSProduct>?> SearchAsync(LSProductSearchParams searchParams)
|
||||||
|
{
|
||||||
|
return await _http.PostAsJsonAsync("/api/LSProduct/Search", searchParams)
|
||||||
|
.ContinueWith(async t =>
|
||||||
|
await t.Result.Content.ReadFromJsonAsync<PagedResult<ELSProduct>>())
|
||||||
|
.Unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ELSProduct?> GetByIdAsync(int id)
|
||||||
|
{
|
||||||
|
return await _http.GetFromJsonAsync<ELSProduct>($"/api/LSProduct/{id}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<HttpResponseMessage> CreateAsync(ELSProduct product)
|
||||||
|
{
|
||||||
|
return await _http.PostAsJsonAsync("/api/LSProduct", product);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<HttpResponseMessage> UpdateAsync(ELSProduct product)
|
||||||
|
{
|
||||||
|
return await _http.PutAsJsonAsync("/api/LSProduct", product);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<HttpResponseMessage> DeleteAsync(int id)
|
||||||
|
{
|
||||||
|
return await _http.DeleteAsync($"/api/LSProduct/{id}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ExportFilteredAsync(LSProductSearchParams searchParams)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var content = new StringContent(JsonSerializer.Serialize(searchParams), Encoding.UTF8, "application/json");
|
||||||
|
var response = await _http.PostAsync("/api/LSProduct/exportfiltered", content);
|
||||||
|
|
||||||
|
if (!response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
var errorContent = await response.Content.ReadAsStringAsync();
|
||||||
|
throw new Exception(errorContent);
|
||||||
|
}
|
||||||
|
var bytes = await response.Content.ReadAsByteArrayAsync();
|
||||||
|
var base64 = Convert.ToBase64String(bytes);
|
||||||
|
var timestamp = DateTime.Now.ToString("yyyyMMddHHmm");
|
||||||
|
|
||||||
|
var fileName = $"productos_{DateTime.Now:yyyyMMddHHmmss}.xlsx";
|
||||||
|
await _js.InvokeVoidAsync("saveAsFile", fileName, base64);
|
||||||
|
}
|
||||||
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
var methodName = MethodBase.GetCurrentMethod()?.Name ?? "UnknownMethod";
|
||||||
|
var message = ex.Message ?? "No message provided";
|
||||||
|
throw new Exception($"{message}", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -16,24 +16,24 @@ namespace phronCare.UIBlazor.Services.Stock
|
|||||||
_js = js;
|
_js = js;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<EProductDivision>> GetAllAsync()
|
public async Task<List<ELSProductDivision>> GetAllAsync()
|
||||||
{
|
{
|
||||||
var result = await _http.GetFromJsonAsync<List<EProductDivision>>("/api/ProductDivision/GetAll");
|
var result = await _http.GetFromJsonAsync<List<ELSProductDivision>>("/api/ProductDivision/GetAll");
|
||||||
return result ?? new List<EProductDivision>();
|
return result ?? new List<ELSProductDivision>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<EProductDivision?> GetByIdAsync(int id)
|
public async Task<ELSProductDivision?> GetByIdAsync(int id)
|
||||||
{
|
{
|
||||||
var result = await _http.GetFromJsonAsync<EProductDivision>($"/api/ProductDivision/GetById/{id}");
|
var result = await _http.GetFromJsonAsync<ELSProductDivision>($"/api/ProductDivision/GetById/{id}");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<HttpResponseMessage> CreateAsync(EProductDivision division)
|
public async Task<HttpResponseMessage> CreateAsync(ELSProductDivision division)
|
||||||
{
|
{
|
||||||
return await _http.PostAsJsonAsync("/api/ProductDivision/Create", division);
|
return await _http.PostAsJsonAsync("/api/ProductDivision/Create", division);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<HttpResponseMessage> UpdateAsync(EProductDivision division)
|
public async Task<HttpResponseMessage> UpdateAsync(ELSProductDivision division)
|
||||||
{
|
{
|
||||||
return await _http.PutAsJsonAsync("/api/ProductDivision/Update", division);
|
return await _http.PutAsJsonAsync("/api/ProductDivision/Update", division);
|
||||||
}
|
}
|
||||||
@ -43,13 +43,13 @@ namespace phronCare.UIBlazor.Services.Stock
|
|||||||
return await _http.DeleteAsync($"/api/ProductDivision/Delete/{id}");
|
return await _http.DeleteAsync($"/api/ProductDivision/Delete/{id}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<PagedResult<EProductDivision>?> SearchAsync(ProductDivisionSearchParams searchParams)
|
public async Task<PagedResult<ELSProductDivision>?> SearchAsync(ProductDivisionSearchParams searchParams)
|
||||||
{
|
{
|
||||||
var url = $"/api/ProductDivision/Search?" +
|
var url = $"/api/ProductDivision/Search?" +
|
||||||
$"term={searchParams.Term}&" +
|
$"term={searchParams.Term}&" +
|
||||||
$"page={searchParams.Page}&" +
|
$"page={searchParams.Page}&" +
|
||||||
$"pageSize={searchParams.PageSize}";
|
$"pageSize={searchParams.PageSize}";
|
||||||
return await _http.GetFromJsonAsync<PagedResult<EProductDivision>>(url);
|
return await _http.GetFromJsonAsync<PagedResult<ELSProductDivision>>(url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user