Skip to content

Commit

Permalink
Add getters/helpers and fixes for Message object
Browse files Browse the repository at this point in the history
- Add IsSelfBilledInvoice, GetCreationDate helpers
- Fix GetSellerCIF, GetBuyerCIF for self billed invoices
- Add test to check proper unmarshaling and helper methods for Message
  • Loading branch information
printesoi committed Mar 30, 2024
1 parent 0d765b5 commit 474ef85
Show file tree
Hide file tree
Showing 2 changed files with 238 additions and 13 deletions.
74 changes: 61 additions & 13 deletions rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,12 @@ type (
MessageFilterType int

Message struct {
CreationDate string `json:"data_creare"`
CIF string `json:"cif"`
ID string `json:"id"`
Type string `json:"tip"`
UploadIndex string `json:"id_solicitare"`
CIF string `json:"cif"`
Details string `json:"detalii"`
Type string `json:"tip"`
ID string `json:"id"`
CreationDate string `json:"data_creare"`
}

// MessagesListResponse is the parsed response from the list messages
Expand Down Expand Up @@ -212,12 +212,24 @@ const (
// Filter that returns only the received invoices
MessageFilterReceived
// Filter that returns only the customer send or received messages
MessageFilterCustomerMessage
MessageFilterBuyerMessage

// MessageTypeError
MessageTypeError = "ERORI FACTURA"
MessageTypeSentInvoice = "FACTURA TRIMISA"
MessageTypeReceivedInvoice = "FACTURA PRIMITA"
MessageTypeBuyerMessage = "MESAJ CUMPARATOR PRIMIT / MESAJ CUMPARATOR TRANSMIS"

messageTimeLayout = "200601021504"
)

var (
regexSellerCIF = regexp.MustCompile("\\bcif_emitent=(\\d+)")
regexBuyerCIF = regexp.MustCompile("\\bcif_beneficiar=(\\d+)")
regexSellerCIF = regexp.MustCompile("\\bcif_emitent=(\\d+)")
regexBuyerCIF = regexp.MustCompile("\\bcif_beneficiar=(\\d+)")
regexErrTypeSelfBilled = regexp.MustCompile("\\btip declarat=AUTOFACTURA\\b")
regexTypeSelfBilled = regexp.MustCompile(" ca autofactutra in numele cif=")
regexSelfBilledSellerCIF = regexp.MustCompile("\\bin numele cif=(\\d+)")
regexSelfBilledBuyerCIF = regexp.MustCompile("\\btransmisa de cif=(\\d+)")

regexZipFile = regexp.MustCompile("^\\d+.xml$")
regexZipSignatureFile = regexp.MustCompile("^semnatura_\\d+.xml$")
Expand Down Expand Up @@ -342,30 +354,30 @@ func (t MessageFilterType) String() string {
return "T"
case MessageFilterReceived:
return "P"
case MessageFilterCustomerMessage:
case MessageFilterBuyerMessage:
return "R"
}
return ""
}

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

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

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

// 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"
return m.Type == MessageTypeBuyerMessage
}

// GetID parses and returns the message ID as int64 (since the API returns it
Expand All @@ -382,18 +394,54 @@ func (m Message) GetUploadIndex() int64 {
return n
}

// IsSelfBilledInvoice returns true if the message represents a self-billed
// invoice.
func (m Message) IsSelfBilledInvoice() bool {
if m.IsError() {
return regexErrTypeSelfBilled.MatchString(m.Details)
}

return regexTypeSelfBilled.MatchString(m.Details)
}

// GetSellerCIF parses message details and returns the seller CIF.
func (m Message) GetSellerCIF() (sellerCIF string) {
sellerCIF, _ = matchFirstSubmatch(m.Details, regexSellerCIF)
if m.IsError() {
return
}
if m.IsReceivedInvoice() {
if m.IsSelfBilledInvoice() {
sellerCIF, _ = matchFirstSubmatch(m.Details, regexSelfBilledSellerCIF)
return
}

sellerCIF, _ = matchFirstSubmatch(m.Details, regexSellerCIF)
return
}
sellerCIF = m.CIF
return
}

// GetBuyerCIF parses message details and returns the buyer CIF.
func (m Message) GetBuyerCIF() (buyerCIF string) {
if m.IsError() {
return
}
if m.IsSelfBilledInvoice() {
buyerCIF = m.CIF
return
}
buyerCIF, _ = matchFirstSubmatch(m.Details, regexBuyerCIF)
return
}

// GetCreationDate parsed CreationDate and returns a time.Time in
// RoZoneLocation.
func (m Message) GetCreationDate() (time.Time, bool) {
t, err := time.ParseInLocation(messageTimeLayout, m.CreationDate, RoZoneLocation)
return t, err == nil
}

