feat: add option to exclude year-end closing entries in SIE export and related reports (#567)

This commit is contained in:
Mattsson
2026-05-25 17:51:54 +02:00
committed by GitHub
parent aeadc8bb1d
commit 0087b7be3f
10 changed files with 57 additions and 6 deletions
+9 -1
View File
@@ -73,6 +73,7 @@ const LABELS = {
iban: 'IBAN:',
bic: 'BIC/SWIFT:',
ocr: 'OCR/Referens:',
paymentReference: 'Betalningsreferens:',
// Footer
orgNoLong: 'Org.nr:',
vatRegNo: 'Momsreg.nr:',
@@ -126,6 +127,7 @@ const LABELS = {
iban: 'IBAN:',
bic: 'BIC/SWIFT:',
ocr: 'Reference:',
paymentReference: 'Payment reference:',
orgNoLong: 'Reg. no.:',
vatRegNo: 'VAT reg. no.:',
// Statutory Swedish phrase — kept verbatim in both locales. Peppol SE-R-005
@@ -765,12 +767,18 @@ export function InvoicePDF({ invoice, customer, items, company, originalInvoiceN
<Text style={styles.paymentLabel}>{L.dueDate}</Text>
<Text style={[styles.paymentValue, { fontWeight: 'bold' }]}>{formatDate(invoice.due_date)}</Text>
</View>
{(company.invoice_show_ocr ?? true) && (
{(company.invoice_show_ocr ?? true) && (company.bankgiro || company.plusgiro) && lang === 'sv' && (
<View style={styles.paymentRow}>
<Text style={styles.paymentLabel}>{L.ocr}</Text>
<Text style={[styles.paymentValue, { fontWeight: 'bold' }]}>{invoice.invoice_number ? generateOcrReference(invoice.invoice_number) : '—'}</Text>
</View>
)}
{lang !== 'sv' && invoice.invoice_number && (
<View style={styles.paymentRow}>
<Text style={styles.paymentLabel}>{L.paymentReference}</Text>
<Text style={[styles.paymentValue, { fontWeight: 'bold' }]}>{invoice.invoice_number}</Text>
</View>
)}
</View>
)}
+7 -1
View File
@@ -16,7 +16,13 @@ export async function generateIncomeStatement(
companyId: string,
fiscalPeriodId: string
): Promise<IncomeStatementReport> {
const { rows } = await generateTrialBalance(supabase, companyId, fiscalPeriodId)
// Exclude year-end closing entries: after closing, P&L accounts (3-8) are
// zeroed by the closing verifikat (8999 → 2099). Including them collapses
// the resultaträkning to zero. The income statement must reflect the
// pre-closing activity for the year.
const { rows } = await generateTrialBalance(supabase, companyId, fiscalPeriodId, {
excludeYearEndClosing: true,
})
// Filter to income/expense accounts (class 3-8)
const incomeExpenseRows = rows.filter(
+7 -1
View File
@@ -57,7 +57,7 @@ export async function generateSIEExport(
)
// Fetch all posted journal entries with lines
const { data: entries } = await supabase
let entriesQuery = supabase
.from('journal_entries')
.select('*, lines:journal_entry_lines(*)')
.eq('company_id', companyId)
@@ -65,6 +65,12 @@ export async function generateSIEExport(
.in('status', ['posted', 'reversed'])
.order('voucher_number')
if (options.exclude_year_end_closing) {
entriesQuery = entriesQuery.neq('source_type', 'year_end')
}
const { data: entries } = await entriesQuery
// Fetch cost centers and projects for dimension records
const { data: costCenters } = await supabase
.from('cost_centers')
+7 -2
View File
@@ -16,7 +16,8 @@ import type { TrialBalanceRow } from '@/types'
export async function generateTrialBalance(
supabase: SupabaseClient,
companyId: string,
fiscalPeriodId: string
fiscalPeriodId: string,
options?: { excludeYearEndClosing?: boolean }
): Promise<{
rows: TrialBalanceRow[]
totalDebit: number
@@ -51,7 +52,7 @@ export async function generateTrialBalance(
}>(({ from, to }) => {
let query = supabase
.from('journal_entry_lines')
.select('account_number, debit_amount, credit_amount, journal_entries!inner(company_id, fiscal_period_id, status)')
.select('account_number, debit_amount, credit_amount, journal_entries!inner(company_id, fiscal_period_id, status, source_type)')
.eq('journal_entries.company_id', companyId)
.eq('journal_entries.fiscal_period_id', fiscalPeriodId)
.in('journal_entries.status', ['posted', 'reversed'])
@@ -60,6 +61,10 @@ export async function generateTrialBalance(
query = query.neq('journal_entry_id', obEntryId)
}
if (options?.excludeYearEndClosing) {
query = query.neq('journal_entries.source_type', 'year_end')
}
return query.range(from, to)
})