gobl

package module
v0.50.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 26, 2023 License: Apache-2.0 Imports: 21 Imported by: 40

README

GOBL

GOBL Logo

Go Business Language. Core library and Schemas.

Released under the Apache 2.0 LICENSE, Copyright 2021,2022 Invopop Ltd..

Lint Test Go Go Report Card GoDoc Latest Tag

Official GOBL documentation site.

Introduction

GOBL, the Go Business Language library and tools, aim to:

  • Help developers build electronic business documents, especially invoices, anywhere in the world.
  • Define a a set of open JSON Schema with the flexibility to be used and shared.
  • Build a global database of local tax categories and, whenever practical to do so, provide current and historical tax rates in code.
  • Validate business documents according to local requirements, including tax ID validation.
  • Define the algorithms used to make tax calculations while avoiding rounding errors.
  • Provide built-in support for signing documents using JSON Web Signatures.
  • Output simple and easy to read JSON documents that emphasize the use of keys instead of abstract codes, like credit-transfer instead of 30 (UNTDID4461 code for sender initiated bank or wire transfer).
  • Be flexible enough to support extreme local complexity but produce output that is easily legible in other countries.
  • Build a global community of contributors tired of the complexity of current standards based on XML or EDI.

Companion Projects

GOBL makes it easy to create business documents, like invoices, but checkout some of the companion projects that help create, use, and convert into other formats:

  • CLI - the official GOBL command line tool, including WASM release for streaming in browsers.
  • Builder - Available to try at build.gobl.org, this tool makes it easy to build, test, and discover the features of GOBL.
  • Generator - Ruby project to convert GOBL JSON Schema into libraries for other languages or documentation.
  • Docs - Content of the official GOBL Documentation Site docs.gobl.org.
  • Ruby - Easily build or read GOBL documents in Ruby.
  • FacturaE - convert into the Spanish FacturaE format.
  • FatturaPA - convert into the Italian FatturaPA format.

Usage

GOBL is a Go library, so the following instructions assume you'd like to build documents from your own Go applications. See some of the links above if you'd like to develop in another language or use a CLI.

Installation

Run the following command to install the package:

go get github.com/invopop/gobl
Building an Invoice

There are lots of different ways to get data into GOBL but for the following example we're going to try and build an invoice in several steps.

First define a minimal or "partial" GOBL Invoice Document:

inv := &bill.Invoice{
	Series:    "F23",
	Code:      "00010",
	IssueDate: cal.MakeDate(2023, time.May, 11),
	Supplier: &org.Party{
		TaxID: &tax.Identity{
			Country: l10n.US,
		},
		Name:  "Provider One Inc.",
		Alias: "Provider One",
		Emails: []*org.Email{
			{
				Address: "billing@provideone.com",
			},
		},
		Addresses: []*org.Address{
			{
				Number:   "16",
				Street:   "Jessie Street",
				Locality: "San Francisco",
				Region:   "CA",
				Code:     "94105",
				Country:  l10n.US,
			},
		},
	},
	Customer: &org.Party{
		Name: "Sample Customer",
		Emails: []*org.Email{
			{
				Address: "email@sample.com",
			},
		},
	},
	Lines: []*bill.Line{
		{
			Quantity: num.MakeAmount(20, 0),
			Item: &org.Item{
				Name:  "A stylish mug",
				Price: num.MakeAmount(2000, 2),
				Unit:  org.UnitHour,
			},
			Taxes: []*tax.Combo{
				{
					Category: common.TaxCategoryST,
					Percent:  num.NewPercentage(85, 3),
				},
			},
		},
	},
}

Notice that the are no sums or calculations yet. The next step involves "inserting" the invoice document into an "envelope". In GOBL, we use the concept of an envelope to hold data and provide functionality to guarantee that no modifications have been made to the payload.

Insert our previous Invoice into an envelope as follows:

// Prepare an "Envelope"
env := gobl.NewEnvelope()
if err := env.Insert(inv); err != nil {
	panic(err)
}

Documentation

Overview

