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  }