Files
accounted/dev_docs/08-BAS-ACCOUNTING-GUIDE.md
T
2026-02-13 14:00:46 +01:00

24 KiB

BAS Accounting Guide for Creator Economy

Overview

This document provides the accounting logic layer for automatic transaction categorization using the Swedish BAS-kontoplan. It covers MCC code mapping, expense validation rules, and VAT handling for influencer-specific transactions.

BAS Account Structure

The BAS-kontoplan uses a hierarchical 4-digit system where each position carries semantic meaning:

Position Name Example Meaning
1 Kontoklass 5410 Category (5 = External costs)
2 Kontogrupp 5410 Type (54 = Consumables)
3 Huvudkonto 5410 Main account for reporting
4 Underkonto 5410 Detail level, VAT codes

This enables validation logic built directly on account number structure.


Account Classes Overview

Class Swedish English Influencer Relevance
1xxx Tillgångar Assets Equipment, bank accounts
2xxx Eget kapital & Skulder Equity & Liabilities VAT, owner withdrawals
3xxx Intäkter Revenue Platform income, sponsorships
4xxx Direkta kostnader Direct costs Merchandise COGS (rare)
5xxx Övriga externa kostnader Other external costs 90% of expenses land here
6xxx Övriga externa kostnader Other external costs Services, representation
7xxx Personalkostnader Personnel costs AB salary (see salary module)
8xxx Finansiella poster Financial items Interest, currency gains/losses

Critical BAS Accounts for Influencers

Assets (Class 1)

Account Name Use Case Notes
1210 Maskiner och inventarier Cameras, computers > 29,400 kr Depreciate over 5 years (20%/year)
1930 Företagskonto Main bank account Primary reconciliation account

Equity & Liabilities (Class 2)

Account Name Use Case Notes
2010 Eget kapital Owner's equity Rolling balance
2013 Eget uttag Private expenses paid with business card Critical for rejected deductions
2018 Egen insättning Owner deposits / travel allowance credit Traktamente booking
2440 Leverantörsskulder Accounts payable If not paying immediately
2611 Utgående moms 25% Output VAT 25% Swedish domestic sales
2614 Utg. moms utländska förvärv Output VAT on foreign purchases Reverse charge (credit side)
2641 Ingående moms Input VAT Deductible VAT on purchases
2645 Ing. moms utländska förvärv Input VAT on foreign purchases Reverse charge (debit side)

Revenue (Class 3)

Account Name Use Case Notes
3001 Försäljning 25% Swedish sponsorships/collaborations Standard domestic
3044 Försäljning tjänst EU AdSense (Ireland), EU affiliates VAT-free, requires Periodisk sammanställning
3045 Försäljning tjänst Export Twitch (USA), non-EU platforms VAT-free (export)
3900 Övriga intäkter Stipends, royalties, misc

Costs (Class 5-6)

Account Name Use Case Notes
5010 Lokalhyra Studio rental Not for home office (strict rules)
5410 Förbrukningsinventarier Cameras, computers < 29,400 kr Direct deduction
5420 Programvaror Adobe CC, Epidemic Sound, SaaS Licenses/subscriptions
5480 Arbetskläder Protective gear, uniforms NOT regular clothes
5490 Övriga förbrukningsartiklar Props, consumable supplies
5800 Resekostnader Train, flights, car rental VAT varies (6% domestic travel)
5820 Taxikostnader Taxi, Uber
5831 Kost och logi Sverige Hotels in Sweden 12% VAT
5832 Kost och logi utlandet Hotels abroad No VAT recovery
5841 Traktamente, avdragsgillt Travel allowance Calculated per Skatteverket rates
5890 Övriga resekostnader Non-deductible travel portion For mixed-use trips
5910 Annonsering Facebook Ads, Google Ads Often triggers reverse charge
5930 Reklamtrycksaker Promotional materials
6071 Representation, avdragsgill Simple refreshments (max 60 kr/person) Very limited deduction
6072 Representation, ej avdragsgill Meals for representation VAT still deductible
6230 Datakommunikation Web hosting, domains, internet Infrastructure
6500 Övriga externa tjänster Photographers, editors (with F-skatt) Consultant services
6991 Övriga avdragsgilla kostnader Miscellaneous deductible Use sparingly
6992 Övriga ej avdragsgilla Fines, penalties No tax effect

MCC Code Mapping

Merchant Category Codes (MCC) are the primary signal for automatic categorization from bank transactions.

