Skip to content

Commit

Permalink
fix bulk.yaml for compatibility; allow to download a PDF based on sou…
Browse files Browse the repository at this point in the history
…rce invoice file and status file which is much faster than waiting for interactive session
  • Loading branch information
toudi committed Dec 10, 2023
1 parent 149e07b commit b00c71c
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 16 deletions.
24 changes: 17 additions & 7 deletions internal/invoice/invoice_collection_parse_issuer.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,29 @@ import (
"os"
)

type xmlInvoice struct {
XMLName xml.Name `xml:"Faktura"`
Issuer string `xml:"Podmiot1>DaneIdentyfikacyjne>NIP"`
type XMLInvoice struct {
XMLName xml.Name `xml:"Faktura"`
Issuer string `xml:"Podmiot1>DaneIdentyfikacyjne>NIP"`
InvoiceNumber string `xml:"Fa>P_2"`
}

func parseInvoiceIssuer(sourceFile string) (string, error) {
var invoice xmlInvoice
invoice, err := ParseInvoice(sourceFile)
if err != nil {
return "", fmt.Errorf("cannot parse issuer: %v", err)
}
return invoice.Issuer, nil
}

func ParseInvoice(sourceFile string) (*XMLInvoice, error) {
var invoice XMLInvoice
xmlContents, err := os.ReadFile(sourceFile)
if err != nil {
return "", fmt.Errorf("unable to read invoice file: %v", err)
return nil, fmt.Errorf("unable to read invoice file: %v", err)
}
if err = xml.Unmarshal(xmlContents, &invoice); err != nil {
return "", fmt.Errorf("unable to parse xml invoice: %v", err)
return nil, fmt.Errorf("unable to parse xml invoice: %v", err)
}
return invoice.Issuer, nil

return &invoice, nil
}
40 changes: 35 additions & 5 deletions internal/sei/api/pdf/download_pdf.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,47 @@ import (
"bytes"
"fmt"
"io"
invoicePkg "ksef/internal/invoice"
"ksef/internal/sei/api/client"
"ksef/internal/sei/api/status"
"ksef/internal/sei/api/upload/interactive"
"net/http"
"os"
"path"
)

const downloadInvoiceXML = "online/Invoice/Get/%s"
const downloadInvoicePDF = "https://%s/web/api/invoice/get-invoice-pdf-file?ksefReferenceNumber=%s"

func DownloadPDF(apiClient *client.APIClient, statusInfo *status.StatusInfo, invoiceNo string, outputPath string) error {
func DownloadPDF(apiClient *client.APIClient, statusInfo *status.StatusInfo, invoice string, outputPath string) error {
// let's check if the specified `invoice` is actually a source XML file.
invoiceStruct, err := invoicePkg.ParseInvoice(invoice)
if err != nil {
// nope. let's continue with the API route
return downloadPDFFromAPI(apiClient, statusInfo, invoice, outputPath)
}
// yes, it is! let's download the PDF based on that.
seiRefNo, err := statusInfo.GetSEIRefNo(invoiceStruct.InvoiceNumber)
if err != nil {
return fmt.Errorf("unable to find the invoice in status file. was it uploaded?")
}
sourceInvoiceBytes, err := os.ReadFile(invoice)
if err != nil {
return fmt.Errorf("unable to read the source file: %v", err)
}

httpSession := client.NewRequestFactory(apiClient)
invoiceXMLReader := bytes.NewReader(sourceInvoiceBytes)

return httpSession.DownloadPDFFromSourceXML(
fmt.Sprintf(downloadInvoicePDF, apiClient.Environment.Host, seiRefNo),
seiRefNo+".xml",
invoiceXMLReader,
path.Join(outputPath, seiRefNo+".pdf"),
)
}

func downloadPDFFromAPI(apiClient *client.APIClient, statusInfo *status.StatusInfo, invoice string, outputPath string) error {
// we have to initialize the interactive session
session := interactive.InteractiveSessionInit(apiClient)
if err := session.Login(statusInfo.Issuer); err != nil {
Expand All @@ -27,7 +57,7 @@ func DownloadPDF(apiClient *client.APIClient, statusInfo *status.StatusInfo, inv

httpSession := session.HTTPSession()

invoiceXMLRequest, err := httpSession.Request("GET", fmt.Sprintf(downloadInvoiceXML, invoiceNo), nil)
invoiceXMLRequest, err := httpSession.Request("GET", fmt.Sprintf(downloadInvoiceXML, invoice), nil)
if err != nil {
return fmt.Errorf("unable to download invoice in XML Format: %v", err)
}
Expand All @@ -46,9 +76,9 @@ func DownloadPDF(apiClient *client.APIClient, statusInfo *status.StatusInfo, inv

invoiceXMLReader := bytes.NewReader(invoiceXML.Bytes())
return httpSession.DownloadPDFFromSourceXML(
fmt.Sprintf(downloadInvoicePDF, apiClient.Environment.Host, invoiceNo),
invoiceNo+".xml",
fmt.Sprintf(downloadInvoicePDF, apiClient.Environment.Host, invoice),
invoice+".xml",
invoiceXMLReader,
path.Join(outputPath, invoiceNo+".pdf"),
path.Join(outputPath, invoice+".pdf"),
)
}
12 changes: 12 additions & 0 deletions internal/sei/api/status/structs.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package status

import "errors"

type KsefInvoiceIdType struct {
InvoiceNumber string `xml:"NumerFaktury" json:"invoiceNumber" yaml:"invoiceNumber"`
KSeFInvoiceReferenceNo string `xml:"NumerKSeFDokumentu" json:"ksefDocumentId" yaml:"ksefDocumentId"`
Expand All @@ -13,3 +15,13 @@ type StatusInfo struct {
Issuer string `json:"issuer" yaml:"issuer"`
InvoiceIds []KsefInvoiceIdType `json:"invoiceIds,omitempty" yaml:"invoiceIds,omitempty"`
}

func (s *StatusInfo) GetSEIRefNo(invoiceNo string) (string, error) {
for _, invoice := range s.InvoiceIds {
if invoice.InvoiceNumber == invoiceNo {
return invoice.KSeFInvoiceReferenceNo, nil
}
}

return "", errors.New("invoice number could not be found")
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ func (i *InteractiveSession) Login(issuer string) error {
}

i.session.SetHeader("SessionToken", initTokenResponse.Token.Value)
fmt.Printf("set token %s\n", initTokenResponse.Token.Value)
fmt.Printf("set ref no: %s\n", initTokenResponse.ReferenceNumber)
// fmt.Printf("set token %s\n", initTokenResponse.Token.Value)
// fmt.Printf("set ref no: %s\n", initTokenResponse.ReferenceNumber)
i.referenceNo = initTokenResponse.ReferenceNumber

return nil
Expand Down
4 changes: 2 additions & 2 deletions przykladowe-pliki-wejsciowe/bulk.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ common:
SystemInfo: WSI Pegasus
# the following values are default and can be omitted
KodFormularza: FA
KodFormularza#KodSystemowy: FA (2)
KodFormularza#WersjaSchemy: 1-0E
KodFormularza#kodSystemowy: FA (2)
KodFormularza#wersjaSchemy: 1-0E
WariantFormularza: 2
Podmiot1:
DaneIdentyfikacyjne:
Expand Down

0 comments on commit b00c71c

Please sign in to comment.