Huom: kirjoituksessa ei puhuta Finvoicen validiudesta itse XML-spesifikaation kanssa, vaan laajemmin XML-määritysten ja hyvien tapojen mukaisesti. Kun jo tuolla eräs ehti viilata pilkkua :) Toki Finvoicen tuotokset menevät XML-parserista läpi, mutta ne eivät ole "hengen mukaisia."
Vilkaisin taas Finvoicen speksejä, kun pitäisi toteuttaa laskun tulostus sitä kautta. Jo vuosia sitten kritisoin tuota ja kyselin tekijöiltä miksi ihmeessä asiat on tehty aivan päin mäntyä. Vastaus oli "tuli vähän kiire." En tajua miten kiire selittää sen, ettei otettu edes perusasioita osaavia ihmisiä tekemään määrittelyä.
Ne, jotka eivät ole Finvoiceen tutustuneet, se on XML-muotoisten laskutietojen välitykseen tarkoitettu standardi. XML taas on rakenteellisten tietojen välitykseen tarkoitettu kieli. Huomatkaa sana "rakenteellisten." Tätä meinaan Finvoicen speksaajat eivät ymmärtäneet.
Normaalisti, jos määriteltäisi vaikkapa katuosoite, sille voidaan antaa täginimi StreetName. Tämä voidaan sitten laittaa vaikkapa Sender-tägin alle, tai Recipient, tai minkä vain. Tiedetään aina, että tuossa on osoite. Miten tekivät Finvoicen speksaajat? Unohtivat kokonaan, että kyse on rakenteellisesta ja tekivät useita eri tägejä osoitteelle. Löytyy SellerStreetName ja tietysti erikseen BuyerStreetName, puhumattakaan DeliveryStreetName:sta. Eli rikottiin XML:n perusidea. Nämä tägit laitetaan tietysti esimerkiksi DeliveryPostalAddressDetails-tägin alle, joka on DeliveryPartyDetails-tägin alla.
Eli siis oikea tapa olisi tämä:
<Seller>
<Address>
<StreetName>Koulukatu 1</StreetName>
</Address>
</Seller>
Onko tuota vaikea lukea ja ymmärtää, että tuo on myyjän katuosoite? Ei. Mutta Finvoicessa asia tehdään näin:
<SellerPartyDetails>
<SellerPostalAddressDetails>
<SellerStreetName>Koulukatu 1</SellerStreetName>
</SellerPostalAddressDetails>
</SellerPartyDetails>
Tässä siis käytetään turhan pitkiä tägejä, ei hyväksikäytetä XML:n sisäänrakennettua rakenteellisuuta eikä anneta mahdollisuutta määrittää suoraan, että StreetName:lla pitää olla tietty esitysmuoto. Tehdään sitten kolme esitysmuotomääritystä ja yritetään muistaa päivittää kaikki kolme, kun muutoksia tulee.
Mitä tämä sitten tarkoittaa? Sitä, että jos haluat jotenkin käyttää osoitetietoja, sinun pitää määritellä asioita moneen kertaan. Sen sijaan, että tietäisit StreetNamen olevan aina katuosoite, pitää nyt määrittää kolme tägiä, jotka ovat katuosoite.
Samoin jatkuva Seller/Buyer/Delivery-alkuosien toitotus on turhaa. Se vain aiheuttaa ylimääräistä tietoliikennettä ja sotkee tiedonkäsittelyä. Oletan, että nämä on haluttu siksi, että ihminen voisi tietoja lukea. Mutta se ei ole tarpeen, sillä ihminen osaa lukea rakenteellista tietoa, kunhan se esitetään vaikkapa sisennettynä. Josta pääsemmekin seuraavaan ongelmaan.
Sisennyksiä ei saa tehdä! Speksi sanoo selvästi: "Jokaisen rivin pitää alkaa "<"-merkillä ja päättyä ">"-merkkiin." Miksi ihmeessä? XML-parserit osaavat kyllä lukea oikeamuotoista XML:ää. Taasko halutaan, että ihminen voi lukea tiedostoa suoraan? Sitten voi käyttää työkalua, joka muotoilee sen näin, jos halutaan.
Myöskin merkistö on pakotettu: "Finvoice-sanomilla käytetään ISO-8859-15-merkistöä." Eli en voi määritellä kyrillisillä merkeillä tietoja, en kanjeilla, en mitenkään. Miksen? Ei sillä että itse heti tarvitsisin, mutta koko maailma ei pyöri tuon merkistön ympärillä. XML-parserit osaavat kyllä lukea eri merkistöjä ongelmitta. Eivätkö tekijät osaa?
Lukuarvot pitää myös esittää XML-määritysten vastaisina. XML-serialisoinnissa käytetään yleisesti lukuarvoissa pistettä desimaalierottimena. Finvoice vaatii pilkun. Myöskin desimaalimäärät on pakotettu, ihan vain "jotta verkkopankissa
e-laskusta voidaan muodostaa maksuehdotus." Pankin järjestelmätkö eivät osaa lukea standardimukaista numerotietoa, ainoastaan tietyllä tavalla määritettyä? Toteutettiin kokonainen Finvoice-palikka, muttei osattaisi tehdä asioita oikein?
Laskurivejä voi myös olla monenlaisia. Laskurivillä ei välttämättä tarvitse olla edes mitään laskurivitietoja! Kaikki ovat silti InvoiceRow. Miksei näitä voitu tehdä omilla tägeillään? "Laskurivi" voi olla vaikkapa vapaamuotoista tekstiä tai välisumma. Ei näin.
Myöskin 2.0-esimerkkitiedostossa on paljon kohtia, joista ei soveltamisohjeessa puhuta mitään. Pitää siis lukea skeematiedostoa ja muita dokumentteja ja arpoa, sen sijaan, että olisi tehty kunnon dokumentaatio.
Miksi meillä on mm EpiBfiPartyDetails sekä EpiBeneficiaryPartyDetails, jotka molemmat kertovat samoista tiedoista?
Miksi esimerkissä on 0 % ALVilla 622,68 euron summa 1500 eurosta? Kopypaste toiminut...
Viitenumeron pitää olla tämän speksin mukaan joko eurooppalainen vaihtelevanpituuksinen tai SPYn mukainen, mutta väkisin 20 numeroa. Harva käyttää 20-numeroisia viitteitä, mutta nyt niihin on sitten pakko laittaa etunollat?
EpiCharge-tägin sisällön pituus pitää olla nolla. Esimerkissä sillä on sisältöä, eli esimerkkilasku ei ole validi. Myöskin esimerkkilasku on kotimaan lasku, silti maksuehto on SEPAn mukainen SLEV eikä kotimainen SHA. Tietenkään en dokumentaatiosta löytänyt tarkemmin tietoa mitä nämä SHA/OUR/SLEV/BEN tarkoittavat, mutta sellaisia arvoja sinne voi laittaa. Ja kuka ihme keksi tägin EpiDateOptionDate?
Pikku huvituksena oli myös yksikköesimerkkinä oleva kwh/h...
Huvittavaa on myös esimerkkilaskussa oleva teksti: "Tavoitteena on, että Finvoice-laskumallia käyttävät yritykset voivat hyödyntää laskun konekielisesti käsiteltäviä tietoja suoraan omissa taloushallinnon järjestelmissä ilman ylimääräisiä muunnoksia. Yhteisestä mallista hyötyy kaikki osapuolet." Niin, miten tästä nyt sitten ilman ylimääräisiä muunnoksia käytetään tietoja hyväksi, kun tiedot on ripoteltu huonosti tägitettyinä, speksinvastaisilla lukuarvoilla ja käytetään yhtä tägiä osoittamaan laskurivejä, seliterivejä ja välisummia? Tämä vain vaikeuttaa tietojen käsittelyä suoraan, ilman muunnoksia. Mutta onko porukassa ketään, joka tämän ymmärtäisi? Ei.
Toki voisi kuvitella, että kun kerran alunperin tehtiin väärin, pakko jatkaa niin. Ei ole. Nyt kun kerran tuli versio 2.0, miksei tähän korjattu asioita? Kuitenkin joudutaan muuttamaan laskun muodostamista ja lukemista, joten samalla vaivalla olisi korjattu nämä asiat ja oikeasti tehty yleismaailmallinen standardi. Nyt tyydyttiin laajentamaan olemassaolevaa ja tekemään asiat vieläkin päin mäntyä. Ja näin varmasti jatkossakin.
Tässä vain taas muutama asia, joihin törmäsin heti määritystä selatessani. Enemmänkin löytyisi, jos kaivaisi. Ja pakko kai on, kun muuten ei saa toteutettua määritystä. Nyt vain pitää muistaa pakottaa XML-tulostus juuri oikeanlaiseksi, kun Pankkiyhdistyksen väki ei osaa muuten lukea tietoja. XML-parserit kyllä osaisivat ilman mitään ongelmia.
Hei Pankkiyhdistys! Ensi kerralla kun teette jotain tällaista, ottakaa vaikka minut konsultoimaan asiassa. Voin vaikka tulla ilmaiseksi niin ei tarvitse sitten tuhlata aikaa puolivillaisten sähellysten kanssa touhuamiseen. Säästän joka tapauksessa aikaa ja rahaa sillä. Kiitos!