Enter Transaction Details

Institutional Activity Report

Date Institution Symbol Activity Shares Price ($) Total Value ($)

Summary Statistics

Total Shares Bought: 0

Total Value Bought: $0.00

Total Shares Sold: 0

Total Value Sold: $0.00


Net Shares (Bought - Sold): 0

Net Value (Bought - Sold): $0.00

Error: Tool failed to initialize. Required elements are missing.

"; return false; } return true; } function ista_openTab(event, tabName) { if (!ista_tabContents || !ista_tabButtons) return; Array.from(ista_tabContents).forEach(tabcontent => { tabcontent.style.display = "none"; tabcontent.classList.remove("active"); }); Array.from(ista_tabButtons).forEach(tablink => { tablink.classList.remove("active"); }); const currentTabElement = document.getElementById(tabName); if (currentTabElement) { currentTabElement.style.display = "block"; currentTabElement.classList.add("active"); } if (event && event.currentTarget) { event.currentTarget.classList.add("active"); } // Update currentTab index based on tabName if (tabName === 'istaDataEntry') { ista_currentTab = 0; } else if (tabName === 'istaActivityReport') { ista_currentTab = 1; ista_renderActivityReport(); // Re-render report when switching to this tab } ista_updateNavigationButtons(); } function ista_updateNavigationButtons() { if (!ista_prevButtonElem || !ista_nextButtonElem || !ista_tabButtons) return; ista_prevButtonElem.disabled = (ista_currentTab === 0); ista_nextButtonElem.disabled = (ista_currentTab === ista_tabButtons.length - 1); } function ista_navigateTab(direction) { if (!ista_tabButtons) return; if (direction === 'next' && ista_currentTab < ista_tabButtons.length - 1) { ista_currentTab++; } else if (direction === 'prev' && ista_currentTab > 0) { ista_currentTab--; } // Simulate a click on the corresponding tab button if (ista_tabButtons[ista_currentTab]) { ista_tabButtons[ista_currentTab].click(); } } function ista_addTransaction() { if (!ista_institutionNameElem || !ista_securitySymbolElem || !ista_transactionDateElem || !ista_activityTypeElem || !ista_sharesElem || !ista_pricePerShareElem || !ista_formErrorElem) { console.error("ISTA Tool: Form elements not found for adding transaction."); return; } ista_formErrorElem.textContent = ''; // Clear previous errors const institutionName = ista_institutionNameElem.value.trim(); const securitySymbol = ista_securitySymbolElem.value.trim(); const transactionDate = ista_transactionDateElem.value; const activityType = ista_activityTypeElem.value; const shares = parseFloat(ista_sharesElem.value); const pricePerShare = parseFloat(ista_pricePerShareElem.value); // Basic Validation if (!institutionName || !securitySymbol || !transactionDate || !activityType || isNaN(shares) || shares <= 0 || isNaN(pricePerShare) || pricePerShare <= 0) { ista_formErrorElem.textContent = 'Please fill in all fields with valid data. Shares and Price must be positive numbers.'; return; } const totalValue = shares * pricePerShare; ista_transactions.push({ date: transactionDate, institution: institutionName, symbol: securitySymbol, activity: activityType, shares: shares, price: pricePerShare, totalValue: totalValue }); // Optional: Sort transactions by date (descending) after adding ista_transactions.sort((a, b) => new Date(b.date) - new Date(a.date)); ista_renderActivityReport(); document.getElementById('istaTransactionForm').reset(); // Reset form fields // Optionally, automatically switch to the report tab after adding a transaction // ista_navigateTab('next'); // or: ista_openTab(null, 'istaActivityReport'); // if you want direct jump without event // For now, let's keep the user on the input tab to add more. // Acknowledge addition (could be a temporary message) ista_formErrorElem.style.color = 'var(--success-color)'; ista_formErrorElem.textContent = 'Transaction added successfully!'; setTimeout(() => { if(ista_formErrorElem) { ista_formErrorElem.textContent = ''; ista_formErrorElem.style.color = 'var(--danger-color)'; // Reset color } }, 3000); } function ista_renderActivityReport() { if (!ista_activityTableBodyElem || !ista_totalSharesBoughtElem || !ista_totalValueBoughtElem || !ista_totalSharesSoldElem || !ista_totalValueSoldElem || !ista_netSharesElem || !ista_netValueElem) { console.error("ISTA Tool: Report elements not found for rendering."); return; } ista_activityTableBodyElem.innerHTML = ''; // Clear existing rows let totalSharesBought = 0; let totalValueBought = 0; let totalSharesSold = 0; let totalValueSold = 0; ista_transactions.forEach(tx => { const row = ista_activityTableBodyElem.insertRow(); row.insertCell().textContent = new Date(tx.date + 'T00:00:00').toLocaleDateString(); //Ensure date is treated as local row.insertCell().textContent = tx.institution; row.insertCell().textContent = tx.symbol; row.insertCell().textContent = tx.activity; row.insertCell().textContent = tx.shares.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 }); row.insertCell().textContent = tx.price.toLocaleString(undefined, { style: 'currency', currency: 'USD' }).replace('US$', ''); // Keep it consistent with $ input row.insertCell().textContent = tx.totalValue.toLocaleString(undefined, { style: 'currency', currency: 'USD' }).replace('US$', ''); if (tx.activity === 'Buy') { totalSharesBought += tx.shares; totalValueBought += tx.totalValue; } else if (tx.activity === 'Sell') { totalSharesSold += tx.shares; totalValueSold += tx.totalValue; } }); const netShares = totalSharesBought - totalSharesSold; const netValue = totalValueBought - totalValueSold; ista_totalSharesBoughtElem.textContent = totalSharesBought.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 }); ista_totalValueBoughtElem.textContent = `$${totalValueBought.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`; ista_totalSharesSoldElem.textContent = totalSharesSold.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 }); ista_totalValueSoldElem.textContent = `$${totalValueSold.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`; ista_netSharesElem.textContent = netShares.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 }); ista_netValueElem.textContent = `$${netValue.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`; } function ista_downloadPDF() { const { jsPDF } = window.jspdf; // Ensure jsPDF is accessed correctly from the window object const reportContent = document.getElementById('istaReportContent'); if (!reportContent) { console.error("ISTA Tool: Report content element not found for PDF generation."); alert("Error: Could not find report content to generate PDF."); return; } if (typeof html2canvas === 'undefined' || typeof jsPDF === 'undefined') { console.error("ISTA Tool: html2canvas or jsPDF is not loaded."); alert("Error: PDF generation libraries not loaded. Please check your internet connection or contact support."); return; } // Temporarily make all text black for better PDF readability if it was light on dark // This example assumes a light background for the report content by default. // If your report content has complex styling that needs to be preserved, test thoroughly. const originalStyles = {}; // To store original styles if changed // Example: If reportContent had a specific background that shouldn't be in PDF // originalStyles.backgroundColor = reportContent.style.backgroundColor; // reportContent.style.backgroundColor = '#ffffff'; // Force white background for PDF capture html2canvas(reportContent, { scale: 2, // Improve resolution useCORS: true, // If you have external images (not applicable here but good practice) onclone: (documentClone) => { // This function is called when html2canvas clones the document. // You can make temporary modifications to the cloned document before rendering. // For example, ensure all text is visible if it relies on background colors not captured well. // This example doesn't need complex modifications here as CSS handles visibility. } }).then(canvas => { const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'p', // portrait unit: 'mm', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = pdf.internal.pageSize.getHeight(); const canvasWidth = canvas.width; const canvasHeight = canvas.height; const ratio = canvasWidth / canvasHeight; let imgWidth = pdfWidth - 20; // pdfWidth minus margins let imgHeight = imgWidth / ratio; // If image height is too large for one page, you might need to split it or scale it down. // This basic example fits it to width and lets height adjust. // For multi-page, more complex logic would be needed. if (imgHeight > pdfHeight - 20) { // Check if it exceeds page height with margin imgHeight = pdfHeight - 20; imgWidth = imgHeight * ratio; } const x = (pdfWidth - imgWidth) / 2; // Center the image const y = 10; // Top margin pdf.addImage(imgData, 'PNG', x, y, imgWidth, imgHeight); pdf.save('Institutional_Activity_Report.pdf'); // Restore original styles if changed // reportContent.style.backgroundColor = originalStyles.backgroundColor; }).catch(error => { console.error("ISTA Tool: Error generating PDF:", error); alert("Error generating PDF. See console for details."); // Restore original styles in case of error too // reportContent.style.backgroundColor = originalStyles.backgroundColor; }); } // Initialize the tool after DOM is fully loaded document.addEventListener('DOMContentLoaded', function() { if (ista_initializeDOMElements()) { // Set default active tab and navigation buttons state ista_openTab(null, 'istaDataEntry'); // Open first tab by default } });
Scroll to Top