aggrid
This commit is contained in:
@@ -110,14 +110,48 @@ const getJTLTransactions = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
// Get transactions for a specific month
|
||||
router.get('/transactions/:monthYear', authenticateToken, async (req, res) => {
|
||||
// Get transactions for a specific time period (month, quarter, or year)
|
||||
router.get('/transactions/:timeRange', authenticateToken, async (req, res) => {
|
||||
try {
|
||||
const { monthYear } = req.params;
|
||||
const { timeRange } = req.params;
|
||||
const transactions = parseCSV();
|
||||
|
||||
const monthTransactions = transactions
|
||||
.filter(t => t.monthYear === monthYear)
|
||||
let filteredTransactions = [];
|
||||
let periodDescription = '';
|
||||
|
||||
if (timeRange.includes('-Q')) {
|
||||
// Quarter format: YYYY-Q1, YYYY-Q2, etc.
|
||||
const [year, quarterPart] = timeRange.split('-Q');
|
||||
const quarter = parseInt(quarterPart);
|
||||
const startMonth = (quarter - 1) * 3 + 1;
|
||||
const endMonth = startMonth + 2;
|
||||
|
||||
filteredTransactions = transactions.filter(t => {
|
||||
if (!t.monthYear) return false;
|
||||
const [tYear, tMonth] = t.monthYear.split('-');
|
||||
const monthNum = parseInt(tMonth);
|
||||
return tYear === year && monthNum >= startMonth && monthNum <= endMonth;
|
||||
});
|
||||
|
||||
periodDescription = `Q${quarter} ${year}`;
|
||||
} else if (timeRange.length === 4) {
|
||||
// Year format: YYYY
|
||||
filteredTransactions = transactions.filter(t => {
|
||||
if (!t.monthYear) return false;
|
||||
const [tYear] = t.monthYear.split('-');
|
||||
return tYear === timeRange;
|
||||
});
|
||||
|
||||
periodDescription = `Jahr ${timeRange}`;
|
||||
} else {
|
||||
// Month format: YYYY-MM
|
||||
filteredTransactions = transactions.filter(t => t.monthYear === timeRange);
|
||||
const [year, month] = timeRange.split('-');
|
||||
const date = new Date(year, month - 1);
|
||||
periodDescription = date.toLocaleDateString('de-DE', { month: 'long', year: 'numeric' });
|
||||
}
|
||||
|
||||
const monthTransactions = filteredTransactions
|
||||
.sort((a, b) => b.parsedDate - a.parsedDate); // Newest first
|
||||
|
||||
// Get JTL transactions for comparison
|
||||
@@ -128,13 +162,34 @@ router.get('/transactions/:monthYear', authenticateToken, async (req, res) => {
|
||||
console.log('JTL database not available, continuing without JTL data');
|
||||
}
|
||||
|
||||
// Filter JTL transactions for the selected month
|
||||
const [year, month] = monthYear.split('-');
|
||||
const jtlMonthTransactions = jtlTransactions.filter(jtl => {
|
||||
const jtlDate = new Date(jtl.dBuchungsdatum);
|
||||
return jtlDate.getFullYear() === parseInt(year) &&
|
||||
jtlDate.getMonth() === parseInt(month) - 1;
|
||||
});
|
||||
// Filter JTL transactions for the selected time period
|
||||
let jtlMonthTransactions = [];
|
||||
|
||||
if (timeRange.includes('-Q')) {
|
||||
const [year, quarterPart] = timeRange.split('-Q');
|
||||
const quarter = parseInt(quarterPart);
|
||||
const startMonth = (quarter - 1) * 3 + 1;
|
||||
const endMonth = startMonth + 2;
|
||||
|
||||
jtlMonthTransactions = jtlTransactions.filter(jtl => {
|
||||
const jtlDate = new Date(jtl.dBuchungsdatum);
|
||||
const jtlMonth = jtlDate.getMonth() + 1; // 0-based to 1-based
|
||||
return jtlDate.getFullYear() === parseInt(year) &&
|
||||
jtlMonth >= startMonth && jtlMonth <= endMonth;
|
||||
});
|
||||
} else if (timeRange.length === 4) {
|
||||
jtlMonthTransactions = jtlTransactions.filter(jtl => {
|
||||
const jtlDate = new Date(jtl.dBuchungsdatum);
|
||||
return jtlDate.getFullYear() === parseInt(timeRange);
|
||||
});
|
||||
} else {
|
||||
const [year, month] = timeRange.split('-');
|
||||
jtlMonthTransactions = jtlTransactions.filter(jtl => {
|
||||
const jtlDate = new Date(jtl.dBuchungsdatum);
|
||||
return jtlDate.getFullYear() === parseInt(year) &&
|
||||
jtlDate.getMonth() === parseInt(month) - 1;
|
||||
});
|
||||
}
|
||||
|
||||
// Add JTL status to each CSV transaction
|
||||
const transactionsWithJTL = monthTransactions.map(transaction => {
|
||||
@@ -199,7 +254,7 @@ router.get('/transactions/:monthYear', authenticateToken, async (req, res) => {
|
||||
'Betrag': jtl.fBetrag ? jtl.fBetrag.toString().replace('.', ',') : '0,00',
|
||||
numericAmount: parseFloat(jtl.fBetrag) || 0,
|
||||
parsedDate: new Date(jtl.dBuchungsdatum),
|
||||
monthYear: monthYear,
|
||||
monthYear: timeRange,
|
||||
hasJTL: true,
|
||||
jtlId: jtl.kZahlungsabgleichUmsatz,
|
||||
isFromCSV: false,
|
||||
@@ -229,7 +284,8 @@ router.get('/transactions/:monthYear', authenticateToken, async (req, res) => {
|
||||
res.json({
|
||||
transactions: allTransactions,
|
||||
summary,
|
||||
monthYear
|
||||
timeRange,
|
||||
periodDescription
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error getting transactions:', error);
|
||||
@@ -290,25 +346,61 @@ const quote = (str, maxLen = 60) => {
|
||||
};
|
||||
|
||||
// DATEV export endpoint
|
||||
router.get('/datev/:monthYear', authenticateToken, async (req, res) => {
|
||||
router.get('/datev/:timeRange', authenticateToken, async (req, res) => {
|
||||
try {
|
||||
const { monthYear } = req.params;
|
||||
const [year, month] = monthYear.split('-');
|
||||
const { timeRange } = req.params;
|
||||
|
||||
// Get transactions for the month
|
||||
// Get transactions for the time period
|
||||
const transactions = parseCSV();
|
||||
const monthTransactions = transactions
|
||||
.filter(t => t.monthYear === monthYear)
|
||||
let filteredTransactions = [];
|
||||
let periodStart, periodEnd, filename;
|
||||
|
||||
if (timeRange.includes('-Q')) {
|
||||
// Quarter format: YYYY-Q1, YYYY-Q2, etc.
|
||||
const [year, quarterPart] = timeRange.split('-Q');
|
||||
const quarter = parseInt(quarterPart);
|
||||
const startMonth = (quarter - 1) * 3 + 1;
|
||||
const endMonth = startMonth + 2;
|
||||
|
||||
filteredTransactions = transactions.filter(t => {
|
||||
if (!t.monthYear) return false;
|
||||
const [tYear, tMonth] = t.monthYear.split('-');
|
||||
const monthNum = parseInt(tMonth);
|
||||
return tYear === year && monthNum >= startMonth && monthNum <= endMonth;
|
||||
});
|
||||
|
||||
periodStart = `${year}${startMonth.toString().padStart(2, '0')}01`;
|
||||
periodEnd = new Date(year, endMonth, 0).toISOString().slice(0, 10).replace(/-/g, '');
|
||||
filename = `DATEV_${year}_Q${quarter}.csv`;
|
||||
} else if (timeRange.length === 4) {
|
||||
// Year format: YYYY
|
||||
filteredTransactions = transactions.filter(t => {
|
||||
if (!t.monthYear) return false;
|
||||
const [tYear] = t.monthYear.split('-');
|
||||
return tYear === timeRange;
|
||||
});
|
||||
|
||||
periodStart = `${timeRange}0101`;
|
||||
periodEnd = `${timeRange}1231`;
|
||||
filename = `DATEV_${timeRange}.csv`;
|
||||
} else {
|
||||
// Month format: YYYY-MM
|
||||
const [year, month] = timeRange.split('-');
|
||||
filteredTransactions = transactions.filter(t => t.monthYear === timeRange);
|
||||
|
||||
periodStart = `${year}${month.padStart(2, '0')}01`;
|
||||
periodEnd = new Date(year, month, 0).toISOString().slice(0, 10).replace(/-/g, '');
|
||||
filename = `DATEV_${year}_${month.padStart(2, '0')}.csv`;
|
||||
}
|
||||
|
||||
const monthTransactions = filteredTransactions
|
||||
.sort((a, b) => a.parsedDate - b.parsedDate); // Oldest first for DATEV
|
||||
|
||||
if (!monthTransactions.length) {
|
||||
return res.status(404).json({ error: 'No transactions found for this month' });
|
||||
return res.status(404).json({ error: 'No transactions found for this time period' });
|
||||
}
|
||||
|
||||
// Build DATEV format
|
||||
const periodStart = `${year}${month.padStart(2, '0')}01`;
|
||||
const periodEnd = new Date(year, month, 0).toISOString().slice(0, 10).replace(/-/g, '');
|
||||
|
||||
const header = buildDatevHeader(periodStart, periodEnd);
|
||||
|
||||
const rows = monthTransactions.map((transaction, index) => {
|
||||
@@ -335,7 +427,6 @@ router.get('/datev/:monthYear', authenticateToken, async (req, res) => {
|
||||
const csv = [header, DATEV_COLS, ...rows].join('\r\n');
|
||||
|
||||
// Set headers for file download
|
||||
const filename = `DATEV_${year}_${month.padStart(2, '0')}.csv`;
|
||||
res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
|
||||
res.setHeader('Content-Type', 'text/csv; charset=latin1');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user