Installatie
- Download de zip van DemoVersion
- Na het uitpakken heb je 6 bestanden:
- UBL_Writer (Huidige versie 1.261)
- UBL_Data
- README.txt (met korte installatie instructies)
- ReleaseNotes_v(n.nnn).txt
- Example_Invoicing.fmp12 (voorbeeld integratie)
- OpenRemoteDemo.fmp12 (voorbeeld openen zonder apart inloggen)
- Plaats UBL_Writer en UBL_Data in de map met de overige bestanden van jouw huidige FileMaker bestanden. Op een FMServer kan je eventueel een aparte map gebruiken.
De bestanden
Het bestand Example_Invoicing bevat uitsluitend een voorbeeld dat laat zien hoe je jouw eigen systeem geschikt kunt maken en kunt koppelen aan UBL_Writer. In de scripts vind je toelichting op de werking, maar dit bestand maakt geen onderdeel uit van UBL_Writer. Je kunt het daarom zonder problemen negeren.
UBL_Writer gebruikt het bestand UBL_Data voor het opslaan van alle gegevens, inclusief de licentie-informatie. Dit databestand is volledig open, maar de veldnamen in de bestaande tabellen en de structuur daarvan worden door UBL_Writer gebruikt.
Je kunt naar wens tabellen, velden, relaties enzovoort toevoegen, zolang je de bestaande structuur intact laat. Bij toekomstige updates blijft dit bestand altijd behouden. In enkele tabellen zijn kolomnamen gereserveerd (zoals Spare_01, Spare_02, enzovoort). Tijdens een update kan het voorkomen dat je wordt gevraagd een dergelijke kolomnaam te wijzigen, omdat deze wordt gebruikt voor nieuwe functionaliteit.
Als alternatief kun je ervoor kiezen om de nieuwste versie van UBL_Data te gebruiken, maar in dat geval zul je je eigen aanpassingen daarin opnieuw moeten opnemen. Het is aan jou om te bepalen welke werkwijze het handigst is.
Open zonder apart inloggen vanuit andere FMP systemen
De gebruikers 'admin' en 'user' in UBL_Writer zijn waarschijnlijk niet in gebruik in jouw eigen FMP-systeem. Als je dan UBL_Writer wil openen, dan zou je iedere keer de ingestelde inlog weer op moeten geven om UBL_Writer te kunnen gebruiken. Je kan het password voor UBL_Writer wel opslaan, maar als je dan vanuit een ander FMP-systeem UBL_Writer laat openen, dan dwingt FMP je toch om de credentials in te voeren.
Gelukkig is dit simpel op te lossen door het zogenaamde fmp-protocol te
gebruiken. Je gebruikt dan in feite een URL om UBL_Writer te openen. Je moet
daarvoor een URL opbouwen en vanuit FielMaker openen, die bestaat 4 onderdelen,
het protocol, de username en password combinatie, het serveradres en de
gebruikte bestandsnaam. Deze ziet er dan zo uit:
fmp://<username>:<password>@<serveradres>/<bestandsnaam>
|
Let ( [
$user = GetAsURLEncoded ( somefile::username ) ; $pwrd = GetAsURLEncoded ( somefile::password ) ; $server = somefile::server_address ; $filename = somefile::filename ] ; "fmp://" & $user & ":" & $pwrd & "@" & $server & "/" & $filename ) |
Je kan de onderdelen op elke manier die jou bevalt opbouwen, hardcoded, met velden, met variabelen of een combinatie. In OpenRemoteDemo.zip is het met een combinatie van velden en variabelen gedaan.
Gebruik maken van deze methode doe je door te starten met dmv de URL UBL_Writer te openen. In de volgende stap ga je naar de lay-out waar je jouw script start om met UBL_Writer te communiceren. Dat is alles.
Voorkeuren en licentie-instellingen (preferences)
De voorkeuren kunnen uitsluitend worden ingesteld met het 'admin'-account. In dit onderdeel leg je onder andere de voorkeuren vast van de organisatie waarvoor je UBL-facturen genereert.
Daarnaast vind je hier de instellingen van de licentie. Wanneer je gebruikmaakt van een proeflicentie, kun je vanuit dit scherm eenvoudig een definitieve licentie aanschaffen. Er is geen extra functionaliteit verborgen achter de koopfunctie: tijdens de proefperiode is alle functionaliteit volledig beschikbaar. Na afloop van de proefperiode kun je echter geen UBL-facturen meer produceren.
Proeflicentie aanvragen met BTW nummer
Voor het aanvragen van een proeflicentie moeten minimaal de volgende velden worden ingevuld: CompanyName, CoCnr, VATnr en Email. Gebruik hiervoor de werkelijke bedrijfsgegevens, omdat anders geen geldige UBL-facturen kunnen worden gegenereerd. De overige velden mogen voorlopig leeg blijven, maar voor het aanmaken van volledig geldige UBL-facturen en voor de aanschaf van een definitieve licentie zijn ook de adresgegevens vereist.
Verplichte invoer KvK nummer:
In Nederland is iedere ondernemer verplicht ingeschreven bij de KvK (Kamer van
Koophandel).
In België is dat de KBO (Kruispuntbank van Ondernemingen,
Belgische ondernemingen kunnen hier hun BTWnummer invullen, zonder BE er voor te
plaatsen)
In UBL_Writer moet dat nummer worden ingevuld i.v.m. het
aanmaken van de factuur als je de licentie besluit af te nemen.
Proeflicentie aanvragen zonder BTW nummer
Als persoon heb je geen BTW nummer en daarvoor is het (fictieve) BTWnummer EU123456789B99 gereserveerd. Bij bedrijfsnaam en KvKnummer mag je invullen wat je wil. Samen met een e-mailadres kan je daarmee een test-licentie aanvragen. Het is met deze instellingen niet mogelijk om de licentie aan te schaffen.
De UBL-documenten die je hiermee genereert kunnen als geldig worden gevalideerd, maar dat komt omdat alleen wordt gecontroleerd of er aan de UBL-syntax wordt voldaan. Je kan het document niet uploaden/versturen naar het Peppol-netwerk, daar zal het worden geweigerd. De licentie zonder BTW nummer verloopt na 7 dagen en kan niet worden vernieuwd en kan niet worden omgezet naar een definitieve licentie.
Eerste keer instellen van een nieuwe versie
Na het downloaden open je UBL_Writer stand-alone met het account 'admin'. Stel vervolgens voor dit account en voor het account 'user' de gewenste wachtwoorden in.
Wanneer je UBL_Writer via FileMaker Server (FMServer) gebruikt, stel dan bij de privilegesets 'maintenance' en '[data entry]' in de extended privileges de waarde fmapp in.
Nadat je deze instellingen hebt uitgevoerd, kun je UBL_Writer vervangen op de locatie waar je het bestand normaal gebruikt.
Creditnota's met UBL_Writer
Creditona's zijn in feite facturen en in UBL_Writer wordt een creditnota op dezelfde wijze verwerkt en omgevormd. Het enige verschil is dat de aantallen negatief worden, de totalen worden daardoor ook negatief. Al het andere blijft hetzelfde en ook het factuurtype blijft hetzelfde: 380 (commercial invoice)
Er is in UBL wel een speciale mogelijkheid van een creditnota, maar dan moeten er ook een aantal extra velden worden gevuld en koppelingen worden gelegd met de originele factuur. Dat probleem gaan we uit de weg door simpel een negatieve factuur te maken.
BTW berekenen en afronden
Er zijn 2 mogelijke manieren om op een factuur de BTW te berekenen.
- Per BTW-klasse over alle factuurlijnen in één keer.
- Per afzonderlijke factuurlijn de BTW berekenen.
Voor beide rekenmethoden geldt altijd eerst: aantal maal netto prijs geeft het netto totaalbedrag. Vervolgens wordt met die totalen ofwel over het cumulatief de BTW berekend óf per factuurlijn.
Het afronden moet op 2 cijfers achter de komma en moet direct na deze bewerking worden uitgevoerd. Daarna worden de resultaten per btw klasse bij elkaar opgeteld. Als laatste worden dan alle netto bedragen en BTW bedragen bij elkaar opgeteld om op het totaal bruto uit te komen
De belastingdienst in de meeste landen accepteert beide methoden, maar je kiest als bedrijf voor één methode en die moet je altijd in alle facturen hanteren. Wisselen tussen methoden is niet toegestaan.
Bij het aanbieden aan UBL_Writer moet je er voor zorgen dat het berekende
cumulatief van de netto en de BTW bedragen bij elkaar opgeteld overeenstemmen
met het eindtotaal op de factuur. In de gegevens die je zelf aanbiedt aan
UBL_Writer is er geen eindtotaal opgenomen, UBL_writer rekent dat totaal zelf
uit aan de hand van jouw gegevens. De BTW per factuurlijn wordt niet door
UBL_Writer nagerekend, want er wordt bij de validatie van een UBL-document
alleen maar gecontroleerd of de totalen met elkar in overeenstemming zijn.
Wanneer er een (kleine) afwijking is ontstaan door afronding, dan levert die
geen probleem op voor de validatie, maar één cent verschil door een verkeerde
optelling zal wél resulteren in een mislukte validatie.
Een factuur aan UBL_Writer aanbieden om te converteren
De werking van UBL_Writer is recht toe recht aan: de inhoud moet in JSON-formaat worden aangeboden, tegelijk met een PDF-weergave die in het uiteindelijke UBL-document wordt opgenomen (embedded).
Zo'n JSON ziet er uit zoals in het voorbeeld in dit document: example.json. In de root staat 4 objecten: buyer, seller, invoice en line. de namen van de objecten en hun inhoud zijn redelijk beschrijvend en hieronder vind je een aantal toelichtingen:
| {} (root) | object (*-verplicht) | comment | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Seller {} | address * | Straat/postbus plus nummer plus toevoeging (bus in BE) | |||||||||
| city * | woonplaats | ||||||||||
| cocName * | Naam van inschrijving bij de KvK | ||||||||||
| creditorNumber | Indien bekend, het leveranciernummer waaronder verkoper bij de koper bekend staat | ||||||||||
| email * | E-mailadres van verkoper | ||||||||||
| iban * | IBAN waar het factuurbedrag naartoe moet worden overgemakt | ||||||||||
| name * | Handelsnaam van verkoper | ||||||||||
| phone | Telefoonnummer | ||||||||||
| zip * | Postcode | ||||||||||
| buyer {} | address * | Straat/postbus plus nummer plus toevoeging (bus in BE) | |||||||||
| casId (* NL) | Alleen verplicht voor Nederlandse bedrijven in facturen aan bedrijven in NL, het easId bij cocNr dus: 0106. Bedrijven buiten NL laten dit veld gewoon leeg en ook bij factureren aan bedrijven buiten NL, mag dit leeg blijven | ||||||||||
| city * | woonplaats | ||||||||||
| cocName * | Naam van inschrijving bij de KvK | ||||||||||
| cocNr | Nummer van inschrijving bij de KvK (voor België gebruik het BTWnr zonder BE er voor) | ||||||||||
| countryIso2 * | Landcode van het land volgens ISO3166-2. Zie ook de 'Valuelist: Country Code' in UBL_Writer | ||||||||||
| debtorNumber * | Het debiteurnummer waaronder koper in uw administratie of boekhouding staat | ||||||||||
| easId * | Voor NL is dit 9944 (btwnr) of 0106 (kvknr),voor BE is dit
atijd 9925. Zie de 'Valuelist: ElectronicAddressScheme' in
UBL_Writer Factureer je aan een school of een stichting die niet BTW-plichtig is, dan hebben die nooit een btwnr. In plaats daarvan hebben zij een 'GLN' of 'Global Location Number. In die gevallen wordt het easId: 0088 en het GLN wordt op de plek van het vatNr ingevuld. |
||||||||||
| email * | E-mailadres van koper | ||||||||||
| iban | Indien bekend het IBAN van de koper, bij automatische incasso is dit verplicht | ||||||||||
| name * | Handelsnaam van koper | ||||||||||
| phone | Telefoonnummer | ||||||||||
| vatNr * | BTW nummer of GLN (Global Location Number) | ||||||||||
| zip * | Postcode | ||||||||||
| invoice {} | currency * | Meestal staat hier EUR, zie ook de 'Valuelist: 'Currency Code' in UBL_Writer | |||||||||
| date * | De factuurdatum. Geef alle kalenderdata altijd op als YYYY+MM+DD, dan is de invoer ondubbelzinnig. | ||||||||||
| deliveryCountryIso2 * | Ivm de BTW moet het land van levering worden opgegeven | ||||||||||
| deliveryDate * | Datum van levering, geef hier de datum van de eerste levering of de factuurdatum op (YYYY+MM+DD) | ||||||||||
| dueDate * | De vervaldatum van de factuur (YYYY+MM+DD) | ||||||||||
| number * | Factuurnummer | ||||||||||
| paymentID (* BE) | Het betalingskenmerk. In België is dit de daar verplichte OGM code. In UBL is deze verplicht maar voor NL bedrijven wordt er automatisch debnr / factuurnr ingevuld indien dit veld leeg is gebleven | ||||||||||
| paymentMeans * | Enkele voorbeelden:
|
||||||||||
| paymentTerms * | De betaalvoorwaarden die je hanteert, bijvoorbeeld '15 dagen na
factuurdatum'. De verplichte 'dueDate' neem dit eigenlijk al voor zijn
rekening. Bij bijvoorbeeld contante betaling of met de betaalterminal, zou hier 'Reeds betaald contant/pin/betaalterminal' kunnen komen te staan |
||||||||||
| poNumber | Een purchaseOrder nummer dat door de klant is opgegeven | ||||||||||
| remark | Een opmerking die opde factuur kan zijn geplaatst | ||||||||||
| type * | 380, dit is het standaardtype UBL-factuur dat UBL_writer maakt. Er zijn andere waarden mogelijk (zie de keuzelijst: Incoice type), maar het kan zijn dat er dan voorwaarden en eisen gaan meespelen waarmee in UBL_Writer geen rekening is gehouden. | ||||||||||
| line [] | amount * | Het product van 'quantity' en 'price' | |||||||||
| buyerProject | dit kan het poNummer zijn, maar ook eennummer dat de klant per artikel heeft opgegeven | ||||||||||
| desciption * | De product omschrijving, een eventueel artikelnummer kan hier naar eigen inzicht worden toegevoegd | ||||||||||
| price * | De prijs (exclusief BTW) per factuureenheid (unit) van het product | ||||||||||
| quantity * | Aantal gefactureerde eenheden van het product | ||||||||||
| taxExempt (*) | Dit blijft leeg wanneer 'vatScheme'='S', in alle andere gevallen moet hier een geldige waarde uit de keuzelijst 'TaxExemptReason' worden ingevuld | ||||||||||
| unit * | Een waarde uit 'UnitCode' is hier verplicht. Veel gebruikt worden 'HUR' voor uren, 'H87' voor stuks etc. zi daarvoor de keuzelijst. | ||||||||||
| vatAmount * | Het a.d.h.v. 'vatPercetage' berekende BTW bedrag over 'amount'. Afronden op 2 cijfers achter de komma | ||||||||||
| vatPercentage * | Het gehanteerde BTW-percentage in procentpunten | ||||||||||
| vatScheme * | Bij normale binnenlandse facturen wordt hier 'S' ingevuld. Voor anderwe schema's de keuzelijst: 'Duty Category' raadplegen |
Voorbeeld van een functie om een JSON op te bouwen
|
Let ( [
$seller = JSONSetElement ( "{}" ; [ "address" ; Instelling::Adres ; JSONString ] ; [ "city" ; Instelling::Plaats ; JSONString ] ; [ "cocName" ; Instelling::Naam ; JSONString ] ; [ "creditorNumber" ; Debiteur::Leverancier ; JSONString ] ; [ "email" ; Instelling::Email ; JSONString ] ; [ "iban" ; Instelling::IBAN ; JSONString ] ; [ "name" ; Instelling::Naam ; JSONString ] ; [ "phone" ; Instelling::Telefoon ; JSONString ] ; [ "zip" ; Instelling::Postcode ; JSONString ] ) ; $buyer = JSONSetElement ( "{}" ; [ "address" ; Debiteur::Adres ; JSONString ] ; [ "city" ; Debiteur::Plaats ; JSONString ] ; [ "casId" ; Debiteur::CasID ; JSONString ] ; [ "cocName" ; Debiteur::Naam ; JSONString ] ; [ "cocNr" ; Debiteur::KvKnr ; JSONString ] ; [ "countryIso2" ; Debiteur::Landcode ; JSONString ] ; [ "debtorNumber" ; Debiteur::Debiteurnr ; JSONString ] ; [ "easId" ; Debiteur::EasID ; JSONString ] ; [ "email" ; Debiteur::Email ; JSONString ] ; [ "iban" ; Debiteur::IBAN ; JSONString ] ; [ "name" ; Debiteur::Naam ; JSONString ] ; [ "phone" ; Debiteur::Telefoon ; JSONString ] ; [ "vatNr" ; Debiteur::BTWnr ; JSONString ] ; [ "zip" ; Debiteur::Postcode ; JSONString ] ) ; $invoice = JSONSetElement ( "{}" ; [ "currency" ; Factuur::Valuta ; JSONString ] ; [ "date" ; Factuur::Datum ; JSONString ] ; [ "deliveryCountryIso2" ; Factuur::LeverlandCode ; JSONString ] ; [ "deliveryDate" ; Factuur::LeverDatum ; JSONString ] ; [ "dueDate" ; Factuur::VervalDatum ; JSONString ] ; [ "number" ; Factuur::Nummer ; JSONString ] ; [ "paymentID" ; Factuur::Betalingskenmerk ; JSONString ] ; [ "paymentMeans" ; Factuur::Betaalwijze ; JSONString ] ; [ "paymentTerms" ; Factuur::Betaalvoorwaarden ; JSONString ] ; [ "poNumber" ; Factuur::PoNummer ; JSONString ] ; [ "remark" ; Factuur::Commentaar ; JSONString ] ; [ "type" ; Factuur::TypeFactuur ; JSONString ] ) ; $line = While ( [ i = 0 ; n = ValueCount ( List ( Regel::_UUID ) ) ; x = "[]" ] ; i < n ; [ i = i + 1 ; x = JSONSetElement ( x ; [ "[+]amount" ; GetNthRecord ( Regel::_cBedrag ; i ) ; JSONString ] ; [ "[:]buyerProject" ; Factuur::PoNummer ; JSONString ] ; [ "[:]description" ; GetNthRecord ( Regel::Omschrijving ; i ) ; JSONString ] ; [ "[:]price" ; GetNthRecord ( Regel::Prijs ; i ) ; JSONNumber ] ; [ "[:]quantity" ; GetNthRecord ( Regel::Aantal ; i ) ; JSONNumber ] ; [ "[:]taxExempt" ; GetNthRecord ( Regel::BtwVrijstelling ; i ) ; JSONString ] ; [ "[:]unit" ; GetNthRecord ( Regel::Eenheid ; i ) ; JSONString ] ; [ "[:]vatAmount" ; GetNthRecord ( Regel::_cBtw ; i ) ; JSONNumber ] ; [ "[:]vatPercentage"; GetNthRecord ( Regel::BtwPerc ; i ) ; JSONNumber ] ; [ "[:]vatScheme" ; GetNthRecord ( Regel::BtwSchema ; i ) ; JSONString ] ) ] ; x ) ] ; JSONSetElement ( "{}" ; [ "seller" ; $seller ; JSONObject ] ; [ "buyer" ; $buyer ; JSONObject ] ; [ "invoice" ; $invoice ; JSONObject ] ; [ "line" ; $line ; JSONArray ] ) ) |