// IsOk returns true if the response corresponding to a download was successful.
func (r *DownloadInvoiceResponse) IsOk() bool {
return r != nil && r.Error == nil
Expand Down
177 changes: 177 additions & 0 deletions rest_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
package efactura

import (
"encoding/json"
"testing"

"github.com/stretchr/testify/assert"
)

func TestUnmarshalMessage(t *testing.T) {
assert := assert.New(t)

type messageTest struct {
JSON []byte

ExpectedMessage Message
ExpectedID int64
ExpectedUploadIndex int64
ExpectedIsError bool
ExpectedIsSentInvoice bool
ExpectedIsReceivedInvoice bool
ExpectedIsBuyerMessage bool
ExpectedIsSelfBilledInvoice bool
ExpectedSellerCIF string
ExpectedBuyerCIF string
}
tests := []messageTest{
{
JSON: []byte(`{}`),
},
{
JSON: []byte(`{
"cif": "123456789",
"data_creare": "202401020304",
"detalii": "Erori de validare identificate la factura transmisa cu id_incarcare=42",
"id": "128",
"id_solicitare": "42",
"tip": "ERORI FACTURA"
}`),
ExpectedMessage: Message{
ID: "128",
Type: MessageTypeError,
UploadIndex: "42",
CIF: "123456789",
Details: "Erori de validare identificate la factura transmisa cu id_incarcare=42",
CreationDate: "202401020304",
},
ExpectedID: int64(128),
ExpectedUploadIndex: int64(42),
ExpectedIsError: true,
},
{
JSON: []byte(`{
"cif": "123456789",
"data_creare": "202401020304",
"detalii": "Erori de validare identificate la factura de tip declarat=AUTOFACTURA, transmisa cu id_incarcare=42",
"id": "128",
"id_solicitare": "42",
"tip": "ERORI FACTURA"
}`),
ExpectedMessage: Message{
ID: "128",
Type: MessageTypeError,
UploadIndex: "42",
CIF: "123456789",
Details: "Erori de validare identificate la factura de tip declarat=AUTOFACTURA, transmisa cu id_incarcare=42",
CreationDate: "202401020304",
},
ExpectedID: int64(128),
ExpectedUploadIndex: int64(42),
ExpectedIsError: true,
ExpectedIsSelfBilledInvoice: true,
},
{
JSON: []byte(`{
"cif": "123456789",
"data_creare": "202401020304",
"detalii": "Factura cu id_incarcare=42 emisa de cif_emitent=123456789 pentru cif_beneficiar=987654321",
"id": "128",
"id_solicitare": "42",
"tip": "FACTURA TRIMISA"
}`),
ExpectedMessage: Message{
ID: "128",
Type: MessageTypeSentInvoice,
UploadIndex: "42",
CIF: "123456789",
Details: "Factura cu id_incarcare=42 emisa de cif_emitent=123456789 pentru cif_beneficiar=987654321",
CreationDate: "202401020304",
},
ExpectedID: int64(128),
ExpectedUploadIndex: int64(42),
ExpectedIsSentInvoice: true,
ExpectedSellerCIF: "123456789",
ExpectedBuyerCIF: "987654321",
},
{
JSON: []byte(`{
"cif": "123456789",
"data_creare": "202401020304",
"detalii": "Factura cu id_incarcare=42 emisa de cif_emitent=987654321 pentru cif_beneficiar=123456789",
"id": "128",
"id_solicitare": "42",
"tip": "FACTURA PRIMITA"
}`),
ExpectedMessage: Message{
ID: "128",
Type: MessageTypeReceivedInvoice,
UploadIndex: "42",
CIF: "123456789",
Details: "Factura cu id_incarcare=42 emisa de cif_emitent=987654321 pentru cif_beneficiar=123456789",
CreationDate: "202401020304",
},
ExpectedID: int64(128),
ExpectedUploadIndex: int64(42),
ExpectedIsReceivedInvoice: true,
ExpectedSellerCIF: "987654321",
ExpectedBuyerCIF: "123456789",
},
{
JSON: []byte(`{
"cif": "123456789",
"data_creare": "202401020304",
"detalii": "Factura cu id_incarcare=42 transmisa de cif=123456789 ca autofactutra in numele cif=987654321",
"id": "128",
"id_solicitare": "42",
"tip": "FACTURA PRIMITA"
}`),
ExpectedMessage: Message{
ID: "128",
Type: MessageTypeReceivedInvoice,
UploadIndex: "42",
CIF: "123456789",
Details: "Factura cu id_incarcare=42 transmisa de cif=123456789 ca autofactutra in numele cif=987654321",
CreationDate: "202401020304",
},
ExpectedID: int64(128),
ExpectedUploadIndex: int64(42),
ExpectedIsReceivedInvoice: true,
ExpectedIsSelfBilledInvoice: true,
ExpectedSellerCIF: "987654321",
ExpectedBuyerCIF: "123456789",
},
// TODO: we also need to check self billed invoices that were issued on
// our behalf.
}
for _, mt := range tests {
var um Message
if !assert.NoError(json.Unmarshal(mt.JSON, &um)) {
continue
}

// Test raw fields
assert.Equal(mt.ExpectedMessage.ID, um.ID)
assert.Equal(mt.ExpectedMessage.Type, um.Type)
assert.Equal(mt.ExpectedMessage.UploadIndex, um.UploadIndex)
assert.Equal(mt.ExpectedMessage.CIF, um.CIF)
assert.Equal(mt.ExpectedMessage.Details, um.Details)
assert.Equal(mt.ExpectedMessage.CreationDate, um.CreationDate)

// Test getters/helpers
assert.Equal(mt.ExpectedID, um.GetID())
assert.Equal(mt.ExpectedUploadIndex, um.GetUploadIndex())
assert.Equal(mt.ExpectedIsError, um.IsError())
assert.Equal(mt.ExpectedIsSentInvoice, um.IsSentInvoice())
assert.Equal(mt.ExpectedIsReceivedInvoice, um.IsReceivedInvoice())
assert.Equal(mt.ExpectedIsBuyerMessage, um.IsBuyerMessage())
assert.Equal(mt.ExpectedIsSelfBilledInvoice, um.IsSelfBilledInvoice())
assert.Equal(mt.ExpectedSellerCIF, um.GetSellerCIF())
assert.Equal(mt.ExpectedBuyerCIF, um.GetBuyerCIF())
if mt.ExpectedMessage.CreationDate != "" {
mdate, ok := um.GetCreationDate()
assert.True(ok)
assert.Equal(mt.ExpectedMessage.CreationDate, mdate.Format(messageTimeLayout))
}
}
}

0 comments on commit 474ef85

Please sign in to comment.