// static/admin/js/billing-history.js // noqa: JS-003 - Uses ...baseData which is data() with safety check const billingLog = window.LogConfig?.loggers?.billingHistory || console; function adminBillingHistory() { // Get base data with safety check for standalone usage const baseData = typeof data === 'function' ? data() : {}; return { // Inherit base layout functionality from init-alpine.js ...baseData, // Page-specific state currentPage: 'billing-history', loading: true, error: null, successMessage: null, // Data invoices: [], vendors: [], statusCounts: { paid: 0, open: 0, draft: 0, uncollectible: 0, void: 0 }, // Filters filters: { vendor_id: '', status: '' }, // Pagination pagination: { page: 1, per_page: 20, total: 0, pages: 0 }, // Sorting sortBy: 'invoice_date', sortOrder: 'desc', // Computed: Total pages get totalPages() { return this.pagination.pages; }, // Computed: Start index for pagination display get startIndex() { if (this.pagination.total === 0) return 0; return (this.pagination.page - 1) * this.pagination.per_page + 1; }, // Computed: End index for pagination display get endIndex() { const end = this.pagination.page * this.pagination.per_page; return end > this.pagination.total ? this.pagination.total : end; }, // Computed: Page numbers for pagination get pageNumbers() { const pages = []; const totalPages = this.totalPages; const current = this.pagination.page; if (totalPages <= 7) { for (let i = 1; i <= totalPages; i++) { pages.push(i); } } else { pages.push(1); if (current > 3) { pages.push('...'); } const start = Math.max(2, current - 1); const end = Math.min(totalPages - 1, current + 1); for (let i = start; i <= end; i++) { pages.push(i); } if (current < totalPages - 2) { pages.push('...'); } pages.push(totalPages); } return pages; }, async init() { // Guard against multiple initialization if (window._adminBillingHistoryInitialized) { billingLog.warn('Already initialized, skipping'); return; } window._adminBillingHistoryInitialized = true; billingLog.info('=== BILLING HISTORY PAGE INITIALIZING ==='); // Load platform settings for rows per page if (window.PlatformSettings) { this.pagination.per_page = await window.PlatformSettings.getRowsPerPage(); } await this.loadVendors(); await this.loadInvoices(); }, async refresh() { this.error = null; this.successMessage = null; await this.loadInvoices(); }, async loadVendors() { try { const data = await apiClient.get('/admin/vendors?limit=1000'); this.vendors = data.vendors || []; billingLog.info(`Loaded ${this.vendors.length} vendors for filter`); } catch (error) { billingLog.error('Failed to load vendors:', error); } }, async loadInvoices() { this.loading = true; this.error = null; try { const params = new URLSearchParams(); params.append('page', this.pagination.page); params.append('per_page', this.pagination.per_page); if (this.filters.vendor_id) params.append('vendor_id', this.filters.vendor_id); if (this.filters.status) params.append('status', this.filters.status); if (this.sortBy) params.append('sort_by', this.sortBy); if (this.sortOrder) params.append('sort_order', this.sortOrder); const data = await apiClient.get(`/admin/subscriptions/billing/history?${params}`); this.invoices = data.invoices || []; this.pagination.total = data.total; this.pagination.pages = data.pages; // Count by status (from loaded data for approximation) this.updateStatusCounts(); billingLog.info(`Loaded ${this.invoices.length} invoices (total: ${this.pagination.total})`); } catch (error) { billingLog.error('Failed to load invoices:', error); this.error = error.message || 'Failed to load billing history'; } finally { this.loading = false; } }, handleSort(key) { if (this.sortBy === key) { this.sortOrder = this.sortOrder === 'asc' ? 'desc' : 'asc'; } else { this.sortBy = key; this.sortOrder = 'asc'; } this.pagination.page = 1; this.loadInvoices(); }, updateStatusCounts() { // Reset counts this.statusCounts = { paid: 0, open: 0, draft: 0, uncollectible: 0, void: 0 }; // Count from current page (approximation) for (const invoice of this.invoices) { if (this.statusCounts[invoice.status] !== undefined) { this.statusCounts[invoice.status]++; } } }, resetFilters() { this.filters = { vendor_id: '', status: '' }; this.pagination.page = 1; this.loadInvoices(); }, previousPage() { if (this.pagination.page > 1) { this.pagination.page--; this.loadInvoices(); } }, nextPage() { if (this.pagination.page < this.totalPages) { this.pagination.page++; this.loadInvoices(); } }, goToPage(pageNum) { if (pageNum !== '...' && pageNum >= 1 && pageNum <= this.totalPages) { this.pagination.page = pageNum; this.loadInvoices(); } }, formatDate(dateStr) { if (!dateStr) return '-'; return new Date(dateStr).toLocaleDateString('de-LU', { year: 'numeric', month: 'short', day: 'numeric' }); }, formatCurrency(cents) { if (cents === null || cents === undefined) return '-'; return new Intl.NumberFormat('de-LU', { style: 'currency', currency: 'EUR' }).format(cents / 100); } }; } billingLog.info('Billing history module loaded');