summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVidhu Kant Sharma <vidhukant@vidhukant.xyz>2022-11-11 22:57:19 +0530
committerVidhu Kant Sharma <vidhukant@vidhukant.xyz>2022-11-11 22:57:19 +0530
commit10eb82c7c00a0a1a75528644fbfbe108a769207f (patch)
treeac5d413830d8e1f15985450230fe20490966fcb6
parent2f4a92b0f1d02096427a2d1c97746bb52cdcc38a (diff)
serving created invoices as both HTML and JSON
-rw-r--r--invoice/db_actions.go12
-rw-r--r--invoice/router.go88
-rw-r--r--main.go2
-rw-r--r--web/templates/partials/item_list.html4
-rw-r--r--web/templates/views/invoice.html (renamed from web/templates/invoice.html)2
5 files changed, 95 insertions, 13 deletions
diff --git a/invoice/db_actions.go b/invoice/db_actions.go
index a4880fa..0cbeec1 100644
--- a/invoice/db_actions.go
+++ b/invoice/db_actions.go
@@ -117,3 +117,15 @@ func getTransports(filter bson.M) ([]Transport, error) {
err = cursor.All(context.TODO(), &transports)
return transports, err
}
+
+func getInvoiceByNumber(invoiceNumber int) (Invoice, error) {
+ var invoice Invoice
+ err := db.Collection("Invoices").FindOne(context.TODO(), bson.M{"InvoiceNumber": invoiceNumber}).Decode(&invoice)
+ return invoice, err
+}
+
+func getInvoiceById(invoiceId primitive.ObjectID) (Invoice, error) {
+ var invoice Invoice
+ err := db.Collection("Invoices").FindOne(context.TODO(), bson.M{"_id": invoiceId}).Decode(&invoice)
+ return invoice, err
+}
diff --git a/invoice/router.go b/invoice/router.go
index 4e33e18..ba6665f 100644
--- a/invoice/router.go
+++ b/invoice/router.go
@@ -20,10 +20,12 @@ package invoice
import (
"github.com/gin-gonic/gin"
"log"
+ "errors"
"net/http"
"strconv"
"go.mongodb.org/mongo-driver/bson/primitive"
- "go.mongodb.org/mongo-driver/bson"
+ "go.mongodb.org/mongo-driver/mongo"
+ //"go.mongodb.org/mongo-driver/bson"
)
func Routes(route *gin.Engine) {
@@ -41,29 +43,95 @@ func Routes(route *gin.Engine) {
ctx.JSON(http.StatusOK, invoices)
})
- // preview invoice
- i.GET("/preview/:invoiceNumber", func(ctx *gin.Context) {
+ // TODO: /preview routes should send error codes as HTML
+ // send invoice as HTML, filtering by InvoiceNumber
+ i.GET("/preview/by-num/:invoiceNumber", func(ctx *gin.Context) {
num := ctx.Param("invoiceNumber")
numInt, _ := strconv.Atoi(num)
- invoice, err := getInvoices(bson.M{"InvoiceNumber": numInt})
+ invoice, err := getInvoiceByNumber(numInt)
if err != nil {
- ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
- log.Printf("ERROR: Failed to read invoice %v from DB: %v\n", numInt, err.Error())
+ if errors.Is(err, mongo.ErrNoDocuments) {
+ ctx.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
+ } else {
+ ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
+ }
+ log.Printf("ERROR: Failed to read invoice #%d from DB: %v\n", numInt, err.Error())
return
}
- if len(invoice) == 0 {
- ctx.JSON(http.StatusNotFound, gin.H{"error": "no invoice with this invoice number"})
- log.Printf("WARN: No invoice with number %v found", numInt)
+ ctx.HTML(http.StatusOK, "invoice.html", gin.H{
+ "Invoice": invoice,
+ })
+ })
+
+ // send invoice as HTML, filtering by ID
+ i.GET("/preview/by-id/:invoiceId", func(ctx *gin.Context) {
+ id, err := primitive.ObjectIDFromHex(ctx.Param("invoiceId"))
+ if err != nil {
+ ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ log.Printf("ERROR: Failed to get invoice with ID, Error parsing ID: %v\n", err.Error())
+ return
+ }
+
+ invoice, err := getInvoiceById(id)
+ if err != nil {
+ if errors.Is(err, mongo.ErrNoDocuments) {
+ ctx.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
+ } else {
+ ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
+ }
+ log.Printf("ERROR: Failed to read invoice %v from DB: %v\n", id, err.Error())
return
}
ctx.HTML(http.StatusOK, "invoice.html", gin.H{
- "Invoice": invoice[0],
+ "Invoice": invoice,
})
})
+ // send invoice as JSON, filtering by InvoiceNumber
+ i.GET("/by-num/:invoiceNumber", func(ctx *gin.Context) {
+ num := ctx.Param("invoiceNumber")
+ numInt, _ := strconv.Atoi(num)
+
+ invoice, err := getInvoiceByNumber(numInt)
+ if err != nil {
+ if errors.Is(err, mongo.ErrNoDocuments) {
+ ctx.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
+ } else {
+ ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
+ }
+ log.Printf("ERROR: Failed to read invoice #%d from DB: %v\n", numInt, err.Error())
+ return
+ }
+
+ ctx.JSON(http.StatusOK, invoice)
+ })
+
+ // send invoice as JSON, filtering by ID
+ i.GET("/by-id/:invoiceId", func(ctx *gin.Context) {
+ id, err := primitive.ObjectIDFromHex(ctx.Param("invoiceId"))
+ if err != nil {
+ ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ log.Printf("ERROR: Failed to get invoice with ID, Error parsing ID: %v\n", err.Error())
+ return
+ }
+
+ invoice, err := getInvoiceById(id)
+ if err != nil {
+ if errors.Is(err, mongo.ErrNoDocuments) {
+ ctx.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
+ } else {
+ ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
+ }
+ log.Printf("ERROR: Failed to read invoice %v from DB: %v\n", id, err.Error())
+ return
+ }
+
+ ctx.JSON(http.StatusOK, invoice)
+ })
+
i.POST("/new", func(ctx *gin.Context) {
var i Invoice
ctx.BindJSON(&i)
diff --git a/main.go b/main.go
index 76c09dc..29378cb 100644
--- a/main.go
+++ b/main.go
@@ -31,6 +31,8 @@ func main() {
defer database.DisconnectDB()
r := gin.New()
+ r.LoadHTMLGlob("web/templates/**/*")
+
item.Routes(r)
brand.Routes(r)
client.Routes(r)
diff --git a/web/templates/partials/item_list.html b/web/templates/partials/item_list.html
index f12a34a..6fdd1f9 100644
--- a/web/templates/partials/item_list.html
+++ b/web/templates/partials/item_list.html
@@ -1,6 +1,6 @@
-{{ define "partials/item_list.html.tmpl" }}
+{{ define "partials/item_list.html" }}
<div class="items">
- {{ range .Items }}
+ {{ range . }}
{{ template "partials/item.html" .}}
{{ end }}
</div>
diff --git a/web/templates/invoice.html b/web/templates/views/invoice.html
index 77825fe..c8a3c70 100644
--- a/web/templates/invoice.html
+++ b/web/templates/views/invoice.html
@@ -10,6 +10,6 @@
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
</head>
<body>
- {{ template "partials/item_list.html" .}}
+ {{ template "partials/item_list.html" .Invoice.Items }}
</body>
</html>