Advies is om bij geval 3 de HTTP-statuscode te controleren. De tabel ExactOnlineREST.FinancialTransaction.TransactionLinesIncremental@eol
bestaat niet; wel bestaat deze tabelnaam in het Incremental
-schema (zie TransactionLinesIncremental: Exact Online Transactieregels (Incrementeel) - Exact Online API Data Model).
Merk op dat het downloaden relatief lang duurt om het een Free Exact Online Plan betreft; deze kent 1 parallel downloadkanaal.
Geval 1
Bij geval 1 komen inderdaad vier regelnummers retour in de browser: 0, 1, 2 en 9999.
Het SQL-statement in Invantive Bridge Online Monitoring is:
select t.*
from ExactOnlineREST.FinancialTransaction.TransactionLines@eol t
where ([EntryNumber] = :w1)
met w1: 20230416
De data is opgeslagen als geval1.json
(12 kB) en vervolgens gecontroleerd via:
select jte.*
from read_file_text@Os('C:\temp\forums3468\geval1.json') rft
join jsontable
( 'value[*]'
passing rft.file_contents
columns EntryNumber int64 path 'EntryNumber'
, LineNumber int16 path 'LineNumber'
) jte
where jte.EntryNumber = 20230416
order
by jte.LineNumber
met als resultaat:
Geval 2
Bij geval 2 worden initieel eerst alle transactieregels gedownload via:
curl --output c:\temp\geval2.json --user vimak@favoreclame.nl:Q0i9h@7uiI6GDAorsgmq https://bridge-online.cloud/7c5b8d84-16a0-49bb-b4e7-3a9a73df59ff/odata4/ExactOnlineREST.FinancialTransaction.TransactionLines@eol
Het SQL-statement in Invantive Bridge Online Monitoring is:
select t.*
from ExactOnlineREST.FinancialTransaction.TransactionLines@eol t
De data is opgeslagen als geval2.json
(373.870 kB) en vervolgens gecontroleerd via:
select jte.*
from read_file_text@Os('C:\temp\forums3468\geval2.json') rft
join jsontable
( 'value[*]'
passing rft.file_contents
columns EntryNumber int64 path 'EntryNumber'
, LineNumber int16 path 'LineNumber'
) jte
where jte.EntryNumber = 20230416
order
by jte.LineNumber
met als resultaat enkel regels 0 en 2:
Geval 3
Bij geval 3 is met de gecorrigeerde URL de download uitgevoerd: .../odata4/ExactOnlineREST.Incremental.TransactionLinesIncremental@eol
via:
curl --output geval3metcorrectie.json --user john.doe@acme.com:secret https://bridge-online.cloud/ACME/odata4/ExactOnlineREST.Incremental.TransactionLinesIncremental@eol
Het SQL-statement in Invantive Bridge Online Monitoring is:
select t.*
from ExactOnlineREST.Incremental.TransactionLinesIncremental@eol t
De data is opgeslagen als geval3metcorrectie.json
(177.780 kB) en vervolgens gecontroleerd via:
select jte.*
from read_file_text@Os('C:\temp\forums3468\geval3metcorrectie.json') rft
join jsontable
( 'value[*]'
passing rft.file_contents
columns EntryNumber int64 path 'EntryNumber'
, LineNumber int16 path 'LineNumber'
) jte
where jte.EntryNumber = 20230416
order
by jte.LineNumber
Deze query leidt tot nul regels.
Analyse
Analyse 1: volledigheid en consistentie
Als eerste stap is gekeken naar volledigheid en consistentie. De volgende statistieken zijn opgevraagd met onderliggende SQL:
Geval | #Rijen | #LineNumber = 0 | #LineNumber = 1 | #LineNumber = 9999 |
---|---|---|---|---|
1 | 4 | 1 | 1 | 1 |
2 | 130621 | 17100 | 22775 | 15394 |
3 | 130621 | 16904 | 22590 | 15146 |
De verwachting is dat de laatste LineNumber 0 en 9999-kolommen grofweg dezelfde waardes bevatten. Dit geldt alleen voor geval 1.
Ter verdieping is in lijn met Schatten omvang Exact Online administratie een server-side telling uitgevoerd van de data in Exact Online. Het aantal rijen was:
Divisiecode | Rijen |
---|---|
2575738 | 2793 |
1861032 | 127828 |
Totaal | 130621 |
Het positieve is dat 130621 aansluit bij de tweede kolom van de eerste tabel bij analyse 1. Echter, het is bijzonder vreemd dat regelnummer 0, 1 en 9999 een verschillende distributie hebben.
Vervolgens is de JSON geanalyseerd voor het aantal transacties overall en per LineNumber 0, 1, 2 en 9999. De getallen bij #LineNumber = 0 en #LineNumber = 9999 zouden grofweg gelijk moeten zijn, en met regelnummer 1 in de buurt. Later is ook #LineNumber is null
toegevoegd omdat dat als onverwachte uitkomst er uit kwam.
Geval | #Overall | #LineNumber=0 | #LineNumber=1 | #LineNumber=2 | #LineNumber=9999 | #LineNumber is null |
---|---|---|---|---|---|---|
1 | 1 | 1 | 1 | 0 | 1 | 0 |
2 | 25058 | 17013 | 19988 | 6130 | 15306 | 3 |
3 | 19218 | 16845 | 19191 | 5688 | 15072 | 3 |
Het voorkomen van LineNumber is null
is uitzonderlijk. Historisch werd - leek het - in de API’s het regelnummer berekend i.p.v. ruw doorgegeven, waardoor regels soms een andere volgorde kregen. Een jaar of 6 geleden is hierin tenminste een verbetering doorgevoerd, maar het ontbreken van een LineNumber
leidt tot per definitie tot problemen in de uitkomsten. Het is dan niet bekend of een regel een kopregel of BTW-regel is, anders dan uit de context van andere velden (zie ook Bijzondere regelnummers zoals 9999 op financiële transacties in Exact Online).
De transacties met een boeking zonder regelnummer zijn zowel in geval 2 als in geval 3: 16900002, 17900033, 18900066. Uit controle blijkt dat dit resultaatboekingen zijn over de jaren 2016, 2017 en 2018. Een controle tegen een aantal andere administraties die nog in gebruik zijn leert dat dit voor die administraties ook geldt: in de jaren 2009…2015 zijn er een aantal boekingen voor BTW en resultaat zonder regelnummer. Blijkbaar is dit probleem niet in 2016 gecorrigeerd, maar in 2019 lijkt het.
Het probleem met LineNumber is null
vervalt hiermee.
Blijft het probleem met de afwijkende aantallen boekstukken per regelnummer, terwijl het totaal wel sluit qua aantal boekstukregels.
Vervolgens is de scope uitgebreid met twee gevallen: TransactionLinesBulk
(geval 4) en SyncTransactionLines
(geval 5), in eerste instantie via enkele SQL-queries.
Metingen met rijen geven:
Geval | #Rijen | #LineNumber = 0 | #LineNumber = 1 | #LineNumber = 9999 |
---|---|---|---|---|
1 (OData4) | 4 | 1 | 1 | 1 |
2 (OData4) | 130621 | 17100 | 22775 | 15394 |
3 (OData4) | 130621 | 16904 | 22590 | 15146 |
4 (SQL) | 130621 | 22503 | 29627 | 20128 |
5 (SQL) | 130621 | 22503 | 29627 | 20128 |
Vervolgens zijn de metingen uitgebreid met ook gevallen 1, 2 en 3 via SQL uit te voeren en geval 4 en 5 via OData4:
Geval | #Rijen | #LineNumber = 0 | #LineNumber = 1 | #LineNumber = 9999 |
---|---|---|---|---|
1 (OData4) | 4 | 1 | 1 | 1 |
1 (SQL) | 4 | 1 | 1 | 1 |
2 (OData4) | 130621 | 17100 | 22775 | 15394 |
2 (SQL) | itgeneor229 | itgeneor229 | itgeneor229 | itgeneor229 |
3 (OData4) | 130621 | 16904 | 22590 | 15146 |
3 (SQL) | 130621 | 22503 | 29627 | 20128 |
4 (SQL) | 130621 | 22503 | 29627 | 20128 |
5 (SQL) | 130621 | 22503 | 29627 | 20128 |
Hierbij valt het op dat de uitkomsten bij verwerking met SQL en OData4/JSON anders zijn voor geval 3.
Vervolgens is een analyse gemaakt van de meeste voorkomende omschrijvingen. Hierbij kwam naar voren dat het abonnement geen downloads groter dan 100.000 rijen toestaat (deze controle wordt momenteel niet uitgevoerd bij de SQL Editor van Invantive Cloud):
Omschrijving | Aantal |
---|---|
invantive.com | 15.212 |
itgenboe115 TOO MANY | 15.189 |
Prijs ex. BTW | 10.410 |
… |
De foutcode itgenboe115
(evenals itgenboe116
, itgenboe114
, itgenboe294
en itgenboe295
) geeft aan dat de regel betrekking heeft op rij boven de 100.000.
Vervolgens is gekeken wat de EntryNumber
en LineNumber
zijn van deze gevallen. Hierbij bleek dat deze volledig ontbreken. Bij controle blijkt dit gewenst gedrag te zijn. Als er meer gedownload wordt dan het abonnement toestaat, dan worden deze velden leeggemaakt indien het datatype dat toestaat.
Eindconclusie is dat het gedrag verklaarbaar is doordat er meer gedownload wordt dan het abonnement toestaat.
Advies is om het abonnement te upgraden van het Free Exact Online Plan naar Invantive Office for Entrepreneurs.
In de programmatuur zijn een aantal verbeteringen uitgevoerd om deze analyse onnodig te maken:
- De lijst met stappen onderaan bij elk requestdetails toont
itgenboe375
enitgenboe376
indien er voor demo-, licentie- of anonymisatie-doeleinden gegevens gewijzigd zijn. - De datawijziging voor licentiebeperking is aangepast zodat er meer duidelijk herkenbare punten zijn, zoals de GUID “CA5B2B7F-7D93-49CB-BE8A-716A78C1D692” en “90C55B00-AD37-404D-A0FC-A3B0F2CACB71”.
Gebruikte SQL
Gebruikte SQL:
select count(*)
from read_file_text@Os('FILENAME.json') rft
join jsontable
( 'value[*]'
passing rft.file_contents
columns EntryNumber int64 path 'EntryNumber'
, LineNumber int16 path 'LineNumber'
) jte
select jte.LineNumber
, count(*)
from read_file_text@Os('FILENAME.json') rft
join jsontable
( 'value[*]'
passing rft.file_contents
columns EntryNumber int64 path 'EntryNumber'
, LineNumber int16 path 'LineNumber'
) jte
where jte.LineNumber in (0, 1, 9999)
group
by jte.LineNumber
order
by LineNumber
--
-- Tel rijen.
--
create or replace table countqueries@inmemorystorage
as
select ste.name
, sdn.label
, sdn.code
, replace(ODATA_SERVICE_URL_FOR_SELECT, '{division}', sdn.code) || '/$count'
url
, ste.name || ' @ ' || sdn.label
orig_system_group
from SystemDivisions@eol sdn
join SYSTEMTABLES@DataDictionary ste
on ste.PROVIDER_NAME = 'ExactOnlineAll'
and ste.CATALOG = 'ExactOnlineREST'
and ste.schema = 'Sync'
and ste.name = 'SyncTransactionLines'
--
-- Stuur de API-verzoeken zonder verdere interpretatie door als een
-- "Native Scalar Request". De resultaten worden vastgelegd in
-- dezelfde tabel "NativePlatformScalarRequest".
--
-- Er wordt gebruik gemaakt van XML-output. JSON wordt verkregen
-- door Content-Type in te stellen.
--
insert into exactonlinerest..nativeplatformscalarrequests@eol
( url
, orig_system_group
, fail_on_error
)
select url
, orig_system_group
--
-- Vervang door false als je niet overal rechten op hebt en true
-- als je dat wel zeker hebt.
-- Tabellen waar de huidige Exact Online gebruiker geen rechten
-- op heeft worden bij false stilletjes overgeslagen.
--
, false
from COUNTQUERIES@InMemoryStorage
--
-- Per tabel en administratie het aantal rijen.
--
select orig_system_group
, RESULT_TEXT
from exactonlinerest..NATIVEPLATFORMSCALARREQUESTS@eol
where SUCCESSFUL = 'Y'
and orig_system_group is not null
select jte.Description
, count(*)
from read_file_text@Os('C:\temp\forums3468\geval2.json') rft
join jsontable
( 'value[*]'
passing rft.file_contents
columns EntryNumber int64 path 'EntryNumber'
, LineNumber int16 path 'LineNumber'
, Description varchar2 path 'Description'
) jte
group
by jte.Description
select jte.*
from read_file_text@Os('C:\temp\forums3468\geval2.json') rft
join jsontable
( 'value[*]'
passing rft.file_contents
columns EntryNumber int64 path 'EntryNumber'
, LineNumber int16 path 'LineNumber'
, Description varchar2 path 'Description'
) jte
where jte.Description like 'invantive%'
or jte.Description like 'itgenboe115%'