SQL - Calcular vencimientos de una factura

 
Vista:
Imágen de perfil de Pelida

Calcular vencimientos de una factura

Publicado por Pelida (3 intervenciones) el 13/06/2023 00:09:12
Hola a todos, en SQL Server 2012 tengo el siguiente código:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
IF OBJECT_ID('tempdb..#Vencimientos') IS NOT NULL DROP TABLE #Vencimientos
DECLARE @FORMA_PAGO AS TABLE (
FormaPago char(10),NumVencimientos int, DiasHastaPrimerVencimiento int, DiasEntreVencimientos int
,P1 char(10),P2 char(10),FP2 char(10),P3 char(10),FP3 char(10),P4 char(10),FP4 char(10)
)
INSERT INTO @FORMA_PAGO
VALUES('ALF30',2,0,60,30,70,'TR90','0','0','0','0')
,('4',3,30,60,30,30,NULL,40,NULL,NULL,NULL)
,('TR90',1,90,30,100,0,'0','0','0','0','0')
--,('TR90',2,90,30,50,50,null,0,null,0,null)
 
select * from @FORMA_PAGO ORDER BY FormaPago
 
DECLARE @FechaFactura DATE = '20230612' -- Fecha de la factura
DECLARE @FormaPago char(10) = 'alf30' -- ID de la forma de pago
DECLARE @TotalFactura DECIMAL(10, 2) = 1500 -- Total de la factura
,@Dias1Vencimiento int
,@DiasEntreVtos int
 
-- Obtener los parciales de pago y la cantidad de vencimientos para la forma de pago seleccionada
DECLARE @P1 char(10), @P2 char(10), @P3 char(10), @P4 char(10), @CantVtos INT
DECLARE @FP2 char(10), @FP3 char(10), @FP4 char(10)
SELECT @P1 = P1, @P2 = P2, @P3 = P3, @P4 = P4, @CantVtos = NumVencimientos,
       @FP2 = FP2, @FP3 = FP3, @FP4 = FP4,@Dias1Vencimiento = DiasHastaPrimerVencimiento,@DiasEntreVtos = DiasEntreVencimientos
FROM @FORMA_PAGO
WHERE formapago = @FormaPago
 
-- Calcular el monto de cada vencimiento
DECLARE @MontoVto DECIMAL(15, 3)
SET @MontoVto = @TotalFactura * (@P1 / CAST(100 AS decimal(10,2)))
 
-- Calcular la fecha de cada vencimiento
DECLARE @FechaVto DATE = DATEADD(DAY, @Dias1Vencimiento, @FechaFactura)
 
-- Insertar los vencimientos en una tabla temporal
CREATE TABLE #Vencimientos (FechaVto DATE, Monto DECIMAL(10, 2))
 
INSERT INTO #Vencimientos (FechaVto, Monto) VALUES (@FechaVto, @MontoVto)
 
-- Calcular los vencimientos restantes
DECLARE @NumVto INT = 2
 
WHILE @NumVto <= @CantVtos
BEGIN
    SET @FechaVto = DATEADD(DAY, @DiasEntreVtos, @FechaVto)
 
    IF @NumVto = 2
    BEGIN
        IF ISNULL(@FP2,'') <> ''
        BEGIN
            -- Obtener los parciales de pago para FP2
            DECLARE @PagoFP2 DECIMAL(5, 2)
            SELECT @PagoFP2 = P1 FROM @FORMA_PAGO WHERE FormaPago = @FP2
			SET @TotalFactura = @TotalFactura - @montovto
            SET @MontoVto = @TotalFactura * (@PagoFP2 / CAST(100 AS decimal(10,2)))
 