Implementation

// lib/accounting/mcc-mapping.ts

interface MCCMapping {
  mcc: string
  description: string
  riskLevel: 'low' | 'medium' | 'high' | 'very_high'
  primaryAccount: string
  secondaryAccount?: string
  requiresUserInput: boolean
  autoRejectReason?: string
  logic: string
}

const MCC_MAPPINGS: MCCMapping[] = [
  // ADVERTISING & MARKETING
  {
    mcc: '7311',
    description: 'Advertising Services',
    riskLevel: 'low',
    primaryAccount: '5910',
    secondaryAccount: '5930',
    requiresUserInput: false,
    logic: 'Standard for Facebook/Google Ads. Triggers EU VAT check.'
  },

  // ELECTRONICS & EQUIPMENT
  {
    mcc: '5732',
    description: 'Electronics Stores',
    riskLevel: 'medium',
    primaryAccount: '5410',
    secondaryAccount: '1210',
    requiresUserInput: false,
    logic: 'Amount determines routing. >29,400 kr → 1210 (asset).'
  },
  {
    mcc: '5946',
    description: 'Camera & Photo Supply',
    riskLevel: 'medium',
    primaryAccount: '5410',
    secondaryAccount: '1210',
    requiresUserInput: false,
    logic: 'Same as electronics. Check amount threshold.'
  },

  // RESTAURANTS & FOOD - HIGH RISK
  {
    mcc: '5812',
    description: 'Eating Places/Restaurants',
    riskLevel: 'high',
    primaryAccount: '6072',
    secondaryAccount: '2013',
    requiresUserInput: true,
    logic: 'Requires user input: Representation or private? Default to private (2013).'
  },
  {
    mcc: '5814',
    description: 'Fast Food',
    riskLevel: 'high',
    primaryAccount: '2013',
    requiresUserInput: false,
    autoRejectReason: 'Fast food is typically private expense',
    logic: 'Default to eget uttag. Rarely valid business expense.'
  },

  // CLOTHING - VERY HIGH RISK (Almost always rejected)
  {
    mcc: '5611',
    description: "Men's Clothing",
    riskLevel: 'very_high',
    primaryAccount: '2013',
    secondaryAccount: '5480',
    requiresUserInput: true,
    autoRejectReason: 'Clothes that can be worn privately are not deductible (RÅ81 1:29)',
    logic: 'Default MUST be 2013 (private). Only 5480 if protective/uniform.'
  },
  {
    mcc: '5621',
    description: "Women's Ready-to-Wear",
    riskLevel: 'very_high',
    primaryAccount: '2013',
    secondaryAccount: '5480',
    requiresUserInput: true,
    autoRejectReason: 'Clothes that can be worn privately are not deductible',
    logic: 'Default MUST be 2013 (private).'
  },
  {
    mcc: '5631',
    description: "Women's Accessories",
    riskLevel: 'very_high',
    primaryAccount: '2013',
    requiresUserInput: false,
    autoRejectReason: 'Accessories are private expenses',
    logic: 'Always 2013.'
  },

  // COSMETICS - VERY HIGH RISK
  {
    mcc: '5977',
    description: 'Cosmetic Stores',
    riskLevel: 'very_high',
    primaryAccount: '2013',
    secondaryAccount: '5490',
    requiresUserInput: true,
    autoRejectReason: 'Cosmetics are private expenses unless specific props',
    logic: 'Default private (2013). Only 5490 if clearly production props.'
  },

  // TRAVEL - MEDIUM RISK
  {
    mcc: '4111',
    description: 'Commuter Transport',
    riskLevel: 'low',
    primaryAccount: '5800',
    requiresUserInput: false,
    logic: 'Train/bus. 6% VAT in Sweden.'
  },
  {
    mcc: '4112',
    description: 'Passenger Railways',
    riskLevel: 'low',
    primaryAccount: '5800',
    requiresUserInput: false,
    logic: 'Train tickets. 6% VAT.'
  },
  {
    mcc: '4121',
    description: 'Taxicabs/Limousines',
    riskLevel: 'medium',
    primaryAccount: '5820',
    secondaryAccount: '2013',
    requiresUserInput: true,
    logic: 'Business trip or private? Ask user.'
  },
  {
    mcc: '4722',
    description: 'Travel Agencies',
    riskLevel: 'medium',
    primaryAccount: '5800',
    secondaryAccount: '2013',
    requiresUserInput: true,
    logic: 'Is the trip business-related? May need to split.'
  },
  {
    mcc: '7011',
    description: 'Hotels/Motels',
    riskLevel: 'medium',
    primaryAccount: '5831',
    secondaryAccount: '5832',
    requiresUserInput: false,
    logic: '5831 for Sweden (12% VAT), 5832 for abroad (no VAT).'
  },

  // SOFTWARE & DIGITAL SERVICES - LOW RISK
  {
    mcc: '7372',
    description: 'Computer Programming',
    riskLevel: 'low',
    primaryAccount: '6230',
    secondaryAccount: '5420',
    requiresUserInput: false,
    logic: 'Web hosting, domains, SaaS subscriptions.'
  },
  {
    mcc: '5734',
    description: 'Computer Software Stores',
    riskLevel: 'low',
    primaryAccount: '5420',
    requiresUserInput: false,
    logic: 'Software licenses.'
  },

  // ALCOHOL - ALWAYS REJECT
  {
    mcc: '5921',
    description: 'Package Stores (Systembolaget)',
    riskLevel: 'very_high',
    primaryAccount: '2013',
    requiresUserInput: false,
    autoRejectReason: 'Alcohol is not deductible',
    logic: 'Always 2013. No exceptions.'
  },

  // GROCERIES - HIGH RISK
  {
    mcc: '5411',
    description: 'Grocery Stores',
    riskLevel: 'high',
    primaryAccount: '2013',
    secondaryAccount: '6072',
    requiresUserInput: true,
    autoRejectReason: 'Food is typically private expense',
    logic: 'Default 2013. Only 6072 if documented representation.'
  },

  // STREAMING SERVICES
  {
    mcc: '4899',
    description: 'Cable/Streaming Services',
    riskLevel: 'medium',
    primaryAccount: '5420',
    secondaryAccount: '2013',
    requiresUserInput: true,
    logic: 'Netflix for research? Usually private. Ask user.'
  },

  // GYM & FITNESS - ALWAYS REJECT
  {
    mcc: '7941',
    description: 'Sports Clubs/Gyms',
    riskLevel: 'very_high',
    primaryAccount: '2013',
    requiresUserInput: false,
    autoRejectReason: 'Gym memberships are private expenses, even for fitness influencers',
    logic: 'Always 2013. IL 9 kap. 2 §'
  }
]

