Automated Expense Categorization Tool

Manage Categories

    Manage Automation Rules (Keywords)

    Keywords help automatically suggest a category for new expenses. Saved in your browser.

    Add New Expense

    $

    Current Session Expenses

    No expenses added for this session yet. Entered expenses are for the current session and will be cleared if you close or refresh the page unless saved by PDF.

    Expense Summary by Category

    No expenses categorized to generate a summary.

    No categories defined.

    `; } pdfHtml += `
    `; // Close aect-pdf-output const pdfOutputEl = toolContainer.querySelector('#aect-pdfOutput'); pdfOutputEl.innerHTML = pdfHtml; const opt = { margin: [0.5, 0.5, 0.5, 0.5], // top, left, bottom, right in inches filename: `Expense_Categorization_Report_${new Date().toISOString().slice(0,10)}.pdf`, image: { type: 'jpeg', quality: 0.98 }, html2canvas: { scale: 2, useCORS: true, logging: false, width: pdfOutputEl.scrollWidth, height: pdfOutputEl.scrollHeight + 20 }, jsPDF: { unit: 'in', format: 'letter', orientation: 'portrait' }, pagebreak: { mode: ['avoid-all', 'css', 'legacy'] } }; html2pdf().from(pdfOutputEl).set(opt).save(); }); // --- Tab Navigation --- window.aect_openTab = function(evt, tabName) { tabs.forEach(tab => tab.style.display = 'none'); tabLinks.forEach(link => link.classList.remove('active')); const activeTabContent = toolContainer.querySelector('#' + tabName); if(activeTabContent) activeTabContent.style.display = 'block'; let clickedIndex = -1; if (evt && evt.currentTarget) { evt.currentTarget.classList.add('active'); tabLinks.forEach((link, index) => { if (link === evt.currentTarget) clickedIndex = index; }); } else { // For direct calls (e.g. init) tabLinks.forEach((link, index) => { if (link.getAttribute('onclick').includes(tabName)) { link.classList.add('active'); clickedIndex = index; } }); } currentTabIndex = clickedIndex !== -1 ? clickedIndex : 0; aect_updateNavButtons(); } window.aect_navigateTab = function(direction) { let newIndex = currentTabIndex; if (direction === 'next' && currentTabIndex < tabs.length - 1) { newIndex++; } else if (direction === 'prev' && currentTabIndex > 0) { newIndex--; } if (tabLinks[newIndex]) { // Check if the link exists tabLinks[newIndex].click(); // Simulate click to trigger openTab and update currentTabIndex correctly } } function aect_updateNavButtons() { prevButton.disabled = currentTabIndex === 0; nextButton.disabled = currentTabIndex === tabs.length - 1; } // --- Initialization --- function initializeTool() { loadFromLocalStorage(); renderCategoriesList(); populateCategorySelects(); renderExpensesTable(); // Show empty state initially renderSummaryReport(); // Show empty state initially expenseDateEl.valueAsDate = new Date(); // Default date to today aect_openTab(null, 'aect-tab1'); // Open first tab by default } initializeTool(); })();
    Scroll to Top