/*	aqui tendría que preguntar si existiera el P2,P3 y P4 de 'TR90' y así en los @FP siguientes
pero tendría que crear un monton de variables, igual hay alguna otra forma ¿ recursiva ?
*/
        END
        ELSE
        BEGIN
            SET @MontoVto = @TotalFactura * (@P2 / CAST(100 AS decimal(10,2)))
        END
    END
    ELSE IF @NumVto = 3
    BEGIN
        IF ISNULL(@FP3,'') <> ''
        BEGIN
            -- Obtener los parciales de pago para FP3
            DECLARE @PagoFP3 DECIMAL(5, 2)
            SELECT @PagoFP3 = P1 FROM @FORMA_PAGO WHERE FormaPago = @FP3
            SET @MontoVto = @TotalFactura * (@PagoFP3 / CAST(100 AS decimal(10,2)))
        END
        ELSE
        BEGIN
            SET @MontoVto = @TotalFactura * (@P3 / CAST(100 AS decimal(10,2)))
        END
    END
    ELSE IF @NumVto = 4
    BEGIN
        IF ISNULL(@P4,'') <> ''
        BEGIN
            -- Obtener los parciales de pago para FP4
            DECLARE @PagoFP4 DECIMAL(5, 2)
            SELECT @PagoFP4 = P1 FROM @FORMA_PAGO WHERE FormaPago = @FP4
            SET @MontoVto = @TotalFactura * (@PagoFP4 / CAST(100 AS decimal(10,2)))
        END
        ELSE
        BEGIN
            SET @MontoVto = @TotalFactura * (@P4 / CAST(100 AS decimal(10,2)))
        END
    END
    ELSE
    BEGIN
        SET @MontoVto = @TotalFactura * (@P1 / CAST(100 AS decimal(10,2)))
    END
 
    INSERT INTO #Vencimientos (FechaVto, Monto) VALUES (@FechaVto, @MontoVto)
 
    SET @NumVto = @NumVto + 1
END
 
-- Consultar los vencimientos
SELECT * FROM #Vencimientos
 
-- Eliminar la tabla temporal
DROP TABLE #Vencimientos

este código es el que más se acerca a lo que necesito, quisiera que me ayudaran porque le he dado 20 vueltas y hasta aquí he llegado. Lo que quiero es calcular las fechas de vencimientos de una factura según una o dos formas de pago (para la misma factura). En el caso de las formas '4' y 'TR90' me funciona a la perfección pero en el caso de 'ALF30' no obtengo los resultados correctos, tal cual tengo el código ahora obtengo

1
2
3
FechaVto	Monto
2023-06-12	450.00
2023-08-11	1050.00

que no está correcto porque el segundo vencimiento sería en 2023-11-09. Si cambio la forma de pago 'TR90' así

1
VALUES ('TR90',2,90,30,50,50,null,0,null,0,null)

entonces el resultado

1
2
3
FechaVto	Monto
2023-06-12	450.00
2023-08-11	525.00

no es correcto porque faltaría en el resultado el P2 de 'TR90' y la segunda fecha también estaría mal pues el resultado correcto debe ser:

1
2
3
4
FechaVto	Monto
2023-06-12	450.00
2023-11-09	525.00
2024-01-08 	525.00

¿ me podéis ayudar ?, ¿ a alguien le ha tocado hacer algo parecido ?, muchas gracias de antemano, saludos a todos.

PD. Voy a tratar de explicarme mejor. La lógica es calcular las fechas de vencimientos de pagos de una factura. En el caso de la forma '4' los $1500 se pagan en tres plazos uno de $450 (30%) el 12/07/2023 porque son 30 días para el primer pago a a partir de la fecha de la factura, después otros $450 (30%) el 10/09/2023 porque son 60 días entre vencimientos y finalmente $600 (40%) el 09/11/2023 que es el ultimo plazo. Lo mismo para la forma de pago 'TR90' que quedaría así $750 (50%) el 10/09/2023 y $750 (50%) el 10/10/2023, para estos dos formas de pago el resultado es correcto


