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 ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								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 > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}