package handlers import ( "net/http" "time" ) // AccountingHandler hanterar dubbel bokföring — egen ledger + Visma type AccountingHandler struct{} func NewAccountingHandler() *AccountingHandler { return &AccountingHandler{} } // LedgerEntry representerar en bokföringspost type LedgerEntry struct { ID string `json:"id"` Date string `json:"date"` VoucherNo string `json:"voucher_no"` Description string `json:"description"` Account string `json:"account"` AccountName string `json:"account_name"` Debit float64 `json:"debit"` Credit float64 `json:"credit"` Balance float64 `json:"balance"` Source string `json:"source"` Synced bool `json:"synced"` VismaID *string `json:"visma_id,omitempty"` CreatedAt time.Time `json:"created_at"` } // AccountBalance representerar kontosaldo type AccountBalance struct { Code string `json:"code"` Name string `json:"name"` Type string `json:"type"` Balance float64 `json:"balance"` LastUpdated string `json:"last_updated"` } // VismaConnection representerar Visma-koppling type VismaConnection struct { Connected bool `json:"connected"` Company string `json:"company"` OrgNumber string `json:"org_number"` LastSync time.Time `json:"last_sync"` SyncStatus string `json:"sync_status"` PendingSync int `json:"pending_sync"` } // GetLedger returnerar egen ledger type GetLedger struct{} func (h *AccountingHandler) GetLedger(w http.ResponseWriter, r *http.Request) { entries := []LedgerEntry{ { ID: "le-001", Date: "2026-08-01", VoucherNo: "V-2026-081", Description: "Faktura #1001 — Kundtjänst AB", Account: "1510", AccountName: "Kundfordringar", Debit: 25000, Credit: 0, Balance: 25000, Source: "internal", Synced: true, VismaID: strPtr("visma-88123"), CreatedAt: time.Now().Add(-96 * time.Hour), }, { ID: "le-002", Date: "2026-08-01", VoucherNo: "V-2026-081", Description: "Faktura #1001 — Kundtjänst AB", Account: "3010", AccountName: "Försäljning tjänster", Debit: 0, Credit: 25000, Balance: -25000, Source: "internal", Synced: true, VismaID: strPtr("visma-88124"), CreatedAt: time.Now().Add(-96 * time.Hour), }, { ID: "le-003", Date: "2026-08-02", VoucherNo: "V-2026-082", Description: "Leverantörsfaktura #L-442 — AWS", Account: "2440", AccountName: "Leverantörsskulder", Debit: 0, Credit: 8500, Balance: -8500, Source: "visma", Synced: true, VismaID: strPtr("visma-88125"), CreatedAt: time.Now().Add(-72 * time.Hour), }, { ID: "le-004", Date: "2026-08-02", VoucherNo: "V-2026-082", Description: "Leverantörsfaktura #L-442 — AWS", Account: "6540", AccountName: "IT-kostnader", Debit: 8500, Credit: 0, Balance: 8500, Source: "visma", Synced: true, VismaID: strPtr("visma-88126"), CreatedAt: time.Now().Add(-72 * time.Hour), }, { ID: "le-005", Date: "2026-08-03", VoucherNo: "V-2026-083", Description: "Lön — Erik Svensson", Account: "7210", AccountName: "Löner", Debit: 45000, Credit: 0, Balance: 45000, Source: "internal", Synced: false, VismaID: nil, CreatedAt: time.Now().Add(-48 * time.Hour), }, { ID: "le-006", Date: "2026-08-03", VoucherNo: "V-2026-083", Description: "Lön — Erik Svensson", Account: "1930", AccountName: "Företagskonto/checkkonto/räkning", Debit: 0, Credit: 45000, Balance: -45000, Source: "internal", Synced: false, VismaID: nil, CreatedAt: time.Now().Add(-48 * time.Hour), }, { ID: "le-007", Date: "2026-08-04", VoucherNo: "V-2026-084", Description: "Zoomer-utbetalning — Anna Lindqvist", Account: "7690", AccountName: "Övriga personalkostnader", Debit: 5000, Credit: 0, Balance: 5000, Source: "quixzoom", Synced: false, VismaID: nil, CreatedAt: time.Now().Add(-24 * time.Hour), }, { ID: "le-008", Date: "2026-08-04", VoucherNo: "V-2026-084", Description: "Zoomer-utbetalning — Anna Lindqvist", Account: "1930", AccountName: "Företagskonto/checkkonto/räkning", Debit: 0, Credit: 5000, Balance: -5000, Source: "quixzoom", Synced: false, VismaID: nil, CreatedAt: time.Now().Add(-24 * time.Hour), }, } writeJSON(w, http.StatusOK, map[string]interface{}{ "ok": true, "entries": entries, "summary": map[string]interface{}{ "total": len(entries), "synced": 4, "pending_sync": 4, "sources": []string{"internal", "visma", "quixzoom"}, }, }) } // GetAccounts returnerar kontoplan type GetAccounts struct{} func (h *AccountingHandler) GetAccounts(w http.ResponseWriter, r *http.Request) { accounts := []AccountBalance{ {Code: "1510", Name: "Kundfordringar", Type: "asset", Balance: 25000, LastUpdated: "2026-08-05"}, {Code: "1930", Name: "Företagskonto", Type: "asset", Balance: -78500, LastUpdated: "2026-08-05"}, {Code: "2010", Name: "Eget kapital", Type: "equity", Balance: 50000, LastUpdated: "2026-08-01"}, {Code: "2440", Name: "Leverantörsskulder", Type: "liability", Balance: -8500, LastUpdated: "2026-08-02"}, {Code: "2610", Name: "Utgående moms", Type: "liability", Balance: 6250, LastUpdated: "2026-08-01"}, {Code: "3010", Name: "Försäljning tjänster", Type: "revenue", Balance: -25000, LastUpdated: "2026-08-01"}, {Code: "6540", Name: "IT-kostnader", Type: "expense", Balance: 8500, LastUpdated: "2026-08-02"}, {Code: "7210", Name: "Löner", Type: "expense", Balance: 45000, LastUpdated: "2026-08-03"}, {Code: "7690", Name: "Övriga personalkostnader", Type: "expense", Balance: 5000, LastUpdated: "2026-08-04"}, } writeJSON(w, http.StatusOK, map[string]interface{}{ "ok": true, "accounts": accounts, }) } // GetVismaStatus returnerar Visma-kopplingsstatus type GetVismaStatus struct{} func (h *AccountingHandler) GetVismaStatus(w http.ResponseWriter, r *http.Request) { status := VismaConnection{ Connected: true, Company: "Landvex AB", OrgNumber: "559141-7042", LastSync: time.Now().Add(-2 * time.Hour), SyncStatus: "partial", PendingSync: 4, } writeJSON(w, http.StatusOK, map[string]interface{}{ "ok": true, "visma": status, }) } // SyncVisma triggar synk till Visma type SyncVisma struct{} func (h *AccountingHandler) SyncVisma(w http.ResponseWriter, r *http.Request) { writeJSON(w, http.StatusOK, map[string]interface{}{ "ok": true, "message": "Sync initiated", "status": "syncing", "pending": 4, }) }