// ═══════════════════════════════════════════════════════════════════════════ // LandveX Finance — Journal View // ═══════════════════════════════════════════════════════════════════════════ export const Journal = { async render(app) { app.render(`

Verifikationer

`); document.getElementById('btn-new-entry').addEventListener('click', () => { this.showEntryForm(app); }); try { const data = await app.api.get('/journal?fiscal_year=2026&period=2026-06'); this.renderJournal(data, app); } catch (e) { document.getElementById('journal-content').innerHTML = `

Fel: ${e.message}

`; } }, renderJournal(data, app) { if (!data.ok || !data.entries) return; document.getElementById('journal-content').innerHTML = `
${data.entries.slice(0, 50).map(e => ` `).join('')}
Nr Datum Beskrivning Belopp Status
#${e.entry_number || '—'} ${e.entry_date?.split('T')[0] || ''} ${e.description} ${this.fmt(e.total_amount || 0)} ${e.status}
${data.entries.length > 50 ? `

Visar 50 av ${data.entries.length} verifikationer

` : ''} `; // Click handlers document.querySelectorAll('#journal-content tbody tr').forEach(tr => { tr.addEventListener('click', () => { const id = tr.dataset.id; this.showEntryDetail(id, app); }); }); }, showEntryForm(app) { document.getElementById('journal-content').innerHTML = `
`; document.getElementById('btn-cancel').addEventListener('click', () => { this.render(app); }); document.getElementById('entry-form').addEventListener('submit', async (e) => { e.preventDefault(); const form = e.target; const lines = []; form.querySelectorAll('.line-row').forEach(row => { const account = row.querySelector('[name="account"]').value; const debit = parseFloat(row.querySelector('[name="debit"]').value) || 0; const credit = parseFloat(row.querySelector('[name="credit"]').value) || 0; if (account && (debit || credit)) { lines.push({ account_number: account, debit, credit, description: '' }); } }); const payload = { entry_date: form.entry_date.value, description: form.description.value, reference: form.reference.value, lines }; try { await app.api.post('/journal', payload); alert('Verifikation sparad!'); this.render(app); } catch (err) { alert('Fel: ' + (err.data?.error || err.message)); } }); }, async showEntryDetail(id, app) { try { const data = await app.api.get(`/journal/${id}`); if (!data.ok) return; const e = data.entry; document.getElementById('journal-content').innerHTML = `

Verifikation #${e.entry_number}

${e.description}

${e.status}
Datum: ${e.entry_date?.split('T')[0]}
Referens: ${e.reference || '—'}
Skapad: ${e.created_at?.split('T')[0]}
Period: ${e.period}

Kontering

${data.lines.map(l => ` `).join('')}
KontoDebetKredit
${l.account_number} ${l.description || ''} ${l.debit ? this.fmt(l.debit) : ''} ${l.credit ? this.fmt(l.credit) : ''}
${e.status === 'draft' ? `
` : ''}
`; document.getElementById('btn-back').addEventListener('click', () => this.render(app)); if (e.status === 'draft') { document.getElementById('btn-post').addEventListener('click', async () => { try { await app.api.post(`/journal/${id}/post`); alert('Verifikation konterad!'); this.render(app); } catch (err) { alert('Fel: ' + (err.data?.error || err.message)); } }); } } catch (e) { console.error(e); } }, fmt(n) { return new Intl.NumberFormat('sv-SE', { minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(n); } };