Final qrcode
This commit is contained in:
parent
572540154d
commit
18a11ef9ed
|
|
@ -1,34 +1,48 @@
|
|||
package document
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/shopspring/decimal"
|
||||
)
|
||||
|
||||
// DocumentExtended represents the ExtendedDocument table from the MyInvois API response.
|
||||
type ExtendedDocument struct {
|
||||
UUID string `json:"uuid"`
|
||||
SubmissionUID string `json:"submissionUid"`
|
||||
LongID string `json:"longId"`
|
||||
InternalID string `json:"internalId"`
|
||||
TypeName string `json:"typeName"`
|
||||
TypeVersionName string `json:"typeVersionName"`
|
||||
IssuerTIN string `json:"issuerTin"`
|
||||
IssuerName string `json:"issuerName"`
|
||||
ReceiverID string `json:"receiverId"`
|
||||
ReceiverName string `json:"receiverName"`
|
||||
DateTimeIssued string `json:"dateTimeIssued"` // ISO8601 UTC
|
||||
DateTimeReceived string `json:"dateTimeReceived"` // ISO8601 UTC
|
||||
DateTimeValidated string `json:"dateTimeValidated"` // ISO8601 UTC
|
||||
TotalExcludingTax decimal.Decimal `json:"totalExcludingTax"`
|
||||
TotalDiscount decimal.Decimal `json:"totalDiscount"`
|
||||
TotalNetAmount decimal.Decimal `json:"totalNetAmount"`
|
||||
TotalPayableAmount decimal.Decimal `json:"totalPayableAmount"`
|
||||
Status string `json:"status"`
|
||||
CancelDateTime string `json:"cancelDateTime"` // ISO8601 UTC
|
||||
RejectRequestDateTime string `json:"rejectRequestDateTime"` // ISO8601 UTC
|
||||
DocumentStatusReason string `json:"documentStatusReason"`
|
||||
CreatedByUserID string `json:"createdByUserId"`
|
||||
Document string `json:"document"`
|
||||
CancelDateTime time.Time `json:"cancelDateTime"`
|
||||
CreatedByUserID string `json:"createdByUserId"`
|
||||
DateTimeIssued time.Time `json:"dateTimeIssued"`
|
||||
DateTimeReceived time.Time `json:"dateTimeReceived"`
|
||||
DateTimeValidated time.Time `json:"dateTimeValidated"`
|
||||
Document string `json:"document"`
|
||||
DocumentStatusReason string `json:"documentStatusReason"`
|
||||
InternalID string `json:"internalId"`
|
||||
IssuerName string `json:"issuerName"`
|
||||
IssuerTin string `json:"issuerTin"`
|
||||
LongID string `json:"longID"`
|
||||
ReceiverID string `json:"receiverId"`
|
||||
ReceiverName string `json:"receiverName"`
|
||||
RejectRequestDateTime any `json:"rejectRequestDateTime"`
|
||||
Status string `json:"status"`
|
||||
SubmissionUID string `json:"submissionUid"`
|
||||
TotalDiscount float64 `json:"totalDiscount"`
|
||||
TotalExcludingTax float64 `json:"totalExcludingTax"`
|
||||
TotalNetAmount float64 `json:"totalNetAmount"`
|
||||
TotalPayableAmount float64 `json:"totalPayableAmount"`
|
||||
TypeName string `json:"typeName"`
|
||||
TypeVersionName string `json:"typeVersionName"`
|
||||
UUID string `json:"uuid"`
|
||||
}
|
||||
|
||||
func (docEx ExtendedDocument) String() string {
|
||||
return fmt.Sprintf(
|
||||
"{UUID: %s, SubmissionUID: %s, LongID: %s, Status: %s, DocumentStatusReason: %s, TotalPayableAmount: %f}",
|
||||
docEx.UUID,
|
||||
docEx.SubmissionUID,
|
||||
docEx.LongID,
|
||||
docEx.Status,
|
||||
docEx.DocumentStatusReason,
|
||||
docEx.TotalPayableAmount)
|
||||
}
|
||||
|
||||
type UBLInvoiceRoot struct {
|
||||
|
|
|
|||
|
|
@ -36,17 +36,14 @@ func GetDocument(accessToken, docUUID string) (document.ExtendedDocument, error)
|
|||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
var resBodyUnformatted map[string]interface{}
|
||||
json.NewDecoder(res.Body).Decode(&resBodyUnformatted)
|
||||
if core.DEBUG {
|
||||
b, _ := json.MarshalIndent(resBodyUnformatted, "", " ")
|
||||
core.LogInfo.Printf("Response (%d):\n%v\n", res.StatusCode, string(b))
|
||||
}
|
||||
|
||||
var respBodyFormatted document.ExtendedDocument
|
||||
json.NewDecoder(res.Body).Decode(&respBodyFormatted)
|
||||
if res.StatusCode == 200 {
|
||||
return respBodyFormatted, nil
|
||||
var respBody document.ExtendedDocument
|
||||
json.NewDecoder(res.Body).Decode(&respBody)
|
||||
if core.DEBUG {
|
||||
b, _ := json.MarshalIndent(respBody, "", " ")
|
||||
core.LogInfo.Printf("Response (%d):\n%v\n", res.StatusCode, string(b))
|
||||
}
|
||||
return respBody, nil
|
||||
} else {
|
||||
core.LogInfo.Printf("ERROR: LHDN GetDocument error response (%d):\n%v\n", res.StatusCode, res.Body)
|
||||
return document.ExtendedDocument{}, errors.New("LHDN GetDocument failed")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
package route
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"iralex-einvoice/config"
|
||||
"iralex-einvoice/core"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"time"
|
||||
)
|
||||
|
||||
func GetDocumentDetails(accessToken, docUUID string) {
|
||||
core.LogInfo.Printf("INFO: sending request GET %s\n", config.LHDN_BASE_URL+"/api/v1.0/documents/"+docUUID+"/details")
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, config.LHDN_BASE_URL+"/api/v1.0/documents/"+docUUID+"/details", nil)
|
||||
if err != nil {
|
||||
core.LogInfo.Printf("ERROR: cannot construct the LHDN GetDocument request: %v", err)
|
||||
// return document.ExtendedDocument{}, err
|
||||
}
|
||||
req.Header.Add("Accept", "application/json")
|
||||
req.Header.Add("Authorization", "Bearer "+accessToken)
|
||||
if core.DEBUG {
|
||||
bytes, _ := httputil.DumpRequestOut(req, true)
|
||||
core.LogInfo.Printf("Request:\n%s\n", bytes)
|
||||
}
|
||||
|
||||
client := &http.Client{
|
||||
Timeout: time.Second * config.DEFAULT_TIMEOUT,
|
||||
}
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
core.LogInfo.Printf("ERROR: couldn't send the LHDN GetDocument request: %v", err)
|
||||
// return document.ExtendedDocument{}, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
var respBody map[string]interface{}
|
||||
json.NewDecoder(res.Body).Decode(&respBody)
|
||||
if core.DEBUG {
|
||||
b, _ := json.MarshalIndent(respBody, "", " ")
|
||||
core.LogInfo.Printf("Response (%d):\n%v\n", res.StatusCode, string(b))
|
||||
}
|
||||
return
|
||||
|
||||
if res.StatusCode == 200 {
|
||||
// var respBody document.ExtendedDocument
|
||||
var respBody map[string]interface{}
|
||||
json.NewDecoder(res.Body).Decode(&respBody)
|
||||
if core.DEBUG {
|
||||
b, _ := json.MarshalIndent(respBody, "", " ")
|
||||
core.LogInfo.Printf("Response (%d):\n%v\n", res.StatusCode, string(b))
|
||||
}
|
||||
// return respBody, nil
|
||||
} else {
|
||||
core.LogInfo.Printf("ERROR: LHDN GetDocument error response (%d):\n%v\n", res.StatusCode, res.Body)
|
||||
// return document.ExtendedDocument{}, errors.New("LHDN GetDocument failed")
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"iralex-einvoice/core"
|
||||
"iralex-einvoice/route"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"runtime/debug"
|
||||
"time"
|
||||
)
|
||||
|
|
@ -25,7 +26,7 @@ type sendQRCodeResponseBody struct {
|
|||
// JSON body, with a single "doc_id" field that contains the LHDN document UUID.
|
||||
func HandleQRCodeGenerate(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Println("Accepted request at /send-qrcode")
|
||||
core.LogInfo.Println("Accepted request at /send-qrcode")
|
||||
core.LogInfo.Println("INFO - Accepted request at /send-qrcode")
|
||||
|
||||
// In case of a panic, do not stop the server, but send a 500.
|
||||
defer func() {
|
||||
|
|
@ -73,12 +74,20 @@ func HandleQRCodeGenerate(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
var link = "https://myinvois.hasil.gov.my/" + reqBody.DocID + "/share/" + docEx.LongID
|
||||
if core.DEBUG {
|
||||
core.LogInfo.Println("INFO - Document formatted", docEx)
|
||||
}
|
||||
|
||||
json.NewEncoder(w).Encode(sendQRCodeResponseBody{
|
||||
DocID: reqBody.DocID,
|
||||
QRCode: link,
|
||||
})
|
||||
if len(docEx.LongID) > 0 {
|
||||
var link = "https://myinvois.hasil.gov.my/" + reqBody.DocID + "/share/" + docEx.LongID
|
||||
json.NewEncoder(w).Encode(sendQRCodeResponseBody{
|
||||
DocID: reqBody.DocID,
|
||||
QRCode: link,
|
||||
})
|
||||
} else {
|
||||
w.WriteHeader(528)
|
||||
fmt.Fprint(w, "528 - document QRCode link is not available")
|
||||
}
|
||||
}
|
||||
|
||||
func HandleDebugQRCodeGenerate(w http.ResponseWriter, r *http.Request) {
|
||||
|
|
@ -93,11 +102,17 @@ func HandleDebugQRCodeGenerate(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
// hardcoded for testing
|
||||
// QR code generation must be parameterized on document UUID
|
||||
const docUUID = "408BMZ0D2AVGTWHDWAH3GQ0K10"
|
||||
const docUUID =
|
||||
// "408BMZ0D2AVGTWHDWAH3GQ0K10"
|
||||
// "B6CGMPM3BBJFYMQRDYKVF15K10"
|
||||
"RSS3HQQF0SXFG06AWSTVE15K10"
|
||||
var longID string = ""
|
||||
|
||||
accessToken := route.AuthenticateFormData(core.CLIENT_ID, core.CLIENT_SECRET_1, core.TIN)
|
||||
|
||||
route.GetDocumentDetails(accessToken, docUUID)
|
||||
return
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, config.LHDN_BASE_URL+"/api/v1.0/documents/"+docUUID+"/raw", nil) // GetDocument
|
||||
if err != nil {
|
||||
fmt.Printf("Error in constructing the request: %v", err)
|
||||
|
|
@ -105,6 +120,8 @@ func HandleDebugQRCodeGenerate(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
req.Header.Add("Accept", "application/json")
|
||||
req.Header.Add("Authorization", "Bearer "+accessToken)
|
||||
bytes, _ := httputil.DumpRequestOut(req, true)
|
||||
fmt.Printf("Request:\n%s\n", bytes)
|
||||
|
||||
client := &http.Client{
|
||||
Timeout: time.Second * config.DEFAULT_TIMEOUT,
|
||||
|
|
@ -118,9 +135,13 @@ func HandleDebugQRCodeGenerate(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
var respBody map[string]interface{}
|
||||
json.NewDecoder(resp.Body).Decode(&respBody)
|
||||
b, _ := json.MarshalIndent(respBody, "", " ")
|
||||
fmt.Printf("Response (%d):\n%v\n", resp.StatusCode, string(b))
|
||||
if resp.StatusCode == 200 {
|
||||
if _longID, ok := respBody["longID"]; ok {
|
||||
longID = _longID.(string)
|
||||
} else {
|
||||
fmt.Println("key doesn't exist")
|
||||
}
|
||||
} else {
|
||||
fmt.Printf("Error\n")
|
||||
|
|
|
|||
|
|
@ -225,11 +225,21 @@ func HandleSubmit(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
if core.DEBUG {
|
||||
core.LogInfo.Println("INFO - Document Details: ", docEx)
|
||||
}
|
||||
|
||||
// If we reached here, everything worked fine.
|
||||
json.NewEncoder(w).Encode(submitResponseBody{
|
||||
DocID: docUUID,
|
||||
QRCode: "https://myinvois.hasil.gov.my/" + docUUID + "/share/" + docEx.LongID,
|
||||
})
|
||||
if len(docEx.LongID) > 0 {
|
||||
var link = "https://myinvois.hasil.gov.my/" + docUUID + "/share/" + docEx.LongID
|
||||
json.NewEncoder(w).Encode(submitResponseBody{
|
||||
DocID: docUUID,
|
||||
QRCode: link,
|
||||
})
|
||||
} else {
|
||||
w.WriteHeader(528)
|
||||
fmt.Fprint(w, "528 - document QRCode link is not available")
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
|
|
|||
Loading…
Reference in New Issue