Enquête F01DGS voor Nationale Bank van België met Exact Online

Enquête

Voor België geldt dat alle ingezetenen wettelijk verplicht zijn de aangifte over hun buitenlandse transacties rechtstreeks aan de NBB (Nationale Bank van België) te leveren. Deze enquête beoogt meer specifiek de dienstentransacties met nietingezetenen.

In Nederland kennen we sinds ongeveer 2004 een vergelijkbare rapportage via DNB aan ECB (DRA), de dienstenrapportage. Dat moet ongeveer het jaar zijn geweest dat we in 3 maanden tijd de volledige DNB/PVK-rapportages volgens WTK gerealiseerd hebben en ergens in die tijd heb ik mijn haren verloren en hopelijk wijsheid gewonnen.

Exact Online

Ook vanuit de Belgische Exact Online kun je deze rapportage automatisch samenstellen. En eigenlijk is dat makkelijker dan een DNB-rapportage. Je kunt bijvoorbeeld met de Exact Online editie van de plug-in “Invantive Control for Excel” de gegevens opvragen. Maar het kan ook met alleen de gratis versie van het Invantive Query Tool.

Een manier om de gegevens te verzamelen is om per leverancier bij te houden als classificatie welke soort van activiteit normaliter afgenomen wordt en op die manier alle transacties met die leverancier per activiteitscode te groeperen en te rapporteren.

F01DGS Queries

De volgende twee queries verzamelen de informatie op basis van de REST API en Invantive SQL. De queries zijn ook terug te vinden bij de menuoptie “Scripts” in Invantive Query Tool.

Eerst de transacties:

select gltransaction_date
,      account_code_attr
,      account_name
,      description
,      amount_value
,      finyear_number_attr
,      finperiod_number_attr
from   GLTransactionlines
where  yearrange_from=<>
and    yearrange_to=<>
and    period_from=<>
and    period_to=<>
--
-- There is a counter party involved.
--
and    account_code_attr is not null 
--
-- Tussenrekening debiteuren.
--
and    glaccount_code_attr = '<>' 
--
-- Accounts Receivables.
--
and    glaccount_type_attr = 22 
--
-- Exclude exchange rate differences.
--
and    gltransaction_transactiontype_number_attr != 82 
--
-- Only in-flow.
--
and    amount_value < 0
order
by     gltransaction_date

En dan de leveranciers en hun classificaties:

select account_code_attr
,      account_name
,      account_vatnumber
,      property_code_attr
,      property_description
from   AccountClassifications
where  sequencenumber_attr = 1
order
by     account_code_attr

Voor gebruik met de 2022 versies van de Exact Online API’s biedt het volgende script een basisexport van de afnames:

select tle.Date
,      tle.Account
,      act.Code AccountCode label 'Account Code'
,      act.Name AccountName label 'Account Name'
,      tle.description
,      tle.AmountDC
,      tle.FinancialYear
,      tle.FinancialPeriod
from   TransactionLinesIncremental tle
join   AccountsIncremental act
on     act.id = tle.Account
where  tle.FinancialYear = 2022
and    tle.FinancialPeriod between 1 and 3
--
-- There is a counter party involved.
--
and    tle.Account is not null
--
-- Tussenrekening debiteuren.
--
and    tle.GLAccount 
       in
       ( select /*+ low_cost */ id 
         from   GLAccountsIncremental 
         where  code = '400000'
         and    type = 20 /* Accounts Receivables. */
       )
--
-- Exclude exchange rate differences.
--
and    tle.Type != 82
--
-- Only in-flow.
--
and    tle.AmountDC < 0
order
by     tle.Date

local export results as "${system:userdocumentsdirectory}\transactieregels.xlsx" format xlsx include headers

select act.Code
,      act.name
,      act.VATNumber
,      act.Country
from   act.AccountsIncremental act
order
by     Code

local export results as "${system:userdocumentsdirectory}\relaties.xlsx" format xlsx include headers

Mocht informatie per artikel nodig zijn en niet het cashflow-moment maar het factuurmoment, dan kan ook gewerkt worden voor F01DGS met:

--
-- Druk op F5 om alles uit te voeren.
--
select /*+ result_set_name('Transactieregels') */ 
       tle.Date
