Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ linters:
- unparam
- zerologlint
settings:
goconst:
ignore-tests: true
staticcheck:
checks:
- all
Expand Down
2 changes: 1 addition & 1 deletion convert/breakdown.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ func newTipoDesglose(gobl *bill.Invoice) *TipoDesglose {

desglose := &TipoDesglose{}

if gobl.Customer == nil || partyTaxCountry(gobl.Customer) == l10n.ES.Tax() {
if gobl.Customer == nil || partyCountry(gobl.Customer) == l10n.ES.Tax() {
desglose.DesgloseFactura = newDesgloseFactura(taxInfo, catTotal.Rates)
} else {
goods, services := splitByTBAIProduct(catTotal.Rates)
Expand Down
38 changes: 19 additions & 19 deletions convert/breakdown_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func TestDesgloseConversion(t *testing.T) {
t.Run("should distinguish goods from services when customer from other country",
func(t *testing.T) {
goblInvoice := invoiceFromCountry("GB")
goblInvoice.Lines[0].Item.Key = "goods"
goblInvoice.Lines[0].Item.Key = org.ItemKeyGoods
_ = goblInvoice.Calculate()

invoice, _ := convert.NewTicketBAI(goblInvoice, ts, role, convert.ZoneBI)
Expand Down Expand Up @@ -93,7 +93,7 @@ func TestDesgloseConversion(t *testing.T) {
},
Taxes: tax.Set{
&tax.Combo{
Category: "VAT",
Category: tax.CategoryVAT,
Rate: "standard",
},
},
Expand All @@ -108,7 +108,7 @@ func TestDesgloseConversion(t *testing.T) {
},
Taxes: tax.Set{
&tax.Combo{
Category: "VAT",
Category: tax.CategoryVAT,
Rate: "standard",
},
},
Expand All @@ -123,7 +123,7 @@ func TestDesgloseConversion(t *testing.T) {
},
Taxes: tax.Set{
&tax.Combo{
Category: "VAT",
Category: tax.CategoryVAT,
Rate: "reduced",
},
},
Expand Down Expand Up @@ -152,7 +152,7 @@ func TestDesgloseConversion(t *testing.T) {
Index: 1,
Quantity: num.MakeAmount(1, 0),
Item: &org.Item{Name: "A", Price: num.NewAmount(10, 0)},
Taxes: tax.Set{&tax.Combo{Category: "VAT", Rate: "standard"}},
Taxes: tax.Set{&tax.Combo{Category: tax.CategoryVAT, Rate: "standard"}},
},
{
Index: 2,
Expand All @@ -164,7 +164,7 @@ func TestDesgloseConversion(t *testing.T) {
},
Taxes: tax.Set{
&tax.Combo{
Category: "VAT",
Category: tax.CategoryVAT,
Rate: "standard",
},
},
Expand Down Expand Up @@ -192,9 +192,9 @@ func TestDesgloseConversion(t *testing.T) {
},
Discounts: []*bill.LineDiscount{DiscountOf(100)},
Taxes: tax.Set{
&tax.Combo{Category: "IRPF", Rate: "pro"},
&tax.Combo{Category: es.TaxCategoryIRPF, Rate: "pro"},
&tax.Combo{
Category: "VAT",
Category: tax.CategoryVAT,
Ext: tax.Extensions{
tbai.ExtKeyExempt: "OT",
},
Expand All @@ -218,7 +218,7 @@ func TestDesgloseConversion(t *testing.T) {
Item: &org.Item{Name: "A", Price: num.NewAmount(10, 0)},
Taxes: tax.Set{
&tax.Combo{
Category: "VAT",
Category: tax.CategoryVAT,
Ext: tax.Extensions{tbai.ExtKeyExempt: "RL"},
},
},
Expand All @@ -240,7 +240,7 @@ func TestDesgloseConversion(t *testing.T) {
Discounts: []*bill.LineDiscount{DiscountOf(100)},
Taxes: tax.Set{
&tax.Combo{
Category: "VAT",
Category: tax.CategoryVAT,
Ext: tax.Extensions{tbai.ExtKeyExempt: "RL"},
},
},
Expand All @@ -260,8 +260,8 @@ func TestDesgloseConversion(t *testing.T) {
Quantity: num.MakeAmount(100, 0),
Item: &org.Item{Name: "A", Price: num.NewAmount(10, 0)},
Taxes: tax.Set{
&tax.Combo{Category: "VAT", Rate: "standard"},
&tax.Combo{Category: "VAT", Rate: "reduced"},
&tax.Combo{Category: tax.CategoryVAT, Rate: "standard"},
&tax.Combo{Category: tax.CategoryVAT, Rate: "reduced"},
},
}}
_ = goblInvoice.Calculate()
Expand Down Expand Up @@ -306,7 +306,7 @@ func TestDesgloseConversion(t *testing.T) {
Quantity: num.MakeAmount(100, 0),
Item: &org.Item{Name: "A", Price: num.NewAmount(10, 0)},
Taxes: tax.Set{
&tax.Combo{Category: "VAT", Rate: "standard+eqs"},
&tax.Combo{Category: tax.CategoryVAT, Rate: "standard+eqs"},
},
}}
_ = goblInvoice.Calculate()
Expand All @@ -326,13 +326,13 @@ func TestDesgloseConversion(t *testing.T) {
Index: 1,
Quantity: num.MakeAmount(1, 0),
Item: &org.Item{
Key: "services",
Key: org.ItemKeyServices,
Name: "A",
Price: num.NewAmount(10, 0),
},
Taxes: tax.Set{
&tax.Combo{
Category: "VAT",
Category: tax.CategoryVAT,
Rate: "standard",
},
},
Expand All @@ -341,13 +341,13 @@ func TestDesgloseConversion(t *testing.T) {
Index: 2,
Quantity: num.MakeAmount(100, 0),
Item: &org.Item{
Key: "goods",
Key: org.ItemKeyGoods,
Name: "A",
Price: num.NewAmount(10, 0),
},
Taxes: tax.Set{
&tax.Combo{
Category: "VAT",
Category: tax.CategoryVAT,
Rate: "general",
Ext: tax.Extensions{tbai.ExtKeyProduct: "resale"},
},
Expand Down Expand Up @@ -440,7 +440,7 @@ func TestDesgloseConversion(t *testing.T) {
Index: 1,
Quantity: num.MakeAmount(100, 0),
Item: &org.Item{Name: "A", Price: num.NewAmount(10, 0)},
Taxes: tax.Set{&tax.Combo{Category: "VAT", Rate: "standard"}},
Taxes: tax.Set{&tax.Combo{Category: tax.CategoryVAT, Rate: "standard"}},
}}
_ = goblInvoice.Calculate()

Expand All @@ -458,7 +458,7 @@ func TestDesgloseConversion(t *testing.T) {
Index: 1,
Quantity: num.MakeAmount(100, 0),
Item: &org.Item{Name: "A", Price: num.NewAmount(10, 0)},
Taxes: tax.Set{&tax.Combo{Category: "VAT", Rate: "standard"}},
Taxes: tax.Set{&tax.Combo{Category: tax.CategoryVAT, Rate: "standard"}},
}}
_ = goblInvoice.Calculate()

Expand Down
31 changes: 30 additions & 1 deletion convert/doc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func TestInvoiceConversion(t *testing.T) {
goblInvoice.Customer.TaxID = nil
goblInvoice.Customer.Identities = []*org.Identity{
{
Key: "passport",
Key: org.IdentityKeyPassport,
Code: "PP123456S",
},
}
Expand All @@ -113,6 +113,35 @@ func TestInvoiceConversion(t *testing.T) {
assert.Empty(t, dest.IDOtro.CodigoPais)
})

t.Run("should use identities when Spanish customer has tax ID without code", func(t *testing.T) {
goblInvoice := test.LoadInvoice("sample-invoice.json")
goblInvoice.Customer.TaxID = &tax.Identity{Country: "ES"}
goblInvoice.Customer.Identities = []*org.Identity{
{Key: org.IdentityKeyPassport, Code: "PP123456S"},
}
invoice, _ := convert.NewTicketBAI(goblInvoice, ts, role, convert.ZoneBI)

dest := invoice.Sujetos.Destinatarios.IDDestinatario[0]
assert.Empty(t, dest.NIF)
assert.Equal(t, "03", dest.IDOtro.IDType)
assert.Equal(t, "PP123456S", dest.IDOtro.ID)
assert.Equal(t, "ES", dest.IDOtro.CodigoPais)
})

t.Run("should use identity country as CodigoPais when no tax ID", func(t *testing.T) {
goblInvoice := test.LoadInvoice("sample-invoice.json")
goblInvoice.Customer.TaxID = nil
goblInvoice.Customer.Identities = []*org.Identity{
{Country: "ES", Key: org.IdentityKeyPassport, Code: "PP123456S"},
}
invoice, _ := convert.NewTicketBAI(goblInvoice, ts, role, convert.ZoneBI)

dest := invoice.Sujetos.Destinatarios.IDDestinatario[0]
assert.Equal(t, "03", dest.IDOtro.IDType)
assert.Equal(t, "PP123456S", dest.IDOtro.ID)
assert.Equal(t, "ES", dest.IDOtro.CodigoPais)
})

t.Run("should allow having no customer (useful for simplied invoices)", func(t *testing.T) {
goblInvoice := test.LoadInvoice("sample-invoice.json")
goblInvoice.Customer = nil
Expand Down
2 changes: 1 addition & 1 deletion convert/invoice.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ func newRetencionSoportada(inv *bill.Invoice) string {
func newClaves(inv *bill.Invoice) []IDClave {
claves := []IDClave{}

if inv.Customer != nil && partyTaxCountry(inv.Customer) != "ES" {
if inv.Customer != nil && partyCountry(inv.Customer) != "ES" {
claves = append(claves, IDClave{
ClaveRegimenIvaOpTrascendencia: "02",
})
Expand Down
16 changes: 8 additions & 8 deletions convert/invoice_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func TestFacturaConversion(t *testing.T) {
Quantity: num.MakeAmount(100, 0),
Item: &org.Item{Name: "A", Price: num.NewAmount(11, 0)},
Discounts: []*bill.LineDiscount{DiscountOf(100)},
Taxes: tax.Set{&tax.Combo{Category: "VAT", Rate: "standard"}},
Taxes: tax.Set{&tax.Combo{Category: tax.CategoryVAT, Rate: "standard"}},
}}
_ = goblInvoice.Calculate()

Expand All @@ -109,8 +109,8 @@ func TestFacturaConversion(t *testing.T) {
Quantity: num.MakeAmount(100, 0),
Item: &org.Item{Name: "A", Price: num.NewAmount(10, 0)},
Taxes: tax.Set{
&tax.Combo{Category: "VAT", Rate: "standard"},
&tax.Combo{Category: "IRPF", Rate: "pro"},
&tax.Combo{Category: tax.CategoryVAT, Rate: "standard"},
&tax.Combo{Category: es.TaxCategoryIRPF, Rate: "pro"},
},
}}
_ = goblInvoice.Calculate()
Expand All @@ -128,8 +128,8 @@ func TestFacturaConversion(t *testing.T) {
Quantity: num.MakeAmount(100, 0),
Item: &org.Item{Name: "A", Price: num.NewAmount(10, 0)},
Taxes: tax.Set{
&tax.Combo{Category: "VAT", Rate: "standard"},
&tax.Combo{Category: "IRPF", Rate: "pro"},
&tax.Combo{Category: tax.CategoryVAT, Rate: "standard"},
&tax.Combo{Category: es.TaxCategoryIRPF, Rate: "pro"},
},
}}
_ = goblInvoice.Calculate()
Expand All @@ -147,7 +147,7 @@ func TestFacturaConversion(t *testing.T) {
Quantity: num.MakeAmount(100, 0),
Item: &org.Item{Name: "A", Price: num.NewAmount(10, 0)},
Taxes: tax.Set{
&tax.Combo{Category: "VAT", Rate: "standard"},
&tax.Combo{Category: tax.CategoryVAT, Rate: "standard"},
},
}}
_ = goblInvoice.Calculate()
Expand All @@ -174,13 +174,13 @@ func TestFacturaConversion(t *testing.T) {
Index: 1,
Quantity: num.MakeAmount(100, 0),
Item: &org.Item{
Key: "goods",
Key: org.ItemKeyGoods,
Name: "A",
Price: num.NewAmount(10, 0),
},
Taxes: tax.Set{
&tax.Combo{
Category: "VAT",
Category: tax.CategoryVAT,
Rate: "standard",
Ext: tax.Extensions{tbai.ExtKeyProduct: "resale"},
},
Expand Down
6 changes: 3 additions & 3 deletions convert/lines_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func TestLines(t *testing.T) {
Index: 1,
Quantity: num.MakeAmount(100, 0),
Item: &org.Item{Name: "A", Price: num.NewAmount(10, 0)},
Taxes: tax.Set{&tax.Combo{Category: "VAT", Rate: "standard"}},
Taxes: tax.Set{&tax.Combo{Category: tax.CategoryVAT, Rate: "standard"}},
}}
_ = goblInvoice.Calculate()

Expand All @@ -46,7 +46,7 @@ func TestLines(t *testing.T) {
Quantity: num.MakeAmount(100, 0),
Item: &org.Item{Name: "A", Price: num.NewAmount(11, 0)},
Discounts: []*bill.LineDiscount{DiscountOf(100)},
Taxes: tax.Set{&tax.Combo{Category: "VAT", Rate: "standard"}},
Taxes: tax.Set{&tax.Combo{Category: tax.CategoryVAT, Rate: "standard"}},
}}
_ = goblInvoice.Calculate()

Expand All @@ -65,7 +65,7 @@ func TestLines(t *testing.T) {
Index: 1,
Quantity: num.MakeAmount(10, 0),
Item: &org.Item{Name: "A", Price: num.NewAmount(121, 0)},
Taxes: tax.Set{&tax.Combo{Category: "VAT", Rate: "standard"}},
Taxes: tax.Set{&tax.Combo{Category: tax.CategoryVAT, Rate: "standard"}},
}}
require.NoError(t, inv.Calculate())
require.NoError(t, inv.RemoveIncludedTaxes())
Expand Down
20 changes: 17 additions & 3 deletions convert/parties.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func newDestinatario(party *org.Party) *IDDestinatario {
ApellidosNombreRazonSocial: party.Name,
}

if partyTaxCountry(party) == "ES" {
if party.TaxID != nil && party.TaxID.Country == "ES" && party.TaxID.Code != "" {
d.NIF = party.TaxID.Code.String()
} else {
d.IDOtro = otherIdentity(party)
Expand Down Expand Up @@ -96,22 +96,36 @@ func otherIdentity(party *org.Party) *IDOtro {
}

for _, id := range party.Identities {
if id == nil || id.Code == "" {
continue
}
it, ok := idTypeCodeMap[id.Key]
if !ok {
continue
}

oid.IDType = it
oid.ID = id.Code.String()
if id.Country != "" {
oid.CodigoPais = id.Country.String()
}
return oid
}

return nil
}

func partyTaxCountry(party *org.Party) l10n.TaxCountryCode {
if party != nil && party.TaxID != nil {
func partyCountry(party *org.Party) l10n.TaxCountryCode {
if party == nil {
return ""
}
if party.TaxID != nil && party.TaxID.Country != "" {
return party.TaxID.Country
}
for _, id := range party.Identities {
if id != nil && id.Country != "" {
return l10n.TaxCountryCode(id.Country)
}
}
return ""
}
Loading