Refactor data processing: enhance getLastConsolidatedYear function to filter valid consolidated data and improve cost indicator handling

This commit is contained in:
Giuliano Paschoalino 2026-01-20 09:58:16 -03:00
parent 43a686bb3b
commit 811f40002b
10 changed files with 125 additions and 49 deletions

View File

@ -14,6 +14,7 @@ import { CativoXLivreChartView } from './CativoXLivreChartView';
import ChartTitle from '../ChartTitle'; import ChartTitle from '../ChartTitle';
import pattern from 'patternomaly' import pattern from 'patternomaly'
import { config } from '../config'; import { config } from '../config';
import { getLastConsolidatedYear } from '../../../utils/dataProcessing';
ChartJS.register( ChartJS.register(
LinearScale, LinearScale,
@ -75,15 +76,45 @@ interface LineBarChartInterface {
export function CativoXLivreChart({ title, subtitle, chartData, label, dataset1, dataset2, dataset3, barLabel, hashurado, miniature }: LineBarChartInterface) { export function CativoXLivreChart({ title, subtitle, chartData, label, dataset1, dataset2, dataset3, barLabel, hashurado, miniature }: LineBarChartInterface) {
const chartRef = useRef<ChartJS>(null); const chartRef = useRef<ChartJS>(null);
const labels = label // Filter data by last consolidated year
const lastConsolidatedYear = getLastConsolidatedYear(chartData || [], true);
// Helper function to extract year from mes field
const extractYear = (mes: string): number => {
if (!mes) return lastConsolidatedYear;
const mesStr = mes.toString();
if (mesStr.includes('-')) {
return parseInt(mesStr.split('-')[0]);
}
if (mesStr.includes('/')) {
return parseInt(mesStr.split('/')[1]);
}
return lastConsolidatedYear;
};
// Filter data and labels together to keep them in sync
const filteredData: { chartData: any[], labels: any[] } = { chartData: [], labels: [] };
chartData?.forEach((value, index) => {
const year = extractYear(value.mes);
if (year === lastConsolidatedYear) {
filteredData.chartData.push(value);
if (label && label[index]) {
filteredData.labels.push(label[index]);
}
}
});
const filteredChartData = filteredData.chartData.length > 0 ? filteredData.chartData : chartData;
const labels = filteredData.labels.length > 0 ? filteredData.labels : label;
const options: any = config(miniature) const options: any = config(miniature)
const hasEstimated = chartData?.some((value) => value.dad_estimado) const hasEstimated = filteredChartData?.some((value) => value.dad_estimado)
const data: any = { const data: any = {
labels, labels,
datasets: chartData?.map(value => value.dad_estimado)?.includes(true) ? [ datasets: filteredChartData?.map(value => value.dad_estimado)?.includes(true) ? [
{ {
type: 'line' as const, type: 'line' as const,
label: dataset1? dataset1 : 'Dataset 1', label: dataset1? dataset1 : 'Dataset 1',
@ -95,53 +126,53 @@ export function CativoXLivreChart({ title, subtitle, chartData, label, dataset1,
}, },
borderWidth: 2, borderWidth: 2,
fill: false, fill: false,
data: chartData?.map(value => parseInt(value.economia_mensal)), data: filteredChartData?.map(value => parseInt(value.economia_mensal)),
}, },
{ {
type: 'bar' as const, type: 'bar' as const,
label: 'Cativo', label: 'Cativo',
data: chartData?.map(value => { data: filteredChartData?.map(value => {
if (!value.dad_estimado) if (!value.dad_estimado)
return parseInt(value.custo_cativo) return parseInt(value.custo_cativo)
}), }),
// skipNull: true, // skipNull: true,
borderRadius: 8, borderRadius: 8,
backgroundColor: '#C2D5FB', backgroundColor: '#C2D5FB',
skipNull: chartData?.map(value => value.dad_estimado)?.includes(true) skipNull: filteredChartData?.map(value => value.dad_estimado)?.includes(true)
}, },
{ {
type: 'bar' as const, type: 'bar' as const,
label: 'Livre', label: 'Livre',
data: chartData?.filter(value => !value.dad_estimad? true : false).map(value => { data: filteredChartData?.filter(value => !value.dad_estimad? true : false).map(value => {
if (!value.dad_estimado) if (!value.dad_estimado)
return parseInt(value.custo_livre) return parseInt(value.custo_livre)
}), }),
// skipNull: true, // skipNull: true,
borderRadius: 8, borderRadius: 8,
backgroundColor: '#255488', backgroundColor: '#255488',
skipNull: chartData?.map(value => value.dad_estimado)?.includes(true) skipNull: filteredChartData?.map(value => value.dad_estimado)?.includes(true)
}, },
{ {
type: 'bar', type: 'bar',
label: 'Est. Cativo', label: 'Est. Cativo',
data: chartData?.map(value => { data: filteredChartData?.map(value => {
if (value.dad_estimado) if (value.dad_estimado)
return parseInt(value.custo_cativo) return parseInt(value.custo_cativo)
}), }),
borderRadius: 8, borderRadius: 8,
backgroundColor: pattern.draw('diagonal-right-left', '#C2D5FB'), backgroundColor: pattern.draw('diagonal-right-left', '#C2D5FB'),
skipNull: chartData?.map(value => value.dad_estimado)?.includes(true) skipNull: filteredChartData?.map(value => value.dad_estimado)?.includes(true)
}, },
{ {
type: 'bar', type: 'bar',
label: 'Est. Livre', label: 'Est. Livre',
data: chartData?.map(value => { data: filteredChartData?.map(value => {
if (value.dad_estimado) if (value.dad_estimado)
return parseInt(value.custo_livre) return parseInt(value.custo_livre)
}), }),
borderRadius: 8, borderRadius: 8,
backgroundColor: pattern.draw('diagonal-right-left', '#255488'), backgroundColor: pattern.draw('diagonal-right-left', '#255488'),
skipNull: chartData?.map(value => value.dad_estimado)?.includes(true) skipNull: filteredChartData?.map(value => value.dad_estimado)?.includes(true)
} }
] : [ ] : [
{ {
@ -155,31 +186,31 @@ export function CativoXLivreChart({ title, subtitle, chartData, label, dataset1,
}, },
borderWidth: 2, borderWidth: 2,
fill: false, fill: false,
data: chartData?.map(value => parseInt(value.economia_mensal)), data: filteredChartData?.map(value => parseInt(value.economia_mensal)),
}, },
{ {
type: 'bar' as const, type: 'bar' as const,
label: 'Cativo', label: 'Cativo',
data: chartData?.map(value => { data: filteredChartData?.map(value => {
if (!value.dad_estimado) if (!value.dad_estimado)
return parseInt(value.custo_cativo) return parseInt(value.custo_cativo)
}), }),
// skipNull: true, // skipNull: true,
borderRadius: 8, borderRadius: 8,
backgroundColor: '#C2D5FB', backgroundColor: '#C2D5FB',
skipNull: chartData?.map(value => value.dad_estimado)?.includes(true) skipNull: filteredChartData?.map(value => value.dad_estimado)?.includes(true)
}, },
{ {
type: 'bar' as const, type: 'bar' as const,
label: 'Livre', label: 'Livre',
data: chartData?.filter(value => !value.dad_estimad? true : false).map(value => { data: filteredChartData?.filter(value => !value.dad_estimad? true : false).map(value => {
if (!value.dad_estimado) if (!value.dad_estimado)
return parseInt(value.custo_livre) return parseInt(value.custo_livre)
}), }),
// skipNull: true, // skipNull: true,
borderRadius: 8, borderRadius: 8,
backgroundColor: '#255488', backgroundColor: '#255488',
skipNull: chartData?.map(value => value.dad_estimado)?.includes(true) skipNull: filteredChartData?.map(value => value.dad_estimado)?.includes(true)
} }
], ],
} }

View File

@ -42,11 +42,12 @@ export default function CostIndicator({graphData, userName, clients}: any) {
useEffect(() => { useEffect(() => {
// Calculate the last consolidated year // Calculate the last consolidated year
const lastYear = getLastConsolidatedYear(graphData, true) const lastYear = getLastConsolidatedYear(graphData, true)
console.log('Last Consolidated Year:', lastYear)
console.log('Graph Data:', graphData)
setLastConsolidatedYear(lastYear) setLastConsolidatedYear(lastYear)
// Populate graph data with consolidated and estimated data for that year // Keep the full dataset to show both years
const populatedData = populateGraphDataForYear(graphData, lastYear) setProcessedGraphData(graphData)
setProcessedGraphData(populatedData)
}, [graphData]) }, [graphData])
useEffect(() => { useEffect(() => {
@ -55,11 +56,11 @@ export default function CostIndicator({graphData, userName, clients}: any) {
{"type" : "=", "field":"dados_cadastrais.cod_smart_unidade", "value": unity} {"type" : "=", "field":"dados_cadastrais.cod_smart_unidade", "value": unity}
] ]
}:{}).then(res => { }:{}).then(res => {
// Apply data processing to filtered result // Keep full dataset without filtering by year
if (res.data.data && res.data.data.length > 0) { if (res.data.data && res.data.data.length > 0) {
const lastYear = getLastConsolidatedYear(res.data.data, true) const lastYear = getLastConsolidatedYear(res.data.data, true)
const populatedData = populateGraphDataForYear(res.data.data, lastYear) setLastConsolidatedYear(lastYear)
setGraphDataState(populatedData) setGraphDataState(res.data.data)
} else { } else {
setGraphDataState(res.data.data) setGraphDataState(res.data.data)
} }
@ -94,17 +95,24 @@ export default function CostIndicator({graphData, userName, clients}: any) {
</Select> </Select>
</FormControl> </FormControl>
<section> <section>
<CostIndicatorChart title='' subtitle='' <CostIndicatorChart title={lastConsolidatedYear?.toLocaleString()} subtitle=''
data1={unity!==''? graphDataState.filter((value, index) => value.mes.slice(0, 4).includes(lastConsolidatedYear?.toString() || '')) data1={unity!==''?
.map(value => value?.custo_unit && !!parseInt(value?.custo_unit) ? value.custo_unit : null) graphDataState
.filter(value => value.mes?.slice(0, 4) === (lastConsolidatedYear && lastConsolidatedYear - 1)?.toString() && value.custo_unit !== undefined)
.map(value => value?.custo_unit && !!parseFloat(value?.custo_unit) ? value.custo_unit : null)
: :
processedGraphData.filter((value, index) => value.mes.slice(0, 4).includes(lastConsolidatedYear?.toString() || '')) processedGraphData
.map(value => value?.custo_unit && !!parseInt(value?.custo_unit) ? value.custo_unit : null)} .filter(value => value.mes?.slice(0, 4) === (lastConsolidatedYear && lastConsolidatedYear - 1)?.toString() && value.custo_unit !== undefined)
data2={unity!==''? graphDataState.filter((value, index) => value.mes.slice(0, 4).includes(lastConsolidatedYear?.toString() || '')) .map(value => value?.custo_unit && !!parseFloat(value?.custo_unit) ? value.custo_unit : null)}
.map(value => value?.custo_unit && !!parseInt(value?.custo_unit) ? value.custo_unit : null) data2={unity!==''?
graphDataState
.filter(value => value.mes?.slice(0, 4) === lastConsolidatedYear?.toString() && value.custo_unit !== undefined)
.map(value => value?.custo_unit && !!parseFloat(value?.custo_unit) ? value.custo_unit : null)
: :
processedGraphData.filter((value, index) => value.mes.slice(0, 4).includes(lastConsolidatedYear?.toString() || '')) processedGraphData
.map(value => value?.custo_unit && !!parseInt(value?.custo_unit) ? value.custo_unit : null)} .filter(value => value.mes?.slice(0, 4) === lastConsolidatedYear?.toString() && value.custo_unit !== undefined)
.map(value => value?.custo_unit && !!parseFloat(value?.custo_unit) ? value.custo_unit : null)}
years={[lastConsolidatedYear ? (lastConsolidatedYear - 1).toString() : '', lastConsolidatedYear?.toString() || '']}
label={months} label={months}
/> />
</section> </section>

View File

@ -69,6 +69,7 @@ export default function Dashboard({ grossAnualGraph, grossAnualYears, grossMensa
const [lastDataBrutaAnualS, setLastDataBrutaAnual] = useState('') const [lastDataBrutaAnualS, setLastDataBrutaAnual] = useState('')
const [processedMensalData, setProcessedMensalData] = useState(grossMensalGraph) const [processedMensalData, setProcessedMensalData] = useState(grossMensalGraph)
const [lastConsolidatedYear, setLastConsolidatedYear] = useState<number | null>(null) const [lastConsolidatedYear, setLastConsolidatedYear] = useState<number | null>(null)
const [lastConsolidatedYearIndicator, setLastConsolidatedYearIndicator] = useState<number | null>(null)
const [open, setOpen] = useState(true); const [open, setOpen] = useState(true);
const handleOpen = () => setOpen(true); const handleOpen = () => setOpen(true);
@ -103,6 +104,13 @@ export default function Dashboard({ grossAnualGraph, grossAnualYears, grossMensa
setLastDataBrutaAnual(`${parseFloat(lastDataAnual).toFixed(3)}`) setLastDataBrutaAnual(`${parseFloat(lastDataAnual).toFixed(3)}`)
}, [grossMensalGraph, grossAnualGraph]) }, [grossMensalGraph, grossAnualGraph])
useEffect(() => {
if (costIndicator && costIndicator.length > 0) {
const lastYear = getLastConsolidatedYear(costIndicator, true)
setLastConsolidatedYearIndicator(lastYear)
}
}, [costIndicator])
return ( return (
<DashboardView> <DashboardView>
<Head> <Head>
@ -153,10 +161,13 @@ export default function Dashboard({ grossAnualGraph, grossAnualYears, grossMensa
<GraphCard title='Indicador de Custo' subtitle='Indicador de Custo - Valores em R$/MWh'> <GraphCard title='Indicador de Custo' subtitle='Indicador de Custo - Valores em R$/MWh'>
<CostIndicatorChart title='' subtitle='' <CostIndicatorChart title='' subtitle=''
data1={costIndicator?.filter((value, index) => value?.mes.slice(0, 4).includes(costIndicator[0].mes.slice(0, 4))).map(value => value?.custo_unit && !!parseInt(value?.custo_unit) ? value.custo_unit : null)} data1={costIndicator
data2={costIndicator?.filter((value, index) => value?.mes.slice(0, 4).includes(costIndicator[costIndicator.length - 1].mes.slice(0, 4))).map(value => value?.custo_unit && !!parseInt(value?.custo_unit) ? value.custo_unit : null)} ?.filter(value => value?.mes?.slice(0, 4) === (lastConsolidatedYearIndicator ? (lastConsolidatedYearIndicator - 1).toString() : ''))
// years={[costIndicator[0].mes.slice(0, 4), costIndicator[costIndicator.length - 1].mes.slice(0, 4)]} .map(value => value?.custo_unit && !!parseFloat(value?.custo_unit) ? value.custo_unit : null)}
years={[previousYear+'', currentYear+'']} data2={costIndicator
?.filter(value => value?.mes?.slice(0, 4) === (lastConsolidatedYearIndicator ? lastConsolidatedYearIndicator.toString() : ''))
.map(value => value?.custo_unit && !!parseFloat(value?.custo_unit) ? value.custo_unit : null)}
years={[lastConsolidatedYearIndicator ? (lastConsolidatedYearIndicator - 1).toString() : '', lastConsolidatedYearIndicator?.toString() || '']}
label={months} label={months}
miniature miniature
/> />

View File

@ -33,6 +33,7 @@ export default function economy({ userName, anual, years, brutaMensal, catLiv, c
const [catLivDataState, setCatLivDataState] = useState(null); const [catLivDataState, setCatLivDataState] = useState(null);
const [indicatorDataState, setIndicatorDataState] = useState(null); const [indicatorDataState, setIndicatorDataState] = useState(null);
const [lastConsolidatedYearIndicator, setLastConsolidatedYearIndicator] = useState<number | null>(null);
const [processedBrutaMensal, setProcessedBrutaMensal] = useState(brutaMensal) const [processedBrutaMensal, setProcessedBrutaMensal] = useState(brutaMensal)
const [lastConsolidatedYear, setLastConsolidatedYear] = useState<number | null>(null) const [lastConsolidatedYear, setLastConsolidatedYear] = useState<number | null>(null)
@ -110,6 +111,14 @@ export default function economy({ userName, anual, years, brutaMensal, catLiv, c
getChartsWithUnity() getChartsWithUnity()
}, [unity]) }, [unity])
useEffect(() => {
if (indicatorDataState && indicatorDataState.length > 0) {
// Determine last consolidated year for cost indicator data (requires dad_estimado === false and custo_unit > 0)
const lastYear = getLastConsolidatedYear(indicatorDataState, true)
setLastConsolidatedYearIndicator(lastYear)
}
}, [indicatorDataState])
return ( return (
<main style={{ width: '100%' }}> <main style={{ width: '100%' }}>
<Head> <Head>
@ -223,9 +232,13 @@ export default function economy({ userName, anual, years, brutaMensal, catLiv, c
</div> </div>
<section> <section>
<CostIndicatorChart title='' subtitle='' <CostIndicatorChart title='' subtitle=''
data1={indicatorDataState?.filter(value => value?.mes.slice(0, 4).includes(previousYear)).map(value => value?.custo_unit && !!parseInt(value?.custo_unit) ? value.custo_unit : null)} data1={indicatorDataState?.
data2={indicatorDataState?.filter(value => value?.mes.slice(0, 4).includes(currentYear)).map(value => value?.custo_unit && !!parseInt(value?.custo_unit) ? value.custo_unit : null)} filter(value => value?.mes?.slice(0, 4) === (lastConsolidatedYearIndicator ? (lastConsolidatedYearIndicator - 1).toString() : ''))
years={[previousYear+'', currentYear+'']} .map(value => value?.custo_unit && !!parseFloat(value?.custo_unit) ? value.custo_unit : null)}
data2={indicatorDataState?.
filter(value => value?.mes?.slice(0, 4) === (lastConsolidatedYearIndicator ? lastConsolidatedYearIndicator.toString() : ''))
.map(value => value?.custo_unit && !!parseFloat(value?.custo_unit) ? value.custo_unit : null)}
years={[lastConsolidatedYearIndicator ? (lastConsolidatedYearIndicator - 1).toString() : '', lastConsolidatedYearIndicator?.toString() || '']}
label={months} label={months}
/> />
</section> </section>

View File

@ -87,7 +87,7 @@ export default function ForgotPassword() {
<legend className="text">Ou</legend> <legend className="text">Ou</legend>
</fieldset> </fieldset>
<p><a href='tel:+55(41) 3012-5900' >+55(41) 3012-5900</a><br/><a href='https://www.energiasmart.com.br' >www.energiasmart.com.br</a></p> <p><a href='tel:+55(41) 3012-5900' >+55(41) 3012-5900</a><br/><a href='https://www.smartenergia.com.br' >www.smartenergia.com.br</a></p>
</ForgotPasswordContainer> </ForgotPasswordContainer>
</ForgotPasswordView> </ForgotPasswordView>

View File

@ -197,11 +197,11 @@ export default function Home() {
<a href="tel:+55(41) 3012-5900">+55(41) 3012-5900</a> <a href="tel:+55(41) 3012-5900">+55(41) 3012-5900</a>
<br /> <br />
<a <a
href="https://www.energiasmart.com.br" href="https://www.smartenergia.com.br"
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
> >
www.energiasmart.com.br www.smartenergia.com.br
</a> </a>
</p> </p>
</LoginContainer> </LoginContainer>

View File

@ -45,7 +45,7 @@ export default function aboutUs({userName, news}: any) {
</> </>
}) })
} }
<a href='https://www.energiasmart.com.br/noticias/' <a href='https://www.smartenergia.com.br/noticias/'
target={"_blank"} target={"_blank"}
rel={"noreferrer"}>Ver todas as notícias</a> rel={"noreferrer"}>Ver todas as notícias</a>

View File

@ -173,7 +173,7 @@ export default function VerifyEmail() {
<legend className="text">Ou</legend> <legend className="text">Ou</legend>
</fieldset> </fieldset>
<p><a href='tel:+55(41)3012-5900' >+55(41) 3012-5900</a><br/><a href='https://www.energiasmart.com.br' >www.energiasmart.com.br</a></p> <p><a href='tel:+55(41)3012-5900' >+55(41) 3012-5900</a><br/><a href='https://www.smartenergia.com.br' >www.smartenergia.com.br</a></p>
</VerifyEmailContainer> </VerifyEmailContainer>
</VerifyEmailView> </VerifyEmailView>

View File

@ -18,11 +18,11 @@ export default function getAPIClient(
const { '@smartAuth-token': token } = parseCookies(ctx) const { '@smartAuth-token': token } = parseCookies(ctx)
const api = axios.create({ const api = axios.create({
// baseURL: 'https://api.energiasmart.com.br/api' // baseURL: 'https://api.smartenergia.com.br/api'
// baseURL: 'https://api.energiasmart.klupp.com.br/api' // baseURL: 'https://api.smartenergia.klupp.com.br/api'
baseURL: baseURL:
process.env.NODE_ENV === 'production' process.env.NODE_ENV === 'production'
? 'https://api.energiasmart.com.br/api' ? 'https://api.smartenergia.com.br/api'
: 'http://127.0.0.1:8000/api' : 'http://127.0.0.1:8000/api'
}) })

View File

@ -49,8 +49,21 @@ export function getLastConsolidatedYear(data: EconomyData[], isMonthly: boolean
return new Date().getFullYear(); return new Date().getFullYear();
} }
// Filter only consolidated data (dad_estimado === false) // Filter only consolidated data (dad_estimado === false explicitly)
const consolidatedData = data.filter(item => !item.dad_estimado); // Also ensure the entry has valid data (not just a date placeholder)
// For cost indicator data, also check that custo_unit is not zero
const consolidatedData = data.filter(item => {
if (item.dad_estimado !== false) return false;
// If custo_unit exists, it must be > 0 to be considered consolidated
if (item.custo_unit !== undefined) {
const costValue = parseFloat(item.custo_unit);
return !isNaN(costValue) && costValue > 0;
}
// For other data types, check if they have valid data fields
return item.economia_acumulada !== undefined || item.economia_mensal !== undefined;
});
// Extract all years present in the dataset (consolidated + estimated) // Extract all years present in the dataset (consolidated + estimated)
const allYears = data const allYears = data