github.com/companieshouse/insolvency-api@v0.0.0-20231024103413-440c973d9e9b/handlers/soa_resource.go (about) 1 package handlers 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 8 "github.com/companieshouse/chs.go/log" 9 "github.com/companieshouse/insolvency-api/constants" 10 "github.com/companieshouse/insolvency-api/dao" 11 "github.com/companieshouse/insolvency-api/models" 12 "github.com/companieshouse/insolvency-api/service" 13 "github.com/companieshouse/insolvency-api/transformers" 14 "github.com/companieshouse/insolvency-api/utils" 15 "github.com/gorilla/mux" 16 ) 17 18 // HandleCreateStatementOfAffairs receives a statement of affairs to be stored against the Insolvency case 19 func HandleCreateStatementOfAffairs(svc dao.Service, helperService utils.HelperService) http.Handler { 20 return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 21 22 // Check transaction is valid 23 transactionID, isValidTransaction := utils.ValidateTransaction(helperService, req, w, "statement of affairs", service.CheckIfTransactionClosed) 24 if !isValidTransaction { 25 return 26 } 27 28 // Decode Request body 29 var request models.StatementOfAffairs 30 err := json.NewDecoder(req.Body).Decode(&request) 31 isValidDecoded := helperService.HandleBodyDecodedValidation(w, req, transactionID, err) 32 if !isValidDecoded { 33 return 34 } 35 36 statementDao := transformers.StatementOfAffairsResourceRequestToDB(&request, transactionID, helperService) 37 38 // Validate all mandatory fields 39 errs := utils.Validate(request) 40 isValidMarshallToDB := helperService.HandleMandatoryFieldValidation(w, req, errs) 41 if !isValidMarshallToDB { 42 return 43 } 44 45 // Validate the provided statement details are in the correct format 46 validationErrs, err := service.ValidateStatementDetails(svc, statementDao, transactionID, req) 47 if err != nil { 48 log.ErrorR(req, fmt.Errorf("failed to validate statement of affairs: [%s]", err)) 49 m := models.NewMessageResponse(fmt.Sprintf("there was a problem handling your request for transaction ID [%s]", transactionID)) 50 utils.WriteJSONWithStatus(w, req, m, http.StatusInternalServerError) 51 return 52 } 53 if validationErrs != "" { 54 log.ErrorR(req, fmt.Errorf("invalid request - failed validation on the following: %s", validationErrs)) 55 m := models.NewMessageResponse("invalid request body: " + validationErrs) 56 utils.WriteJSONWithStatus(w, req, m, http.StatusBadRequest) 57 return 58 } 59 60 // Validate if supplied attachment matches attachments associated with supplied transactionID in mongo db 61 attachment, err := svc.GetAttachmentFromInsolvencyResource(transactionID, statementDao.Attachments[0]) 62 isValidAttachment := helperService.HandleAttachmentValidation(w, req, transactionID, attachment, err) 63 if !isValidAttachment { 64 return 65 } 66 67 // Validate the supplied attachment is a valid type 68 if attachment.Type != constants.StatementOfAffairsDirector.String() && attachment.Type != constants.StatementOfAffairsLiquidator.String() && attachment.Type != constants.StatementOfConcurrence.String() { 69 err := fmt.Errorf("attachment id [%s] is an invalid type for this request: %v", statementDao.Attachments[0], attachment.Type) 70 responseMessage := ("attachment is not a " + constants.StatementOfAffairsDirector.String() + ", " + constants.StatementOfAffairsLiquidator.String() + " or a " + constants.StatementOfConcurrence.String()) 71 72 helperService.HandleAttachmentTypeValidation(w, req, responseMessage, err) 73 return 74 } 75 76 // Creates the statement of affairs resource in mongo if all previous checks pass 77 statusCode, err := svc.CreateStatementOfAffairsResource(statementDao, transactionID) 78 isValidCreateResource := helperService.HandleCreateResourceValidation(w, req, statusCode, err) 79 if !isValidCreateResource { 80 return 81 } 82 83 daoResponse := transformers.StatementOfAffairsDaoToResponse(statementDao) 84 85 log.InfoR(req, fmt.Sprintf("successfully added statement of affairs resource with transaction ID: %s, to mongo", transactionID)) 86 87 utils.WriteJSONWithStatus(w, req, daoResponse, http.StatusCreated) 88 }) 89 } 90 91 // HandleGetStatementOfAffairs retrieves a statement of affairs stored against the Insolvency Case 92 func HandleGetStatementOfAffairs(svc dao.Service) http.Handler { 93 return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 94 vars := mux.Vars(req) 95 transactionID := utils.GetTransactionIDFromVars(vars) 96 if transactionID == "" { 97 log.ErrorR(req, fmt.Errorf("there is no transaction ID in the URL path")) 98 m := models.NewMessageResponse("transaction ID is not in the URL path") 99 utils.WriteJSONWithStatus(w, req, m, http.StatusBadRequest) 100 return 101 } 102 103 log.InfoR(req, fmt.Sprintf("start GET request for get statement of affairs with transaction id: %s", transactionID)) 104 105 statementOfAffairs, err := svc.GetStatementOfAffairsResource(transactionID) 106 if err != nil { 107 log.ErrorR(req, fmt.Errorf("failed to get statement of affairs from insolvency resource in db for transaction [%s]: %v", transactionID, err)) 108 m := models.NewMessageResponse("there was a problem handling your request") 109 utils.WriteJSONWithStatus(w, req, m, http.StatusInternalServerError) 110 return 111 } 112 if statementOfAffairs.StatementDate == "" { 113 m := models.NewMessageResponse(fmt.Sprintf("statement of affairs not found on transaction with ID: [%s]", transactionID)) 114 utils.WriteJSONWithStatus(w, req, m, http.StatusNotFound) 115 return 116 } 117 118 log.InfoR(req, fmt.Sprintf("successfully retrieved statement of affairs resource with transaction ID: %s, from mongo", transactionID)) 119 120 utils.WriteJSONWithStatus(w, req, transformers.StatementOfAffairsDaoToResponse(&statementOfAffairs), http.StatusOK) 121 }) 122 } 123 124 // HandleDeleteStatementOfAffairs deletes a statement of affairs resource from an insolvency case 125 func HandleDeleteStatementOfAffairs(svc dao.Service) http.Handler { 126 return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 127 vars := mux.Vars(req) 128 transactionID := utils.GetTransactionIDFromVars(vars) 129 if transactionID == "" { 130 log.ErrorR(req, fmt.Errorf("there is no transaction ID in the URL path")) 131 m := models.NewMessageResponse("transaction ID is not in the URL path") 132 utils.WriteJSONWithStatus(w, req, m, http.StatusBadRequest) 133 return 134 } 135 136 log.InfoR(req, fmt.Sprintf("start DELETE request for submit statement of affairs with transaction id: %s", transactionID)) 137 138 // Check if transaction is closed 139 isTransactionClosed, err, httpStatus := service.CheckIfTransactionClosed(transactionID, req) 140 if err != nil { 141 log.ErrorR(req, fmt.Errorf("error checking transaction status for [%v]: [%s]", transactionID, err)) 142 m := models.NewMessageResponse(fmt.Sprintf("error checking transaction status for [%v]: [%s]", transactionID, err)) 143 utils.WriteJSONWithStatus(w, req, m, httpStatus) 144 return 145 } 146 if isTransactionClosed { 147 log.ErrorR(req, fmt.Errorf("transaction [%v] is already closed and cannot be updated", transactionID)) 148 m := models.NewMessageResponse(fmt.Sprintf("transaction [%v] is already closed and cannot be updated", transactionID)) 149 utils.WriteJSONWithStatus(w, req, m, httpStatus) 150 return 151 } 152 153 // Delete SOA from DB 154 statusCode, err := svc.DeleteStatementOfAffairsResource(transactionID) 155 if err != nil { 156 log.ErrorR(req, err) 157 m := models.NewMessageResponse(err.Error()) 158 utils.WriteJSONWithStatus(w, req, m, statusCode) 159 return 160 } 161 162 log.InfoR(req, fmt.Sprintf("successfully deleted statement of affairs from insolvency case with transaction ID: %s", transactionID)) 163 164 w.Header().Set("Content-Type", "application/json") 165 w.WriteHeader(statusCode) 166 }) 167 }