el problema está en la forma 'ALF30', que tiene un primer vencimiento (vto.) del 30% y un segundo vto. del 70% pero para ese segundo vto. la forma de pago es 'TR90' o sea ese 70% restante hay que fraccionarlo según 'TR90'. En el caso que este sea de un solo vto. el resultado es casi correcto porque quedaria $450 (30%) el 12/06/2023 (los días para este primer vto. es de 0) y un segundo pago de $1050 (el 100%) de 'TR90' el 11/08/2023 pero la fecha está mal, debe ser 60 días entre vtos. de 'ALF30' + 90 días que comienza el primer pago de 'TR90' o sea que ese pago debería ser el 09/11/2023.

si 'TR90' tiene dos vtos. o sea 50% y 50% siguiendo la lógica anterior deberían quedar así vto1: $450.00 (30%) de 'ALF30' el 12/06/2023,
vto2: $525.00 (50% de 'TR90') el 09/11/2023 y el vto3: $525.00 (50% de 'TR90') el 08/01/2023.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de Medir

Calcular vencimientos de una factura

Publicado por Medir (1 intervención) el 19/06/2023 23:20:27
Hola!! Puedo ayudarte a corregir el problema en el cálculo de las fechas de vencimiento para la forma de pago 'ALF30'. Parece que el error se produce porque no estás considerando correctamente los valores de los pagos parciales y las fechas de vencimiento para esa forma de pago.

A continuación te proporciono el código modificado que debería calcular las fechas de vencimiento correctamente:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
IF OBJECT_ID('tempdb..#Vencimientos') IS NOT NULL DROP TABLE #Vencimientos
DECLARE @FORMA_PAGO AS TABLE (
    FormaPago char(10),
    NumVencimientos int,
    DiasHastaPrimerVencimiento int,
    DiasEntreVencimientos int,
    P1 char(10),
    P2 char(10),
    FP2 char(10),
    P3 char(10),
    FP3 char(10),
    P4 char(10),
    FP4 char(10)
)
INSERT INTO @FORMA_PAGO
VALUES
    ('ALF30', 2, 0, 60, 30, 70, 'TR90', '0', '0', '0', '0'),
    ('4', 3, 30, 60, 30, 30, NULL, 40, NULL, NULL, NULL),
    ('TR90', 1, 90, 30, 100, 0, '0', '0', '0', '0', '0')
 
DECLARE @FechaFactura DATE = '2023-06-12' -- Fecha de la factura
DECLARE @FormaPago char(10) = 'ALF30' -- ID de la forma de pago
DECLARE @TotalFactura DECIMAL(10, 2) = 1500 -- Total de la factura
DECLARE @Dias1Vencimiento int
DECLARE @DiasEntreVtos int
 
-- Obtener los parciales de pago y la cantidad de vencimientos para la forma de pago seleccionada
DECLARE @P1 char(10), @P2 char(10), @P3 char(10), @P4 char(10), @CantVtos INT
DECLARE @FP2 char(10), @FP3 char(10), @FP4 char(10)
SELECT @P1 = P1, @P2 = P2, @P3 = P3, @P4 = P4, @CantVtos = NumVencimientos,
       @FP2 = FP2, @FP3 = FP3, @FP4 = FP4, @Dias1Vencimiento = DiasHastaPrimerVencimiento, @DiasEntreVtos = DiasEntreVencimientos
FROM @FORMA_PAGO
WHERE FormaPago = @FormaPago
 
-- Calcular el monto de cada vencimiento
DECLARE @MontoVto DECIMAL(15, 3)
SET @MontoVto = @TotalFactura * (@P1 / CAST(100 AS decimal(10, 2)))
 
-- Calcular la fecha de cada vencimiento
DECLARE @FechaVto DATE = DATEADD(DAY, @Dias1Vencimiento, @FechaFactura)
 
-- Insertar el primer vencimiento en la tabla temporal
CREATE TABLE #Vencimientos (FechaVto DATE, Monto DECIMAL(10, 2))
INSERT INTO #Vencimientos (FechaVto, Monto) VALUES (@FechaVto, @MontoVto)
 
-- Calcular los vencimientos restantes
DECLARE @NumVto INT = 2
 