,      tle.EntryNumber
,      tle.LineNumber
,      act.Code AccountCode label 'Account Code'
,      act.Name AccountName label 'Account Name'
,      act.VATNumber AccountVATNumber label 'Account VAT number'
,      act.Country AccountCountry label 'Account Country'
,      tle.description
,      tle.AmountDC
,      tle.FinancialYear
,      tle.FinancialPeriod
,      itm.Code ItemCode
,      itm.Description ItemDescription
,      igp.Code ItemGroupCode
from   TransactionLinesIncremental tle
join   ItemsIncremental itm
on     itm.Id = tle.Item
join   ExactOnlineREST..ItemGroups igp
on     igp.Id = itm.ItemGroup
join   AccountsIncremental act
on     act.id = tle.Account
where  tle.FinancialYear = 2023
--
-- No total line and no VAT line.
--
and    tle.LineNumber not in (0, 9999)
and    ( tle.FinancialPeriod between 1 and 3 )
--
-- There is a counter party involved.
--
and    tle.Account is not null
and    tle.JournalCode in ('700', '710')
order
by     tle.Date

local export results as "${system:userdocumentsdirectory}\transactieregels.xlsx" format xlsx include headers

select act.Code
,      act.name
,      act.VATNumber
,      act.Country
from   act.AccountsIncremental act
order
by     act.Code

local export results as "${system:userdocumentsdirectory}\relaties.xlsx" format xlsx include headers

Ik gebruik de volgende applicatiemodule voor F01DGS met Invantive Cloud:

declare
  p_run           boolean;
  p_jaar          number;
  p_maand_start   number;
  p_maand_einde   number;
  --
  l_workbook      excel_workbook;
  l_worksheet     excel_worksheet;
  l_xlsx_filename varchar2;
  l_binary        blob;
