v1.43.11 - Filtro de período personalizável em relatórios

This commit is contained in:
marcoitaloesp-ai 2025-12-16 16:47:03 +00:00 committed by GitHub
parent 30d58c375c
commit efbd5e8aa2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 73 additions and 5 deletions

View File

@ -5,6 +5,32 @@ O formato segue [Keep a Changelog](https://keepachangelog.com/pt-BR/).
Este projeto adota [Versionamento Semântico](https://semver.org/pt-BR/).
## [1.43.11] - 2025-12-16
### Added
- **Relatórios - Filtro de Período**
- Seletores de "Data Início" e "Data Fim" nos relatórios:
* Por Categoria
* Por Centro de Custo
* Maiores Gastos
- Período padrão: Início do ano (01/01/2025) até hoje (16/12/2025)
- Usuário pode alterar o período livremente
- Interface responsiva: campos lado a lado em desktop, empilhados em mobile
- Parâmetros `start_date` e `end_date` enviados à API
- Traduções:
* pt-BR: "Data Início", "Data Fim"
* en: "Start Date", "End Date"
* es: "Fecha Inicio", "Fecha Fin"
### Changed
- **Frontend - Reports.jsx**
- Estados `startDate` e `endDate` adicionados
- useEffect atualizado com dependências `startDate` e `endDate`
- Parâmetros de data incluídos em:
* `reportService.getByCategory()`
* `reportService.getByCostCenter()`
* `reportService.getTopExpenses()`
## [1.43.10] - 2025-12-16
### Fixed

View File

@ -1 +1 @@
1.43.10
1.43.11

View File

@ -1841,6 +1841,8 @@
"overdue": "Overdue",
"savingsRate": "Savings Rate",
"selectPeriod": "Select Period",
"startDate": "Start Date",
"endDate": "End Date",
"subtitle": "Detailed analysis of your finances",
"summary": "Summary",
"thisMonth": "This Month",

View File

@ -1806,6 +1806,8 @@
"accounts": "Por Cuenta",
"period": "Período",
"selectPeriod": "Seleccionar período",
"startDate": "Fecha Inicio",
"endDate": "Fecha Fin",
"thisMonth": "Este mes",
"lastMonth": "Mes anterior",
"last3Months": "Últimos 3 meses",

View File

@ -1847,6 +1847,8 @@
"overdue": "Vencidas",
"savingsRate": "Taxa de Poupança",
"selectPeriod": "Selecionar Período",
"startDate": "Data Início",
"endDate": "Data Fim",
"subtitle": "Análise detalhada das suas finanças",
"summary": "Resumo",
"thisMonth": "Este Mês",

View File

@ -49,6 +49,10 @@ const Reports = () => {
const [year, setYear] = useState(new Date().getFullYear());
const [months, setMonths] = useState(12);
// Date range filters (default: start of year to today)
const [startDate, setStartDate] = useState(new Date(new Date().getFullYear(), 0, 1).toISOString().split('T')[0]);
const [endDate, setEndDate] = useState(new Date().toISOString().split('T')[0]);
// Data states
const [summary, setSummary] = useState(null);
const [categoryData, setCategoryData] = useState(null);
@ -76,7 +80,7 @@ const Reports = () => {
setSummary(summaryRes);
break;
case 'category':
const params = { type: 'debit' };
const params = { type: 'debit', start_date: startDate, end_date: endDate };
if (selectedCategory) {
params.parent_id = selectedCategory.category_id;
}
@ -92,7 +96,7 @@ const Reports = () => {
setDayOfWeekData(dowRes);
break;
case 'topExpenses':
const topRes = await reportService.getTopExpenses({ limit: 20 });
const topRes = await reportService.getTopExpenses({ limit: 20, start_date: startDate, end_date: endDate });
setTopExpenses(topRes);
break;
case 'projection':
@ -104,7 +108,7 @@ const Reports = () => {
setComparison(compRes);
break;
case 'costCenter':
const ccParams = {};
const ccParams = { start_date: startDate, end_date: endDate };
if (selectedCostCenter) {
ccParams.cost_center_id = selectedCostCenter.id ?? 0;
}
@ -136,7 +140,7 @@ const Reports = () => {
} finally {
setLoading(false);
}
}, [activeTab, year, months, selectedCategory, selectedCostCenter, selectedCostCenterCategory]);
}, [activeTab, year, months, selectedCategory, selectedCostCenter, selectedCostCenterCategory, startDate, endDate]);
useEffect(() => {
loadData();
@ -2148,6 +2152,38 @@ const Reports = () => {
{t('reports.subtitle')}
</p>
</div>
{/* Date Range Filters */}
{(activeTab === 'category' || activeTab === 'costCenter' || activeTab === 'topExpenses') && (
<div className={`d-flex ${isMobile ? 'flex-column w-100' : 'gap-2 align-items-center'}`}>
<div className={`d-flex ${isMobile ? 'w-100 mb-2' : ''} gap-2`}>
<div className={isMobile ? 'flex-grow-1' : ''}>
<label className="text-slate-400 mb-1 d-block" style={{ fontSize: '0.75rem' }}>
{t('reports.startDate')}
</label>
<input
type="date"
className="form-control form-control-sm bg-slate-800 text-white border-slate-700"
value={startDate}
onChange={(e) => setStartDate(e.target.value)}
style={{ fontSize: isMobile ? '0.875rem' : '0.875rem' }}
/>
</div>
<div className={isMobile ? 'flex-grow-1' : ''}>
<label className="text-slate-400 mb-1 d-block" style={{ fontSize: '0.75rem' }}>
{t('reports.endDate')}
</label>
<input
type="date"
className="form-control form-control-sm bg-slate-800 text-white border-slate-700"
value={endDate}
onChange={(e) => setEndDate(e.target.value)}
style={{ fontSize: isMobile ? '0.875rem' : '0.875rem' }}
/>
</div>
</div>
</div>
)}
</div>
{/* Tabs */}