Keyword-Based Categorization

For generic MCCs (Amazon, PayPal), analyze transaction description text.

// lib/accounting/keyword-rules.ts

interface KeywordRule {
  keywords: string[]
  account: string
  confidence: 'high' | 'medium' | 'low'
  vatTreatment?: 'standard' | 'reverse_charge' | 'none'
}

const KEYWORD_RULES: KeywordRule[] = [
  // Software & Subscriptions
  {
    keywords: ['adobe', 'creative cloud'],
    account: '5420',
    confidence: 'high',
    vatTreatment: 'reverse_charge'  // Adobe Ireland
  },
  {
    keywords: ['epidemic sound'],
    account: '5420',
    confidence: 'high',
    vatTreatment: 'standard'  // Swedish company
  },
  {
    keywords: ['canva'],
    account: '5420',
    confidence: 'high',
    vatTreatment: 'reverse_charge'
  },
  {
    keywords: ['spotify', 'spotify ab'],
    account: '2013',  // Usually private
    confidence: 'medium'
  },
  {
    keywords: ['spotify for business', 'soundtrack'],
    account: '5420',
    confidence: 'high'
  },

  // Web Infrastructure
  {
    keywords: ['one.com', 'loopia', 'godaddy', 'namecheap', 'cloudflare'],
    account: '6230',
    confidence: 'high'
  },
  {
    keywords: ['vercel', 'netlify', 'heroku', 'aws', 'digitalocean'],
    account: '6230',
    confidence: 'high',
    vatTreatment: 'reverse_charge'
  },

  // Advertising Platforms
  {
    keywords: ['facebook', 'meta', 'instagram ads', 'fb ads'],
    account: '5910',
    confidence: 'high',
    vatTreatment: 'reverse_charge'  // Meta Ireland
  },
  {
    keywords: ['google ads', 'adwords'],
    account: '5910',
    confidence: 'high',
    vatTreatment: 'reverse_charge'  // Google Ireland
  },
  {
    keywords: ['tiktok ads', 'tiktok for business'],
    account: '5910',
    confidence: 'high',
    vatTreatment: 'reverse_charge'
  },

  // Transport
  {
    keywords: ['uber', 'bolt', 'taxi'],
    account: '5820',
    confidence: 'medium'  // Could be private
  },
  {
    keywords: ['sj', 'mtrx', 'sj biljett'],
    account: '5800',
    confidence: 'high'
  },
  {
    keywords: ['sas', 'norwegian', 'ryanair', 'flygbiljett'],
    account: '5800',
    confidence: 'medium'  // Could be private trip
  },

  // Always Private
  {
    keywords: ['systembolaget'],
    account: '2013',
    confidence: 'high'
  },
  {
    keywords: ['apotek', 'apoteket', 'apotea'],
    account: '2013',
    confidence: 'high'
  },
  {
    keywords: ['ica', 'coop', 'willys', 'hemköp', 'lidl'],
    account: '2013',
    confidence: 'medium'  // Usually private groceries
  }
]

