Skip to content

gem for assist working with SAF-T (Standard Audit File for Tax)

Notifications You must be signed in to change notification settings

dodoas/ruby-saft

Repository files navigation

SAF-T (Standard Audit File for Tax)

SAF-T is developed by OECD (Organisation for Economic Co-operation and Development). v1.0 was shipped in 2005, v2.0 was shipped in 2010.

https://en.wikipedia.org/wiki/SAF-T

Skatteetaten = The norwegian tax administration

In Norway we use version v2.0 of the format, but Skatteetaten in Norway has make some modifications and released their own versioning starting on v1.0, but that was a continuation on v2.0. I believe the only changes are related to which nodes should be used for what, so 100% backward compatible for SAF-T v2.0.

This gem is developed to work in Norway but it should be possible to make it work for all SAF-T versions. We didn't implement all Nodes but it should be quite easy to add.

Tested and verified for: None yet, Norway is in development

Even if you are able to create a AuditFile instance it doesn't mean it is valid per the xsd. There are some nodes where you have to choose this set of nodes or this other set of nodes. It would be possible to create such a structure with dry-stuct as well but we would end up with a lot more Nodes, also a bigger difference on xml structure and structs.

Setup

# if you use SAF-T to write xmls you probably want the files to be as compact as
# possible in production but nicely formatted in development end test.
# default value is AS_XML

if production
  SAFT.nokogiri_save_setting = Nokogiri::XML::Node::SaveOptions::AS_XML
else
  SAFT.nokogiri_save_setting = Nokogiri::XML::Node::SaveOptions::DEFAULT_XML
end

Usage

require "saft"

# read a SAF-T file

xml = File.read("saft.xml")
audit_file = SAFT::V2.parse(xml) # instance of SAFT::V2::Types::AuditFile or raises type errors
audit_file.header.company.name #  name from xml

# create a SAF-T file
audit_file = SAFT::V2::Types::AuditFile.call({
  header: {
    audit_file_version: "1.10",
    audit_file_country: "NO",
    audit_file_date_created: Date.today,
    # ...
  }
})

xml_content = SAFT::V2.scribe(audit_file)
# it is recommended to validate against the xsd before taking it further because 
# it is possible to create invalid xml
validations = SAFT::V2.validate(xml_content)
validations.valid? # true || false
validations.errors? # [] # array of Nokogiri::XML::SyntaxError from xsd errors

We supply three types of AuditFile which all can be used to generate the xml. Relaxed, Strict and Sliced. Relaxed does not have any constrains on text length so you are more likely to have XSD errors this way. Strict has more constraints in place, it would raise Dry::Struct::Error when called with invalid options. And the last mode, Sliced. It would cut the string at max length available.

Norway

Main site for skatteetaten https://www.skatteetaten.no/en/business-and-organisation/start-and-run/best-practices-accounting-and-cash-register-systems/saf-t-financial/documentation/

Git repo from skatteetaten https://github.com/Skatteetaten/saf-t

SAF-T contains two formats, SAF-T Financial and SAF-T Cash Register.

Every electronic ERP system has to implement SAF-T Financial. SAF-T Cash Register is either for the cash register to implement or the ERP, I don't know yet. (I believe Cash Register since there should be event log which include open drawer, copy receipt, etc)

Html

We also ship a render for html view. It also ships styles

audit_file = SAFT::V2::Types::AuditFile.call({})
html = SAFT::V2.to_html(audit_file)
css = SAFT::V2::HTML.css
css_path = SAFT::V2::HTML.css_path

Dev to rebuild styles

pnpm tailwindcss -i lib/saft/v2/html.css -o ./lib/saft/v2/html_dist.css

About

gem for assist working with SAF-T (Standard Audit File for Tax)

Resources

Stars

Watchers

Forks

Packages

No packages published