feat: Implementación de Secciones, Recargos, Porc. Pago Dist. y backend E/S Dist.
Backend API:
- Recargos por Zona (`dist_RecargoZona`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/recargos`.
  - Lógica de negocio para vigencias (cierre/reapertura de períodos).
  - Auditoría en `dist_RecargoZona_H`.
- Porcentajes de Pago Distribuidores (`dist_PorcPago`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/porcentajespago`.
  - Lógica de negocio para vigencias.
  - Auditoría en `dist_PorcPago_H`.
- Porcentajes/Montos Pago Canillitas (`dist_PorcMonPagoCanilla`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/porcentajesmoncanilla`.
  - Lógica de negocio para vigencias.
  - Auditoría en `dist_PorcMonPagoCanilla_H`.
- Secciones de Publicación (`dist_dtPubliSecciones`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/secciones`.
  - Auditoría en `dist_dtPubliSecciones_H`.
- Entradas/Salidas Distribuidores (`dist_EntradasSalidas`):
  - Implementado backend (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Lógica para determinar precios/recargos/porcentajes aplicables.
  - Cálculo de monto y afectación de saldos de distribuidores en `cue_Saldos`.
  - Auditoría en `dist_EntradasSalidas_H`.
- Correcciones de Mapeo Dapper:
  - Aplicados alias explícitos en repositorios de RecargoZona, PorcPago, PorcMonCanilla, PubliSeccion,
    Canilla, Distribuidor y Precio para asegurar mapeo correcto de IDs y columnas.
Frontend React:
- Recargos por Zona:
  - `recargoZonaService.ts`.
  - `RecargoZonaFormModal.tsx` para crear/editar períodos de recargos.
  - `GestionarRecargosPublicacionPage.tsx` para listar y gestionar recargos por publicación.
- Porcentajes de Pago Distribuidores:
  - `porcPagoService.ts`.
  - `PorcPagoFormModal.tsx`.
  - `GestionarPorcentajesPagoPage.tsx`.
- Porcentajes/Montos Pago Canillitas:
  - `porcMonCanillaService.ts`.
  - `PorcMonCanillaFormModal.tsx`.
  - `GestionarPorcMonCanillaPage.tsx`.
- Secciones de Publicación:
  - `publiSeccionService.ts`.
  - `PubliSeccionFormModal.tsx`.
  - `GestionarSeccionesPublicacionPage.tsx`.
- Navegación:
  - Actualizadas rutas y menús para acceder a la gestión de recargos, porcentajes (dist. y canillita) y secciones desde la vista de una publicación.
- Layout:
  - Uso consistente de `Box` con Flexbox en lugar de `Grid` en nuevos modales y páginas para evitar errores de tipo.
											 
										 
										
											2025-05-21 14:58:52 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								using  GestionIntegral.Api.Data ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								using  GestionIntegral.Api.Data.Repositories.Contables ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								using  GestionIntegral.Api.Data.Repositories.Distribucion ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								using  GestionIntegral.Api.Dtos.Distribucion ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								using  GestionIntegral.Api.Models.Distribucion ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								using  Microsoft.Extensions.Logging ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								using  System ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								using  System.Collections.Generic ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								using  System.Data ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								using  System.Globalization ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								using  System.Linq ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								using  System.Threading.Tasks ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								namespace  GestionIntegral.Api.Services.Distribucion  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    public  class  EntradaSalidaDistService  :  IEntradaSalidaDistService 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        private  readonly  IEntradaSalidaDistRepository  _esRepository ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        private  readonly  IPublicacionRepository  _publicacionRepository ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        private  readonly  IDistribuidorRepository  _distribuidorRepository ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        private  readonly  IPrecioRepository  _precioRepository ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        private  readonly  IRecargoZonaRepository  _recargoZonaRepository ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        private  readonly  IPorcPagoRepository  _porcPagoRepository ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        private  readonly  ISaldoRepository  _saldoRepository ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        private  readonly  IEmpresaRepository  _empresaRepository ;  // Para obtener IdEmpresa de la publicación 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        private  readonly  DbConnectionFactory  _connectionFactory ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        private  readonly  ILogger < EntradaSalidaDistService >  _logger ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        public  EntradaSalidaDistService ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            IEntradaSalidaDistRepository  esRepository , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            IPublicacionRepository  publicacionRepository , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            IDistribuidorRepository  distribuidorRepository , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            IPrecioRepository  precioRepository , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            IRecargoZonaRepository  recargoZonaRepository , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            IPorcPagoRepository  porcPagoRepository , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ISaldoRepository  saldoRepository , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            IEmpresaRepository  empresaRepository , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            DbConnectionFactory  connectionFactory , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ILogger < EntradaSalidaDistService >  logger ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            _esRepository  =  esRepository ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            _publicacionRepository  =  publicacionRepository ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            _distribuidorRepository  =  distribuidorRepository ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            _precioRepository  =  precioRepository ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            _recargoZonaRepository  =  recargoZonaRepository ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            _porcPagoRepository  =  porcPagoRepository ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            _saldoRepository  =  saldoRepository ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            _empresaRepository  =  empresaRepository ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            _connectionFactory  =  connectionFactory ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            _logger  =  logger ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        private  async  Task < EntradaSalidaDistDto >  MapToDto ( EntradaSalidaDist  es ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( es  = =  null )  return  null ! ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            var  publicacionData  =  await  _publicacionRepository . GetByIdAsync ( es . IdPublicacion ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            var  distribuidorData  =  await  _distribuidorRepository . GetByIdAsync ( es . IdDistribuidor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            
							 
						 
					
						
							
								
									
										
										
										
											2025-05-23 15:47:39 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Obtener el valor bruto del movimiento 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            decimal  valorBrutoMovimiento  =  await  CalcularMontoMovimiento ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                es . IdPublicacion ,  es . IdDistribuidor ,  es . Fecha ,  es . Cantidad ,  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                es . TipoMovimiento ,  // Pasamos el tipo de movimiento original aquí 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                es . IdPrecio ,  es . IdRecargo ,  es . IdPorcentaje ,  distribuidorData . Distribuidor ? . IdZona 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												feat: Implementación de Secciones, Recargos, Porc. Pago Dist. y backend E/S Dist.
Backend API:
- Recargos por Zona (`dist_RecargoZona`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/recargos`.
  - Lógica de negocio para vigencias (cierre/reapertura de períodos).
  - Auditoría en `dist_RecargoZona_H`.
- Porcentajes de Pago Distribuidores (`dist_PorcPago`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/porcentajespago`.
  - Lógica de negocio para vigencias.
  - Auditoría en `dist_PorcPago_H`.
- Porcentajes/Montos Pago Canillitas (`dist_PorcMonPagoCanilla`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/porcentajesmoncanilla`.
  - Lógica de negocio para vigencias.
  - Auditoría en `dist_PorcMonPagoCanilla_H`.
- Secciones de Publicación (`dist_dtPubliSecciones`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/secciones`.
  - Auditoría en `dist_dtPubliSecciones_H`.
- Entradas/Salidas Distribuidores (`dist_EntradasSalidas`):
  - Implementado backend (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Lógica para determinar precios/recargos/porcentajes aplicables.
  - Cálculo de monto y afectación de saldos de distribuidores en `cue_Saldos`.
  - Auditoría en `dist_EntradasSalidas_H`.
- Correcciones de Mapeo Dapper:
  - Aplicados alias explícitos en repositorios de RecargoZona, PorcPago, PorcMonCanilla, PubliSeccion,
    Canilla, Distribuidor y Precio para asegurar mapeo correcto de IDs y columnas.
Frontend React:
- Recargos por Zona:
  - `recargoZonaService.ts`.
  - `RecargoZonaFormModal.tsx` para crear/editar períodos de recargos.
  - `GestionarRecargosPublicacionPage.tsx` para listar y gestionar recargos por publicación.
- Porcentajes de Pago Distribuidores:
  - `porcPagoService.ts`.
  - `PorcPagoFormModal.tsx`.
  - `GestionarPorcentajesPagoPage.tsx`.
- Porcentajes/Montos Pago Canillitas:
  - `porcMonCanillaService.ts`.
  - `PorcMonCanillaFormModal.tsx`.
  - `GestionarPorcMonCanillaPage.tsx`.
- Secciones de Publicación:
  - `publiSeccionService.ts`.
  - `PubliSeccionFormModal.tsx`.
  - `GestionarSeccionesPublicacionPage.tsx`.
- Navegación:
  - Actualizadas rutas y menús para acceder a la gestión de recargos, porcentajes (dist. y canillita) y secciones desde la vista de una publicación.
- Layout:
  - Uso consistente de `Box` con Flexbox en lugar de `Grid` en nuevos modales y páginas para evitar errores de tipo.
											 
										 
										
											2025-05-21 14:58:52 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-05-23 15:47:39 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Ajustar para el DTO: si es "Entrada", el monto calculado es un crédito (negativo o positivo según convención) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Para consistencia con el ajuste de saldo, si es Entrada, el MontoCalculado para el DTO puede ser el valor 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // que se le "acredita" al distribuidor (o sea, el valor de la mercadería devuelta). 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // La lógica de +/- para el saldo ya está en Crear/Actualizar/Eliminar. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Aquí solo mostramos el valor del movimiento. Si es entrada, es el valor de lo devuelto. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Si es salida, es el valor de lo que se le factura. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // El método CalcularMonto ya devuelve el monto que el distribuidor DEBE pagar por una SALIDA. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Para una ENTRADA (devolución), el valor de esa mercadería es el mismo, pero opera en sentido contrario al saldo. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            decimal  montoCalculadoParaDto  =  valorBrutoMovimiento ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Si queremos que el DTO muestre las entradas como un valor que "reduce la deuda", 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // podría ser positivo. Si queremos que refleje el impacto directo en la factura (salidas suman, entradas restan), 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // podríamos hacerlo negativo. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Por ahora, dejaremos que CalcularMontoMovimiento devuelva el valor de una "Salida", 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // y si es "Entrada", este mismo valor es el que se acredita. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // La columna `MontoCalculado` en el DTO representará el valor de la transacción. 
							 
						 
					
						
							
								
									
										
											 
										
											
												feat: Implementación de Secciones, Recargos, Porc. Pago Dist. y backend E/S Dist.
Backend API:
- Recargos por Zona (`dist_RecargoZona`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/recargos`.
  - Lógica de negocio para vigencias (cierre/reapertura de períodos).
  - Auditoría en `dist_RecargoZona_H`.
- Porcentajes de Pago Distribuidores (`dist_PorcPago`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/porcentajespago`.
  - Lógica de negocio para vigencias.
  - Auditoría en `dist_PorcPago_H`.
- Porcentajes/Montos Pago Canillitas (`dist_PorcMonPagoCanilla`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/porcentajesmoncanilla`.
  - Lógica de negocio para vigencias.
  - Auditoría en `dist_PorcMonPagoCanilla_H`.
- Secciones de Publicación (`dist_dtPubliSecciones`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/secciones`.
  - Auditoría en `dist_dtPubliSecciones_H`.
- Entradas/Salidas Distribuidores (`dist_EntradasSalidas`):
  - Implementado backend (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Lógica para determinar precios/recargos/porcentajes aplicables.
  - Cálculo de monto y afectación de saldos de distribuidores en `cue_Saldos`.
  - Auditoría en `dist_EntradasSalidas_H`.
- Correcciones de Mapeo Dapper:
  - Aplicados alias explícitos en repositorios de RecargoZona, PorcPago, PorcMonCanilla, PubliSeccion,
    Canilla, Distribuidor y Precio para asegurar mapeo correcto de IDs y columnas.
Frontend React:
- Recargos por Zona:
  - `recargoZonaService.ts`.
  - `RecargoZonaFormModal.tsx` para crear/editar períodos de recargos.
  - `GestionarRecargosPublicacionPage.tsx` para listar y gestionar recargos por publicación.
- Porcentajes de Pago Distribuidores:
  - `porcPagoService.ts`.
  - `PorcPagoFormModal.tsx`.
  - `GestionarPorcentajesPagoPage.tsx`.
- Porcentajes/Montos Pago Canillitas:
  - `porcMonCanillaService.ts`.
  - `PorcMonCanillaFormModal.tsx`.
  - `GestionarPorcMonCanillaPage.tsx`.
- Secciones de Publicación:
  - `publiSeccionService.ts`.
  - `PubliSeccionFormModal.tsx`.
  - `GestionarSeccionesPublicacionPage.tsx`.
- Navegación:
  - Actualizadas rutas y menús para acceder a la gestión de recargos, porcentajes (dist. y canillita) y secciones desde la vista de una publicación.
- Layout:
  - Uso consistente de `Box` con Flexbox en lugar de `Grid` en nuevos modales y páginas para evitar errores de tipo.
											 
										 
										
											2025-05-21 14:58:52 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  new  EntradaSalidaDistDto 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                IdParte  =  es . IdParte , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                IdPublicacion  =  es . IdPublicacion , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                NombrePublicacion  =  publicacionData . Publicacion ? . Nombre  ? ?  "N/A" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                IdEmpresaPublicacion  =  publicacionData . Publicacion ? . IdEmpresa  ? ?  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                NombreEmpresaPublicacion  =  publicacionData . NombreEmpresa  ? ?  "N/A" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                IdDistribuidor  =  es . IdDistribuidor , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                NombreDistribuidor  =  distribuidorData . Distribuidor ? . Nombre  ? ?  "N/A" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                Fecha  =  es . Fecha . ToString ( "yyyy-MM-dd" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                TipoMovimiento  =  es . TipoMovimiento , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                Cantidad  =  es . Cantidad , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                Remito  =  es . Remito , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                Observacion  =  es . Observacion , 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-23 15:47:39 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                MontoCalculado  =  montoCalculadoParaDto  // Representa el valor de los N ejemplares 
							 
						 
					
						
							
								
									
										
											 
										
											
												feat: Implementación de Secciones, Recargos, Porc. Pago Dist. y backend E/S Dist.
Backend API:
- Recargos por Zona (`dist_RecargoZona`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/recargos`.
  - Lógica de negocio para vigencias (cierre/reapertura de períodos).
  - Auditoría en `dist_RecargoZona_H`.
- Porcentajes de Pago Distribuidores (`dist_PorcPago`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/porcentajespago`.
  - Lógica de negocio para vigencias.
  - Auditoría en `dist_PorcPago_H`.
- Porcentajes/Montos Pago Canillitas (`dist_PorcMonPagoCanilla`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/porcentajesmoncanilla`.
  - Lógica de negocio para vigencias.
  - Auditoría en `dist_PorcMonPagoCanilla_H`.
- Secciones de Publicación (`dist_dtPubliSecciones`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/secciones`.
  - Auditoría en `dist_dtPubliSecciones_H`.
- Entradas/Salidas Distribuidores (`dist_EntradasSalidas`):
  - Implementado backend (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Lógica para determinar precios/recargos/porcentajes aplicables.
  - Cálculo de monto y afectación de saldos de distribuidores en `cue_Saldos`.
  - Auditoría en `dist_EntradasSalidas_H`.
- Correcciones de Mapeo Dapper:
  - Aplicados alias explícitos en repositorios de RecargoZona, PorcPago, PorcMonCanilla, PubliSeccion,
    Canilla, Distribuidor y Precio para asegurar mapeo correcto de IDs y columnas.
Frontend React:
- Recargos por Zona:
  - `recargoZonaService.ts`.
  - `RecargoZonaFormModal.tsx` para crear/editar períodos de recargos.
  - `GestionarRecargosPublicacionPage.tsx` para listar y gestionar recargos por publicación.
- Porcentajes de Pago Distribuidores:
  - `porcPagoService.ts`.
  - `PorcPagoFormModal.tsx`.
  - `GestionarPorcentajesPagoPage.tsx`.
- Porcentajes/Montos Pago Canillitas:
  - `porcMonCanillaService.ts`.
  - `PorcMonCanillaFormModal.tsx`.
  - `GestionarPorcMonCanillaPage.tsx`.
- Secciones de Publicación:
  - `publiSeccionService.ts`.
  - `PubliSeccionFormModal.tsx`.
  - `GestionarSeccionesPublicacionPage.tsx`.
- Navegación:
  - Actualizadas rutas y menús para acceder a la gestión de recargos, porcentajes (dist. y canillita) y secciones desde la vista de una publicación.
- Layout:
  - Uso consistente de `Box` con Flexbox en lugar de `Grid` en nuevos modales y páginas para evitar errores de tipo.
											 
										 
										
											2025-05-21 14:58:52 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        private  async  Task < decimal >  CalcularMontoMovimiento ( int  idPublicacion ,  int  idDistribuidor ,  DateTime  fecha ,  int  cantidad ,  string  tipoMovimiento , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                            int  idPrecio ,  int  idRecargo ,  int  idPorcentaje ,  int?  idZonaDistribuidor ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        { 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-23 15:47:39 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // YA NO SE DEVUELVE 0 PARA ENTRADA AQUÍ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // if (tipoMovimiento == "Entrada") return 0;  
							 
						 
					
						
							
								
									
										
											 
										
											
												feat: Implementación de Secciones, Recargos, Porc. Pago Dist. y backend E/S Dist.
Backend API:
- Recargos por Zona (`dist_RecargoZona`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/recargos`.
  - Lógica de negocio para vigencias (cierre/reapertura de períodos).
  - Auditoría en `dist_RecargoZona_H`.
- Porcentajes de Pago Distribuidores (`dist_PorcPago`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/porcentajespago`.
  - Lógica de negocio para vigencias.
  - Auditoría en `dist_PorcPago_H`.
- Porcentajes/Montos Pago Canillitas (`dist_PorcMonPagoCanilla`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/porcentajesmoncanilla`.
  - Lógica de negocio para vigencias.
  - Auditoría en `dist_PorcMonPagoCanilla_H`.
- Secciones de Publicación (`dist_dtPubliSecciones`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/secciones`.
  - Auditoría en `dist_dtPubliSecciones_H`.
- Entradas/Salidas Distribuidores (`dist_EntradasSalidas`):
  - Implementado backend (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Lógica para determinar precios/recargos/porcentajes aplicables.
  - Cálculo de monto y afectación de saldos de distribuidores en `cue_Saldos`.
  - Auditoría en `dist_EntradasSalidas_H`.
- Correcciones de Mapeo Dapper:
  - Aplicados alias explícitos en repositorios de RecargoZona, PorcPago, PorcMonCanilla, PubliSeccion,
    Canilla, Distribuidor y Precio para asegurar mapeo correcto de IDs y columnas.
Frontend React:
- Recargos por Zona:
  - `recargoZonaService.ts`.
  - `RecargoZonaFormModal.tsx` para crear/editar períodos de recargos.
  - `GestionarRecargosPublicacionPage.tsx` para listar y gestionar recargos por publicación.
- Porcentajes de Pago Distribuidores:
  - `porcPagoService.ts`.
  - `PorcPagoFormModal.tsx`.
  - `GestionarPorcentajesPagoPage.tsx`.
- Porcentajes/Montos Pago Canillitas:
  - `porcMonCanillaService.ts`.
  - `PorcMonCanillaFormModal.tsx`.
  - `GestionarPorcMonCanillaPage.tsx`.
- Secciones de Publicación:
  - `publiSeccionService.ts`.
  - `PubliSeccionFormModal.tsx`.
  - `GestionarSeccionesPublicacionPage.tsx`.
- Navegación:
  - Actualizadas rutas y menús para acceder a la gestión de recargos, porcentajes (dist. y canillita) y secciones desde la vista de una publicación.
- Layout:
  - Uso consistente de `Box` con Flexbox en lugar de `Grid` en nuevos modales y páginas para evitar errores de tipo.
											 
										 
										
											2025-05-21 14:58:52 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            var  precioConfig  =  await  _precioRepository . GetByIdAsync ( idPrecio ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-23 15:47:39 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Es crucial que idPrecio sea válido y se haya determinado correctamente antes de llamar aquí. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Si precioConfig es null, se lanzará una excepción abajo, lo cual está bien si es un estado inesperado. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( precioConfig  = =  null ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                _logger . LogError ( "Configuración de precio ID {IdPrecio} no encontrada al calcular monto para Pub {IdPublicacion}, Dist {IdDistribuidor}, Fecha {Fecha}" ,  idPrecio ,  idPublicacion ,  idDistribuidor ,  fecha ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Dependiendo de la regla de negocio, podrías devolver 0 o lanzar una excepción. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Si un precio es OBLIGATORIO para cualquier movimiento, lanzar excepción es más apropiado. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Si puede haber movimientos sin precio (ej. cortesía que no se factura), entonces 0. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // En este contexto, un precio es fundamental para el cálculo. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                throw  new  InvalidOperationException ( $"Configuración de precio ID {idPrecio} no encontrada. No se puede calcular el monto." ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												feat: Implementación de Secciones, Recargos, Porc. Pago Dist. y backend E/S Dist.
Backend API:
- Recargos por Zona (`dist_RecargoZona`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/recargos`.
  - Lógica de negocio para vigencias (cierre/reapertura de períodos).
  - Auditoría en `dist_RecargoZona_H`.
- Porcentajes de Pago Distribuidores (`dist_PorcPago`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/porcentajespago`.
  - Lógica de negocio para vigencias.
  - Auditoría en `dist_PorcPago_H`.
- Porcentajes/Montos Pago Canillitas (`dist_PorcMonPagoCanilla`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/porcentajesmoncanilla`.
  - Lógica de negocio para vigencias.
  - Auditoría en `dist_PorcMonPagoCanilla_H`.
- Secciones de Publicación (`dist_dtPubliSecciones`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/secciones`.
  - Auditoría en `dist_dtPubliSecciones_H`.
- Entradas/Salidas Distribuidores (`dist_EntradasSalidas`):
  - Implementado backend (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Lógica para determinar precios/recargos/porcentajes aplicables.
  - Cálculo de monto y afectación de saldos de distribuidores en `cue_Saldos`.
  - Auditoría en `dist_EntradasSalidas_H`.
- Correcciones de Mapeo Dapper:
  - Aplicados alias explícitos en repositorios de RecargoZona, PorcPago, PorcMonCanilla, PubliSeccion,
    Canilla, Distribuidor y Precio para asegurar mapeo correcto de IDs y columnas.
Frontend React:
- Recargos por Zona:
  - `recargoZonaService.ts`.
  - `RecargoZonaFormModal.tsx` para crear/editar períodos de recargos.
  - `GestionarRecargosPublicacionPage.tsx` para listar y gestionar recargos por publicación.
- Porcentajes de Pago Distribuidores:
  - `porcPagoService.ts`.
  - `PorcPagoFormModal.tsx`.
  - `GestionarPorcentajesPagoPage.tsx`.
- Porcentajes/Montos Pago Canillitas:
  - `porcMonCanillaService.ts`.
  - `PorcMonCanillaFormModal.tsx`.
  - `GestionarPorcMonCanillaPage.tsx`.
- Secciones de Publicación:
  - `publiSeccionService.ts`.
  - `PubliSeccionFormModal.tsx`.
  - `GestionarSeccionesPublicacionPage.tsx`.
- Navegación:
  - Actualizadas rutas y menús para acceder a la gestión de recargos, porcentajes (dist. y canillita) y secciones desde la vista de una publicación.
- Layout:
  - Uso consistente de `Box` con Flexbox en lugar de `Grid` en nuevos modales y páginas para evitar errores de tipo.
											 
										 
										
											2025-05-21 14:58:52 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            decimal  precioDia  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            DayOfWeek  diaSemana  =  fecha . DayOfWeek ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            switch  ( diaSemana ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                case  DayOfWeek . Monday :  precioDia  =  precioConfig . Lunes  ? ?  0 ;  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                case  DayOfWeek . Tuesday :  precioDia  =  precioConfig . Martes  ? ?  0 ;  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                case  DayOfWeek . Wednesday :  precioDia  =  precioConfig . Miercoles  ? ?  0 ;  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                case  DayOfWeek . Thursday :  precioDia  =  precioConfig . Jueves  ? ?  0 ;  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                case  DayOfWeek . Friday :  precioDia  =  precioConfig . Viernes  ? ?  0 ;  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                case  DayOfWeek . Saturday :  precioDia  =  precioConfig . Sabado  ? ?  0 ;  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                case  DayOfWeek . Sunday :  precioDia  =  precioConfig . Domingo  ? ?  0 ;  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            decimal  valorRecargo  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-23 15:47:39 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( idRecargo  >  0  & &  idZonaDistribuidor . HasValue ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												feat: Implementación de Secciones, Recargos, Porc. Pago Dist. y backend E/S Dist.
Backend API:
- Recargos por Zona (`dist_RecargoZona`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/recargos`.
  - Lógica de negocio para vigencias (cierre/reapertura de períodos).
  - Auditoría en `dist_RecargoZona_H`.
- Porcentajes de Pago Distribuidores (`dist_PorcPago`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/porcentajespago`.
  - Lógica de negocio para vigencias.
  - Auditoría en `dist_PorcPago_H`.
- Porcentajes/Montos Pago Canillitas (`dist_PorcMonPagoCanilla`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/porcentajesmoncanilla`.
  - Lógica de negocio para vigencias.
  - Auditoría en `dist_PorcMonPagoCanilla_H`.
- Secciones de Publicación (`dist_dtPubliSecciones`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/secciones`.
  - Auditoría en `dist_dtPubliSecciones_H`.
- Entradas/Salidas Distribuidores (`dist_EntradasSalidas`):
  - Implementado backend (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Lógica para determinar precios/recargos/porcentajes aplicables.
  - Cálculo de monto y afectación de saldos de distribuidores en `cue_Saldos`.
  - Auditoría en `dist_EntradasSalidas_H`.
- Correcciones de Mapeo Dapper:
  - Aplicados alias explícitos en repositorios de RecargoZona, PorcPago, PorcMonCanilla, PubliSeccion,
    Canilla, Distribuidor y Precio para asegurar mapeo correcto de IDs y columnas.
Frontend React:
- Recargos por Zona:
  - `recargoZonaService.ts`.
  - `RecargoZonaFormModal.tsx` para crear/editar períodos de recargos.
  - `GestionarRecargosPublicacionPage.tsx` para listar y gestionar recargos por publicación.
- Porcentajes de Pago Distribuidores:
  - `porcPagoService.ts`.
  - `PorcPagoFormModal.tsx`.
  - `GestionarPorcentajesPagoPage.tsx`.
- Porcentajes/Montos Pago Canillitas:
  - `porcMonCanillaService.ts`.
  - `PorcMonCanillaFormModal.tsx`.
  - `GestionarPorcMonCanillaPage.tsx`.
- Secciones de Publicación:
  - `publiSeccionService.ts`.
  - `PubliSeccionFormModal.tsx`.
  - `GestionarSeccionesPublicacionPage.tsx`.
- Navegación:
  - Actualizadas rutas y menús para acceder a la gestión de recargos, porcentajes (dist. y canillita) y secciones desde la vista de una publicación.
- Layout:
  - Uso consistente de `Box` con Flexbox en lugar de `Grid` en nuevos modales y páginas para evitar errores de tipo.
											 
										 
										
											2025-05-21 14:58:52 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                 var  recargoConfig  =  await  _recargoZonaRepository . GetActiveByPublicacionZonaAndDateAsync ( idPublicacion ,  idZonaDistribuidor . Value ,  fecha ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( recargoConfig  ! =  null ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    valorRecargo  =  recargoConfig . Valor ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            decimal  precioConRecargo  =  precioDia  +  valorRecargo ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            decimal  montoBase  =  precioConRecargo  *  cantidad ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( idPorcentaje  >  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                var  porcConfig  =  await  _porcPagoRepository . GetByIdAsync ( idPorcentaje ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( porcConfig  ! =  null ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                { 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-23 15:47:39 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    // El porcentaje de pago del distribuidor es lo que ÉL PAGA a la editorial. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // Entonces, el monto es (precio_tapa_con_recargo * cantidad) * (porcentaje_pago_dist / 100) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  ( montoBase  *  porcConfig . Porcentaje )  /  100 ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												feat: Implementación de Secciones, Recargos, Porc. Pago Dist. y backend E/S Dist.
Backend API:
- Recargos por Zona (`dist_RecargoZona`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/recargos`.
  - Lógica de negocio para vigencias (cierre/reapertura de períodos).
  - Auditoría en `dist_RecargoZona_H`.
- Porcentajes de Pago Distribuidores (`dist_PorcPago`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/porcentajespago`.
  - Lógica de negocio para vigencias.
  - Auditoría en `dist_PorcPago_H`.
- Porcentajes/Montos Pago Canillitas (`dist_PorcMonPagoCanilla`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/porcentajesmoncanilla`.
  - Lógica de negocio para vigencias.
  - Auditoría en `dist_PorcMonPagoCanilla_H`.
- Secciones de Publicación (`dist_dtPubliSecciones`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/secciones`.
  - Auditoría en `dist_dtPubliSecciones_H`.
- Entradas/Salidas Distribuidores (`dist_EntradasSalidas`):
  - Implementado backend (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Lógica para determinar precios/recargos/porcentajes aplicables.
  - Cálculo de monto y afectación de saldos de distribuidores en `cue_Saldos`.
  - Auditoría en `dist_EntradasSalidas_H`.
- Correcciones de Mapeo Dapper:
  - Aplicados alias explícitos en repositorios de RecargoZona, PorcPago, PorcMonCanilla, PubliSeccion,
    Canilla, Distribuidor y Precio para asegurar mapeo correcto de IDs y columnas.
Frontend React:
- Recargos por Zona:
  - `recargoZonaService.ts`.
  - `RecargoZonaFormModal.tsx` para crear/editar períodos de recargos.
  - `GestionarRecargosPublicacionPage.tsx` para listar y gestionar recargos por publicación.
- Porcentajes de Pago Distribuidores:
  - `porcPagoService.ts`.
  - `PorcPagoFormModal.tsx`.
  - `GestionarPorcentajesPagoPage.tsx`.
- Porcentajes/Montos Pago Canillitas:
  - `porcMonCanillaService.ts`.
  - `PorcMonCanillaFormModal.tsx`.
  - `GestionarPorcMonCanillaPage.tsx`.
- Secciones de Publicación:
  - `publiSeccionService.ts`.
  - `PubliSeccionFormModal.tsx`.
  - `GestionarSeccionesPublicacionPage.tsx`.
- Navegación:
  - Actualizadas rutas y menús para acceder a la gestión de recargos, porcentajes (dist. y canillita) y secciones desde la vista de una publicación.
- Layout:
  - Uso consistente de `Box` con Flexbox en lugar de `Grid` en nuevos modales y páginas para evitar errores de tipo.
											 
										 
										
											2025-05-21 14:58:52 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-23 15:47:39 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Si no hay porcentaje de pago específico, se asume que el distribuidor paga el 100% del monto base. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  montoBase ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												feat: Implementación de Secciones, Recargos, Porc. Pago Dist. y backend E/S Dist.
Backend API:
- Recargos por Zona (`dist_RecargoZona`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/recargos`.
  - Lógica de negocio para vigencias (cierre/reapertura de períodos).
  - Auditoría en `dist_RecargoZona_H`.
- Porcentajes de Pago Distribuidores (`dist_PorcPago`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/porcentajespago`.
  - Lógica de negocio para vigencias.
  - Auditoría en `dist_PorcPago_H`.
- Porcentajes/Montos Pago Canillitas (`dist_PorcMonPagoCanilla`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/porcentajesmoncanilla`.
  - Lógica de negocio para vigencias.
  - Auditoría en `dist_PorcMonPagoCanilla_H`.
- Secciones de Publicación (`dist_dtPubliSecciones`):
  - CRUD completo (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Endpoints anidados bajo `/publicaciones/{idPublicacion}/secciones`.
  - Auditoría en `dist_dtPubliSecciones_H`.
- Entradas/Salidas Distribuidores (`dist_EntradasSalidas`):
  - Implementado backend (Modelos, DTOs, Repositorio, Servicio, Controlador).
  - Lógica para determinar precios/recargos/porcentajes aplicables.
  - Cálculo de monto y afectación de saldos de distribuidores en `cue_Saldos`.
  - Auditoría en `dist_EntradasSalidas_H`.
- Correcciones de Mapeo Dapper:
  - Aplicados alias explícitos en repositorios de RecargoZona, PorcPago, PorcMonCanilla, PubliSeccion,
    Canilla, Distribuidor y Precio para asegurar mapeo correcto de IDs y columnas.
Frontend React:
- Recargos por Zona:
  - `recargoZonaService.ts`.
  - `RecargoZonaFormModal.tsx` para crear/editar períodos de recargos.
  - `GestionarRecargosPublicacionPage.tsx` para listar y gestionar recargos por publicación.
- Porcentajes de Pago Distribuidores:
  - `porcPagoService.ts`.
  - `PorcPagoFormModal.tsx`.
  - `GestionarPorcentajesPagoPage.tsx`.
- Porcentajes/Montos Pago Canillitas:
  - `porcMonCanillaService.ts`.
  - `PorcMonCanillaFormModal.tsx`.
  - `GestionarPorcMonCanillaPage.tsx`.
- Secciones de Publicación:
  - `publiSeccionService.ts`.
  - `PubliSeccionFormModal.tsx`.
  - `GestionarSeccionesPublicacionPage.tsx`.
- Navegación:
  - Actualizadas rutas y menús para acceder a la gestión de recargos, porcentajes (dist. y canillita) y secciones desde la vista de una publicación.
- Layout:
  - Uso consistente de `Box` con Flexbox en lugar de `Grid` en nuevos modales y páginas para evitar errores de tipo.
											 
										 
										
											2025-05-21 14:58:52 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        public  async  Task < IEnumerable < EntradaSalidaDistDto > >  ObtenerTodosAsync ( DateTime ?  fechaDesde ,  DateTime ?  fechaHasta ,  int?  idPublicacion ,  int?  idDistribuidor ,  string?  tipoMovimiento ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            var  movimientos  =  await  _esRepository . GetAllAsync ( fechaDesde ,  fechaHasta ,  idPublicacion ,  idDistribuidor ,  tipoMovimiento ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            var  dtos  =  new  List < EntradaSalidaDistDto > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            foreach  ( var  mov  in  movimientos ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                dtos . Add ( await  MapToDto ( mov ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  dtos ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        public  async  Task < EntradaSalidaDistDto ? >  ObtenerPorIdAsync ( int  idParte ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            var  movimiento  =  await  _esRepository . GetByIdAsync ( idParte ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  movimiento  = =  null  ?  null  :  await  MapToDto ( movimiento ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        public  async  Task < ( EntradaSalidaDistDto ?  Movimiento ,  string?  Error ) >  CrearMovimientoAsync ( CreateEntradaSalidaDistDto  createDto ,  int  idUsuario ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            var  publicacion  =  await  _publicacionRepository . GetByIdSimpleAsync ( createDto . IdPublicacion ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( publicacion  = =  null  | |  publicacion . Habilitada  ! =  true )  return  ( null ,  "Publicación no válida o no habilitada." ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            var  distribuidor  =  await  _distribuidorRepository . GetByIdSimpleAsync ( createDto . IdDistribuidor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( distribuidor  = =  null )  return  ( null ,  "Distribuidor no válido." ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( await  _esRepository . ExistsByRemitoAndTipoForPublicacionAsync ( createDto . Remito ,  createDto . TipoMovimiento ,  createDto . IdPublicacion ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  ( null ,  $"Ya existe un movimiento de '{createDto.TipoMovimiento}' con el remito N°{createDto.Remito} para esta publicación." ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Determinar IDs de Precio, Recargo y Porcentaje activos en la fecha del movimiento 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            var  precioActivo  =  await  _precioRepository . GetActiveByPublicacionAndDateAsync ( createDto . IdPublicacion ,  createDto . Fecha . Date ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( precioActivo  = =  null )  return  ( null ,  $"No hay un precio definido para la publicación '{publicacion.Nombre}' en la fecha {createDto.Fecha:dd/MM/yyyy}." ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            RecargoZona ?  recargoActivo  =  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( distribuidor . IdZona . HasValue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                 recargoActivo  =  await  _recargoZonaRepository . GetActiveByPublicacionZonaAndDateAsync ( createDto . IdPublicacion ,  distribuidor . IdZona . Value ,  createDto . Fecha . Date ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            var  porcPagoActivo  =  await  _porcPagoRepository . GetActiveByPublicacionDistribuidorAndDateAsync ( createDto . IdPublicacion ,  createDto . IdDistribuidor ,  createDto . Fecha . Date ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            var  nuevoES  =  new  EntradaSalidaDist 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                IdPublicacion  =  createDto . IdPublicacion , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                IdDistribuidor  =  createDto . IdDistribuidor , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                Fecha  =  createDto . Fecha . Date , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                TipoMovimiento  =  createDto . TipoMovimiento , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                Cantidad  =  createDto . Cantidad , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                Remito  =  createDto . Remito , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                Observacion  =  createDto . Observacion , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                IdPrecio  =  precioActivo . IdPrecio , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                IdRecargo  =  recargoActivo ? . IdRecargo  ? ?  0 ,  // 0 si no aplica 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                IdPorcentaje  =  porcPagoActivo ? . IdPorcentaje  ? ?  0  // 0 si no aplica 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            using  var  connection  =  _connectionFactory . CreateConnection ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( connection  is  System . Data . Common . DbConnection  dbConn )  await  dbConn . OpenAsync ( ) ;  else  connection . Open ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            using  var  transaction  =  connection . BeginTransaction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            try 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                var  esCreada  =  await  _esRepository . CreateAsync ( nuevoES ,  idUsuario ,  transaction ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( esCreada  = =  null )  throw  new  DataException ( "Error al registrar el movimiento." ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Afectar Saldo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                decimal  montoAfectacion  =  await  CalcularMontoMovimiento ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    esCreada . IdPublicacion ,  esCreada . IdDistribuidor ,  esCreada . Fecha ,  esCreada . Cantidad ,  esCreada . TipoMovimiento , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    esCreada . IdPrecio ,  esCreada . IdRecargo ,  esCreada . IdPorcentaje ,  distribuidor . IdZona ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Si es Salida, montoAfectacion es positivo (aumenta deuda). Si es Entrada, es 0 por CalcularMontoMovimiento, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // pero para el saldo, una Entrada (devolución) debería restar del saldo deudor. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Por lo tanto, el monto real a restar del saldo si es Entrada sería el valor de esos ejemplares devueltos. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if ( esCreada . TipoMovimiento  = =  "Entrada" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                     // Recalcular como si fuera salida para obtener el valor a acreditar/restar del saldo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    montoAfectacion  =  await  CalcularMontoMovimiento ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        esCreada . IdPublicacion ,  esCreada . IdDistribuidor ,  esCreada . Fecha ,  esCreada . Cantidad ,  "Salida" ,  // Forzar tipo Salida para cálculo de valor 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        esCreada . IdPrecio ,  esCreada . IdRecargo ,  esCreada . IdPorcentaje ,  distribuidor . IdZona ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    montoAfectacion  * =  - 1 ;  // Hacerlo negativo para restar del saldo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                bool  saldoActualizado  =  await  _saldoRepository . ModificarSaldoAsync ( "Distribuidores" ,  esCreada . IdDistribuidor ,  publicacion . IdEmpresa ,  montoAfectacion ,  transaction ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! saldoActualizado )  throw  new  DataException ( "Error al actualizar el saldo del distribuidor." ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                transaction . Commit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                _logger . LogInformation ( "Movimiento ID {Id} creado y saldo afectado por Usuario ID {UserId}." ,  esCreada . IdParte ,  idUsuario ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  ( await  MapToDto ( esCreada ) ,  null ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            catch  ( Exception  ex ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                try  {  transaction . Rollback ( ) ;  }  catch  {  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                _logger . LogError ( ex ,  "Error CrearMovimientoAsync para Pub ID {IdPub}" ,  createDto . IdPublicacion ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  ( null ,  $"Error interno: {ex.Message}" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        public  async  Task < ( bool  Exito ,  string?  Error ) >  ActualizarMovimientoAsync ( int  idParte ,  UpdateEntradaSalidaDistDto  updateDto ,  int  idUsuario ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								             // La actualización de un movimiento que afecta saldos es compleja. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								             // Si cambia la cantidad, el monto original y el nuevo deben calcularse, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								             // y la diferencia debe aplicarse al saldo. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								             // Por ahora, este DTO solo permite cambiar Cantidad y Observacion. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								             // Cambiar otros campos como Fecha, Publicacion, Distribuidor implicaría recalcular todo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								             // y posiblemente anular el movimiento original y crear uno nuevo. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            using  var  connection  =  _connectionFactory . CreateConnection ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( connection  is  System . Data . Common . DbConnection  dbConn )  await  dbConn . OpenAsync ( ) ;  else  connection . Open ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            using  var  transaction  =  connection . BeginTransaction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            try 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                var  esExistente  =  await  _esRepository . GetByIdAsync ( idParte ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( esExistente  = =  null )  return  ( false ,  "Movimiento no encontrado." ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                var  publicacion  =  await  _publicacionRepository . GetByIdSimpleAsync ( esExistente . IdPublicacion ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                 if  ( publicacion  = =  null )  return  ( false ,  "Publicación asociada no encontrada." ) ;  // Muy raro 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                var  distribuidor  =  await  _distribuidorRepository . GetByIdSimpleAsync ( esExistente . IdDistribuidor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                 if  ( distribuidor  = =  null )  return  ( false ,  "Distribuidor asociado no encontrado." ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // 1. Calcular monto del movimiento original (antes de la actualización) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                decimal  montoOriginal  =  await  CalcularMontoMovimiento ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    esExistente . IdPublicacion ,  esExistente . IdDistribuidor ,  esExistente . Fecha ,  esExistente . Cantidad ,  esExistente . TipoMovimiento , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    esExistente . IdPrecio ,  esExistente . IdRecargo ,  esExistente . IdPorcentaje ,  distribuidor . IdZona ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if ( esExistente . TipoMovimiento  = =  "Entrada" )  montoOriginal  * =  - 1 ;  // Para revertir 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // 2. Actualizar la entidad en la BD (esto también guarda en historial) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                var  esParaActualizar  =  new  EntradaSalidaDist 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    IdParte  =  esExistente . IdParte , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    IdPublicacion  =  esExistente . IdPublicacion ,  // No cambia 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    IdDistribuidor  =  esExistente . IdDistribuidor ,  // No cambia 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    Fecha  =  esExistente . Fecha ,  // No cambia 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    TipoMovimiento  =  esExistente . TipoMovimiento ,  // No cambia 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    Cantidad  =  updateDto . Cantidad ,  // Nuevo valor 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    Remito  =  esExistente . Remito ,  // No cambia 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    Observacion  =  updateDto . Observacion ,  // Nuevo valor 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    IdPrecio  =  esExistente . IdPrecio ,  // No cambia 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    IdRecargo  =  esExistente . IdRecargo ,  // No cambia 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    IdPorcentaje  =  esExistente . IdPorcentaje  // No cambia 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                var  actualizado  =  await  _esRepository . UpdateAsync ( esParaActualizar ,  idUsuario ,  transaction ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! actualizado )  throw  new  DataException ( "Error al actualizar el movimiento." ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // 3. Calcular monto del movimiento nuevo (después de la actualización) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                decimal  montoNuevo  =  await  CalcularMontoMovimiento ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    esParaActualizar . IdPublicacion ,  esParaActualizar . IdDistribuidor ,  esParaActualizar . Fecha ,  esParaActualizar . Cantidad ,  esParaActualizar . TipoMovimiento , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    esParaActualizar . IdPrecio ,  esParaActualizar . IdRecargo ,  esParaActualizar . IdPorcentaje ,  distribuidor . IdZona ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if ( esParaActualizar . TipoMovimiento  = =  "Entrada" )  montoNuevo  * =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // 4. Ajustar saldo con la diferencia 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                decimal  diferenciaAjusteSaldo  =  montoNuevo  -  montoOriginal ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( diferenciaAjusteSaldo  ! =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    bool  saldoActualizado  =  await  _saldoRepository . ModificarSaldoAsync ( "Distribuidores" ,  esExistente . IdDistribuidor ,  publicacion . IdEmpresa ,  diferenciaAjusteSaldo ,  transaction ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( ! saldoActualizado )  throw  new  DataException ( "Error al ajustar el saldo del distribuidor tras la actualización." ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                transaction . Commit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                _logger . LogInformation ( "Movimiento ID {Id} actualizado y saldo ajustado por Usuario ID {UserId}." ,  idParte ,  idUsuario ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  ( true ,  null ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            catch  ( KeyNotFoundException )  {  try  {  transaction . Rollback ( ) ;  }  catch  {  }  return  ( false ,  "Movimiento no encontrado." ) ;  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            catch  ( Exception  ex ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                try  {  transaction . Rollback ( ) ;  }  catch  {  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                _logger . LogError ( ex ,  "Error ActualizarMovimientoAsync ID: {Id}" ,  idParte ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  ( false ,  $"Error interno: {ex.Message}" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        public  async  Task < ( bool  Exito ,  string?  Error ) >  EliminarMovimientoAsync ( int  idParte ,  int  idUsuario ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            using  var  connection  =  _connectionFactory . CreateConnection ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( connection  is  System . Data . Common . DbConnection  dbConn )  await  dbConn . OpenAsync ( ) ;  else  connection . Open ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            using  var  transaction  =  connection . BeginTransaction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            try 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                var  esExistente  =  await  _esRepository . GetByIdAsync ( idParte ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( esExistente  = =  null )  return  ( false ,  "Movimiento no encontrado." ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                var  publicacion  =  await  _publicacionRepository . GetByIdSimpleAsync ( esExistente . IdPublicacion ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( publicacion  = =  null )  return  ( false ,  "Publicación asociada no encontrada." ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                var  distribuidor  =  await  _distribuidorRepository . GetByIdSimpleAsync ( esExistente . IdDistribuidor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( distribuidor  = =  null )  return  ( false ,  "Distribuidor asociado no encontrado." ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // 1. Calcular el monto del movimiento a eliminar para revertir el saldo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                decimal  montoReversion  =  await  CalcularMontoMovimiento ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    esExistente . IdPublicacion ,  esExistente . IdDistribuidor ,  esExistente . Fecha ,  esExistente . Cantidad ,  esExistente . TipoMovimiento , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    esExistente . IdPrecio ,  esExistente . IdRecargo ,  esExistente . IdPorcentaje ,  distribuidor . IdZona ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Si es Salida, el monto es positivo, al revertir restamos. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Si es Entrada, el monto es 0 (por Calcular...), pero su efecto en saldo fue negativo, al revertir sumamos el valor. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if ( esExistente . TipoMovimiento  = =  "Salida" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    montoReversion  * =  - 1 ;  // Para restar del saldo lo que se sumó 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  if  ( esExistente . TipoMovimiento  = =  "Entrada" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // Recalcular el valor como si fuera salida para saber cuánto se restó del saldo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                     montoReversion  =  await  CalcularMontoMovimiento ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        esExistente . IdPublicacion ,  esExistente . IdDistribuidor ,  esExistente . Fecha ,  esExistente . Cantidad ,  "Salida" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        esExistente . IdPrecio ,  esExistente . IdRecargo ,  esExistente . IdPorcentaje ,  distribuidor . IdZona ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // No se multiplica por -1 aquí, porque el saldo ya lo tiene restado, al eliminar revertimos sumando. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // 2. Eliminar el registro (esto también guarda en historial) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                var  eliminado  =  await  _esRepository . DeleteAsync ( idParte ,  idUsuario ,  transaction ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! eliminado )  throw  new  DataException ( "Error al eliminar el movimiento." ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // 3. Ajustar Saldo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                bool  saldoActualizado  =  await  _saldoRepository . ModificarSaldoAsync ( "Distribuidores" ,  esExistente . IdDistribuidor ,  publicacion . IdEmpresa ,  montoReversion ,  transaction ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! saldoActualizado )  throw  new  DataException ( "Error al revertir el saldo del distribuidor tras la eliminación." ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                transaction . Commit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                _logger . LogInformation ( "Movimiento ID {Id} eliminado y saldo revertido por Usuario ID {UserId}." ,  idParte ,  idUsuario ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  ( true ,  null ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            catch  ( KeyNotFoundException )  {  try  {  transaction . Rollback ( ) ;  }  catch  {  }  return  ( false ,  "Movimiento no encontrado." ) ;  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            catch  ( Exception  ex ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                try  {  transaction . Rollback ( ) ;  }  catch  {  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                _logger . LogError ( ex ,  "Error EliminarMovimientoAsync ID: {Id}" ,  idParte ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  ( false ,  $"Error interno: {ex.Message}" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}