Amount-Based Routing (Asset vs Expense)

// lib/accounting/asset-routing.ts

const PRISBASBELOPP_2025 = 58800
const HALF_PBB = PRISBASBELOPP_2025 / 2  // 29,400 kr

interface AssetDecision {
  shouldCapitalize: boolean
  account: string
  depreciationYears?: number
  depreciationRate?: number
}

function routeEquipmentPurchase(
  amountExVat: number,
  mccCode: string
): AssetDecision {
  const isEquipmentMCC = ['5732', '5946', '5045'].includes(mccCode)
  
  if (!isEquipmentMCC) {
    return { shouldCapitalize: false, account: '5410' }
  }

  if (amountExVat > HALF_PBB) {
    return {
      shouldCapitalize: true,
      account: '1210',
      depreciationYears: 5,
      depreciationRate: 0.20
    }
  }

  return {
    shouldCapitalize: false,
    account: '5410'
  }
}

// Update HALF_PBB annually - Skatteverket publishes in November

Reverse Charge VAT Handling

When purchasing services from foreign (usually EU) companies, Swedish businesses must self-report VAT.

Detection Logic

// lib/accounting/reverse-charge.ts

interface ReverseChargeResult {
  applies: boolean
  reason: string
  bookings: Array<{
    account: string
    debit?: number
    credit?: number
    description: string
  }>
}

const EU_DIGITAL_SERVICES_VENDORS = [
  { name: 'meta', country: 'IE', keywords: ['facebook', 'meta', 'instagram'] },
  { name: 'google', country: 'IE', keywords: ['google', 'youtube', 'adwords'] },
  { name: 'adobe', country: 'IE', keywords: ['adobe'] },
  { name: 'microsoft', country: 'IE', keywords: ['microsoft', 'office 365', 'azure'] },
  { name: 'amazon', country: 'LU', keywords: ['aws', 'amazon web services'] },
  { name: 'canva', country: 'AU', keywords: ['canva'] },  // Non-EU, different treatment
]

function handleForeignPurchase(
  amount: number,
  vendorName: string,
  vendorCountry: string,
  expenseAccount: string
): ReverseChargeResult {
  const isEU = isEUCountry(vendorCountry)
  const vatRate = 0.25
  const vatAmount = amount * vatRate

  if (isEU && vendorCountry !== 'SE') {
    // EU purchase - reverse charge applies
    return {
      applies: true,
      reason: `Omvänd skattskyldighet - inköp från ${vendorCountry}`,
      bookings: [
        { account: expenseAccount, debit: amount, description: 'Kostnad' },
        { account: '2645', debit: vatAmount, description: 'Beräknad ing. moms utl. förvärv' },
        { account: '2614', credit: vatAmount, description: 'Utg. moms utl. förvärv' },
        { account: '1930', credit: amount, description: 'Utbetalning' }
      ]
    }
  }

  if (!isEU) {
    // Non-EU purchase - no reverse charge, just expense
    return {
      applies: false,
      reason: 'Import från land utanför EU',
      bookings: [
        { account: expenseAccount, debit: amount, description: 'Kostnad' },
        { account: '1930', credit: amount, description: 'Utbetalning' }
      ]
    }
  }

  // Swedish domestic
  return {
    applies: false,
    reason: 'Inrikes inköp',
    bookings: []  // Normal VAT handling
  }
}

Momsdeklaration Mapping

