Total Owners
โ€”
Total Properties
โ€”
Statements This Month
โ€”
Statements Saved
โ€”

Your Owners

๐Ÿ‘ค

No owners yet.

Go to Owners & Properties to add your first owner.

Recent Statements

๐Ÿ“‹

No statements saved yet.

`); w.document.close(); } function markSent(id) { const stmt = savedStatements.find(s=>s.id===id); if (!stmt) return; stmt.sentAt = new Date().toISOString(); saveAll(); renderArchive(); toast('๐Ÿ“ง Marked as sent!'); } function deleteStmt(id) { if (!confirm('Delete this statement from the archive?')) return; savedStatements = savedStatements.filter(s=>s.id!==id); saveAll(); renderArchive(); toast('Statement deleted.'); } // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• // RENT AUTO-SYNC FROM TENANT PORTAL // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• function syncRentFromTenantPortal() { // Pull payments from rv_accounting (tenant portal / accounting module) let acctTx = []; try { acctTx = JSON.parse(localStorage.getItem('rv_accounting') || '[]'); } catch(e){} const rentTx = acctTx.filter(t => t.type==='income' && t.category==='Rent Payment'); let added = 0; rentTx.forEach(tx => { // Try to match to an owner's property by address const month = tx.date.slice(0,7); owners.forEach(owner => { (owner.properties||[]).forEach(prop => { const propKey = prop.address.toLowerCase().slice(0,10); const txProp = (tx.property||'').toLowerCase(); if (txProp.includes(propKey.slice(0,8))) { // Check not already entered const exists = expenses.find(e=>e.ownerId===owner.id&&e.propId===prop.id&&e.month===month&&e.type==='rent'&&Math.abs(e.amount-tx.amount)<1); if (!exists) { expenses.push({ id:uid(), ownerId:owner.id, propId:prop.id, month, type:'rent', category:'Rent Payment', amount:tx.amount, notes:'Auto-synced from tenant portal', date:tx.date }); added++; } } }); }); }); if (added > 0) { saveAll(); renderExpTable(); toast(`โœ… Synced ${added} rent payment(s) from tenant portal!`); } else toast('โ„น๏ธ No new rent payments to sync.'); } // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• // HELPERS // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• function propTypeIcon(type) { if (type === 'commercial') return '๐Ÿข'; if (type === 'rent-to-own') return '๐Ÿ”‘'; return '๐Ÿ '; } function propTypeBadge(type) { if (type === 'commercial') return 'COMMERCIAL'; if (type === 'rent-to-own') return 'RENT-TO-OWN'; return 'RESIDENTIAL'; } function fmtDollar(n) { return '$' + Math.abs(n).toLocaleString('en-US',{minimumFractionDigits:2,maximumFractionDigits:2}); } function fmtMonth(m) { if (!m) return ''; const [y,mo] = m.split('-'); const d = new Date(parseInt(y), parseInt(mo)-1, 1); return d.toLocaleDateString('en-US',{month:'long',year:'numeric'}); } function toast(msg) { const el = document.getElementById('os-toast'); el.textContent = msg; el.classList.add('show'); setTimeout(()=>el.classList.remove('show'), 3000); } // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• // INIT // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• document.addEventListener('DOMContentLoaded', () => { loadAll(); refreshDashboard(); // Close modal on overlay click document.getElementById('prop-modal-overlay').addEventListener('click', e => { if (e.target === document.getElementById('prop-modal-overlay')) closePropModal(); }); });