@hed-hog/finance 0.0.261 → 0.0.266
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dto/update-finance-scenario-settings.dto.d.ts +7 -0
- package/dist/dto/update-finance-scenario-settings.dto.d.ts.map +1 -0
- package/dist/dto/update-finance-scenario-settings.dto.js +39 -0
- package/dist/dto/update-finance-scenario-settings.dto.js.map +1 -0
- package/dist/finance-data.controller.d.ts +61 -7
- package/dist/finance-data.controller.d.ts.map +1 -1
- package/dist/finance-data.controller.js +23 -3
- package/dist/finance-data.controller.js.map +1 -1
- package/dist/finance.service.d.ts +79 -9
- package/dist/finance.service.d.ts.map +1 -1
- package/dist/finance.service.js +471 -70
- package/dist/finance.service.js.map +1 -1
- package/hedhog/data/route.yaml +9 -0
- package/hedhog/data/setting_group.yaml +152 -0
- package/hedhog/frontend/app/_lib/use-finance-data.ts.ejs +31 -3
- package/hedhog/frontend/app/planning/cash-flow-forecast/page.tsx.ejs +38 -7
- package/hedhog/frontend/app/planning/receivables-calendar/page.tsx.ejs +3 -1
- package/hedhog/frontend/app/planning/scenarios/page.tsx.ejs +74 -4
- package/hedhog/frontend/app/reports/actual-vs-forecast/page.tsx.ejs +361 -0
- package/hedhog/frontend/app/reports/aging-default/page.tsx.ejs +368 -0
- package/hedhog/frontend/app/reports/cash-position/page.tsx.ejs +432 -0
- package/hedhog/frontend/messages/en.json +182 -0
- package/hedhog/frontend/messages/pt.json +182 -0
- package/hedhog/query/triggers-period-close.sql +361 -0
- package/package.json +8 -8
- package/src/dto/update-finance-scenario-settings.dto.ts +21 -0
- package/src/finance-data.controller.ts +18 -3
- package/src/finance.service.ts +781 -79
|
@@ -1310,6 +1310,188 @@
|
|
|
1310
1310
|
"total": "Total"
|
|
1311
1311
|
}
|
|
1312
1312
|
},
|
|
1313
|
+
"ActualVsForecastPage": {
|
|
1314
|
+
"header": {
|
|
1315
|
+
"title": "Realizado vs Previsto",
|
|
1316
|
+
"description": "Compare o desempenho realizado com as projeções financeiras"
|
|
1317
|
+
},
|
|
1318
|
+
"breadcrumbs": {
|
|
1319
|
+
"home": "Início",
|
|
1320
|
+
"finance": "Financeiro",
|
|
1321
|
+
"current": "Realizado vs Previsto"
|
|
1322
|
+
},
|
|
1323
|
+
"actions": {
|
|
1324
|
+
"export": "Exportar"
|
|
1325
|
+
},
|
|
1326
|
+
"filters": {
|
|
1327
|
+
"horizon": "Horizonte",
|
|
1328
|
+
"scenario": "Cenário",
|
|
1329
|
+
"days30": "30 dias",
|
|
1330
|
+
"days60": "60 dias",
|
|
1331
|
+
"days90": "90 dias",
|
|
1332
|
+
"days180": "180 dias",
|
|
1333
|
+
"days365": "365 dias"
|
|
1334
|
+
},
|
|
1335
|
+
"scenarios": {
|
|
1336
|
+
"base": "Base",
|
|
1337
|
+
"pessimistic": "Pessimista",
|
|
1338
|
+
"optimistic": "Otimista"
|
|
1339
|
+
},
|
|
1340
|
+
"messages": {
|
|
1341
|
+
"updating": "Atualizando dados..."
|
|
1342
|
+
},
|
|
1343
|
+
"cards": {
|
|
1344
|
+
"totalForecast": "Total Previsto",
|
|
1345
|
+
"totalActual": "Total Realizado",
|
|
1346
|
+
"totalDeviation": "Desvio Total",
|
|
1347
|
+
"accuracy": "Acurácia"
|
|
1348
|
+
},
|
|
1349
|
+
"chart": {
|
|
1350
|
+
"title": "Evolução Realizado vs Previsto",
|
|
1351
|
+
"description": "Comparativo da série temporal entre valores previstos e realizados",
|
|
1352
|
+
"forecastLabel": "Previsto",
|
|
1353
|
+
"actualLabel": "Realizado"
|
|
1354
|
+
},
|
|
1355
|
+
"table": {
|
|
1356
|
+
"title": "Detalhamento por período",
|
|
1357
|
+
"description": "Acompanhe o desvio de cada ponto da projeção",
|
|
1358
|
+
"headers": {
|
|
1359
|
+
"date": "Data",
|
|
1360
|
+
"forecast": "Previsto",
|
|
1361
|
+
"actual": "Realizado",
|
|
1362
|
+
"deviation": "Desvio",
|
|
1363
|
+
"percentDeviation": "% Desvio",
|
|
1364
|
+
"status": "Status"
|
|
1365
|
+
},
|
|
1366
|
+
"empty": "Sem dados para o período selecionado."
|
|
1367
|
+
},
|
|
1368
|
+
"status": {
|
|
1369
|
+
"above": "Acima",
|
|
1370
|
+
"below": "Abaixo",
|
|
1371
|
+
"onTarget": "No alvo"
|
|
1372
|
+
}
|
|
1373
|
+
},
|
|
1374
|
+
"CashPositionReportPage": {
|
|
1375
|
+
"header": {
|
|
1376
|
+
"title": "Posição de Caixa",
|
|
1377
|
+
"description": "Acompanhe saldos e movimentações de caixa por conta"
|
|
1378
|
+
},
|
|
1379
|
+
"breadcrumbs": {
|
|
1380
|
+
"home": "Início",
|
|
1381
|
+
"finance": "Financeiro",
|
|
1382
|
+
"current": "Posição de Caixa"
|
|
1383
|
+
},
|
|
1384
|
+
"actions": {
|
|
1385
|
+
"export": "Exportar"
|
|
1386
|
+
},
|
|
1387
|
+
"filters": {
|
|
1388
|
+
"horizon": "Horizonte",
|
|
1389
|
+
"scenario": "Cenário",
|
|
1390
|
+
"bankAccount": "Conta bancária",
|
|
1391
|
+
"allBankAccounts": "Todas as contas",
|
|
1392
|
+
"days30": "30 dias",
|
|
1393
|
+
"days60": "60 dias",
|
|
1394
|
+
"days90": "90 dias",
|
|
1395
|
+
"days180": "180 dias",
|
|
1396
|
+
"days365": "365 dias"
|
|
1397
|
+
},
|
|
1398
|
+
"scenarios": {
|
|
1399
|
+
"base": "Base",
|
|
1400
|
+
"pessimistic": "Pessimista",
|
|
1401
|
+
"optimistic": "Otimista"
|
|
1402
|
+
},
|
|
1403
|
+
"messages": {
|
|
1404
|
+
"updating": "Atualizando dados..."
|
|
1405
|
+
},
|
|
1406
|
+
"cards": {
|
|
1407
|
+
"currentBalance": "Saldo Atual",
|
|
1408
|
+
"reconciledBalance": "Saldo Conciliado",
|
|
1409
|
+
"inflows": "Entradas",
|
|
1410
|
+
"outflows": "Saídas",
|
|
1411
|
+
"netMovement": "Movimentação Líquida"
|
|
1412
|
+
},
|
|
1413
|
+
"chart": {
|
|
1414
|
+
"title": "Evolução do saldo",
|
|
1415
|
+
"description": "Variação acumulada do saldo no período",
|
|
1416
|
+
"balanceLabel": "Saldo acumulado"
|
|
1417
|
+
},
|
|
1418
|
+
"table": {
|
|
1419
|
+
"title": "Últimas movimentações",
|
|
1420
|
+
"description": "Lançamentos mais recentes conforme filtros aplicados",
|
|
1421
|
+
"headers": {
|
|
1422
|
+
"date": "Data",
|
|
1423
|
+
"description": "Descrição",
|
|
1424
|
+
"type": "Tipo",
|
|
1425
|
+
"value": "Valor"
|
|
1426
|
+
},
|
|
1427
|
+
"empty": "Nenhuma movimentação encontrada."
|
|
1428
|
+
},
|
|
1429
|
+
"types": {
|
|
1430
|
+
"inflow": "Entrada",
|
|
1431
|
+
"outflow": "Saída"
|
|
1432
|
+
}
|
|
1433
|
+
},
|
|
1434
|
+
"AgingDefaultReportPage": {
|
|
1435
|
+
"header": {
|
|
1436
|
+
"title": "Aging de Inadimplência",
|
|
1437
|
+
"description": "Visualize os atrasos de recebíveis por faixa de vencimento"
|
|
1438
|
+
},
|
|
1439
|
+
"breadcrumbs": {
|
|
1440
|
+
"home": "Início",
|
|
1441
|
+
"finance": "Financeiro",
|
|
1442
|
+
"current": "Aging de Inadimplência"
|
|
1443
|
+
},
|
|
1444
|
+
"filters": {
|
|
1445
|
+
"horizon": "Horizonte",
|
|
1446
|
+
"scenario": "Cenário",
|
|
1447
|
+
"days30": "30 dias",
|
|
1448
|
+
"days60": "60 dias",
|
|
1449
|
+
"days90": "90 dias",
|
|
1450
|
+
"days180": "180 dias",
|
|
1451
|
+
"days365": "365 dias"
|
|
1452
|
+
},
|
|
1453
|
+
"scenarios": {
|
|
1454
|
+
"base": "Base",
|
|
1455
|
+
"pessimistic": "Pessimista",
|
|
1456
|
+
"optimistic": "Otimista"
|
|
1457
|
+
},
|
|
1458
|
+
"messages": {
|
|
1459
|
+
"updating": "Atualizando dados..."
|
|
1460
|
+
},
|
|
1461
|
+
"cards": {
|
|
1462
|
+
"totalDefault": "Inadimplência Total",
|
|
1463
|
+
"lateClients": "Clientes em atraso",
|
|
1464
|
+
"over90Days": "Acima de 90 dias",
|
|
1465
|
+
"defaultRate": "Taxa de Inadimplência"
|
|
1466
|
+
},
|
|
1467
|
+
"chart": {
|
|
1468
|
+
"title": "Distribuição por faixa",
|
|
1469
|
+
"description": "Concentração da inadimplência por período de atraso",
|
|
1470
|
+
"range0to30": "0–30 dias",
|
|
1471
|
+
"range31to60": "31–60 dias",
|
|
1472
|
+
"range61to90": "61–90 dias",
|
|
1473
|
+
"range90plus": "> 90 dias"
|
|
1474
|
+
},
|
|
1475
|
+
"table": {
|
|
1476
|
+
"title": "Detalhamento por cliente",
|
|
1477
|
+
"description": "Aging de inadimplência por cliente",
|
|
1478
|
+
"headers": {
|
|
1479
|
+
"client": "Cliente",
|
|
1480
|
+
"range0to30": "0–30 dias",
|
|
1481
|
+
"range31to60": "31–60 dias",
|
|
1482
|
+
"range61to90": "61–90 dias",
|
|
1483
|
+
"range90plus": "> 90 dias",
|
|
1484
|
+
"total": "Total",
|
|
1485
|
+
"risk": "Risco"
|
|
1486
|
+
},
|
|
1487
|
+
"empty": "Nenhum dado de inadimplência encontrado."
|
|
1488
|
+
},
|
|
1489
|
+
"risk": {
|
|
1490
|
+
"high": "Alto",
|
|
1491
|
+
"medium": "Médio",
|
|
1492
|
+
"low": "Baixo"
|
|
1493
|
+
}
|
|
1494
|
+
},
|
|
1313
1495
|
"ReceivablesCalendarPage": {
|
|
1314
1496
|
"status": {
|
|
1315
1497
|
"confirmado": "Confirmado",
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
-- Triggers de proteção por período fechado (PostgreSQL)
|
|
2
|
+
-- Script idempotente: pode ser executado múltiplas vezes.
|
|
3
|
+
|
|
4
|
+
-- ==========================================================
|
|
5
|
+
-- Helpers
|
|
6
|
+
-- ==========================================================
|
|
7
|
+
|
|
8
|
+
CREATE OR REPLACE FUNCTION fn_is_in_closed_period(p_date timestamptz)
|
|
9
|
+
RETURNS boolean
|
|
10
|
+
LANGUAGE plpgsql
|
|
11
|
+
AS $$
|
|
12
|
+
DECLARE
|
|
13
|
+
v_exists boolean;
|
|
14
|
+
BEGIN
|
|
15
|
+
IF p_date IS NULL THEN
|
|
16
|
+
RETURN FALSE;
|
|
17
|
+
END IF;
|
|
18
|
+
|
|
19
|
+
SELECT EXISTS (
|
|
20
|
+
SELECT 1
|
|
21
|
+
FROM period_close pc
|
|
22
|
+
WHERE pc.status = 'closed'
|
|
23
|
+
AND p_date >= pc.period_start
|
|
24
|
+
AND p_date <= pc.period_end
|
|
25
|
+
)
|
|
26
|
+
INTO v_exists;
|
|
27
|
+
|
|
28
|
+
RETURN COALESCE(v_exists, FALSE);
|
|
29
|
+
END;
|
|
30
|
+
$$;
|
|
31
|
+
|
|
32
|
+
CREATE OR REPLACE FUNCTION fn_assert_not_in_closed_period(
|
|
33
|
+
p_date timestamptz,
|
|
34
|
+
p_entity text,
|
|
35
|
+
p_operation text
|
|
36
|
+
)
|
|
37
|
+
RETURNS void
|
|
38
|
+
LANGUAGE plpgsql
|
|
39
|
+
AS $$
|
|
40
|
+
BEGIN
|
|
41
|
+
IF fn_is_in_closed_period(p_date) THEN
|
|
42
|
+
RAISE EXCEPTION
|
|
43
|
+
'% blocked: % falls in a closed period',
|
|
44
|
+
p_operation,
|
|
45
|
+
p_entity;
|
|
46
|
+
END IF;
|
|
47
|
+
END;
|
|
48
|
+
$$;
|
|
49
|
+
|
|
50
|
+
-- ==========================================================
|
|
51
|
+
-- period_close: registro fechado é imutável
|
|
52
|
+
-- ==========================================================
|
|
53
|
+
|
|
54
|
+
CREATE OR REPLACE FUNCTION fn_guard_period_close_immutability()
|
|
55
|
+
RETURNS trigger
|
|
56
|
+
LANGUAGE plpgsql
|
|
57
|
+
AS $$
|
|
58
|
+
BEGIN
|
|
59
|
+
IF TG_OP = 'UPDATE' THEN
|
|
60
|
+
IF OLD.status = 'closed' THEN
|
|
61
|
+
RAISE EXCEPTION
|
|
62
|
+
'UPDATE blocked: closed period_close id=% is immutable',
|
|
63
|
+
OLD.id;
|
|
64
|
+
END IF;
|
|
65
|
+
|
|
66
|
+
RETURN NEW;
|
|
67
|
+
END IF;
|
|
68
|
+
|
|
69
|
+
IF TG_OP = 'DELETE' THEN
|
|
70
|
+
IF OLD.status = 'closed' THEN
|
|
71
|
+
RAISE EXCEPTION
|
|
72
|
+
'DELETE blocked: closed period_close id=% is immutable',
|
|
73
|
+
OLD.id;
|
|
74
|
+
END IF;
|
|
75
|
+
|
|
76
|
+
RETURN OLD;
|
|
77
|
+
END IF;
|
|
78
|
+
|
|
79
|
+
RETURN COALESCE(NEW, OLD);
|
|
80
|
+
END;
|
|
81
|
+
$$;
|
|
82
|
+
|
|
83
|
+
DROP TRIGGER IF EXISTS trg_guard_period_close_immutability ON period_close;
|
|
84
|
+
|
|
85
|
+
CREATE TRIGGER trg_guard_period_close_immutability
|
|
86
|
+
BEFORE UPDATE OR DELETE
|
|
87
|
+
ON period_close
|
|
88
|
+
FOR EACH ROW
|
|
89
|
+
EXECUTE FUNCTION fn_guard_period_close_immutability();
|
|
90
|
+
|
|
91
|
+
-- ==========================================================
|
|
92
|
+
-- financial_title
|
|
93
|
+
-- ==========================================================
|
|
94
|
+
|
|
95
|
+
CREATE OR REPLACE FUNCTION fn_guard_financial_title_closed_period()
|
|
96
|
+
RETURNS trigger
|
|
97
|
+
LANGUAGE plpgsql
|
|
98
|
+
AS $$
|
|
99
|
+
DECLARE
|
|
100
|
+
v_date timestamptz;
|
|
101
|
+
BEGIN
|
|
102
|
+
IF TG_OP = 'DELETE' THEN
|
|
103
|
+
v_date := COALESCE(OLD.competence_date, OLD.issue_date, OLD.created_at);
|
|
104
|
+
PERFORM fn_assert_not_in_closed_period(v_date, 'financial_title', 'DELETE');
|
|
105
|
+
RETURN OLD;
|
|
106
|
+
END IF;
|
|
107
|
+
|
|
108
|
+
v_date := COALESCE(NEW.competence_date, NEW.issue_date, NEW.created_at);
|
|
109
|
+
PERFORM fn_assert_not_in_closed_period(v_date, 'financial_title', TG_OP);
|
|
110
|
+
|
|
111
|
+
RETURN NEW;
|
|
112
|
+
END;
|
|
113
|
+
$$;
|
|
114
|
+
|
|
115
|
+
DROP TRIGGER IF EXISTS trg_guard_financial_title_closed_period ON financial_title;
|
|
116
|
+
|
|
117
|
+
CREATE TRIGGER trg_guard_financial_title_closed_period
|
|
118
|
+
BEFORE INSERT OR UPDATE OR DELETE
|
|
119
|
+
ON financial_title
|
|
120
|
+
FOR EACH ROW
|
|
121
|
+
EXECUTE FUNCTION fn_guard_financial_title_closed_period();
|
|
122
|
+
|
|
123
|
+
-- ==========================================================
|
|
124
|
+
-- financial_installment
|
|
125
|
+
-- ==========================================================
|
|
126
|
+
|
|
127
|
+
CREATE OR REPLACE FUNCTION fn_guard_financial_installment_closed_period()
|
|
128
|
+
RETURNS trigger
|
|
129
|
+
LANGUAGE plpgsql
|
|
130
|
+
AS $$
|
|
131
|
+
DECLARE
|
|
132
|
+
v_date timestamptz;
|
|
133
|
+
BEGIN
|
|
134
|
+
IF TG_OP = 'DELETE' THEN
|
|
135
|
+
v_date := COALESCE(OLD.competence_date, OLD.due_date, OLD.created_at);
|
|
136
|
+
PERFORM fn_assert_not_in_closed_period(v_date, 'financial_installment', 'DELETE');
|
|
137
|
+
RETURN OLD;
|
|
138
|
+
END IF;
|
|
139
|
+
|
|
140
|
+
v_date := COALESCE(NEW.competence_date, NEW.due_date, NEW.created_at);
|
|
141
|
+
PERFORM fn_assert_not_in_closed_period(v_date, 'financial_installment', TG_OP);
|
|
142
|
+
|
|
143
|
+
RETURN NEW;
|
|
144
|
+
END;
|
|
145
|
+
$$;
|
|
146
|
+
|
|
147
|
+
DROP TRIGGER IF EXISTS trg_guard_financial_installment_closed_period ON financial_installment;
|
|
148
|
+
|
|
149
|
+
CREATE TRIGGER trg_guard_financial_installment_closed_period
|
|
150
|
+
BEFORE INSERT OR UPDATE OR DELETE
|
|
151
|
+
ON financial_installment
|
|
152
|
+
FOR EACH ROW
|
|
153
|
+
EXECUTE FUNCTION fn_guard_financial_installment_closed_period();
|
|
154
|
+
|
|
155
|
+
-- ==========================================================
|
|
156
|
+
-- settlement
|
|
157
|
+
-- ==========================================================
|
|
158
|
+
|
|
159
|
+
CREATE OR REPLACE FUNCTION fn_guard_settlement_closed_period()
|
|
160
|
+
RETURNS trigger
|
|
161
|
+
LANGUAGE plpgsql
|
|
162
|
+
AS $$
|
|
163
|
+
DECLARE
|
|
164
|
+
v_date timestamptz;
|
|
165
|
+
BEGIN
|
|
166
|
+
IF TG_OP = 'DELETE' THEN
|
|
167
|
+
v_date := COALESCE(OLD.settled_at, OLD.created_at);
|
|
168
|
+
PERFORM fn_assert_not_in_closed_period(v_date, 'settlement', 'DELETE');
|
|
169
|
+
RETURN OLD;
|
|
170
|
+
END IF;
|
|
171
|
+
|
|
172
|
+
v_date := COALESCE(NEW.settled_at, NEW.created_at);
|
|
173
|
+
PERFORM fn_assert_not_in_closed_period(v_date, 'settlement', TG_OP);
|
|
174
|
+
|
|
175
|
+
RETURN NEW;
|
|
176
|
+
END;
|
|
177
|
+
$$;
|
|
178
|
+
|
|
179
|
+
DROP TRIGGER IF EXISTS trg_guard_settlement_closed_period ON settlement;
|
|
180
|
+
|
|
181
|
+
CREATE TRIGGER trg_guard_settlement_closed_period
|
|
182
|
+
BEFORE INSERT OR UPDATE OR DELETE
|
|
183
|
+
ON settlement
|
|
184
|
+
FOR EACH ROW
|
|
185
|
+
EXECUTE FUNCTION fn_guard_settlement_closed_period();
|
|
186
|
+
|
|
187
|
+
-- ==========================================================
|
|
188
|
+
-- settlement_allocation
|
|
189
|
+
-- ==========================================================
|
|
190
|
+
|
|
191
|
+
CREATE OR REPLACE FUNCTION fn_guard_settlement_allocation_closed_period()
|
|
192
|
+
RETURNS trigger
|
|
193
|
+
LANGUAGE plpgsql
|
|
194
|
+
AS $$
|
|
195
|
+
DECLARE
|
|
196
|
+
v_settlement_id integer;
|
|
197
|
+
v_settled_at timestamptz;
|
|
198
|
+
BEGIN
|
|
199
|
+
v_settlement_id := COALESCE(NEW.settlement_id, OLD.settlement_id);
|
|
200
|
+
|
|
201
|
+
SELECT s.settled_at
|
|
202
|
+
INTO v_settled_at
|
|
203
|
+
FROM settlement s
|
|
204
|
+
WHERE s.id = v_settlement_id;
|
|
205
|
+
|
|
206
|
+
PERFORM fn_assert_not_in_closed_period(
|
|
207
|
+
v_settled_at,
|
|
208
|
+
'settlement_allocation',
|
|
209
|
+
TG_OP
|
|
210
|
+
);
|
|
211
|
+
|
|
212
|
+
RETURN COALESCE(NEW, OLD);
|
|
213
|
+
END;
|
|
214
|
+
$$;
|
|
215
|
+
|
|
216
|
+
DROP TRIGGER IF EXISTS trg_guard_settlement_allocation_closed_period ON settlement_allocation;
|
|
217
|
+
|
|
218
|
+
CREATE TRIGGER trg_guard_settlement_allocation_closed_period
|
|
219
|
+
BEFORE INSERT OR UPDATE OR DELETE
|
|
220
|
+
ON settlement_allocation
|
|
221
|
+
FOR EACH ROW
|
|
222
|
+
EXECUTE FUNCTION fn_guard_settlement_allocation_closed_period();
|
|
223
|
+
|
|
224
|
+
-- ==========================================================
|
|
225
|
+
-- installment_allocation
|
|
226
|
+
-- ==========================================================
|
|
227
|
+
|
|
228
|
+
CREATE OR REPLACE FUNCTION fn_guard_installment_allocation_closed_period()
|
|
229
|
+
RETURNS trigger
|
|
230
|
+
LANGUAGE plpgsql
|
|
231
|
+
AS $$
|
|
232
|
+
DECLARE
|
|
233
|
+
v_installment_id integer;
|
|
234
|
+
v_date timestamptz;
|
|
235
|
+
BEGIN
|
|
236
|
+
v_installment_id := COALESCE(NEW.installment_id, OLD.installment_id);
|
|
237
|
+
|
|
238
|
+
SELECT COALESCE(fi.competence_date, fi.due_date, fi.created_at)
|
|
239
|
+
INTO v_date
|
|
240
|
+
FROM financial_installment fi
|
|
241
|
+
WHERE fi.id = v_installment_id;
|
|
242
|
+
|
|
243
|
+
PERFORM fn_assert_not_in_closed_period(
|
|
244
|
+
v_date,
|
|
245
|
+
'installment_allocation',
|
|
246
|
+
TG_OP
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
RETURN COALESCE(NEW, OLD);
|
|
250
|
+
END;
|
|
251
|
+
$$;
|
|
252
|
+
|
|
253
|
+
DROP TRIGGER IF EXISTS trg_guard_installment_allocation_closed_period ON installment_allocation;
|
|
254
|
+
|
|
255
|
+
CREATE TRIGGER trg_guard_installment_allocation_closed_period
|
|
256
|
+
BEFORE INSERT OR UPDATE OR DELETE
|
|
257
|
+
ON installment_allocation
|
|
258
|
+
FOR EACH ROW
|
|
259
|
+
EXECUTE FUNCTION fn_guard_installment_allocation_closed_period();
|
|
260
|
+
|
|
261
|
+
-- ==========================================================
|
|
262
|
+
-- bank_statement
|
|
263
|
+
-- ==========================================================
|
|
264
|
+
|
|
265
|
+
CREATE OR REPLACE FUNCTION fn_guard_bank_statement_closed_period()
|
|
266
|
+
RETURNS trigger
|
|
267
|
+
LANGUAGE plpgsql
|
|
268
|
+
AS $$
|
|
269
|
+
DECLARE
|
|
270
|
+
v_date timestamptz;
|
|
271
|
+
BEGIN
|
|
272
|
+
IF TG_OP = 'DELETE' THEN
|
|
273
|
+
v_date := COALESCE(OLD.period_start, OLD.imported_at, OLD.created_at);
|
|
274
|
+
PERFORM fn_assert_not_in_closed_period(v_date, 'bank_statement', 'DELETE');
|
|
275
|
+
RETURN OLD;
|
|
276
|
+
END IF;
|
|
277
|
+
|
|
278
|
+
v_date := COALESCE(NEW.period_start, NEW.imported_at, NEW.created_at);
|
|
279
|
+
PERFORM fn_assert_not_in_closed_period(v_date, 'bank_statement', TG_OP);
|
|
280
|
+
|
|
281
|
+
RETURN NEW;
|
|
282
|
+
END;
|
|
283
|
+
$$;
|
|
284
|
+
|
|
285
|
+
DROP TRIGGER IF EXISTS trg_guard_bank_statement_closed_period ON bank_statement;
|
|
286
|
+
|
|
287
|
+
CREATE TRIGGER trg_guard_bank_statement_closed_period
|
|
288
|
+
BEFORE INSERT OR UPDATE OR DELETE
|
|
289
|
+
ON bank_statement
|
|
290
|
+
FOR EACH ROW
|
|
291
|
+
EXECUTE FUNCTION fn_guard_bank_statement_closed_period();
|
|
292
|
+
|
|
293
|
+
-- ==========================================================
|
|
294
|
+
-- bank_statement_line
|
|
295
|
+
-- ==========================================================
|
|
296
|
+
|
|
297
|
+
CREATE OR REPLACE FUNCTION fn_guard_bank_statement_line_closed_period()
|
|
298
|
+
RETURNS trigger
|
|
299
|
+
LANGUAGE plpgsql
|
|
300
|
+
AS $$
|
|
301
|
+
DECLARE
|
|
302
|
+
v_date timestamptz;
|
|
303
|
+
BEGIN
|
|
304
|
+
IF TG_OP = 'DELETE' THEN
|
|
305
|
+
v_date := COALESCE(OLD.posted_date, OLD.created_at);
|
|
306
|
+
PERFORM fn_assert_not_in_closed_period(v_date, 'bank_statement_line', 'DELETE');
|
|
307
|
+
RETURN OLD;
|
|
308
|
+
END IF;
|
|
309
|
+
|
|
310
|
+
v_date := COALESCE(NEW.posted_date, NEW.created_at);
|
|
311
|
+
PERFORM fn_assert_not_in_closed_period(v_date, 'bank_statement_line', TG_OP);
|
|
312
|
+
|
|
313
|
+
RETURN NEW;
|
|
314
|
+
END;
|
|
315
|
+
$$;
|
|
316
|
+
|
|
317
|
+
DROP TRIGGER IF EXISTS trg_guard_bank_statement_line_closed_period ON bank_statement_line;
|
|
318
|
+
|
|
319
|
+
CREATE TRIGGER trg_guard_bank_statement_line_closed_period
|
|
320
|
+
BEFORE INSERT OR UPDATE OR DELETE
|
|
321
|
+
ON bank_statement_line
|
|
322
|
+
FOR EACH ROW
|
|
323
|
+
EXECUTE FUNCTION fn_guard_bank_statement_line_closed_period();
|
|
324
|
+
|
|
325
|
+
-- ==========================================================
|
|
326
|
+
-- bank_reconciliation
|
|
327
|
+
-- ==========================================================
|
|
328
|
+
|
|
329
|
+
CREATE OR REPLACE FUNCTION fn_guard_bank_reconciliation_closed_period()
|
|
330
|
+
RETURNS trigger
|
|
331
|
+
LANGUAGE plpgsql
|
|
332
|
+
AS $$
|
|
333
|
+
DECLARE
|
|
334
|
+
v_settlement_id integer;
|
|
335
|
+
v_settled_at timestamptz;
|
|
336
|
+
BEGIN
|
|
337
|
+
v_settlement_id := COALESCE(NEW.settlement_id, OLD.settlement_id);
|
|
338
|
+
|
|
339
|
+
SELECT s.settled_at
|
|
340
|
+
INTO v_settled_at
|
|
341
|
+
FROM settlement s
|
|
342
|
+
WHERE s.id = v_settlement_id;
|
|
343
|
+
|
|
344
|
+
PERFORM fn_assert_not_in_closed_period(
|
|
345
|
+
v_settled_at,
|
|
346
|
+
'bank_reconciliation',
|
|
347
|
+
TG_OP
|
|
348
|
+
);
|
|
349
|
+
|
|
350
|
+
RETURN COALESCE(NEW, OLD);
|
|
351
|
+
END;
|
|
352
|
+
$$;
|
|
353
|
+
|
|
354
|
+
DROP TRIGGER IF EXISTS trg_guard_bank_reconciliation_closed_period ON bank_reconciliation;
|
|
355
|
+
|
|
356
|
+
CREATE TRIGGER trg_guard_bank_reconciliation_closed_period
|
|
357
|
+
BEFORE INSERT OR UPDATE OR DELETE
|
|
358
|
+
ON bank_reconciliation
|
|
359
|
+
FOR EACH ROW
|
|
360
|
+
EXECUTE FUNCTION fn_guard_bank_reconciliation_closed_period();
|
|
361
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hed-hog/finance",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.266",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"dependencies": {
|
|
@@ -9,14 +9,14 @@
|
|
|
9
9
|
"@nestjs/core": "^11",
|
|
10
10
|
"@nestjs/jwt": "^11",
|
|
11
11
|
"@nestjs/mapped-types": "*",
|
|
12
|
-
"@hed-hog/api-pagination": "0.0.
|
|
13
|
-
"@hed-hog/contact": "0.0.
|
|
14
|
-
"@hed-hog/api-prisma": "0.0.
|
|
15
|
-
"@hed-hog/api-locale": "0.0.
|
|
12
|
+
"@hed-hog/api-pagination": "0.0.6",
|
|
13
|
+
"@hed-hog/contact": "0.0.266",
|
|
14
|
+
"@hed-hog/api-prisma": "0.0.5",
|
|
15
|
+
"@hed-hog/api-locale": "0.0.13",
|
|
16
|
+
"@hed-hog/tag": "0.0.266",
|
|
16
17
|
"@hed-hog/api-types": "0.0.1",
|
|
17
|
-
"@hed-hog/
|
|
18
|
-
"@hed-hog/api": "0.0.
|
|
19
|
-
"@hed-hog/core": "0.0.261"
|
|
18
|
+
"@hed-hog/core": "0.0.266",
|
|
19
|
+
"@hed-hog/api": "0.0.4"
|
|
20
20
|
},
|
|
21
21
|
"exports": {
|
|
22
22
|
".": {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Type } from 'class-transformer';
|
|
2
|
+
import { IsBoolean, IsNumber, IsOptional } from 'class-validator';
|
|
3
|
+
|
|
4
|
+
export class UpdateFinanceScenarioSettingsDto {
|
|
5
|
+
@Type(() => Number)
|
|
6
|
+
@IsNumber()
|
|
7
|
+
atrasoMedio: number;
|
|
8
|
+
|
|
9
|
+
@Type(() => Number)
|
|
10
|
+
@IsNumber()
|
|
11
|
+
taxaInadimplencia: number;
|
|
12
|
+
|
|
13
|
+
@Type(() => Number)
|
|
14
|
+
@IsNumber()
|
|
15
|
+
crescimentoReceita: number;
|
|
16
|
+
|
|
17
|
+
@IsOptional()
|
|
18
|
+
@Type(() => Boolean)
|
|
19
|
+
@IsBoolean()
|
|
20
|
+
setAsDefault?: boolean;
|
|
21
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Role } from '@hed-hog/api';
|
|
2
|
-
import { Controller, Get } from '@nestjs/common';
|
|
2
|
+
import { Body, Controller, Get, Param, Patch, Query } from '@nestjs/common';
|
|
3
|
+
import { UpdateFinanceScenarioSettingsDto } from './dto/update-finance-scenario-settings.dto';
|
|
3
4
|
import { FinanceService } from './finance.service';
|
|
4
5
|
|
|
5
6
|
@Role()
|
|
@@ -8,7 +9,21 @@ export class FinanceDataController {
|
|
|
8
9
|
constructor(private readonly financeService: FinanceService) {}
|
|
9
10
|
|
|
10
11
|
@Get('data')
|
|
11
|
-
async getData(
|
|
12
|
-
|
|
12
|
+
async getData(
|
|
13
|
+
@Query('horizonte') horizonte?: string,
|
|
14
|
+
@Query('cenario') cenario?: string,
|
|
15
|
+
) {
|
|
16
|
+
return this.financeService.getData({
|
|
17
|
+
horizonteDias: horizonte,
|
|
18
|
+
cenario,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@Patch('scenarios/:cenario')
|
|
23
|
+
async updateScenarioSettings(
|
|
24
|
+
@Param('cenario') cenario: string,
|
|
25
|
+
@Body() data: UpdateFinanceScenarioSettingsDto,
|
|
26
|
+
) {
|
|
27
|
+
return this.financeService.updateScenarioSettings(cenario, data);
|
|
13
28
|
}
|
|
14
29
|
}
|