@credithub/harlan-components 1.109.1 → 1.109.3

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.
@@ -146,18 +146,9 @@ var ChartSystem = function (_a) {
146
146
  serasa: null,
147
147
  boaVista: null
148
148
  });
149
- useEffect(function () {
150
- var serasaChanged = consultaSerasa !== lastComplementary.current.serasa;
151
- var boaVistaChanged = consultaBoaVista !== lastComplementary.current.boaVista;
152
- if (serasaChanged || boaVistaChanged) {
153
- lastComplementary.current = {
154
- serasa: consultaSerasa,
155
- boaVista: consultaBoaVista
156
- };
157
- refetchChart();
158
- }
159
- // eslint-disable-next-line react-hooks/exhaustive-deps
160
- }, [consultaSerasa, consultaBoaVista]);
149
+ // Evita escrever documentHistory repetidamente com o mesmo conteúdo
150
+ var lastDocHistorySigRef = useRef('');
151
+ // (refetch de histórico por mudança complementar centralizado no hook useChartData)
161
152
  var errorMessage = typeof errorChart === 'string' ? new Error(errorChart) : errorChart;
162
153
  var isOpen = useToggle(true)[0];
163
154
  // Usa valores já calculados de globalData.protestosData (calculados uma única vez em protestos.tsx)