Package gobl contains all the base models for GOBL.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrNoRegion is used when the envelope is missing a region.
	ErrNoRegion = NewError("no-region")

	// ErrNoDocument is provided when the envelope does not contain a
	// document payload.
	ErrNoDocument = NewError("no-document")

	// ErrValidation is used when a document fails a validation request.
	ErrValidation = NewError("validation")

	// ErrCalculation wraps around errors that we're generated during a
	// call to perform calculations on a document.
	ErrCalculation = NewError("calculation")

	// ErrMarshal is provided when there has been a problem attempting to encode
	// or marshal an object, usually into JSON.
	ErrMarshal = NewError("marshal")

	// ErrUnmarshal is used when that has been a problem attempting to read the
	// source data.
	ErrUnmarshal = NewError("unmarshal")

	// ErrDraft is raised when attempting to perform an operation that can only
	// be performed on an envelope that is not a draft.
	ErrDraft = NewError("draft")

	// ErrSignature identifies an issue related to signatures.
	ErrSignature = NewError("signature")

	// ErrInternal is a "catch-all" for errors that are not expected.
	ErrInternal = NewError("internal")

	// ErrUnknownSchema is provided when we attempt to determine the schema for an object
	// or from an ID and cannot find a match.
	ErrUnknownSchema = NewError("unknown-schema")
)
View Source
var EnvelopeSchema = schema.GOBL.Add("envelope")

EnvelopeSchema sets the general definition of the schema ID for this version of the envelope.

Functions

func Parse added in v0.26.1

func Parse(data []byte) (interface{}, error)

Parse unmarshals the provided data and uses the schema ID to determine what type of object we're dealing with. As long as the provided data contains a schema registered in GOBL, a new object instance will be returned.

Types

type Calculable

type Calculable interface {
	Calculate() error
}

Calculable defines the methods expected of a document payload that contains a `Calculate` method to be used to perform any additional calculations.

type Correctable added in v0.41.0

type Correctable interface {
	Correct(...cbc.Option) error
}

Correctable defines the expected interface of a document that can be corrected.

type Document

type Document struct {
	// contains filtered or unexported fields
}

Document helps us handle the document's contents by essentially wrapping around the contents and ensuring that a `$schema` property is added automatically when marshalling into JSON.

func NewDocument added in v0.18.0

func NewDocument(payload interface{}) (*Document, error)

NewDocument instantiates a Document wrapper around the provided object.

func (*Document) Calculate added in v0.41.0

func (d *Document) Calculate() error

Calculate will attempt to run the calculation method on the document payload.

func (*Document) Clone added in v0.41.0

func (d *Document) Clone() (*Document, error)

Clone makes a copy of the document by serializing and deserializing it. the contents into a new document instance.

func (*Document) Correct added in v0.41.0

func (d *Document) Correct(opts ...cbc.Option) error

Correct will attempt to run the correction method on the document using some of the provided options.

func (*Document) Digest added in v0.17.0

func (d *Document) Digest() (*dsig.Digest, error)

Digest calculates a digital digest using the canonical JSON of the document.

func (*Document) Instance added in v0.18.0

func (d *Document) Instance() interface{}

Instance returns a prepared version of the document's content.

func (*Document) IsEmpty added in v0.22.3

func (d *Document) IsEmpty() bool

IsEmpty returns true if no payload has been set yet.

func (Document) JSONSchema added in v0.17.0

func (Document) JSONSchema() *jsonschema.Schema

JSONSchema returns a jsonschema.Schema instance.

func (*Document) MarshalJSON added in v0.17.0

func (d *Document) MarshalJSON() ([]byte, error)

MarshalJSON satisfies the json.Marshaler interface.

func (*Document) Schema added in v0.17.0

func (d *Document) Schema() schema.ID

Schema provides the document's schema.

func (*Document) UnmarshalJSON added in v0.17.0

func (d *Document) UnmarshalJSON(data []byte) error

UnmarshalJSON satisfies the json.Unmarshaler interface.

func (*Document) Validate added in v0.18.0

func (d *Document) Validate() error

Validate checks to ensure the document has everything it needs and will pass on the validation call to the payload.

func (*Document) ValidateWithContext added in v0.38.0

func (d *Document) ValidateWithContext(ctx context.Context) error

ValidateWithContext checks to ensure the document has everything it needs and will pass on the validation call to the payload.

type Envelope

type Envelope struct {
	// Schema identifies the schema that should be used to understand this document
	Schema schema.ID `json:"$schema" jsonschema:"title=JSON Schema ID"`
	// Details on what the contents are
	Head *Header `json:"head" jsonschema:"title=Header"`
	// The data inside the envelope
	Document *Document `json:"doc" jsonschema:"title=Document"`
	// JSON Web Signatures of the header
	Signatures []*dsig.Signature `json:"sigs,omitempty" jsonschema:"title=Signatures"`
}

Envelope wraps around a document adding headers and digital signatures. An Envelope is similar to a regular envelope in the physical world, it keeps the contents safe and helps get the document where its needed.

func Envelop added in v0.20.0

func Envelop(doc interface{}) (*Envelope, error)

Envelop is a convenience method that will build a new envelope and insert the contents document provided in a single swoop. The resulting envelope will still need to be signed afterwards.

func NewEnvelope

func NewEnvelope() *Envelope

NewEnvelope builds a new envelope object ready for data to be inserted and signed. If you are loading data from json, you can safely use a regular `new(Envelope)` call directly.

Example (Complete)
package main

import (
	"encoding/json"
	"fmt"

	"github.com/invopop/gobl"
	"github.com/invopop/gobl/note"
	"github.com/invopop/gobl/uuid"
)

func main() {
	// Prepare a new Envelope with a region
	env := gobl.NewEnvelope()
	env.Head.UUID = uuid.MustParse("871c1e6a-8b5c-11ec-af5f-3e7e00ce5635")

	// Prepare a payload and insert
	msg := &note.Message{
		Content: "sample message content",
	}
	if err := env.Insert(msg); err != nil {
		panic(err.Error())
	}
	if err := env.Validate(); err != nil {
		panic(err.Error())
	}

	data, err := json.MarshalIndent(env, "", "\t")
	if err != nil {
		panic(err.Error())
	}
	fmt.Printf("%v\n", string(data))
}
Output:

{
	"$schema": "https://gobl.org/draft-0/envelope",
	"head": {
		"uuid": "871c1e6a-8b5c-11ec-af5f-3e7e00ce5635",
		"dig": {
			"alg": "sha256",
			"val": "7d539c46ca03a4ecb1fcc4cb00d2ada34275708ee326caafee04d9dcfed862ee"
		}
	},
	"doc": {
		"$schema": "https://gobl.org/draft-0/note/message",
		"content": "sample message content"
	}
}

func (*Envelope) Calculate added in v0.28.0

func (e *Envelope) Calculate() error

Calculate is used to perform calculations on the envelope's document contents to ensure everything looks correct. Headers will be refreshed to ensure they have the latest valid digest.

func (*Envelope) Correct added in v0.40.0

func (e *Envelope) Correct(opts ...cbc.Option) (*Envelope, error)

Correct will attempt to build a new envelope as a correction of the current envelope contents, if possible.

func (*Envelope) Extract

func (e *Envelope) Extract() interface{}

Extract the contents of the envelope into the provided document type.

func (*Envelope) Insert

func (e *Envelope) Insert(doc interface{}) error

Insert takes the provided document and inserts it into this envelope. Calculate will be called automatically.

func (*Envelope) Sign

func (e *Envelope) Sign(key *dsig.PrivateKey) error

Sign uses the private key to sign the envelope headers. Validation is performed automatically, and an error will be raised if still in draft mode.

func (*Envelope) Validate

func (e *Envelope) Validate() error

Validate ensures that the envelope contains everything it should to be considered valid GoBL.

func (*Envelope) ValidateWithContext added in v0.38.0

func (e *Envelope) ValidateWithContext(ctx context.Context) error

ValidateWithContext ensures that the envelope contains everything it should to be considered valid GoBL.

type Error

type Error struct {
	Key   string `json:"key"`
	Cause error  `json:"cause"`
}

Error provides a structure to better be able to make error comparisons. The contents can also be serialised as JSON ready to send to a client if needed.

func NewError

func NewError(key string) *Error

NewError provides a new error with a code that is meant to provide a context.

func (*Error) Error

func (e *Error) Error() string

Error provides a string representation of the error.

func (*Error) Is

func (e *Error) Is(target error) bool

Is checks to see if the target error matches the current error or part of the chain.

func (*Error) WithCause

func (e *Error) WithCause(err error) *Error

WithCause is used to copy and add an underlying error to this one.

func (*Error) WithErrorf

func (e *Error) WithErrorf(format string, a ...interface{}) *Error

WithErrorf wraps around the `fmt.Errorf` call to provide a more meaningful error in the context.

type Header struct {
	// Unique UUIDv1 identifier for the envelope.
	UUID uuid.UUID `json:"uuid" jsonschema:"title=UUID"`

	// Digest of the canonical JSON body.
	Digest *dsig.Digest `json:"dig" jsonschema:"title=Digest"`

	// Seals of approval from other organisations that can only be added to
	// non-draft envelopes.
	Stamps []*cbc.Stamp `json:"stamps,omitempty" jsonschema:"title=Stamps"`

	// Set of labels that describe but have no influence on the data.
	Tags []string `json:"tags,omitempty" jsonschema:"title=Tags"`

	// Additional semi-structured information about this envelope.
	Meta cbc.Meta `json:"meta,omitempty" jsonschema:"title=Meta"`

	// Any information that may be relevant to other humans about this envelope
	Notes string `json:"notes,omitempty" jsonschema:"title=Notes"`

	// When true, implies that this document should not be considered final. Digital signatures are optional.
	Draft bool `json:"draft,omitempty" jsonschema:"title=Draft"`
}

Header defines the metadata of the body. The header is used as the payload for the JSON Web Signatures, so we want this to be as compact as possible.

func NewHeader

func NewHeader() *Header

NewHeader creates a new header and automatically assigns a UUIDv1.

func (*Header) AddStamp added in v0.37.1

func (h *Header) AddStamp(s *cbc.Stamp)

AddStamp adds a new stamp to the header. If the stamp already exists, it will be overwritten.

func (*Header) Validate

func (h *Header) Validate() error

Validate checks that the header contains the basic information we need to function.

func (*Header) ValidateWithContext added in v0.38.0

func (h *Header) ValidateWithContext(ctx context.Context) error

ValidateWithContext checks that the header contains the basic information we need to function.

type Signatures

type Signatures []*dsig.Signature

Signatures keeps together a list of signatures that we're used to sign the document head contents.

type Version added in v0.11.0

type Version string

Version defines the semver for this version of GOBL.

const VERSION Version = "v0.50.0"

VERSION is the current version of the GOBL library.

func (Version) Semver added in v0.11.0

func (v Version) Semver() *semver.Version

Semver parses and returns semver

Directories

Path Synopsis
Package bill provides models for dealing with Billing and specifically invoicing.
Package bill provides models for dealing with Billing and specifically invoicing.
Package c14n provides canonical JSON encoding and decoding.
Package c14n provides canonical JSON encoding and decoding.
Package cal provides simple date handling.
Package cal provides simple date handling.
Package cbc provides a set of Common Basid Components.
Package cbc provides a set of Common Basid Components.
Package currency provides models for dealing with currencies.
Package currency provides models for dealing with currencies.
Package dsig provides models for dealing with digital signatures.
Package dsig provides models for dealing with digital signatures.
examples
Package i18n provides internationalization models.
Package i18n provides internationalization models.
internal
currency
Package currency is used internally to generate Go currency structures from a data source.
Package currency is used internally to generate Go currency structures from a data source.
here
Package here provides creation of here-documents from raw strings.
Package here provides creation of here-documents from raw strings.
iotools
Package iotools helps with reading documents.
Package iotools helps with reading documents.
schemas
Package schemas helps generate JSON Schema files from the main GOBL packages.
Package schemas helps generate JSON Schema files from the main GOBL packages.
Package l10n provides localization models and data.
Package l10n provides localization models and data.
Package note provides models for generating simple messages.
Package note provides models for generating simple messages.
Package num provides support for dealing with amounts and percentages without rounding errors.
Package num provides support for dealing with amounts and percentages without rounding errors.
Package org contains structures related to organization.
Package org contains structures related to organization.
Package pay handles models related to payments.
Package pay handles models related to payments.
Package regimes simple ensures that each of the individually defined tax regimes is loaded correctly and ready to use from other GOBL packages.
Package regimes simple ensures that each of the individually defined tax regimes is loaded correctly and ready to use from other GOBL packages.
co
Package co handles tax regime data for Colombia.
Package co handles tax regime data for Colombia.
common
Package common provides re-usable regime related structures and data.
Package common provides re-usable regime related structures and data.
es
Package es provides tax regime support for Spain.
Package es provides tax regime support for Spain.
fr
Package fr provides the tax region definition for France.
Package fr provides the tax region definition for France.
gb
Package gb provides the United Kingdom tax regime.
Package gb provides the United Kingdom tax regime.
it
Package it provides the Italian tax regime.
Package it provides the Italian tax regime.
nl
Package nl provides the Dutch region definition
Package nl provides the Dutch region definition
pt
Package pt provides models for dealing with the Portuguese tax regime.
Package pt provides models for dealing with the Portuguese tax regime.
us
Package us provides models for dealing with the United States of America.
Package us provides models for dealing with the United States of America.
Package schema provides a simple way to register and lookup schemas.
Package schema provides a simple way to register and lookup schemas.
Package tax encapsulates models related to taxation.
Package tax encapsulates models related to taxation.
Package uuid provides a wrapper for handling UUID codes.
Package uuid provides a wrapper for handling UUID codes.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL