infakt-cli/main.go

141 lines
3.1 KiB
Go

package main
import (
"context"
"encoding/json"
"log"
"os"
"path"
"strings"
"gitea.dwysokinski.me/Kichiyaki/infakt-cli/internal/infakt"
"github.com/urfave/cli/v2"
)
const (
appName = "infakt-cli"
)
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"
app.HelpName = appName
app.Flags = []cli.Flag{
&cli.StringFlag{
Name: "url",
Aliases: []string{"u"},
DefaultText: "https://api.infakt.pl",
},
&cli.StringFlag{
Name: "apiKey",
EnvVars: []string{"INFAKT_API_KEY"},
Required: true,
},
}
app.Commands = []*cli.Command{
newInvoiceCmd(),
}
app.EnableBashCompletion = true
return app
}
const defaultDownloadPath = "./"
func newInvoiceCmd() *cli.Command {
return &cli.Command{
Name: "invoice",
Subcommands: []*cli.Command{
{
Name: "create",
Action: func(c *cli.Context) error {
b, err := os.ReadFile(c.Path("file"))
if err != nil {
return err
}
var params []infakt.CreateInvoiceParams
if err = json.Unmarshal(b, &params); err != nil {
return err
}
var clientOpts []infakt.ClientOption
if url := c.String("url"); url != "" {
clientOpts = append(clientOpts, infakt.WithBaseURL(url))
}
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)
if err != nil {
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
}
invoicePath := path.Join(downloadPath, strings.ReplaceAll(invoice.Number, "/", "-")+".pdf")
if err = downloadInvoice(c.Context, client, invoice.UUID, invoicePath); err != nil {
log.Printf("couldn't download invoice #%d: %s", i+1, err)
continue
}
log.Printf("invoice '%s' saved on disk: '%s'", invoice.Number, invoicePath)
}
return nil
},
Flags: []cli.Flag{
&cli.PathFlag{
Name: "file",
Aliases: []string{"f"},
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)
}