Scenario Ruta Description
Domestic purchase 25% VAT 48 (utgående), deduct in 48 Normal
EU service purchase (reverse charge) 21 (purchase amount), 48 (calculated VAT) Self-report
Non-EU service purchase No VAT reporting Just expense

Revenue Account Selection

// lib/accounting/revenue-routing.ts

interface RevenueRouting {
  account: string
  vatRate: number
  momsRuta: number
  requiresPeriodiskSammanstallning: boolean
}

function routeRevenue(
  customerCountry: string,
  customerType: 'business' | 'consumer',
  hasValidVatNumber: boolean
): RevenueRouting {
  // Swedish customer
  if (customerCountry === 'SE') {
    return {
      account: '3001',  // Försäljning 25%
      vatRate: 25,
      momsRuta: 5,
      requiresPeriodiskSammanstallning: false
    }
  }

  // EU business with VAT number
  if (isEUCountry(customerCountry) && customerType === 'business' && hasValidVatNumber) {
    return {
      account: '3044',  // Försäljning tjänst EU
      vatRate: 0,
      momsRuta: 39,
      requiresPeriodiskSammanstallning: true  // Quarterly report required!
    }
  }

  // EU consumer (OSS rules may apply if >10k EUR/year)
  if (isEUCountry(customerCountry) && customerType === 'consumer') {
    return {
      account: '3001',  // Or OSS-specific account
      vatRate: 25,  // Swedish VAT until OSS threshold
      momsRuta: 5,
      requiresPeriodiskSammanstallning: false
    }
  }

  // Non-EU (USA, etc.) - Export
  return {
    account: '3045',  // Försäljning tjänst Export
    vatRate: 0,
    momsRuta: 40,
    requiresPeriodiskSammanstallning: false
  }
}

Conservative Bias Principle

The system must be designed with a conservative bias - prefer rejecting deductions over accepting questionable ones.

Rationale

  • Burden of proof lies with taxpayer (IL 9 kap. 2 §)
  • Skattetillägg (tax surcharge) is 40% of avoided tax
  • Better to warn user than cause audit problems

Implementation

// lib/accounting/risk-assessment.ts

interface RiskAssessment {
  riskLevel: 'low' | 'medium' | 'high' | 'very_high'
  suggestedAccount: string
  requiresConfirmation: boolean
  warningMessage?: string
  legalBasis?: string
}

function assessTransactionRisk(
  mcc: string,
  amount: number,
  description: string
): RiskAssessment {
  const mapping = getMCCMapping(mcc)
  
  if (mapping.riskLevel === 'very_high') {
    return {
      riskLevel: 'very_high',
      suggestedAccount: '2013',  // Default to private (eget uttag)
      requiresConfirmation: true,
      warningMessage: mapping.autoRejectReason,
      legalBasis: 'IL 9 kap. 2 § - Privata levnadskostnader'
    }
  }

  if (mapping.riskLevel === 'high') {
    return {
      riskLevel: 'high',
      suggestedAccount: mapping.primaryAccount,
      requiresConfirmation: true,
      warningMessage: `Denna typ av utgift kräver dokumentation. ${mapping.logic}`
    }
  }

  // Low/medium risk - auto-categorize but allow override
  return {
    riskLevel: mapping.riskLevel,
    suggestedAccount: mapping.primaryAccount,
    requiresConfirmation: false
  }
}

Private Use Split

For items with mixed business/private use:

// lib/accounting/split-usage.ts

interface SplitTransaction {
  businessPortion: {
    account: string
    amount: number
  }
  privatePortion: {
    account: string  // Always 2013
    amount: number
  }
}

function splitMixedUse(
  totalAmount: number,
  businessPercentage: number,
  expenseAccount: string
): SplitTransaction {
  const businessAmount = totalAmount * (businessPercentage / 100)
  const privateAmount = totalAmount - businessAmount

  return {
    businessPortion: {
      account: expenseAccount,
      amount: Math.round(businessAmount * 100) / 100
    },
    privatePortion: {
      account: '2013',
      amount: Math.round(privateAmount * 100) / 100
    }
  }
}

// UI should ask: "Används denna uteslutande i företaget?"
// If no → prompt for percentage split

Travel Allowance (Traktamente)

For business trips, the owner can claim tax-free travel allowance at Skatteverket's rates.

// lib/accounting/traktamente.ts