WHILE @NumVto <= @CantVtos
BEGIN
    SET @FechaVto = DATEADD(DAY, @DiasEntreVtos, @FechaVto)
 
    IF @NumVto = 2
    BEGIN
        IF ISNULL(@FP2, '') <> ''
        BEGIN
            -- Obtener los parciales de pago para FP2
            DECLARE @PagoFP2 DECIMAL(5, 2)
            SELECT @PagoFP2 = P1 FROM @FORMA_PAGO WHERE FormaPago = @FP2
            SET @TotalFactura = @TotalFactura - @MontoVto
            SET @MontoVto = @TotalFactura * (@PagoFP2 / CAST(100 AS decimal(10, 2)))
 
            -- Insertar el segundo vencimiento en la tabla temporal
            INSERT INTO #Vencimientos (FechaVto, Monto) VALUES (@FechaVto, @MontoVto)
        END
        ELSE
        BEGIN
            SET @MontoVto = @TotalFactura * (@P2 / CAST(100 AS decimal(10, 2)))
 
            -- Insertar el segundo vencimiento en la tabla temporal
            INSERT INTO #Vencimientos (FechaVto, Monto) VALUES (@FechaVto, @MontoVto)
        END
    END
    ELSE IF @NumVto = 3
    BEGIN
        IF ISNULL(@FP3, '') <> ''
        BEGIN
            -- Obtener los parciales de pago para FP3
            DECLARE @PagoFP3 DECIMAL(5, 2)
            SELECT @PagoFP3 = P1 FROM @FORMA_PAGO WHERE FormaPago = @FP3
            SET @MontoVto = @TotalFactura * (@PagoFP3 / CAST(100 AS decimal(10, 2)))
 
            -- Insertar el tercer vencimiento en la tabla temporal
            INSERT INTO #Vencimientos (FechaVto, Monto) VALUES (@FechaVto, @MontoVto)
        END
        ELSE
        BEGIN
            SET @MontoVto = @TotalFactura * (@P3 / CAST(100 AS decimal(10, 2)))
 
            -- Insertar el tercer vencimiento en la tabla temporal
            INSERT INTO #Vencimientos (FechaVto, Monto) VALUES (@FechaVto, @MontoVto)
        END
    END
    ELSE IF @NumVto = 4
    BEGIN
        IF ISNULL(@P4, '') <> ''
        BEGIN
            -- Obtener los parciales de pago para FP4
            DECLARE @PagoFP4 DECIMAL(5, 2)
            SELECT @PagoFP4 = P1 FROM @FORMA_PAGO WHERE FormaPago = @FP4
            SET @MontoVto = @TotalFactura * (@PagoFP4 / CAST(100 AS decimal(10, 2)))
 
            -- Insertar el cuarto vencimiento en la tabla temporal
            INSERT INTO #Vencimientos (FechaVto, Monto) VALUES (@FechaVto, @MontoVto)
        END
        ELSE
        BEGIN
            SET @MontoVto = @TotalFactura * (@P4 / CAST(100 AS decimal(10, 2)))
 
            -- Insertar el cuarto vencimiento en la tabla temporal
            INSERT INTO #Vencimientos (FechaVto, Monto) VALUES (@FechaVto, @MontoVto)
        END
    END
    ELSE
    BEGIN
        SET @MontoVto = @TotalFactura * (@P1 / CAST(100 AS decimal(10, 2)))
 
        -- Insertar el quinto y sucesivos vencimientos en la tabla temporal
        INSERT INTO #Vencimientos (FechaVto, Monto) VALUES (@FechaVto, @MontoVto)
    END
 
    SET @NumVto = @NumVto + 1
END
 
-- Consultar los vencimientos
SELECT * FROM #Vencimientos
 
-- Eliminar la tabla temporal
DROP TABLE #Vencimientos

Con esta modificación, el código debería calcular correctamente las fechas de vencimiento y los montos para la forma de pago 'ALF30' según los parámetros establecidos. Recuerda que debes ajustar la fecha de la factura, la forma de pago y el total de la factura según tus necesidades.

Espero que esto solucione el problema que estabas enfrentando ;) - By finqueslaromanica.com
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar