Skip to content

Commit

Permalink
Update to GOBL's extensions refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
cavalle committed Aug 29, 2023
1 parent 0eae0e8 commit 927dc6e
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 197 deletions.
5 changes: 1 addition & 4 deletions body.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,7 @@ type scontoMaggiorazione struct {
}

func newFatturaElettronicaBody(inv *bill.Invoice) (*fatturaElettronicaBody, error) {
dbs, err := newDatiBeniServizi(inv)
if err != nil {
return nil, err
}
dbs := newDatiBeniServizi(inv)

dp, err := newDatiPagamento(inv)
if err != nil {
Expand Down
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/invopop/gobl.fatturapa
go 1.19

require (
github.com/invopop/gobl v0.54.0
github.com/invopop/gobl v0.54.1-0.20230828145858-ddfafb15835d
github.com/invopop/xmldsig v0.7.0
github.com/magefile/mage v1.14.0
github.com/spf13/cobra v1.7.0
Expand Down Expand Up @@ -32,3 +32,5 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
software.sslmate.com/src/go-pkcs12 v0.2.0 // indirect
)

replace github.com/invopop/gobl => ../gobl
128 changes: 18 additions & 110 deletions items.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
package fatturapa

import (
"fmt"
"strconv"

"github.com/invopop/gobl/bill"
"github.com/invopop/gobl/cbc"
"github.com/invopop/gobl/i18n"
"github.com/invopop/gobl/num"
"github.com/invopop/gobl/regimes/common"
"github.com/invopop/gobl/regimes/it"
"github.com/invopop/gobl/tax"
)

var taxCategoryVat = regime.Category(common.TaxCategoryVAT)

// datiBeniServizi contains all data related to the goods and services sold.
type datiBeniServizi struct {
DettaglioLinee []*dettaglioLinee
Expand Down Expand Up @@ -42,57 +37,35 @@ type datiRiepilogo struct {
RiferimentoNormativo string `xml:",omitempty"`
}

func newDatiBeniServizi(inv *bill.Invoice) (*datiBeniServizi, error) {
dl, err := generateLineDetails(inv)
if err != nil {
return nil, err
}

dr, err := generateTaxSummary(inv)
if err != nil {
return nil, err
}

func newDatiBeniServizi(inv *bill.Invoice) *datiBeniServizi {
return &datiBeniServizi{
DettaglioLinee: dl,
DatiRiepilogo: dr,
}, nil
DettaglioLinee: generateLineDetails(inv),
DatiRiepilogo: generateTaxSummary(inv),
}
}

func generateLineDetails(inv *bill.Invoice) ([]*dettaglioLinee, error) {
func generateLineDetails(inv *bill.Invoice) []*dettaglioLinee {
var dl []*dettaglioLinee

for _, line := range inv.Lines {
vatRate := ""

for _, tax := range line.Taxes {
if tax.Category == common.TaxCategoryVAT {
vatRate = formatPercentage(tax.Percent)
break
}
}

codeNatura, err := findCodeNaturaLine(line)
if err != nil {
return nil, err
}
vatTax := line.Taxes.Get(common.TaxCategoryVAT)

dl = append(dl, &dettaglioLinee{
NumeroLinea: strconv.Itoa(line.Index),
Descrizione: line.Item.Name,
Quantita: formatAmount(&line.Quantity),
PrezzoUnitario: formatAmount(&line.Item.Price),
PrezzoTotale: formatAmount(&line.Sum),
AliquotaIVA: vatRate,
Natura: codeNatura,
AliquotaIVA: formatPercentage(vatTax.Percent),
Natura: vatTax.Ext[it.ExtKeySDINature].String(),
ScontoMaggiorazione: extractLinePriceAdjustments(line),
})
}

return dl, nil
return dl
}

func generateTaxSummary(inv *bill.Invoice) ([]*datiRiepilogo, error) {
func generateTaxSummary(inv *bill.Invoice) []*datiRiepilogo {
var dr []*datiRiepilogo
var vatRateTotals []*tax.RateTotal

Expand All @@ -104,21 +77,16 @@ func generateTaxSummary(inv *bill.Invoice) ([]*datiRiepilogo, error) {
}

for _, rateTotal := range vatRateTotals {
codeNatura, err := findCodeNaturaSummary(rateTotal)
if err != nil {
return nil, err
}

dr = append(dr, &datiRiepilogo{
AliquotaIVA: formatPercentage(rateTotal.Percent),
Natura: codeNatura,
Natura: rateTotal.Ext[it.ExtKeySDINature].String(),
ImponibileImporto: formatAmount(&rateTotal.Base),
Imposta: formatAmount(&rateTotal.Amount),
RiferimentoNormativo: findRiferimentoNormativo(rateTotal),
})
}

return dr, nil
return dr
}

func extractLinePriceAdjustments(line *bill.Line) []*scontoMaggiorazione {
Expand All @@ -143,76 +111,16 @@ func extractLinePriceAdjustments(line *bill.Line) []*scontoMaggiorazione {
return scontiMaggiorazioni
}

func findCodeNaturaLine(line *bill.Line) (string, error) {
rateKey := findZeroVatTaxRate(line)
if rateKey == "" {
return "", nil
}

return findCodeNatura(rateKey)
}

func findCodeNaturaSummary(rateTotal *tax.RateTotal) (string, error) {
if !isZeroRate(rateTotal.Percent) {
return "", nil
}

return findCodeNatura(rateTotal.Key)
}

func findCodeNatura(rateKey cbc.Key) (string, error) {
rate := findRate(taxCategoryVat.Rates, rateKey)
if rate == nil {
return "", fmt.Errorf("'Natura' code not found for VAT rate of zero with key '%s'", rateKey)
}

code := rate.Codes[it.KeyFatturaPANatura]
if code == "" {
return "", fmt.Errorf("'Natura' code not found for VAT rate of zero with key '%s'", rateKey)
}

return code.String(), nil
}

func findRiferimentoNormativo(rateTotal *tax.RateTotal) string {
if !isZeroRate(rateTotal.Percent) {
return ""
}

rate := findRate(taxCategoryVat.Rates, rateTotal.Key)
if rate == nil {
return ""
}

return rate.Name[i18n.IT]
}

func findRate(rates []*tax.Rate, taxRateKey cbc.Key) *tax.Rate {
for _, rate := range rates {
if rate.Key == taxRateKey {
return rate
}
}
return nil
}
def := regime.ExtensionDef(it.ExtKeySDINature)

func findZeroVatTaxRate(line *bill.Line) cbc.Key {
var combo *tax.Combo
nature := rateTotal.Ext[it.ExtKeySDINature]

for _, tax := range line.Taxes {
if tax.Category == common.TaxCategoryVAT {
combo = tax
break
for _, c := range def.Codes {
if c.Code == nature {
return c.Name[i18n.IT]
}
}

if combo == nil || !isZeroRate(combo.Percent) {
return ""
}

return combo.Rate
}

func isZeroRate(percent *num.Percentage) bool {
return percent == nil || percent.IsZero()
return ""
}
18 changes: 1 addition & 17 deletions parties.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,6 @@ func newCedentePrestatore(inv *bill.Invoice) (*supplier, error) {
return nil, err
}

rf, err := findCodeRegimeFiscale(inv)
if err != nil {
return nil, err
}

contatti := newContatti(s)

return &supplier{
Expand All @@ -93,7 +88,7 @@ func newCedentePrestatore(inv *bill.Invoice) (*supplier, error) {
IdCodice: s.TaxID.Code.String(),
},
Anagrafica: newAnagrafica(s),
RegimeFiscale: rf,
RegimeFiscale: s.Ext[it.ExtKeySDIFiscalRegime].String(),
},
Sede: address,
IscrizioneREA: newIscrizioneREA(s),
Expand Down Expand Up @@ -165,17 +160,6 @@ func newContatti(party *org.Party) *contatti {
return c
}

func findCodeRegimeFiscale(inv *bill.Invoice) (string, error) {
ss := inv.ScenarioSummary()

regimeFiscale := ss.Codes[it.KeyFatturaPARegimeFiscale]
if regimeFiscale == "" {
return "", errors.New("could not find RegimeFiscale code for supplier")
}

return regimeFiscale.String(), nil
}

func customerFiscaleIVA(id *tax.Identity, fallBack string) *taxID {
idCodice := id.Code.String()

Expand Down
34 changes: 2 additions & 32 deletions retained_taxes.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,53 +53,23 @@ func newDatiRitenuta(cat cbc.Code, rateTotal *tax.RateTotal) (*datiRitenuta, err
if err != nil {
return nil, err
}
codeCP, err := findCodeCausalePagamento(cat, rateTotal.Key)
if err != nil {
return nil, err
}

return &datiRitenuta{
TipoRitenuta: codeTR,
ImportoRitenuta: amount,
AliquotaRitenuta: rate,
CausalePagamento: codeCP,
CausalePagamento: rateTotal.Ext[it.ExtKeySDIRetainedTax].String(),
}, nil
}

func findCodeTipoRitenuta(cat cbc.Code) (string, error) {
taxCategory := regime.Category(cat)

code := taxCategory.Codes[it.KeyFatturaPATipoRitenuta]
code := taxCategory.Map[it.KeyFatturaPATipoRitenuta]

if code == "" {
return "", fmt.Errorf("could not find TipoRitenuta code for tax category %s", cat)
}

return code.String(), nil
}

func findCodeCausalePagamento(cat cbc.Code, rateKey cbc.Key) (string, error) {
taxCategory := regime.Category(cat)

for _, rate := range taxCategory.Rates {
if rate.Key == rateKey {
code := rate.Codes[it.KeyFatturaPACausalePagamento]

if code == "" {
return "", fmt.Errorf(
"could not find CausalePagamento code for tax category %s and rate %s",
cat,
rateKey,
)
}

return code.String(), nil
}
}

return "", fmt.Errorf(
"could not find CausalePagamento code for tax category %s and rate %s",
cat,
rateKey,
)
}
21 changes: 12 additions & 9 deletions test/data/invoice-hotel.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@
"uuid": "679a2f25-7483-11ec-9722-7ea2cb436ff6",
"dig": {
"alg": "sha256",
"val": "6b11d0f68c974b79dc14f6f5957837f03e0ee6a9579a2fc1583125624b8560c2"
"val": "796bb9019577dcda5b03baa8916eb2e46d6ba975618d42203f39941e36bd338c"
}
},
"doc": {
"$schema": "https://gobl.org/draft-0/bill/invoice",
"type": "standard",
"series": "SAMPLE",
"code": "002",
"type": "standard",
"issue_date": "2023-05-21",
"currency": "EUR",
"tax": {
"prices_include": "VAT"
},
"issue_date": "2023-05-21",
"supplier": {
"name": "Hotel California",
"tax_id": {
Expand Down Expand Up @@ -74,7 +74,10 @@
"taxes": [
{
"cat": "VAT",
"rate": "excluded"
"rate": "exempt",
"ext": {
"it-sdi-nature": "N1"
}
}
],
"total": "1.00"
Expand Down Expand Up @@ -117,7 +120,10 @@
"code": "VAT",
"rates": [
{
"key": "excluded",
"key": "exempt",
"ext": {
"it-sdi-nature": "N1"
},
"base": "1.00",
"amount": "0.00"
},
Expand All @@ -139,8 +145,5 @@
"advance": "29.00",
"due": "97.00"
}
},
"sigs": [
"eyJhbGciOiJFUzI1NiIsImtpZCI6ImZmNzU5MTVmLWY2ZjgtNDU4Ny04OTBhLWNjZDhiODZiZjhmNSJ9.eyJ1dWlkIjoiNjc5YTJmMjUtNzQ4My0xMWVjLTk3MjItN2VhMmNiNDM2ZmY2IiwiZGlnIjp7ImFsZyI6InNoYTI1NiIsInZhbCI6IjZiMTFkMGY2OGM5NzRiNzlkYzE0ZjZmNTk1NzgzN2YwM2UwZWU2YTk1NzlhMmZjMTU4MzEyNTYyNGI4NTYwYzIifX0.0AFzvSGsoZPNYpn_nsnuf9XIpk-8rADHshYwaJnCbFZVva3xlI7r3_u-d-vQV-B9x8FuDWXJRRyXMbRLTYPoOA"
]
}
}
Loading

0 comments on commit 927dc6e

Please sign in to comment.