Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

106 refactor process approver response #107

Merged
merged 4 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/goapp/controller/item/item-controller-interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ import "net/http"
type ItemController interface {
GetItems(w http.ResponseWriter, r *http.Request)
CreateItem(w http.ResponseWriter, r *http.Request)
ProcessResponse(w http.ResponseWriter, r *http.Request)
}
71 changes: 71 additions & 0 deletions src/goapp/controller/item/item-controller.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package item

import (
"bytes"
"encoding/json"
"fmt"
"main/model"
Expand Down Expand Up @@ -174,5 +175,75 @@ func (c *itemController) CreateItem(w http.ResponseWriter, r *http.Request) {
return
}
w.Write(jsonResp)
}

func (c *itemController) ProcessResponse(w http.ResponseWriter, r *http.Request) {
// Decode payload
var req model.ProcessResponseRequest
err := json.NewDecoder(r.Body).Decode(&req)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}

// Validate payload
valid, err := c.Service.Item.ValidateItem(req)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

if !valid {
http.Error(w, "Invalid request", http.StatusBadRequest)
return
}

// Update item response
err = c.Service.Item.UpdateItemResponse(req)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

// Post callback
c.postCallback(req.ItemId)

// Prepare response
w.WriteHeader(http.StatusOK)
}

func (c *itemController) postCallback(id string) {
item, err := c.Service.Item.GetItemById(id)
if err != nil {
fmt.Println("Error getting item by id: ", id)
return
}

if item.CallbackUrl == "" {
fmt.Println("No callback url found")
return
} else {
params := model.ResponseCallback{
ItemId: id,
IsApproved: item.IsApproved,
Remarks: item.ApproverRemarks,
ResponseDate: item.DateResponded,
RespondedBy: item.RespondedBy,
}

jsonReq, err := json.Marshal(params)
if err != nil {
return
}

res, err := http.Post(item.CallbackUrl, "application/json", bytes.NewBuffer(jsonReq))
if err != nil {
fmt.Println("Error posting callback: ", err)
return
}

isCallbackFailed := res.StatusCode != 200

err = c.Service.Item.UpdateItemCallback(id, isCallbackFailed)
}
}
11 changes: 0 additions & 11 deletions src/goapp/model/approvals.go

This file was deleted.

58 changes: 39 additions & 19 deletions src/goapp/model/item.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
package model

type Item struct {
Id string `json:"id"`
Application string `json:"application"`
ApproverRemarks string `json:"approverRemarks"`
Body string `json:"body"`
Created string `json:"created"`
DateResponded string `json:"dateResponded"`
DateSent string `json:"dateSent"`
IsApproved bool `json:"isApproved"`
Module string `json:"module"`
Subject string `json:"subject"`
ApproveText string `json:"approveText"`
RejectText string `json:"rejectText"`
ApproveUrl string `json:"approveUrl"`
RejectUrl string `json:"rejectUrl"`
AllowReassign bool `json:"allowReassign"`
AllowReassignUrl string `json:"allowReassignUrl"`
RespondedBy string `json:"respondedBy"`
Approvers []string `json:"approvers"`
RequestedBy string `json:"requestedBy"`
Id string `json:"id"`
Application string `json:"application"`
ApproverRemarks string `json:"approverRemarks"`
Body string `json:"body"`
Created string `json:"created"`
DateResponded string `json:"dateResponded"`
DateSent string `json:"dateSent"`
IsApproved bool `json:"isApproved"`
Module string `json:"module"`
Subject string `json:"subject"`
ApproveText string `json:"approveText"`
CallbackUrl string `json:"callbackUrl"`
ReassignCallbackUrl string `json:"reassignCallbackUrl"`
RejectText string `json:"rejectText"`
ApproveUrl string `json:"approveUrl"`
RejectUrl string `json:"rejectUrl"`
AllowReassign bool `json:"allowReassign"`
AllowReassignUrl string `json:"allowReassignUrl"`
RespondedBy string `json:"respondedBy"`
Approvers []string `json:"approvers"`
RequestedBy string `json:"requestedBy"`
}

type ItemOptions struct {
Expand Down Expand Up @@ -69,3 +71,21 @@ type ApprovalRequestApprover struct {
ItemId string
ApproverEmail string
}

type ProcessResponseRequest struct {
ApplicationId string `json:"applicationId"`
ApplicationModuleId string `json:"applicationModuleId"`
ItemId string `json:"itemId"`
ApproverEmail string `json:"approverEmail"`
Remarks string `json:"remarks"`
IsApproved string `json:"isApproved"`
Username string `json:"username"`
}

type ResponseCallback struct {
ItemId string `json:"itemId"`
IsApproved bool `json:"isApproved"`
Remarks string `json:"remarks"`
ResponseDate string `json:"responseDate"`
RespondedBy string `json:"respondedBy"`
}
4 changes: 4 additions & 0 deletions src/goapp/repository/item/item-repository-interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ import (
)

type ItemRepository interface {
GetItemById(id string) (*model.Item, error)
GetItemsBy(itemOptions model.ItemOptions) ([]model.Item, error)
GetTotalItemsBy(itemOptions model.ItemOptions) (int, error)
InsertItem(appModuleId, subject, body, requesterEmail string) (string, error)
UpdateItemCallback(id string, isCallbackFailed bool) error
UpdateItemDateSent(id string) error
UpdateItemResponse(id, remarks, email string, isApproved bool) error
ValidateItem(appId, appModuleId, itemId, email string) (bool, error)
}
101 changes: 101 additions & 0 deletions src/goapp/repository/item/item-repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,64 @@ func NewItemRepository(db db.Database) ItemRepository {
}
}

func (r *itemRepository) GetItemById(id string) (*model.Item, error) {
row, err := r.Query("PR_Items_Select_ById", sql.Named("Id", id))
if err != nil {
return nil, err
}

result, err := r.RowsToMap(row)
if err != nil {
return nil, err
}

item := model.Item{
Id: id,
Application: result[0]["Application"].(string),
Module: result[0]["Module"].(string),
ApproveText: result[0]["ApproveText"].(string),
RejectText: result[0]["RejectText"].(string),
}

if result[0]["ApproverRemarks"] != nil {
item.ApproverRemarks = result[0]["ApproverRemarks"].(string)
}

if result[0]["Body"] != nil {
item.Body = result[0]["Body"].(string)
}

if result[0]["DateResponded"] != nil {
item.DateResponded = result[0]["DateResponded"].(time.Time).Format("2006-01-02T15:04:05.000Z")
}

if result[0]["DateSent"] != nil {
item.DateSent = result[0]["DateSent"].(time.Time).String()
}

if result[0]["IsApproved"] != nil {
item.IsApproved = result[0]["IsApproved"].(bool)
}

if result[0]["Subject"] != nil {
item.Subject = result[0]["Subject"].(string)
}

if result[0]["CallbackUrl"] != nil {
item.CallbackUrl = result[0]["CallbackUrl"].(string)
}

if result[0]["ReassignCallbackUrl"] != nil {
item.ReassignCallbackUrl = result[0]["ReassignCallbackUrl"].(string)
}

if result[0]["RespondedBy"] != nil {
item.RespondedBy = result[0]["RespondedBy"].(string)
}

return &item, nil
}

