feat: Implementación módulos Empresas, Plantas, Tipos y Estados Bobina
Backend API:
- Implementado CRUD completo para Empresas (DE001-DE004):
- EmpresaRepository, EmpresaService, EmpresasController.
- Lógica de creación/eliminación de saldos iniciales en EmpresaService.
- Transacciones y registro en tablas _H.
- Verificación de permisos específicos.
- Implementado CRUD completo para Plantas de Impresión (IP001-IP004):
- PlantaRepository, PlantaService, PlantasController.
- Transacciones y registro en tablas _H.
- Verificación de permisos.
- Implementado CRUD completo para Tipos de Bobina (IB006-IB009):
- TipoBobinaRepository, TipoBobinaService, TiposBobinaController.
- Transacciones y registro en tablas _H.
- Verificación de permisos.
- Implementado CRUD completo para Estados de Bobina (IB010-IB013):
- EstadoBobinaRepository, EstadoBobinaService, EstadosBobinaController.
- Transacciones y registro en tablas _H.
- Verificación de permisos.
Frontend React:
- Módulo Empresas:
- empresaService.ts para interactuar con la API.
- EmpresaFormModal.tsx para crear/editar empresas.
- GestionarEmpresasPage.tsx con tabla, filtro, paginación y menú de acciones.
- Integración con el hook usePermissions para control de acceso.
- Módulo Plantas de Impresión:
- plantaService.ts.
- PlantaFormModal.tsx.
- GestionarPlantasPage.tsx con tabla, filtro, paginación y acciones.
- Integración con usePermissions.
- Módulo Tipos de Bobina:
- tipoBobinaService.ts.
- TipoBobinaFormModal.tsx.
- GestionarTiposBobinaPage.tsx con tabla, filtro, paginación y acciones.
- Integración con usePermissions.
- Módulo Estados de Bobina:
- estadoBobinaService.ts.
- EstadoBobinaFormModal.tsx.
- GestionarEstadosBobinaPage.tsx con tabla, filtro, paginación y acciones.
- Integración con usePermissions.
- Navegación:
- Añadidas sub-pestañas y rutas para los nuevos módulos dentro de "Distribución" (Empresas) e "Impresión" (Plantas, Tipos Bobina, Estados Bobina).
- Creado ImpresionIndexPage.tsx para la navegación interna del módulo de Impresión.
Correcciones:
- Corregido el uso de CommitAsync/RollbackAsync a Commit/Rollback síncronos en PlantaService.cs debido a que IDbTransaction no los soporta asíncronamente.
2025-05-09 10:08:53 -03:00
using Dapper ;
using GestionIntegral.Api.Data.Repositories.Impresion ;
2025-06-30 15:26:14 -03:00
using GestionIntegral.Api.Dtos.Impresion ;
feat: Implementación módulos Empresas, Plantas, Tipos y Estados Bobina
Backend API:
- Implementado CRUD completo para Empresas (DE001-DE004):
- EmpresaRepository, EmpresaService, EmpresasController.
- Lógica de creación/eliminación de saldos iniciales en EmpresaService.
- Transacciones y registro en tablas _H.
- Verificación de permisos específicos.
- Implementado CRUD completo para Plantas de Impresión (IP001-IP004):
- PlantaRepository, PlantaService, PlantasController.
- Transacciones y registro en tablas _H.
- Verificación de permisos.
- Implementado CRUD completo para Tipos de Bobina (IB006-IB009):
- TipoBobinaRepository, TipoBobinaService, TiposBobinaController.
- Transacciones y registro en tablas _H.
- Verificación de permisos.
- Implementado CRUD completo para Estados de Bobina (IB010-IB013):
- EstadoBobinaRepository, EstadoBobinaService, EstadosBobinaController.
- Transacciones y registro en tablas _H.
- Verificación de permisos.
Frontend React:
- Módulo Empresas:
- empresaService.ts para interactuar con la API.
- EmpresaFormModal.tsx para crear/editar empresas.
- GestionarEmpresasPage.tsx con tabla, filtro, paginación y menú de acciones.
- Integración con el hook usePermissions para control de acceso.
- Módulo Plantas de Impresión:
- plantaService.ts.
- PlantaFormModal.tsx.
- GestionarPlantasPage.tsx con tabla, filtro, paginación y acciones.
- Integración con usePermissions.
- Módulo Tipos de Bobina:
- tipoBobinaService.ts.
- TipoBobinaFormModal.tsx.
- GestionarTiposBobinaPage.tsx con tabla, filtro, paginación y acciones.
- Integración con usePermissions.
- Módulo Estados de Bobina:
- estadoBobinaService.ts.
- EstadoBobinaFormModal.tsx.
- GestionarEstadosBobinaPage.tsx con tabla, filtro, paginación y acciones.
- Integración con usePermissions.
- Navegación:
- Añadidas sub-pestañas y rutas para los nuevos módulos dentro de "Distribución" (Empresas) e "Impresión" (Plantas, Tipos Bobina, Estados Bobina).
- Creado ImpresionIndexPage.tsx para la navegación interna del módulo de Impresión.
Correcciones:
- Corregido el uso de CommitAsync/RollbackAsync a Commit/Rollback síncronos en PlantaService.cs debido a que IDbTransaction no los soporta asíncronamente.
2025-05-09 10:08:53 -03:00
using GestionIntegral.Api.Models.Impresion ;
using Microsoft.Extensions.Logging ;
using System.Collections.Generic ;
using System.Data ;
using System.Linq ;
using System.Text ;
using System.Threading.Tasks ;
namespace GestionIntegral.Api.Data.Repositories.Impresion
{
public class EstadoBobinaRepository : IEstadoBobinaRepository
{
private readonly DbConnectionFactory _connectionFactory ;
private readonly ILogger < EstadoBobinaRepository > _logger ;
public EstadoBobinaRepository ( DbConnectionFactory connectionFactory , ILogger < EstadoBobinaRepository > logger )
{
_connectionFactory = connectionFactory ;
_logger = logger ;
}
public async Task < IEnumerable < EstadoBobina > > GetAllAsync ( string? denominacionFilter )
{
var sqlBuilder = new StringBuilder ( "SELECT Id_EstadoBobina AS IdEstadoBobina, Denominacion, Obs FROM dbo.bob_dtEstadosBobinas WHERE 1=1" ) ;
var parameters = new DynamicParameters ( ) ;
if ( ! string . IsNullOrWhiteSpace ( denominacionFilter ) )
{
sqlBuilder . Append ( " AND Denominacion LIKE @DenominacionFilter" ) ;
parameters . Add ( "DenominacionFilter" , $"%{denominacionFilter}%" ) ;
}
sqlBuilder . Append ( " ORDER BY Denominacion;" ) ;
try
{
using var connection = _connectionFactory . CreateConnection ( ) ;
return await connection . QueryAsync < EstadoBobina > ( sqlBuilder . ToString ( ) , parameters ) ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error al obtener todos los Estados de Bobina. Filtro: {Denominacion}" , denominacionFilter ) ;
return Enumerable . Empty < EstadoBobina > ( ) ;
}
}
2025-06-30 15:26:14 -03:00
public async Task < IEnumerable < EstadoBobinaDropdownDto > > GetAllDropdownAsync ( )
{
var sqlBuilder = new StringBuilder ( "SELECT Id_EstadoBobina AS IdEstadoBobina, Denominacion FROM dbo.bob_dtEstadosBobinas WHERE 1=1" ) ;
var parameters = new DynamicParameters ( ) ;
sqlBuilder . Append ( " ORDER BY Denominacion;" ) ;
try
{
using var connection = _connectionFactory . CreateConnection ( ) ;
return await connection . QueryAsync < EstadoBobinaDropdownDto > ( sqlBuilder . ToString ( ) , parameters ) ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error al obtener todos los Estados de Bobina." ) ;
return Enumerable . Empty < EstadoBobinaDropdownDto > ( ) ;
}
}
feat: Implementación módulos Empresas, Plantas, Tipos y Estados Bobina
Backend API:
- Implementado CRUD completo para Empresas (DE001-DE004):
- EmpresaRepository, EmpresaService, EmpresasController.
- Lógica de creación/eliminación de saldos iniciales en EmpresaService.
- Transacciones y registro en tablas _H.
- Verificación de permisos específicos.
- Implementado CRUD completo para Plantas de Impresión (IP001-IP004):
- PlantaRepository, PlantaService, PlantasController.
- Transacciones y registro en tablas _H.
- Verificación de permisos.
- Implementado CRUD completo para Tipos de Bobina (IB006-IB009):
- TipoBobinaRepository, TipoBobinaService, TiposBobinaController.
- Transacciones y registro en tablas _H.
- Verificación de permisos.
- Implementado CRUD completo para Estados de Bobina (IB010-IB013):
- EstadoBobinaRepository, EstadoBobinaService, EstadosBobinaController.
- Transacciones y registro en tablas _H.
- Verificación de permisos.
Frontend React:
- Módulo Empresas:
- empresaService.ts para interactuar con la API.
- EmpresaFormModal.tsx para crear/editar empresas.
- GestionarEmpresasPage.tsx con tabla, filtro, paginación y menú de acciones.
- Integración con el hook usePermissions para control de acceso.
- Módulo Plantas de Impresión:
- plantaService.ts.
- PlantaFormModal.tsx.
- GestionarPlantasPage.tsx con tabla, filtro, paginación y acciones.
- Integración con usePermissions.
- Módulo Tipos de Bobina:
- tipoBobinaService.ts.
- TipoBobinaFormModal.tsx.
- GestionarTiposBobinaPage.tsx con tabla, filtro, paginación y acciones.
- Integración con usePermissions.
- Módulo Estados de Bobina:
- estadoBobinaService.ts.
- EstadoBobinaFormModal.tsx.
- GestionarEstadosBobinaPage.tsx con tabla, filtro, paginación y acciones.
- Integración con usePermissions.
- Navegación:
- Añadidas sub-pestañas y rutas para los nuevos módulos dentro de "Distribución" (Empresas) e "Impresión" (Plantas, Tipos Bobina, Estados Bobina).
- Creado ImpresionIndexPage.tsx para la navegación interna del módulo de Impresión.
Correcciones:
- Corregido el uso de CommitAsync/RollbackAsync a Commit/Rollback síncronos en PlantaService.cs debido a que IDbTransaction no los soporta asíncronamente.
2025-05-09 10:08:53 -03:00
public async Task < EstadoBobina ? > GetByIdAsync ( int id )
{
const string sql = "SELECT Id_EstadoBobina AS IdEstadoBobina, Denominacion, Obs FROM dbo.bob_dtEstadosBobinas WHERE Id_EstadoBobina = @Id" ;
try
{
using var connection = _connectionFactory . CreateConnection ( ) ;
return await connection . QuerySingleOrDefaultAsync < EstadoBobina > ( sql , new { Id = id } ) ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error al obtener Estado de Bobina por ID: {IdEstadoBobina}" , id ) ;
return null ;
}
}
public async Task < bool > ExistsByDenominacionAsync ( string denominacion , int? excludeId = null )
{
var sqlBuilder = new StringBuilder ( "SELECT COUNT(1) FROM dbo.bob_dtEstadosBobinas WHERE Denominacion = @Denominacion" ) ;
var parameters = new DynamicParameters ( ) ;
parameters . Add ( "Denominacion" , denominacion ) ;
if ( excludeId . HasValue )
{
sqlBuilder . Append ( " AND Id_EstadoBobina != @ExcludeId" ) ;
parameters . Add ( "ExcludeId" , excludeId . Value ) ;
}
try
{
using var connection = _connectionFactory . CreateConnection ( ) ;
var count = await connection . ExecuteScalarAsync < int > ( sqlBuilder . ToString ( ) , parameters ) ;
return count > 0 ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error en ExistsByDenominacionAsync para Estado de Bobina con denominación: {Denominacion}" , denominacion ) ;
return true ; // Asumir que existe en caso de error
}
}
public async Task < bool > IsInUseAsync ( int id )
{
// Verificar si el estado de bobina está referenciado en bob_StockBobinas
const string sqlCheckStock = "SELECT TOP 1 1 FROM dbo.bob_StockBobinas WHERE Id_EstadoBobina = @IdEstadoBobina" ;
try
{
using var connection = _connectionFactory . CreateConnection ( ) ;
var inStock = await connection . ExecuteScalarAsync < int? > ( sqlCheckStock , new { IdEstadoBobina = id } ) ;
return inStock . HasValue & & inStock . Value = = 1 ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error en IsInUseAsync para Estado de Bobina ID: {IdEstadoBobina}" , id ) ;
return true ; // Asumir en uso si hay error
}
}
// --- Métodos de Escritura (USAN TRANSACCIÓN) ---
public async Task < EstadoBobina ? > CreateAsync ( EstadoBobina nuevoEstadoBobina , int idUsuario , IDbTransaction transaction )
{
const string sqlInsert = @ "
INSERT INTO dbo . bob_dtEstadosBobinas ( Denominacion , Obs )
OUTPUT INSERTED . Id_EstadoBobina AS IdEstadoBobina , INSERTED . Denominacion , INSERTED . Obs
VALUES ( @Denominacion , @Obs ) ; ";
const string sqlInsertHistorico = @ "
INSERT INTO dbo . bob_dtEstadosBobinas_H ( Id_EstadoBobina , Denominacion , Obs , Id_Usuario , FechaMod , TipoMod )
VALUES ( @IdEstadoBobina , @Denominacion , @Obs , @IdUsuario , @FechaMod , @TipoMod ) ; ";
var connection = transaction . Connection ! ;
var insertedEstado = await connection . QuerySingleAsync < EstadoBobina > (
sqlInsert ,
new { nuevoEstadoBobina . Denominacion , nuevoEstadoBobina . Obs } ,
transaction : transaction
) ;
if ( insertedEstado = = null | | insertedEstado . IdEstadoBobina < = 0 )
{
throw new DataException ( "No se pudo obtener el ID del estado de bobina insertado." ) ;
}
await connection . ExecuteAsync ( sqlInsertHistorico , new
{
IdEstadoBobina = insertedEstado . IdEstadoBobina ,
insertedEstado . Denominacion ,
insertedEstado . Obs ,
IdUsuario = idUsuario ,
FechaMod = DateTime . Now ,
TipoMod = "Insertada"
} , transaction : transaction ) ;
return insertedEstado ;
}
public async Task < bool > UpdateAsync ( EstadoBobina estadoBobinaAActualizar , int idUsuario , IDbTransaction transaction )
{
var connection = transaction . Connection ! ;
var estadoActual = await connection . QuerySingleOrDefaultAsync < EstadoBobina > (
"SELECT Id_EstadoBobina AS IdEstadoBobina, Denominacion, Obs FROM dbo.bob_dtEstadosBobinas WHERE Id_EstadoBobina = @Id" ,
new { Id = estadoBobinaAActualizar . IdEstadoBobina } ,
transaction ) ;
if ( estadoActual = = null ) throw new KeyNotFoundException ( $"No se encontró el estado de bobina con ID {estadoBobinaAActualizar.IdEstadoBobina} para actualizar." ) ;
const string sqlUpdate = "UPDATE dbo.bob_dtEstadosBobinas SET Denominacion = @Denominacion, Obs = @Obs WHERE Id_EstadoBobina = @IdEstadoBobina;" ;
const string sqlInsertHistorico = @ "
INSERT INTO dbo . bob_dtEstadosBobinas_H ( Id_EstadoBobina , Denominacion , Obs , Id_Usuario , FechaMod , TipoMod )
VALUES ( @IdEstadoBobina , @DenominacionActual , @ObsActual , @IdUsuario , @FechaMod , @TipoMod ) ; ";
await connection . ExecuteAsync ( sqlInsertHistorico , new
{
IdEstadoBobina = estadoActual . IdEstadoBobina ,
DenominacionActual = estadoActual . Denominacion , // Valor ANTES
ObsActual = estadoActual . Obs , // Valor ANTES
IdUsuario = idUsuario ,
FechaMod = DateTime . Now ,
TipoMod = "Modificada"
} , transaction : transaction ) ;
var rowsAffected = await connection . ExecuteAsync ( sqlUpdate , new
{
estadoBobinaAActualizar . Denominacion ,
estadoBobinaAActualizar . Obs ,
estadoBobinaAActualizar . IdEstadoBobina
} , transaction : transaction ) ;
return rowsAffected = = 1 ;
}
public async Task < bool > DeleteAsync ( int id , int idUsuario , IDbTransaction transaction )
{
var connection = transaction . Connection ! ;
var estadoActual = await connection . QuerySingleOrDefaultAsync < EstadoBobina > (
"SELECT Id_EstadoBobina AS IdEstadoBobina, Denominacion, Obs FROM dbo.bob_dtEstadosBobinas WHERE Id_EstadoBobina = @Id" ,
new { Id = id } ,
transaction ) ;
if ( estadoActual = = null ) throw new KeyNotFoundException ( $"No se encontró el estado de bobina con ID {id} para eliminar." ) ;
const string sqlDelete = "DELETE FROM dbo.bob_dtEstadosBobinas WHERE Id_EstadoBobina = @Id" ;
const string sqlInsertHistorico = @ "
INSERT INTO dbo . bob_dtEstadosBobinas_H ( Id_EstadoBobina , Denominacion , Obs , Id_Usuario , FechaMod , TipoMod )
VALUES ( @IdEstadoBobina , @Denominacion , @Obs , @IdUsuario , @FechaMod , @TipoMod ) ; ";
await connection . ExecuteAsync ( sqlInsertHistorico , new
{
IdEstadoBobina = estadoActual . IdEstadoBobina ,
estadoActual . Denominacion , // Valor ANTES
estadoActual . Obs , // Valor ANTES
IdUsuario = idUsuario ,
FechaMod = DateTime . Now ,
TipoMod = "Eliminada"
} , transaction : transaction ) ;
var rowsAffected = await connection . ExecuteAsync ( sqlDelete , new { Id = id } , transaction : transaction ) ;
return rowsAffected = = 1 ;
}
2025-06-12 19:36:21 -03:00
public async Task < IEnumerable < ( EstadoBobinaHistorico Historial , string NombreUsuarioModifico ) > > GetHistorialAsync (
DateTime ? fechaDesde , DateTime ? fechaHasta ,
int? idUsuarioModifico , string? tipoModificacion ,
int? idEstadoBobinaOriginal )
{
using var connection = _connectionFactory . CreateConnection ( ) ;
var sqlBuilder = new StringBuilder ( @ "
SELECT
h . Id_EstadoBobina , h . Denominacion , h . Obs ,
h . Id_Usuario , h . FechaMod , h . TipoMod ,
u . Nombre + ' ' + u . Apellido AS NombreUsuarioModifico
FROM dbo . bob_dtEstadosBobinas_H h
JOIN dbo . gral_Usuarios u ON h . Id_Usuario = u . Id
WHERE 1 = 1 ");
var parameters = new DynamicParameters ( ) ;
if ( fechaDesde . HasValue ) { sqlBuilder . Append ( " AND h.FechaMod >= @FechaDesdeParam" ) ; parameters . Add ( "FechaDesdeParam" , fechaDesde . Value . Date ) ; }
if ( fechaHasta . HasValue ) { sqlBuilder . Append ( " AND h.FechaMod <= @FechaHastaParam" ) ; parameters . Add ( "FechaHastaParam" , fechaHasta . Value . Date . AddDays ( 1 ) . AddTicks ( - 1 ) ) ; }
if ( idUsuarioModifico . HasValue ) { sqlBuilder . Append ( " AND h.Id_Usuario = @IdUsuarioModificoParam" ) ; parameters . Add ( "IdUsuarioModificoParam" , idUsuarioModifico . Value ) ; }
if ( ! string . IsNullOrWhiteSpace ( tipoModificacion ) ) { sqlBuilder . Append ( " AND h.TipoMod = @TipoModParam" ) ; parameters . Add ( "TipoModParam" , tipoModificacion ) ; }
if ( idEstadoBobinaOriginal . HasValue ) { sqlBuilder . Append ( " AND h.Id_EstadoBobina = @IdEstadoBobinaOriginalParam" ) ; parameters . Add ( "IdEstadoBobinaOriginalParam" , idEstadoBobinaOriginal . Value ) ; }
sqlBuilder . Append ( " ORDER BY h.FechaMod DESC;" ) ;
try
{
var result = await connection . QueryAsync < EstadoBobinaHistorico , string , ( EstadoBobinaHistorico , string ) > (
sqlBuilder . ToString ( ) ,
( hist , userName ) = > ( hist , userName ) ,
parameters ,
splitOn : "NombreUsuarioModifico"
) ;
return result ;
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Error al obtener historial de Estados de Bobina." ) ;
return Enumerable . Empty < ( EstadoBobinaHistorico , string ) > ( ) ;
}
}
feat: Implementación módulos Empresas, Plantas, Tipos y Estados Bobina
Backend API:
- Implementado CRUD completo para Empresas (DE001-DE004):
- EmpresaRepository, EmpresaService, EmpresasController.
- Lógica de creación/eliminación de saldos iniciales en EmpresaService.
- Transacciones y registro en tablas _H.
- Verificación de permisos específicos.
- Implementado CRUD completo para Plantas de Impresión (IP001-IP004):
- PlantaRepository, PlantaService, PlantasController.
- Transacciones y registro en tablas _H.
- Verificación de permisos.
- Implementado CRUD completo para Tipos de Bobina (IB006-IB009):
- TipoBobinaRepository, TipoBobinaService, TiposBobinaController.
- Transacciones y registro en tablas _H.
- Verificación de permisos.
- Implementado CRUD completo para Estados de Bobina (IB010-IB013):
- EstadoBobinaRepository, EstadoBobinaService, EstadosBobinaController.
- Transacciones y registro en tablas _H.
- Verificación de permisos.
Frontend React:
- Módulo Empresas:
- empresaService.ts para interactuar con la API.
- EmpresaFormModal.tsx para crear/editar empresas.
- GestionarEmpresasPage.tsx con tabla, filtro, paginación y menú de acciones.
- Integración con el hook usePermissions para control de acceso.
- Módulo Plantas de Impresión:
- plantaService.ts.
- PlantaFormModal.tsx.
- GestionarPlantasPage.tsx con tabla, filtro, paginación y acciones.
- Integración con usePermissions.
- Módulo Tipos de Bobina:
- tipoBobinaService.ts.
- TipoBobinaFormModal.tsx.
- GestionarTiposBobinaPage.tsx con tabla, filtro, paginación y acciones.
- Integración con usePermissions.
- Módulo Estados de Bobina:
- estadoBobinaService.ts.
- EstadoBobinaFormModal.tsx.
- GestionarEstadosBobinaPage.tsx con tabla, filtro, paginación y acciones.
- Integración con usePermissions.
- Navegación:
- Añadidas sub-pestañas y rutas para los nuevos módulos dentro de "Distribución" (Empresas) e "Impresión" (Plantas, Tipos Bobina, Estados Bobina).
- Creado ImpresionIndexPage.tsx para la navegación interna del módulo de Impresión.
Correcciones:
- Corregido el uso de CommitAsync/RollbackAsync a Commit/Rollback síncronos en PlantaService.cs debido a que IDbTransaction no los soporta asíncronamente.
2025-05-09 10:08:53 -03:00
}
}