@@ -188,7 +179,7 @@ var ChartSystem = function (_a) {
188
179
  var loadingProgress = (chartDataProgress + dividasProgress) / 2;
189
180
  var modulesReady = useMemo(function () { return areModulesLoaded(globalData); }, [globalData]);
190
181
  useEffect(function () {
191
- var _a, _b;
182
+ var _a, _b, _c, _d;
192
183
  if (!dataUpdated && chartData && modulesReady) {
193
184
  var protestoHistory_1 = (_b = (_a = chartData.protestos) === null || _a === void 0 ? void 0 : _a.map(function (p) {
194
185
  var _a, _b;
@@ -200,34 +191,61 @@ var ChartSystem = function (_a) {
200
191
  });
201
192
  }).sort(function (a, b) { return new Date(a.data).getTime() - new Date(b.data).getTime(); })) !== null && _b !== void 0 ? _b : [];
202
193
  var protestoLiminar_1 = calcularProtestoLiminar(protestoHistory_1);
203
- setGlobalState(function (prev) {
204
- var _a, _b;
205
- var docHistory = {
206
- protestoHistory: protestoHistory_1,
207
- protestoLiminar: protestoLiminar_1,
208
- quantidadeProtestos: quantidadeProtestos,
209
- quantidadeProcessos: (_b = (_a = chartData.pieChartTotalConfig) === null || _a === void 0 ? void 0 : _a.processosJuridicos) !== null && _b !== void 0 ? _b : 0,
210
- quantidadeDividas: quantidadeDividas,
211
- quantidadeDividasSerasa: quantidadeSerasa,
212
- quantidadeDividasBoaVista: quantidadeBoaVista,
213
- quantidadeChequesSemFundos: quantidadeCCFs,
214
- ultimaOcorrenciaChequesSemFundos: ultimaOcorrenciaCCF,
215
- valorTotalDividasSerasa: valorTotalSerasa,
216
- valorTotalDividasBoaVista: valorTotalBoaVista,
217
- valorTotalProtestos: valorTotalProtestos,
218
- valorTotalDividas: valorTotalDividas,
219
- ultimaOcorrenciaProtestos: ultimaOcorrenciaProtestos,
220
- ultimaOcorrenciaDividas: ultimaOcorrenciaDividas,
221
- ultimaOcorrenciaPefinBoaVista: quantidadeBoaVista > 0 && ultimaOcorrenciaBoaVista
222
- ? ultimaOcorrenciaBoaVista
223
- : undefined,
224
- ultimaOcorrenciaPefinSerasa: quantidadeSerasa > 0 && ultimaOcorrenciaSerasa
225
- ? ultimaOcorrenciaSerasa
226
- : undefined
227
- };
228
- return __assign(__assign({}, prev), { documentHistory: docHistory });
194
+ // Cria assinatura estável para evitar setState repetido
195
+ var signature = JSON.stringify({
196
+ protestoHistory: protestoHistory_1,
197
+ protestoLiminar: protestoLiminar_1,
198
+ quantidadeProtestos: quantidadeProtestos,
199
+ quantidadeProcessos: (_d = (_c = chartData.pieChartTotalConfig) === null || _c === void 0 ? void 0 : _c.processosJuridicos) !== null && _d !== void 0 ? _d : 0,
200
+ quantidadeDividas: quantidadeDividas,
201
+ quantidadeDividasSerasa: quantidadeSerasa,
202
+ quantidadeDividasBoaVista: quantidadeBoaVista,
203
+ quantidadeChequesSemFundos: quantidadeCCFs,
204
+ ultimaOcorrenciaChequesSemFundos: ultimaOcorrenciaCCF,
205
+ valorTotalDividasSerasa: valorTotalSerasa,
206
+ valorTotalDividasBoaVista: valorTotalBoaVista,
207
+ valorTotalProtestos: valorTotalProtestos,
208
+ valorTotalDividas: valorTotalDividas,
209
+ ultimaOcorrenciaProtestos: ultimaOcorrenciaProtestos,
210
+ ultimaOcorrenciaDividas: ultimaOcorrenciaDividas,
211
+ ultimaOcorrenciaPefinBoaVista: quantidadeBoaVista > 0 && ultimaOcorrenciaBoaVista
212
+ ? ultimaOcorrenciaBoaVista
213
+ : undefined,
214
+ ultimaOcorrenciaPefinSerasa: quantidadeSerasa > 0 && ultimaOcorrenciaSerasa
215
+ ? ultimaOcorrenciaSerasa
216
+ : undefined
229
217
  });
230
- setDataUpdated(true);
218
+ if (signature !== lastDocHistorySigRef.current) {
219
+ setGlobalState(function (prev) {
220
+ var _a, _b;
221
+ var docHistory = {
222
+ protestoHistory: protestoHistory_1,
223
+ protestoLiminar: protestoLiminar_1,
224
+ quantidadeProtestos: quantidadeProtestos,
225
+ quantidadeProcessos: (_b = (_a = chartData.pieChartTotalConfig) === null || _a === void 0 ? void 0 : _a.processosJuridicos) !== null && _b !== void 0 ? _b : 0,
226
+ quantidadeDividas: quantidadeDividas,
227
+ quantidadeDividasSerasa: quantidadeSerasa,
228
+ quantidadeDividasBoaVista: quantidadeBoaVista,
229
+ quantidadeChequesSemFundos: quantidadeCCFs,
230
+ ultimaOcorrenciaChequesSemFundos: ultimaOcorrenciaCCF,
231
+ valorTotalDividasSerasa: valorTotalSerasa,
232
+ valorTotalDividasBoaVista: valorTotalBoaVista,
233
+ valorTotalProtestos: valorTotalProtestos,
234
+ valorTotalDividas: valorTotalDividas,
235
+ ultimaOcorrenciaProtestos: ultimaOcorrenciaProtestos,
236
+ ultimaOcorrenciaDividas: ultimaOcorrenciaDividas,
237
+ ultimaOcorrenciaPefinBoaVista: quantidadeBoaVista > 0 && ultimaOcorrenciaBoaVista
238
+ ? ultimaOcorrenciaBoaVista
239
+ : undefined,
240
+ ultimaOcorrenciaPefinSerasa: quantidadeSerasa > 0 && ultimaOcorrenciaSerasa
241
+ ? ultimaOcorrenciaSerasa
242
+ : undefined
243
+ };
244
+ return __assign(__assign({}, prev), { documentHistory: docHistory });
245
+ });
246
+ lastDocHistorySigRef.current = signature;
247
+ setDataUpdated(true);
248
+ }
231
249
  }
232
250
  }, [
233
251
  chartData,
@@ -48,13 +48,13 @@ var ClickableStatusMessage = styled(StatusMessage)(templateObject_3 || (template
48
48
  // Wrapper para o texto clicável dentro do StatusMessage
49
49
  var ClickableText = styled.span(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n cursor: pointer;\n &:hover {\n opacity: 0.85;\n }\n"], ["\n cursor: pointer;\n &:hover {\n opacity: 0.85;\n }\n"])));
50
50
  var ConsultaSimplesSection = function (_a) {
51
- var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
52
- var documento = _a.documento, children = _a.children, onClose = _a.onClose, onClickPrint = _a.onClickPrint, isFinancial = _a.isFinancial, ctime = _a.ctime, printMode = _a.printMode, _x = _a.tags, tags = _x === void 0 ? [] : _x, rest = __rest(_a, ["documento", "children", "onClose", "onClickPrint", "isFinancial", "ctime", "printMode", "tags"]);
51
+ var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
52
+ var documento = _a.documento, children = _a.children, onClose = _a.onClose, onClickPrint = _a.onClickPrint, isFinancial = _a.isFinancial, ctime = _a.ctime, printMode = _a.printMode, _y = _a.tags, tags = _y === void 0 ? [] : _y, rest = __rest(_a, ["documento", "children", "onClose", "onClickPrint", "isFinancial", "ctime", "printMode", "tags"]);
53
53
  var ctx = useContext(Queries.Finder);
54
54
  var data = useGlobalData().data;
55
55
  var posthog = usePostHog().posthog;
56
56
  // Hook para observar mutações no DOM e chamar callback quando estável
57
- var _y = usePrintWhenStable({
57
+ var _z = usePrintWhenStable({
58
58
  debounceTime: 500,
59
59
  maxWaitTime: 30000,
60
60
  onStart: function () {
@@ -65,7 +65,7 @@ var ConsultaSimplesSection = function (_a) {
65
65
  // Chama o callback externo (Harlan decide como imprimir)
66
66
  onClickPrint === null || onClickPrint === void 0 ? void 0 : onClickPrint();
67
67
  }
68
- }), printWhenStable = _y.printWhenStable, isWaiting = _y.isWaiting;
68
+ }), printWhenStable = _z.printWhenStable, isWaiting = _z.isWaiting;
69
69
  // Handler que usa o observer ao invés de imprimir diretamente
70
70
  var handlePrint = function () {
71
71
  printWhenStable();
@@ -131,12 +131,10 @@ var ConsultaSimplesSection = function (_a) {
131
131
  ? 'Processo Jurídico'
132
132
  : 'Processos Jurídicos')
133
133
  : '', (_o = data.processosJuridicosData) === null || _o === void 0 ? void 0 : _o.error),
134
- makeItem('Liminar', (_p = data.liminar) === null || _p === void 0 ? void 0 : _p.isLoaded, data.liminar &&
135
- (data.liminar.totalProtestos === 'NADA CONSTA' ||
136
- data.liminar.message === 'Encontrado')
134
+ makeItem('Liminar', (_p = data.liminar) === null || _p === void 0 ? void 0 : _p.isLoaded, ((_q = data.liminar) === null || _q === void 0 ? void 0 : _q.message) === 'Encontrado'
137
135
  ? 'Indício de Liminar'
138
- : '', (_q = data.liminar) === null || _q === void 0 ? void 0 : _q.error),
139
- makeItem('Potenciais Protestos Entrantes', true, ((_r = data.editalData) === null || _r === void 0 ? void 0 : _r.recentesCount)
136
+ : '', (_r = data.liminar) === null || _r === void 0 ? void 0 : _r.error),
137
+ makeItem('Potenciais Protestos Entrantes', true, ((_s = data.editalData) === null || _s === void 0 ? void 0 : _s.recentesCount)
140
138
  ? "".concat(data.editalData.recentesCount === 1 ? '1 Potencial Protesto Entrante' : "".concat(data.editalData.recentesCount, " Potenciais Protestos Entrantes"))
141
139
  : ''
142
140
  // Não exibe erro de edital - deve falhar silenciosamente
@@ -155,8 +153,8 @@ var ConsultaSimplesSection = function (_a) {
155
153
  data.dividasPublicas ||
156
154
  data.processosJuridicos ||
157
155
  receitaStatus ||
158
- ((_s = data.liminar) === null || _s === void 0 ? void 0 : _s.message) === 'Encontrado' ||
159
- (((_t = data.editalData) === null || _t === void 0 ? void 0 : _t.recentesCount) &&
156
+ ((_t = data.liminar) === null || _t === void 0 ? void 0 : _t.message) === 'Encontrado' ||
157
+ (((_u = data.editalData) === null || _u === void 0 ? void 0 : _u.recentesCount) &&
160
158
  hasOneOfTags(tags, ['diamante', 'diamante-new']));
161
159
  var statusType = isError ? 'warning' : hasPendencias ? 'error' : 'success';
162
160
  useEffect(function () {
@@ -283,13 +281,13 @@ var ConsultaSimplesSection = function (_a) {
283
281
  }
284
282
  return item.text ? (item.label === 'Potenciais Protestos Entrantes' ? (React.createElement(ClickableStatusMessage, { key: item.label, type: "error", onClick: scrollToEditais, title: "Clique para ver detalhes" }, item.text)) : (React.createElement(StatusMessage, { key: item.label, type: "error" }, item.text))) : null;
285
283
  }),
286
- ((_u = data.editalData) === null || _u === void 0 ? void 0 : _u.isLoaded) &&
287
- !!((_v = data.editalData) === null || _v === void 0 ? void 0 : _v.vencidosCount) &&
284
+ ((_v = data.editalData) === null || _v === void 0 ? void 0 : _v.isLoaded) &&
285
+ !!((_w = data.editalData) === null || _w === void 0 ? void 0 : _w.vencidosCount) &&
288
286
  data.editalData.vencidosCount > 0 &&
289
287
  hasOneOfTags(tags, ['diamante', 'diamante-new']) && (React.createElement(StatusMessage, { type: "error" },
290
288
  React.createElement(ClickableText, { onClick: scrollToEditais, title: "Clique para ver detalhes" },
291
289
  "Cart\u00F3rio com dificuldade para intimar",
292
- ((_w = data.editalData) === null || _w === void 0 ? void 0 : _w.dataEditalMaisAntigo) &&
290
+ ((_x = data.editalData) === null || _x === void 0 ? void 0 : _x.dataEditalMaisAntigo) &&
293
291
  " desde o: ".concat(data.editalData.dataEditalMaisAntigo))))), onClose: onClose, icon: ConsultaSimplesIcon, variant: isLoading ? 'loading' : 'default', ctx: ctx, loadingProps: {
294
292
  percentage: (ctx === null || ctx === void 0 ? void 0 : ctx.progress) || 0,
295
293
  hidden: !isLoading
@@ -245,7 +245,7 @@ var Liminar = function (_a) {
245
245
  setData(function (prev) { return (__assign(__assign({}, prev), { liminar: {
246
246
  /* -------------------------------------------------------------
247
247
  * Há 3 fontes possíveis de indício de liminar:
248
- * 1) API (Cenprot/Serasa) ‑ indiciosApi
248
+ * 1) API (Cenprot/Serasa) ‑ indiciosApi
249
249
  * 2) Liminar detectada por protestos passados ‑ indiciosDeLiminarProtestosDoPassado
250
250
  * 3) Processos Judiciais com assuntos compatíveis ‑ processosComAssuntoValido
251
251
  * ----------------------------------------------------------- */
@@ -266,8 +266,29 @@ var Liminar = function (_a) {
266
266
  }
267
267
  });
268
268
  }); };
269
- if (isFinancial)
269
+ if (isFinancial) {
270
270
  fetch();
271
+ }
272
+ else {
273
+ // Se não for financial, marca como carregado imediatamente
274
+ var dossie = globalData === null || globalData === void 0 ? void 0 : globalData.dossie;
275
+ var processosJuridicos = globalData === null || globalData === void 0 ? void 0 : globalData.processosJuridicosData;
276
+ var depsLoaded = !!(processosJuridicos === null || processosJuridicos === void 0 ? void 0 : processosJuridicos.isLoaded) && !!(dossie === null || dossie === void 0 ? void 0 : dossie.carousel);
277
+ if (depsLoaded && !processedRef.current) {
278
+ setData(function (prev) { return (__assign(__assign({}, prev), { liminar: {
279
+ indiciosDeLiminar: false,
280
+ message: 'Não encontrado',
281
+ isLoaded: true,
282
+ processosComLiminarIds: [],
283
+ indiciosDeLiminarProtestosDoPassado: false,
284
+ protestosDoPassadoIds: '',
285
+ invertedProcessos: [],
286
+ origensLiminar: [],
287
+ descricaoLiminar: 'Não encontrado'
288
+ } })); });
289
+ processedRef.current = true;
290
+ }
291
+ }
271
292
  }, [
272
293
  isFinancial,
273
294
  ctx.type,
@@ -276,7 +297,8 @@ var Liminar = function (_a) {
276
297
  globalData === null || globalData === void 0 ? void 0 : globalData.processosJuridicosData,
277
298
  processosComAssuntoValido,
278
299
  setData,
279
- foundBusinessEntity
300
+ foundBusinessEntity,
301
+ protestosIsReady
280
302
  ]);
281
303
  var ready = processedRef.current &&
282
304
  !!((_h = globalData === null || globalData === void 0 ? void 0 : globalData.processosJuridicosData) === null || _h === void 0 ? void 0 : _h.isLoaded) &&
@@ -28,7 +28,7 @@ import ProtestosGeraisIcon from '../../assets/icones/protestosGerais';
28
28
  import ProtestosImpostosIcon from '../../assets/icones/protestosImpostos';
29
29
  import { useGlobalData } from '../../contexts/globalDataContext';
30
30
  import { classifyProtestos, useProtestosClassification } from '../../hooks/useProtestosClassification';
31
- import { clearMoneyString } from '../../utils/number';
31
+ import { parseMoneyValue } from '../../utils/number';
32
32
  import { parseProtesto } from '../../utils/parseProtesto';
33
33
  import XPathUtils from '../../utils/xpath';
34
34
  import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react';
@@ -87,8 +87,7 @@ var Protestos = function () {
87
87
  // Calcula valorTotalProtestos uma única vez somando todos os valores
88
88
  var todosProtestos = __spreadArray(__spreadArray(__spreadArray([], protestosDeCredito, true), protestosDeImposto, true), protestosGerais, true);
89
89
  var valorTotalProtestos = todosProtestos.reduce(function (total, protesto) {
90
- var valorStr = (protesto === null || protesto === void 0 ? void 0 : protesto.valor) || '0';
91
- var valorNumero = Number(clearMoneyString(valorStr)) || 0;
90
+ var valorNumero = parseMoneyValue(protesto === null || protesto === void 0 ? void 0 : protesto.valor);
92
91
  return total + valorNumero;
93
92
  }, 0);
94
93
  setData(function (prevState) {
@@ -3,7 +3,7 @@ var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cook
3
3
  return cooked;
4
4
  };
5
5
  import { Chart, registerables } from 'chart.js';
6
- import React, { useContext } from 'react';
6
+ import React, { useContext, useMemo } from 'react';
7
7
  import styled, { ThemeProvider } from 'styled-components';
8
8
  import { Addresses, BankAccounts, CCF, ChartSystem, Contacts, DividasPublicas, Dossie, Falencia, Partners, ProcessosJuridicos, Protestos, Queries, RefinBoaVista, RefinSerasa, useQuery, Veiculos, WebServiceProvider } from './';
9
9
  import Modal from './components/common/modal';
@@ -29,16 +29,19 @@ import theme from './styles/theme';
29
29
  import { hasOneOfTags } from './utils/tags';
30
30
  Chart.register.apply(Chart, registerables);
31
31
  var Wrapper = styled.div(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n font-family: 'Open Sans Condensed';\n display: flex;\n flex-direction: column;\n gap: 20px;\n margin-bottom: 20px;\n\n * {\n -webkit-print-color-adjust: exact !important;\n print-color-adjust: exact !important;\n }\n\n @media print {\n @page {\n size: auto;\n margin: 5mm;\n }\n }\n"], ["\n font-family: 'Open Sans Condensed';\n display: flex;\n flex-direction: column;\n gap: 20px;\n margin-bottom: 20px;\n\n * {\n -webkit-print-color-adjust: exact !important;\n print-color-adjust: exact !important;\n }\n\n @media print {\n @page {\n size: auto;\n margin: 5mm;\n }\n }\n"])));
32
+ // Componente de dependência de Protestos estabilizado em escopo de módulo
33
+ var ProtestosWithCCFDependency = React.memo(function (_a) {
34
+ var children = _a.children, documento = _a.documento;
35
+ var ctxFinder = useContext(Queries.Finder);
36
+ var ctxCCF = useContext(Queries.CCF);
37
+ var depends = useMemo(function () { return [ctxFinder, ctxCCF]; }, [ctxFinder, ctxCCF]);
38
+ return (React.createElement(Queries.Protestos.Request, { data: { documento: documento }, depends: depends }, children));
39
+ });
32
40
  var FinderDependency = function (_a) {
33
41
  var children = _a.children, documento = _a.documento;
34
42
  var ctxFinder = useContext(Queries.Finder);
35
- var ProtestosWithCCFDependency = function (_a) {
36
- var children = _a.children;
37
- var ctxCCF = useContext(Queries.CCF);
38
- return (React.createElement(Queries.Protestos.Request, { data: { documento: documento }, depends: [ctxFinder, ctxCCF] }, children));
39
- };
40
43
  return (React.createElement(Queries.CCF.Request, { data: { documento: documento }, depends: [ctxFinder] },
41
- React.createElement(ProtestosWithCCFDependency, null, children)));
44
+ React.createElement(ProtestosWithCCFDependency, { documento: documento }, children)));
42
45
  };
43
46
  var GraficosAnaliticosDependency = function (_a) {
44
47
  var children = _a.children, documento = _a.documento;
@@ -4,3 +4,16 @@ export declare function formatValue(valor?: number): string | undefined;
4
4
  export declare function sum(valores: number[]): number;
5
5
  export declare const extractIntegerFromText: (text: string | null) => number;
6
6
  export declare const clearMoneyString: (value: string) => string;
7
+ /**
8
+ * Converte uma string de valor monetário para número, tratando múltiplos formatos.
9
+ *
10
+ * Suporta os seguintes formatos:
11
+ * - "1.695,80" (formato brasileiro com separador de milhar)
12
+ * - "1695,80" (formato brasileiro sem separador de milhar)
13
+ * - "1695.80" (formato internacional)
14
+ * - "169580" (número puro - será interpretado como centavos se muito grande)
15
+ *
16
+ * @param value - String ou número representando o valor monetário
17
+ * @returns Número em formato decimal (ex: 1695.80)
18
+ */
19
+ export declare const parseMoneyValue: (value: string | number | null | undefined) => number;
@@ -27,3 +27,71 @@ export var extractIntegerFromText = function (text) {
27
27
  export var clearMoneyString = function (value) {
28
28
  return value.replace(/\./g, '').replace(/,/g, '.');
29
29
  };
30
+ /**
31
+ * Converte uma string de valor monetário para número, tratando múltiplos formatos.
32
+ *
33
+ * Suporta os seguintes formatos:
34
+ * - "1.695,80" (formato brasileiro com separador de milhar)
35
+ * - "1695,80" (formato brasileiro sem separador de milhar)
36
+ * - "1695.80" (formato internacional)
37
+ * - "169580" (número puro - será interpretado como centavos se muito grande)
38
+ *
39
+ * @param value - String ou número representando o valor monetário
40
+ * @returns Número em formato decimal (ex: 1695.80)
41
+ */
42
+ export var parseMoneyValue = function (value) {
43
+ if (value === null || value === undefined)
44
+ return 0;
45
+ // Se já for número, retorna direto
46
+ if (typeof value === 'number') {
47
+ return isNaN(value) ? 0 : value;
48
+ }
49
+ // Se for string vazia, retorna 0
50
+ var str = String(value).trim();
51
+ if (!str || str === '0')
52
+ return 0;
53
+ // Remove espaços e caracteres não numéricos exceto ponto e vírgula
54
+ var cleaned = str.replace(/[^\d.,]/g, '');
55
+ // Se não tem ponto nem vírgula, é número puro
56
+ if (!cleaned.includes('.') && !cleaned.includes(',')) {
57
+ var num_1 = Number(cleaned);
58
+ // Se for número puro sem separador decimal, verifica se pode ser centavos
59
+ // Valores monetários típicos de protestos raramente ultrapassam R$ 50.000
60
+ // Se o número tem 5+ dígitos, verifica se faz mais sentido como centavos
61
+ if (cleaned.length >= 5) {
62
+ var asCentavos = num_1 / 100;
63
+ // Se interpretado como centavos resulta em valor razoável (< 50000),
64
+ // assume que é centavos (ex: 169580 -> 1695.80, 271353 -> 2713.53)
65
+ if (asCentavos < 50000 && asCentavos > 0) {
66
+ return asCentavos;
67
+ }
68
+ }
69
+ return num_1;
70
+ }
71
+ // Detecta formato: se tem vírgula, assume formato brasileiro (1.695,80 ou 1695,80)
72
+ if (cleaned.includes(',')) {
73
+ // Remove pontos (separadores de milhar) e substitui vírgula por ponto
74
+ cleaned = cleaned.replace(/\./g, '').replace(',', '.');
75
+ var num_2 = Number(cleaned);
76
+ return isNaN(num_2) ? 0 : num_2;
77
+ }
78
+ // Se só tem ponto, pode ser formato internacional ou separador de milhar
79
+ // Se tem mais de um ponto, assume que são separadores de milhar
80
+ var dots = (cleaned.match(/\./g) || []).length;
81
+ if (dots > 1) {
82
+ // Múltiplos pontos = separadores de milhar (formato internacional: 1.695.80)
83
+ cleaned = cleaned.replace(/\./g, '');
84
+ var num_3 = Number(cleaned);
85
+ // Se o número resultante for muito grande, assume que o último ponto era decimal
86
+ if (num_3 > 1000000) {
87
+ // Pega os últimos 2 dígitos como centavos
88
+ var integerPart = Math.floor(num_3 / 100);
89
+ var decimalPart = num_3 % 100;
90
+ return integerPart + decimalPart / 100;
91
+ }
92
+ return isNaN(num_3) ? 0 : num_3;
93
+ }
94
+ // Um único ponto = separador decimal (formato internacional: 1695.80)
95
+ var num = Number(cleaned);
96
+ return isNaN(num) ? 0 : num;
97
+ };