func (r *itemRepository) GetItemsBy(itemOptions model.ItemOptions) ([]model.Item, error) {
var params []interface{}

Expand Down Expand Up @@ -161,6 +219,17 @@ func (r *itemRepository) InsertItem(appModuleId, subject, body, requesterEmail s
return resultItem[0]["Id"].(string), nil
}

func (r *itemRepository) UpdateItemCallback(id string, isCallbackFailed bool) error {
_, err := r.Query("PR_Items_Update_Callback",
sql.Named("ItemId", id),
sql.Named("IsCallbackFailed", isCallbackFailed),
)
if err != nil {
return err
}
return nil
}

func (r *itemRepository) UpdateItemDateSent(id string) error {
_, err := r.Query("PR_Items_Update_DateSent",
sql.Named("Id", id),
Expand All @@ -172,3 +241,35 @@ func (r *itemRepository) UpdateItemDateSent(id string) error {

return nil
}

func (r *itemRepository) UpdateItemResponse(id, remarks, email string, isApproved bool) error {
_, err := r.Query("PR_Items_Update_Response",
sql.Named("Id", id),
sql.Named("ApproverRemarks", remarks),
sql.Named("Username", email),
sql.Named("IsApproved", isApproved),
)
if err != nil {
return err
}
return nil
}

func (r *itemRepository) ValidateItem(appId, appModuleId, itemId, email string) (bool, error) {
row, err := r.Query("PR_Items_IsValid",
sql.Named("ApplicationId", appId),
sql.Named("ApplicationModuleId", appModuleId),
sql.Named("ItemId", itemId),
sql.Named("ApproverEmail", email),
)
if err != nil {
return false, err
}

result, err := r.RowsToMap(row)
if err != nil {
return false, err
}

return result[0]["IsValid"] == "1", nil
}
2 changes: 1 addition & 1 deletion src/goapp/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func setPageRoutes() {
func setApiRoutes() {
httpRouter.GET("/api/request/types", m.Chain(rtApi.GetRequestTypes, m.AzureAuth()))
httpRouter.POST("/api/request", ctrl.Item.CreateItem)
httpRouter.POST("/api/process", rtApprovals.ProcessResponseHandler)
httpRouter.POST("/api/process", ctrl.Item.ProcessResponse)
httpRouter.GET("/api/items/type/{type:[0-2]+}/status/{status:[0-3]+}", m.Chain(ctrl.Item.GetItems, m.AzureAuth()))
httpRouter.GET("/api/search/users/{search}", m.Chain(rtApi.SearchUserFromActiveDirectory, m.AzureAuth()))
httpRouter.GET("/api/responsereassignedapi/{itemGuid}/{approver}/{ApplicationId}/{ApplicationModuleId}/{itemId}/{ApproveText}/{RejectText}", m.Chain(rtApprovals.ReAssignApproverHandler, m.AzureAuth()))
Expand Down
50 changes: 0 additions & 50 deletions src/goapp/routes/pages/approvals/response.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@ import (
"bytes"
"encoding/json"
"fmt"
"main/model"
session "main/pkg/session"
"main/pkg/sql"
template "main/pkg/template"
"net/http"
"os"
"strconv"
"time"

"github.com/gorilla/mux"
Expand Down Expand Up @@ -181,54 +179,6 @@ func ResponseHandler(w http.ResponseWriter, r *http.Request) {
}
}

func ProcessResponseHandler(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case "POST":
// Decode payload
var req model.TypRequestProcess
err := json.NewDecoder(r.Body).Decode(&req)
if err != nil {

return
}

db := connectSql()
defer db.Close()

// Validate payload
params := make(map[string]interface{})
params["ApplicationId"] = req.ApplicationId
params["ApplicationModuleId"] = req.ApplicationModuleId
params["ItemId"] = req.ItemId
params["ApproverEmail"] = req.ApproverEmail
verification, err := db.ExecuteStoredProcedureWithResult("PR_Items_IsValid", params)
handleErrorReturn(w, err)
authReq := true
authReq = session.IsAuthRequired(req.ApplicationModuleId)
if !authReq {
verification[0]["IsValid"] = "1"
}

if verification[0]["IsValid"] == "1" {
for k := range params {
delete(params, k)
}
isApproved, _ := strconv.ParseBool(req.IsApproved)
params["Id"] = req.ItemId
params["IsApproved"] = isApproved
params["ApproverRemarks"] = req.Remarks
params["Username"] = req.ApproverEmail
_, err := db.ExecuteStoredProcedure("PR_Items_Update_Response", params)
handleErrorReturn(w, err)
postCallback(req.ItemId)
return
} else {
http.Error(w, err.Error(), http.StatusUnauthorized)
return
}
}
}

func ProcessFailedCallbacks() {
db := connectSql()
defer db.Close()
Expand Down
4 changes: 4 additions & 0 deletions src/goapp/service/item/item-service-interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ import (
)

type ItemService interface {
GetItemById(id string) (*model.Item, error)
GetAll(itemOptions model.ItemOptions) (model.Response, error)
InsertItem(item model.ItemInsertRequest) (string, error)
UpdateItemCallback(itemId string, isCallbackFailed bool) error
UpdateItemDateSent(itemId string) error
UpdateItemResponse(req model.ProcessResponseRequest) error
ValidateItem(req model.ProcessResponseRequest) (bool, error)
}
Loading
Loading