// 2024 rates - update annually
const TRAKTAMENTE_RATES = {
  sweden: {
    fullDay: 260,      // Hel dag
    halfDay: 130,      // Halv dag
    night: 130         // Nattraktamente
  },
  // Foreign rates vary by country - see Skatteverket's list
  foreign: {
    USA: { fullDay: 620, reduced: 434 },
    UK: { fullDay: 550, reduced: 385 },
    Germany: { fullDay: 420, reduced: 294 },
    // ... etc
  }
}

interface TraktamenteCalculation {
  amount: number
  bookings: Array<{
    account: string
    debit?: number
    credit?: number
  }>
}

function calculateTraktamente(
  destination: 'sweden' | string,
  fullDays: number,
  halfDays: number,
  nights: number
): TraktamenteCalculation {
  const rates = destination === 'sweden' 
    ? TRAKTAMENTE_RATES.sweden 
    : TRAKTAMENTE_RATES.foreign[destination] || TRAKTAMENTE_RATES.sweden

  const amount = 
    (fullDays * rates.fullDay) +
    (halfDays * (rates.halfDay || rates.fullDay / 2)) +
    (nights * (rates.night || 0))

  return {
    amount,
    bookings: [
      { account: '5841', debit: amount },   // Traktamente, avdragsgillt
      { account: '2018', credit: amount }   // Egen insättning (skuld till ägare)
    ]
  }
}

Non-Cash Transactions (Barter/Gifts)

Influencers receive products that must be accounted for even without bank transaction.

// lib/accounting/non-cash.ts

interface BarterTransaction {
  productValue: number
  hasMotprestation: boolean  // Required post/exposure?
  usedInBusiness: boolean
  bookings: Array<{
    account: string
    debit?: number
    credit?: number
    description: string
  }>
}

function bookBarterTransaction(
  productValue: number,
  hasMotprestation: boolean,
  usedInBusiness: boolean
): BarterTransaction['bookings'] {
  if (!hasMotprestation && productValue < 450) {
    // Tax-free promotional gift
    return []  // No booking required
  }

  if (hasMotprestation) {
    // Taxable barter - must recognize as income
    const bookings = [
      { account: '3001', credit: productValue, description: 'Förmån/Byteshandel' },
      { account: '1510', debit: productValue, description: 'Fordran (kvittad mot produkt)' }
    ]

    if (usedInBusiness) {
      // Can also expense it
      bookings.push(
        { account: '5490', debit: productValue, description: 'Rekvisita' },
        { account: '1510', credit: productValue, description: 'Kvittning fordran' }
      )
    } else {
      // Private use - eget uttag
      bookings.push(
        { account: '2013', debit: productValue, description: 'Eget uttag (förmån)' },
        { account: '1510', credit: productValue, description: 'Kvittning fordran' }
      )
    }

    return bookings
  }

  // Gift without motprestation but valuable - still taxable
  return [
    { account: '3001', credit: productValue, description: 'Skattepliktig gåva' },
    { account: '2013', debit: productValue, description: 'Eget uttag (gåva)' }
  ]
}

System Configuration

// lib/accounting/config.ts

export const ACCOUNTING_CONFIG = {
  // Update annually
  prisbasbelopp: 58800,  // 2025
  halfPrisbasbelopp: 29400,
  
  // VAT rates
  vatRates: {
    standard: 25,
    reduced: 12,  // Food, hotels
    low: 6,       // Transport, books
  },

  // Depreciation defaults
  depreciation: {
    equipment: { years: 5, rate: 0.20 },
    computers: { years: 3, rate: 0.33 },
    vehicles: { years: 5, rate: 0.20 },
  },

  // Risk thresholds
  riskSettings: {
    autoRejectVeryHigh: true,
    requireConfirmationHigh: true,
    allowOverrideMedium: true,
  }
}

Integration Points

This guide integrates with:

  1. Transaction categorization UI (05-UI-SPECIFICATION.md) - Swipe interface uses MCC mapping
  2. Tax calculator (06-IMPLEMENTATION-GUIDE.md) - Uses account classifications for tax estimation
  3. Invoice VAT rules (04-API-SPECIFICATION.md) - Revenue account selection aligns with momsdeklaration
  4. Expense warnings (06-IMPLEMENTATION-GUIDE.md) - Risk levels drive warning display

Annual Maintenance

Update each January:

  1. Prisbasbelopp (from Skatteverket, published November)
  2. Traktamente rates (Skatteverket)
  3. Any BAS account changes (BAS-kontogruppen)
  4. Tax rates if changed by Riksdag