# Offertes en facturen importeren

Als je overstapt naar Borkol vanuit een ander offerte- of facturatiesysteem, hoeven je bestaande documenten niet vanaf nul te beginnen. De import brengt documenttypes, contacten, offertes, facturen, betalingen en nummerreeksen over vanuit één JSON-export, zodat je nummering doorgaat waar het oude systeem ophield in plaats van opnieuw bij 1 te beginnen.

Hier is nog geen selfservice-importscherm voor: Borkol-support voert hem voor je uit vanuit een JSON-bestand dat jij (of je oude systeem) aanlevert.

## Hoe het werkt

Support voert `php artisan sales:import {tenant} {file}` uit tegen de export. Voeg eerst `--dry-run` toe om het bestand te valideren en te zien hoeveel rijen van elk type zouden worden geïmporteerd, zonder iets weg te schrijven — deze run rolt altijd terug en slaat nooit media op tijdens een droogloop. Een echte run importeert alles in het bestand, of niets: elke fout op rijniveau (een totaal dat niet klopt, een onbekende nummerreeks, een geweigerde afbeeldings- of PDF-bron) rolt de hele import terug, en het commando meldt elke fout op zijn locatie in het bestand (bijvoorbeeld `quotes[0] (q-1).total_amount: …`).

De import is idempotent op `external_id`: hetzelfde bestand twee keer uitvoeren, of een bestand met nieuwe rijen toegevoegd aan een eerder bestand, slaat alles over wat al is geïmporteerd en voegt alleen het nieuwe toe.

## Wat het bestand bevat

De export is één JSON-document met vijf optionele top-level arrays:

| Sleutel | Wat het bevat |
| --- | --- |
| `document_types[]` | De benoemde nummerreeksvoorvoegsels die je oude systeem gebruikte |
| `contacts[]` | Klanten, elk met een `external_id` en getypeerde adressen |
| `quotes[]` | Offertes, met hun regels, omvangonderdelen en (optioneel) een handtekening |
| `invoices[]` | Facturen en creditnota's, met hun regels en betalingen |
| `series[]` | De tellers die moeten worden gezaaid zodat nieuwe nummers doorgaan waar de oude stopten |

### Contacten

Elk contact heeft een echte naam, optionele bedrijfsvelden, en een `external_id` die je zelf toewijst — dezelfde waarde wordt gebruikt om dit contact te matchen met offertes en facturen in hetzelfde of een later bestand. Adressen zijn getypeerd als **factuuradres** of **werkadres**, overeenkomend met de twee adrestypen waar een offerte of factuur naar kan verwijzen.

### Offertes

Elke offerte heeft zijn `number`, `status`, data, regels en omvangonderdelen, plus zijn eigen `external_id`. Een offerte kan ook een `signature_url` en `signed_pdf_url` bevatten (voor een geaccepteerde offerte die is ondertekend) en tot het gebruikelijke maximum aantal foto's als `photos[]` — allemaal opgegeven als URL's die bij de import worden opgehaald en in Borkol worden opgeslagen. Een **conceptoffert**e krijgt bij de import nooit een nummer, net zoals een concept in het live systeem er nooit een heeft.

### Facturen

Elke factuur heeft zijn `number`, of het een `invoice` of `credit_note` is, zijn status, data, regels en eventuele al geregistreerde betalingen. Een creditnota verwijst naar de factuur die hij corrigeert.

### Reeksen

Elke invoer benoemt een `scope` (offerte, factuur of creditnota), optioneel een specifiek documenttype, de boekhoudkundige `period` waarop hij van toepassing is, en de hoogste `value` die al is uitgegeven in die periode. Na de import pakt de live nummering het nummer direct na die waarde op — er wordt niets hernummerd en er ontstaan geen gaten.

## Media

Handtekeningen, ondertekende PDF's en factuur-PDF's die via URL worden aangeleverd, worden gedownload en op dezelfde manier opgeslagen als een document dat binnen Borkol wordt gegenereerd; offertefoto's worden aan je mediabibliotheek toegevoegd zoals elke andere upload. Alleen gewone openbare webadressen worden geaccepteerd als bron — privé-, lokale of anderszins onbereikbare adressen worden geweigerd.
