Skip to content

Commit

Permalink
Change type of downloadID func param from int to int64 and some doc f…
Browse files Browse the repository at this point in the history
…ixes
  • Loading branch information
printesoi committed Mar 10, 2024
1 parent 2617bfb commit f6ad598
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 51 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright [yyyy] [name of copyright owner]
Copyright 2024 Victor Dodon

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
19 changes: 12 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Package efactura provides a client for using the ANAF e-factura API.

## Installation ##

e-factura-go is compatible with modern Go releases in module mode, with Go installed:
e-factura-go requires Go version >= 1.20. With Go installed:

```bash
go get github.com/printesoi/e-factura-go
Expand Down Expand Up @@ -34,7 +34,7 @@ go get github.com/printesoi/e-factura-go@main
## Usage ##

This package can be use both for interacting with (calling) the ANAF e-factura
API via the Client object and for generating an UBL Invoice XML.
API via the Client object and for generating an Invoice UBL XML.

```go
import "github.com/printesoi/e-factura-go"
Expand Down Expand Up @@ -204,13 +204,13 @@ if validateRes.IsOk() {
}
```
## Generating an Invoice
TODO: See TestInvoiceBuilder() from builders_test.go for an example of using
InvoiceBuilder for creating an Invoice.
## Tasks ##
- [ ] Support full OAuth2 authentication flow for the client, not just passing
the initial token. This however will be tricky to implement properly since
the OAuth2 app registered in the ANAF developer profile must have a fixed
list of HTTPS redirect URLs and the redirect URL used for creating the OAuth2
config must exactly matche one of the URLs.
- [ ] Add tests for all REST API calls and more tests for validating generated
XML (maybe checking with the tools provided by mfinante).
- [ ] Implement CreditNote.
Expand All @@ -220,6 +220,11 @@ if validateRes.IsOk() {
- [ ] Check and test API limits.
- [ ] Godoc and more code examples.
- [ ] Test coverage
- [ ] SuppTestInvoiceBuilderort full OAuth2 authentication flow for the client, not just passing
the initial token. This however will be tricky to implement properly since
the OAuth2 app registered in the ANAF developer profile must have a fixed
list of HTTPS redirect URLs and the redirect URL used for creating the OAuth2
config must exactly matche one of the URLs.
## Contributing ##
Expand Down
3 changes: 1 addition & 2 deletions doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License

package efactura

/*
Package efactura provides a client for using the ANAF e-factura API.
Usage:
import "github.com/printesoi/e-factura-go"
*/
package efactura
37 changes: 12 additions & 25 deletions invoice.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ import (
"github.com/m29h/xml"
)

// Invoice is the object that represents an e-factura invoice. The invoice
// object aims to be a type safe invoice that serializes to the UBL 2.1 syntax
// with CUIS RO v1.0.1 customization ID.
type Invoice struct {
// These need to be first fields, because apparently the validators care
// about the order of xml nodes.
Expand Down Expand Up @@ -114,10 +117,10 @@ type Invoice struct {
// Term: Referinţa contractului
// Cardinality: 0..1
ContractDocumentReference *IDNode `xml:"urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2 ContractDocumentReference,omitempty"`
// ID: BT-18-1
// ID: BT-18
// Term: Identificatorul obiectului facturat
// Cardinality: 0..1
// ID: BT-18-2
// ID: BT-18-1
// Term: Identificatorul obiectului schemei
// Cardinality: 0..1
AdditionalDocumentReference *ValueWithAttrs `xml:"urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2 AdditionalDocumentReference,omitempty"`
Expand Down Expand Up @@ -190,20 +193,24 @@ type Invoice struct {
Comment string `xml:",comment"`
}

func (iv *Invoice) Initialize() {
// Prefill sets the NS, NScac, NScbc and Comment properties for ensuring that
// the required attributes and properties are set vor a valid UBL XML.
func (iv *Invoice) Prefill() {
iv.NS = XMLNSInvoice2
iv.NScac = XMLNSUBLcac
iv.NScbc = XMLNSUBLcbc
iv.UBLVersionID = UBLVersionID
iv.CustomizationID = CIUSRO_v101
iv.Comment = "Generated with " + efacturaVersion
if iv.Comment == "" {
iv.Comment = "Generated with " + efacturaVersion
}
}

func (iv Invoice) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
// this is just to strip away methods like MarshalXML
type invoice Invoice

iv.Initialize()
iv.Prefill()
return e.EncodeElement(invoice(iv), start)
}

Expand Down Expand Up @@ -445,36 +452,29 @@ type InvoiceCustomerPostalAddress struct {
// ID: BT-50
// Term: Adresa Cumpărătorului - Linia 1
// Cardinality: 0..1

// Field: PostalAddress.Line2
// ID: BT-51
// Term: Adresa Cumpărătorului - Linia 2
// Cardinality: 0..1

// Field: PostalAddress.Line3
// ID: BT-163
// Term: Adresa Cumpărătorului - Linia 3

// Field: PostalAddress.CityName
// ID: BT-52
// Term: Localitatea Cumpărătorului
// Cardinality: 0..1

// Field: PostalAddress.PostalZone
// ID: BT-53
// Term: Codul poştal al Cumpărătorului
// Cardinality: 0..1

// Field: PostalAddress.CountrySubentity
// ID: BT-54
// Term: Subdiviziunea ţării Cumpărătorului
// Cardinality: 0..1

// Feild: PostalAddress.CountryIdentificationCode
// ID: BT-55
// Term: Codul ţării Cumpărătorului
// Cardinality: 1..1

PostalAddress
}

Expand Down Expand Up @@ -540,37 +540,30 @@ type InvoiceTaxRepresentativePostalAddress struct {
// ID: BT-64
// Term: Adresa reprezentantului fiscal - Linia 1
// Cardinality: 0..1

// Field: PostalAddress.Line2
// ID: BT-64
// Term: Adresa reprezentantului fiscal - Linia 2
// Cardinality: 0..1

// Field: PostalAddress.Line3
// ID: BT-164
// Term: Adresa reprezentantului fiscal - Linia 3
// Cardinality: 0..1

// Field: PostalAddress.CityName
// ID: BT-66
// Term: Localitatea reprezentantului fiscal
// Cardinality: 0..1

// Field: PostalAddress.PostalZone
// ID: BT-67
// Term: Codul poştal al reprezentantului fiscal
// Cardinality: 0..1

// Field: PostalAddress.CountrySubentity
// ID: BT-68
// Term: Subdiviziunea ţării reprezentantului fiscal
// Cardinality: 0..1

// Feild: PostalAddress.CountryIdentificationCode
// ID: BT-69
// Term: Codul ţării reprezentantului fiscal
// Cardinality: 1..1

PostalAddress
}

Expand Down Expand Up @@ -608,32 +601,26 @@ type InvoiceDeliveryAddress struct {
// ID: BT-75
// Term: Adresa de livrare - Linia 1
// Cardinality: 0..1

// Field: PostalAddress.Line2
// ID: BT-76
// Term: Adresa de livrare - Linia 2
// Cardinality: 0..1

// Field: PostalAddress.Line3
// ID: BT-165
// Term: Adresa de livrare - Linia 3
// Cardinality: 0..1

// Field: PostalAddress.CityName
// ID: BT-77
// Term: Localitatea de livrare
// Cardinality: 0..1

// Field: PostalAddress.PostalZone
// ID: BT-78
// Term: Codul poştal al de livrare
// Cardinality: 0..1

// Field: PostalAddress.CountrySubentity
// ID: BT-79
// Term: Subdiviziunea ţării de livrare
// Cardinality: 0..1

// Feild: PostalAddress.CountryIdentificationCode
// ID: BT-80
// Term: Codul țării de livrare
Expand Down
13 changes: 9 additions & 4 deletions rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,8 @@ func (r *UploadResponse) IsOk() bool {
return r != nil && r.ExecutionStatus != nil && *r.ExecutionStatus == 0
}

// Returns the upload index (should only be called when IsOk() == true).
// GetUploadIndex returns the upload index (should only be called when
// IsOk() == true).
func (r *UploadResponse) GetUploadIndex() int64 {
if r == nil || r.UploadIndex == nil {
return 0
Expand Down Expand Up @@ -242,18 +243,22 @@ func (t MessageFilterType) String() string {
return ""
}

// IsError returns true if message type is ERORI FACTURA
func (m Message) IsError() bool {
return m.Type == "ERORI FACTURA"
}

// IsSentInvoice returns true if message type is FACTURA TRIMISA
func (m Message) IsSentInvoice() bool {
return m.Type == "FACTURA TRIMISA"
}

// IsReceivedInvoice returns true if message type is FACTURA PRIMITA
func (m Message) IsReceivedInvoice() bool {
return m.Type == "FACTURA PRIMITA"
}

//IsBuyerMessage returns true if message type is MESAJ CUMPARATOR PRIMIT / MESAJ CUMPARATOR TRANSMIS
func (m Message) IsBuyerMessage() bool {
return m.Type == "MESAJ CUMPARATOR PRIMIT / MESAJ CUMPARATOR TRANSMIS"
}
Expand Down Expand Up @@ -535,12 +540,12 @@ func (c *Client) GetMessagesListPagination(
return
}

// DownloadInvoice download an invoice zip for a given download index
// DownloadInvoice downloads an invoice zip for a given download index.
func (c *Client) DownloadInvoice(
ctx context.Context, downloadID int,
ctx context.Context, downloadID int64,
) (response *DownloadInvoiceResponse, err error) {
query := url.Values{
"id": {strconv.Itoa(downloadID)},
"id": {strconv.FormatInt(downloadID, 10)},
}
req, er := c.newApiRequest(ctx, http.MethodGet, apiPathDownload, query, nil)
if err = er; err != nil {
Expand Down
32 changes: 20 additions & 12 deletions xml_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,17 @@ import (
)

// Date is a wrapper of the time.Time type which marshals to XML in the
// YYYY-MM-DDD.
// YYYY-MM-DD format.
type Date struct {
time.Time
}

// MakeDateLocal creates a date with the provided year, month and day in the
// Local time zone location.
func MakeDateLocal(year int, month time.Month, day int) Date {
return Date{time.Date(year, month, day, 0, 0, 0, 0, time.Local)}
}

func MakeDateUTC(year int, month time.Month, day int) Date {
return Date{time.Date(year, month, day, 0, 0, 0, 0, time.UTC)}
}

func (d Date) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
v := d.Format(time.DateOnly)
return e.EncodeElement(v, start)
Expand All @@ -56,13 +54,14 @@ func (dt *Date) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
return nil
}

// Ptr is a helper to return a *Date in contexts where a pointer is needed.
func (d Date) Ptr() *Date {
return &d
}

// IsInitialized if the Date is initialized (ie is created explicitly with a
// constructor or initialized by setting the Time, not implicitly via var
// declaration with no initialization).
// IsInitialized checks if the Date is initialized (ie is created explicitly
// with a constructor or initialized by setting the Time, not implicitly via
// var declaration with no initialization).
func (d Date) IsInitialized() bool {
return d != Date{}
}
Expand Down Expand Up @@ -114,28 +113,37 @@ type ValueWithAttrs struct {
Attributes []xml.Attr `xml:",any,attr,omitempty"`
}

// Ptr is a helper method to return a *ValueWithAttrs from the receiver in
// contexts where a pointer is needed.
func (v ValueWithAttrs) Ptr() *ValueWithAttrs {
return &v
}

// MakeValueWithAttrs create a ValueWithAttrs using the provided chardata value
// and attributes.
func MakeValueWithAttrs(value string, attrs ...xml.Attr) ValueWithAttrs {
return ValueWithAttrs{
Value: value,
Attributes: attrs,
}
}

// NewValueWithAttrs same as [MakeValueWithAttrs] but a pointer is returned.
func NewValueWithAttrs(value string, attrs ...xml.Attr) *ValueWithAttrs {
return MakeValueWithAttrs(value, attrs...).Ptr()
}

// MakeValueWithScheme creates ValueWithAttrs with the provided chardata value
// and an attribute named `schemeID` with the given scheme ID.
func MakeValueWithScheme(value string, schemeID string) ValueWithAttrs {
return MakeValueWithAttrs(value, xml.Attr{
Name: xml.Name{Local: "schemeID"},
Value: schemeID,
})
}

func NewValueWithAttrs(value string, attrs ...xml.Attr) *ValueWithAttrs {
return MakeValueWithAttrs(value, attrs...).Ptr()
}

// GetAttrByName returns the attribute by local name. If no attribute with the
// given name exists, an empty xml.Attr is returned.
func (v *ValueWithAttrs) GetAttrByName(name string) (attr xml.Attr) {
if v == nil {
return
Expand Down

0 comments on commit f6ad598

Please sign in to comment.