begin
  --
  -- Get parameters.
  --
  p_run := cast(cloud_http.get_request_form_value('p_run') as boolean);
  --
  if coalesce(p_run, false) = false
  then
    --
    -- Enter parameters manually (currently solely a button to start synchronization).
    --
    cloud_http.set_use_template(true);
    cloud_http.set_template_step_name(translate_resources('{res:itgen_parameters}'));
    cloud_http.append_line_to_response_body_text('<form method="post" enctype="multipart/form-data">');
    cloud_http.append_line_to_response_body_text('<input type="hidden" id="p_run" name="p_run" value="true"/>');
    cloud_http.append_line_to_response_body_text('<ul>');
    cloud_http.append_line_to_response_body_text('<li><label for="p_jaar">Boekjaar</label></li><li><input type="number" id="p_jaar" name="p_jaar" value="true" min="2020" max="2999" /></li>');
    cloud_http.append_line_to_response_body_text('<li><label for="p_maand_start">Boekperiode vanaf</label></li><li><input type="number" id="p_maand_start" name="p_maand_start" value="true" min="1" max="12" /></li>');
    cloud_http.append_line_to_response_body_text('<li><label for="p_maand_einde">Boekperiode tot/met</label></li><li><input type="number" id="p_maand_einde" name="p_maand_einde" value="true" min="1" max="12" /></li>');
    cloud_http.append_line_to_response_body_text('<li><input type="submit" value="Download"/></li>');
    cloud_http.append_line_to_response_body_text('</ul>');
    cloud_http.append_line_to_response_body_text('</form>');
  else
    --
    -- Maak rapport.
    --
    p_jaar := to_number(cloud_http.get_request_form_value('p_jaar'));
    p_maand_start := to_number(cloud_http.get_request_form_value('p_maand_start'));
    p_maand_einde := to_number(cloud_http.get_request_form_value('p_maand_einde'));
    --
    if p_jaar is null
    then
      raise_application_error(-20163, 'Het boekjaar ontbreekt.');
    end if;
    if p_jaar > year(sysdateutc)
    then
      raise_application_error(-20163, 'Het boekjaar ligt in de toekomst.');
    end if;
    if p_maand_start is null
    then
      raise_application_error(-20163, 'De start boekperiode ontbreekt.');
    end if;
    if p_maand_einde is null
    then
      raise_application_error(-20163, 'De eind boekperiode ontbreekt.');
    end if;
    if p_maand_einde < p_maand_start
    then
      raise_application_error(-20163, 'De eind boekperiode ligt voor de start boekperiode.');
    end if;
    --
    create or replace table transacties@inmemorystorage
    as
    select /*+ result_set_name('Transactieregels') */ 
           tle.Date
           label 'Boekdatum'
    ,      tle.EntryNumber
           label 'Boekstuknummer'
    ,      tle.LineNumber
           label 'Regelnummer'
    ,      act.Code AccountCode label 'Relatiecode'
    ,      act.Name AccountName label 'Relatienaam'
    ,      act.VATNumber AccountVATNumber label 'Relatie BTW-nummer'
    ,      act.Country AccountCountry label 'Relatie Land'
    ,      tle.description
           label 'Omschrijving'
    ,      tle.AmountDC
           label 'Bedrag'
    ,      tle.FinancialYear
           label 'Boekjaar'
    ,      tle.FinancialPeriod
           label 'Boekperiode'
    ,      itm.Code 
           ItemCode
           label 'Artikelcode'
    ,      itm.Description 
           ItemDescription
           label 'Artikelomschrijving'
    ,      igp.Code 
           ItemGroupCode
           label 'Artikelgroep'
    from   TransactionLinesIncremental@eol tle
    left
    outer
    join   ItemsIncremental@eol itm
    on     itm.Id = tle.Item
    left
    outer
    join   ExactOnlineREST..ItemGroups@eol igp
    on     igp.Id = itm.ItemGroup
    join   AccountsIncremental@eol act
    on     act.id = tle.Account
    where  tle.FinancialYear = p_jaar
    --
    -- No total line and no VAT line.
    --
    and    tle.LineNumber not in (0, 9999)
    and    ( tle.FinancialPeriod between p_maand_start and p_maand_einde )
    --
    -- There is a counter party involved.
    --
    and    tle.Account is not null
    and    tle.JournalCode like '7%'
    order
    by     tle.Date
    ;
    create or replace table relaties@inmemorystorage
    as
    select act.Code label 'Code'
    ,      act.name label 'Naam'
    ,      act.VATNumber label 'BTW-nummer'
    ,      act.Country label 'Land'
    from   act.AccountsIncremental@eol act
    order
    by     act.Code
    ;
    --
    -- Retrieve results as an Excel workbook.
    --
    l_xlsx_filename := 'rapport-' || to_char(sysdateutc, 'YYYYMMDDHH24MISS') || '.xlsx';
    l_workbook := excel.new();
    --
    -- Add a worksheet with a title.
    --
    l_worksheet := excel.add_worksheet
    ( l_workbook
    , 'Parameters'
    );
    excel.set_cell_contents(l_worksheet, 'A1', 'Data voor F01DGS');
    excel.set_cell_contents(l_worksheet, 'A3', 'Aangemaakt (UTC)');
    excel.set_cell_contents(l_worksheet, 'B3', sysdateutc);
    excel.set_cell_contents(l_worksheet, 'A4', 'Boekjaar');
    excel.set_cell_contents(l_worksheet, 'B4', p_jaar);
    excel.set_cell_contents(l_worksheet, 'A5', 'Boekperiode vanaf');
    excel.set_cell_contents(l_worksheet, 'B5', p_maand_start);
    excel.set_cell_contents(l_worksheet, 'A6', 'Boekperiode tot/met');
    excel.set_cell_contents(l_worksheet, 'B6', p_maand_einde);
    --
    l_worksheet := excel.add_worksheet
    ( l_workbook
    , 'Transacties'
    );
    excel.fill_using_query(l_worksheet, 'select * except rowid$ from transacties@inmemorystorage');
    --
    l_worksheet := excel.add_worksheet
    ( l_workbook
    , 'Relaties'
    );
    excel.fill_using_query(l_worksheet, 'select * except rowid$ from relaties@inmemorystorage');
    --
    -- Retrieve the resulting XLSX-file.
    --
    l_binary := excel.export_to_xlsx(l_workbook);
    --
    -- Return the XLSX file to the user.
    --
    cloud_http.set_response_body_binary(l_binary);
    cloud_http.set_response_content_type('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    cloud_http.set_response_header_value('Content-Disposition', 'attachment; filename="' || l_xlsx_filename || '"');
  end if;
end;