feat: add download flag to invoice create

This commit is contained in:
Dawid Wysokiński 2023-04-09 08:37:23 +02:00
parent c51fe15e77
commit 4bf3756171
Signed by: Kichiyaki
GPG Key ID: B5445E357FB8B892
2 changed files with 91 additions and 7 deletions

View File

@ -17,9 +17,8 @@ const (
defaultBaseURL = "https://api.infakt.pl"
defaultTimeout = 10 * time.Second
//nolint:gosec
apiKeyHeader = "X-inFakt-ApiKey"
reqPerMinute = 150
endpointCreateInvoice = "/api/v3/invoices.json"
apiKeyHeader = "X-inFakt-ApiKey"
reqPerMinute = 150
)
type Client struct {
@ -60,6 +59,8 @@ func NewClient(apiKey string, opts ...ClientOption) *Client {
return c
}
const endpointCreateInvoice = "/api/v3/invoices.json"
type CreateInvoiceParamsService struct {
Name string `json:"name"`
TaxSymbol string `json:"tax_symbol,omitempty"`
@ -123,6 +124,38 @@ func (c *Client) CreateInvoice(ctx context.Context, params CreateInvoiceParams)
return invoice, nil
}
const endpointGetInvoicePDF = "/api/v3/invoices/%s/pdf.json"
func (c *Client) GetInvoicePDF(ctx context.Context, invoiceUUID, documentType, locale string, w io.Writer) error {
values := urlpkg.Values{
"document_type": []string{documentType},
}
if locale != "" {
values["locale"] = []string{locale}
}
req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf(endpointGetInvoicePDF, invoiceUUID)+"?"+values.Encode(), nil)
if err != nil {
return err
}
resp, err := c.do(req)
if err != nil {
return err
}
defer func() {
_, _ = io.Copy(io.Discard, resp.Body)
_ = resp.Body.Close()
}()
if _, err = io.Copy(w, resp.Body); err != nil {
return err
}
return nil
}
func (c *Client) postJSON(ctx context.Context, url string, body any) (*http.Response, error) {
buf := bytes.NewBuffer(nil)
if err := json.NewEncoder(buf).Encode(body); err != nil {

59
main.go
View File

@ -1,9 +1,12 @@
package main
import (
"context"
"encoding/json"
"log"
"os"
pathpkg "path"
"strings"
"gitea.dwysokinski.me/Kichiyaki/infakt-cli/internal/infakt"
"github.com/urfave/cli/v2"
@ -14,6 +17,12 @@ const (
)
func main() {
if err := newApp().Run(os.Args); err != nil {
log.Fatal(err)
}
}
func newApp() *cli.App {
app := cli.NewApp()
app.Name = appName
app.Usage = "CLI tool for interacting with the InFakt API"
@ -34,12 +43,11 @@ func main() {
newInvoiceCmd(),
}
app.EnableBashCompletion = true
if err := app.Run(os.Args); err != nil {
log.Fatal(err)
}
return app
}
const defaultDownloadPath = "./"
func newInvoiceCmd() *cli.Command {
return &cli.Command{
Name: "invoice",
@ -63,6 +71,11 @@ func newInvoiceCmd() *cli.Command {
}
client := infakt.NewClient(c.String("apiKey"), clientOpts...)
downloadInvoices := c.Bool("download")
downloadPath := c.String("downloadPath")
if downloadPath == "" {
downloadPath = defaultDownloadPath
}
for i, p := range params {
invoice, err := client.CreateInvoice(c.Context, p)
@ -70,7 +83,21 @@ func newInvoiceCmd() *cli.Command {
log.Printf("couldn't create invoice #%d: %s", i+1, err)
continue
}
log.Printf("invoice #%d created with number %s", i+1, invoice.Number)
if !downloadInvoices {
continue
}
path := pathpkg.Join(downloadPath, strings.ReplaceAll(invoice.Number, "/", "-")+".pdf")
if err = downloadInvoice(c.Context, client, invoice.UUID, path); err != nil {
log.Printf("couldn't download invoice #%d: %s", i+1, err)
continue
}
log.Printf("invoice '%s' saved on disk: %s", invoice.Number, path)
}
return nil
@ -82,8 +109,32 @@ func newInvoiceCmd() *cli.Command {
Usage: "Path to .json file with invoice params",
Required: true,
},
&cli.BoolFlag{
Name: "download",
DefaultText: "false",
Usage: "Specifies whether to download invoices",
},
&cli.PathFlag{
Name: "downloadPath",
DefaultText: defaultDownloadPath,
Usage: "Specifies where invoices are to be downloaded",
},
},
},
},
}
}
const invoicePDFPerm = 0644
func downloadInvoice(ctx context.Context, client *infakt.Client, invoiceUUID, name string) error {
f, err := os.OpenFile(name, os.O_TRUNC|os.O_CREATE|os.O_WRONLY, invoicePDFPerm)
if err != nil {
return err
}
defer func() {
_ = f.Close()
}()
return client.GetInvoicePDF(ctx, invoiceUUID, "original", "pe", f)
}