| 
									
										
											  
											
												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.Data.Repositories; // Para IZonaRepository | 
					
						
							|  |  |  | using GestionIntegral.Api.Data.Repositories.Distribucion; | 
					
						
							| 
									
										
										
										
											2025-06-12 19:36:21 -03:00
										 |  |  | using GestionIntegral.Api.Dtos.Auditoria; | 
					
						
							| 
									
										
											  
											
												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.Dtos.Zonas; | 
					
						
							|  |  |  | using GestionIntegral.Api.Models.Distribucion; // Para Zona | 
					
						
							|  |  |  | using System.Collections.Generic; | 
					
						
							|  |  |  | using System.Linq; | 
					
						
							|  |  |  | using System.Threading.Tasks; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace GestionIntegral.Api.Services.Distribucion | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     public class ZonaService : IZonaService | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         private readonly IZonaRepository _zonaRepository; | 
					
						
							|  |  |  |         private readonly ILogger<ZonaService> _logger; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public ZonaService(IZonaRepository zonaRepository, ILogger<ZonaService> logger) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             _zonaRepository = zonaRepository; | 
					
						
							|  |  |  |             _logger = logger; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public async Task<IEnumerable<ZonaDto>> ObtenerTodasAsync(string? nombreFilter, string? descripcionFilter) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             var zonas = await _zonaRepository.GetAllAsync(nombreFilter, descripcionFilter, soloActivas: true); // Solo activas por defecto | 
					
						
							|  |  |  |             // Mapeo Entidad -> DTO | 
					
						
							|  |  |  |             return zonas.Select(z => new ZonaDto | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 IdZona = z.IdZona, | 
					
						
							|  |  |  |                 Nombre = z.Nombre, | 
					
						
							|  |  |  |                 Descripcion = z.Descripcion | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public async Task<ZonaDto?> ObtenerPorIdAsync(int id) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             var zona = await _zonaRepository.GetByIdAsync(id, soloActivas: true); // Solo activa por defecto | 
					
						
							|  |  |  |             if (zona == null) return null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // Mapeo Entidad -> DTO | 
					
						
							|  |  |  |             return new ZonaDto | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 IdZona = zona.IdZona, | 
					
						
							|  |  |  |                 Nombre = zona.Nombre, | 
					
						
							|  |  |  |                 Descripcion = zona.Descripcion | 
					
						
							|  |  |  |             }; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public async Task<(ZonaDto? Zona, string? Error)> CrearAsync(CreateZonaDto createDto, int idUsuario) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             // Validación: Nombre duplicado (entre zonas activas) | 
					
						
							|  |  |  |             if (await _zonaRepository.ExistsByNameAsync(createDto.Nombre, null, soloActivas: true)) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 return (null, "El nombre de la zona ya existe."); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             var nuevaZona = new Zona | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 Nombre = createDto.Nombre, | 
					
						
							|  |  |  |                 Descripcion = createDto.Descripcion, | 
					
						
							|  |  |  |                 Estado = true // Las zonas nuevas siempre están activas | 
					
						
							|  |  |  |             }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             var zonaCreada = await _zonaRepository.CreateAsync(nuevaZona, idUsuario); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (zonaCreada == null) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 _logger.LogError("Falló la creación de la Zona en el repositorio para el nombre: {Nombre}", createDto.Nombre); | 
					
						
							|  |  |  |                 return (null, "Error al crear la zona en la base de datos."); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // Mapeo de Entidad creada a DTO | 
					
						
							|  |  |  |             var zonaDto = new ZonaDto | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 IdZona = zonaCreada.IdZona, | 
					
						
							|  |  |  |                 Nombre = zonaCreada.Nombre, | 
					
						
							|  |  |  |                 Descripcion = zonaCreada.Descripcion | 
					
						
							|  |  |  |             }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return (zonaDto, null); // Éxito | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public async Task<(bool Exito, string? Error)> ActualizarAsync(int id, UpdateZonaDto updateDto, int idUsuario) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             // Verificar si la zona existe y está activa para poder modificarla (regla de negocio) | 
					
						
							|  |  |  |             var zonaExistente = await _zonaRepository.GetByIdAsync(id, soloActivas: true); | 
					
						
							|  |  |  |             if (zonaExistente == null) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 // Podría no existir o estar inactiva | 
					
						
							|  |  |  |                 var zonaInactiva = await _zonaRepository.GetByIdAsync(id, soloActivas: false); | 
					
						
							|  |  |  |                 if (zonaInactiva != null) | 
					
						
							|  |  |  |                     return (false, "No se puede modificar una zona eliminada (inactiva)."); | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                     return (false, "Zona no encontrada."); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // Validación: Nombre duplicado (excluyendo el ID actual, entre zonas activas) | 
					
						
							|  |  |  |             if (await _zonaRepository.ExistsByNameAsync(updateDto.Nombre, id, soloActivas: true)) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 return (false, "El nombre de la zona ya existe para otro registro activo."); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // Mapeo de DTO a Entidad para actualizar | 
					
						
							|  |  |  |             zonaExistente.Nombre = updateDto.Nombre; | 
					
						
							|  |  |  |             zonaExistente.Descripcion = updateDto.Descripcion; | 
					
						
							|  |  |  |             // No modificamos el estado aquí, solo nombre y descripción | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             var actualizado = await _zonaRepository.UpdateAsync(zonaExistente, idUsuario); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (!actualizado) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 _logger.LogError("Falló la actualización de la Zona en el repositorio para el ID: {Id}", id); | 
					
						
							|  |  |  |                 return (false, "Error al actualizar la zona en la base de datos."); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return (true, null); // Éxito | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public async Task<(bool Exito, string? Error)> EliminarAsync(int id, int idUsuario) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             // Verificar si la zona existe (incluso si está inactiva, para evitar errores) | 
					
						
							|  |  |  |             var zonaExistente = await _zonaRepository.GetByIdAsync(id, soloActivas: false); | 
					
						
							|  |  |  |             if (zonaExistente == null) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 return (false, "Zona no encontrada."); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             // Si ya está inactiva, consideramos la operación exitosa (idempotencia) | 
					
						
							| 
									
										
										
										
											2025-06-12 19:36:21 -03:00
										 |  |  |             if (!zonaExistente.Estado) | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
											  
											
												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
										 |  |  |                 return (true, null); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // Validación: No se puede eliminar si está en uso por distribuidores o canillas activos | 
					
						
							|  |  |  |             if (await _zonaRepository.IsInUseAsync(id)) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 return (false, "No se puede eliminar. La zona está asignada a distribuidores o canillas activos."); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // Realizar el Soft Delete | 
					
						
							|  |  |  |             var eliminado = await _zonaRepository.SoftDeleteAsync(id, idUsuario); | 
					
						
							|  |  |  |             if (!eliminado) | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-06-12 19:36:21 -03:00
										 |  |  |                 _logger.LogError("Falló la eliminación lógica de la Zona en el repositorio para el ID: {Id}", id); | 
					
						
							| 
									
										
											  
											
												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
										 |  |  |                 return (false, "Error al eliminar la zona de la base de datos."); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return (true, null); // Éxito | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-06-12 19:36:21 -03:00
										 |  |  |          | 
					
						
							|  |  |  |         public async Task<IEnumerable<ZonaHistorialDto>> ObtenerHistorialAsync( | 
					
						
							|  |  |  |         DateTime? fechaDesde, DateTime? fechaHasta, | 
					
						
							|  |  |  |         int? idUsuarioModifico, string? tipoModificacion, | 
					
						
							|  |  |  |         int? idZonaAfectada) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         var historialData = await _zonaRepository.GetHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idZonaAfectada); | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         return historialData.Select(h => new ZonaHistorialDto | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             Id_Zona = h.Historial.Id_Zona, | 
					
						
							|  |  |  |             Nombre = h.Historial.Nombre, | 
					
						
							|  |  |  |             Descripcion = h.Historial.Descripcion, | 
					
						
							|  |  |  |             Estado = h.Historial.Estado, | 
					
						
							|  |  |  |             Id_Usuario = h.Historial.Id_Usuario, | 
					
						
							|  |  |  |             NombreUsuarioModifico = h.NombreUsuarioModifico, | 
					
						
							|  |  |  |             FechaMod = h.Historial.FechaMod, | 
					
						
							|  |  |  |             TipoMod = h.Historial.TipoMod | 
					
						
							|  |  |  |         }).ToList(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
											  
											
												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
										 |  |  |     } | 
					
						
							|  |  |  | } |