github.com/companieshouse/lfp-pay-api@v0.0.0-20230203133422-0ca455cd79f9/handlers/create_payable_resource.go (about)

     1  package handlers
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"net/http"
     7  	"strings"
     8  
     9  	"github.com/companieshouse/chs.go/authentication"
    10  	"github.com/companieshouse/chs.go/log"
    11  	"github.com/companieshouse/lfp-pay-api-core/models"
    12  	"github.com/companieshouse/lfp-pay-api/config"
    13  	"github.com/companieshouse/lfp-pay-api/dao"
    14  	"github.com/companieshouse/lfp-pay-api/transformers"
    15  	"github.com/companieshouse/lfp-pay-api/utils"
    16  	"github.com/companieshouse/lfp-pay-api/validators"
    17  	"gopkg.in/go-playground/validator.v9"
    18  )
    19  
    20  // CreatePayableResourceHandler takes a http requests and creates a new payable resource
    21  func CreatePayableResourceHandler(svc dao.Service) http.Handler {
    22  	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    23  		var request models.PayableRequest
    24  		err := json.NewDecoder(r.Body).Decode(&request)
    25  
    26  		// request body failed to get decoded
    27  		if err != nil {
    28  			log.ErrorR(r, fmt.Errorf("invalid request"))
    29  			m := models.NewMessageResponse("failed to read request body")
    30  			utils.WriteJSONWithStatus(w, r, m, http.StatusBadRequest)
    31  			return
    32  		}
    33  
    34  		userDetails := r.Context().Value(authentication.ContextKeyUserDetails)
    35  		if userDetails == nil {
    36  			log.ErrorR(r, fmt.Errorf("user details not in context"))
    37  			m := models.NewMessageResponse("user details not in request context")
    38  			utils.WriteJSONWithStatus(w, r, m, http.StatusInternalServerError)
    39  			return
    40  		}
    41  
    42  		companyNumber := r.Context().Value(config.CompanyNumber)
    43  		if companyNumber == nil {
    44  			log.ErrorR(r, fmt.Errorf("company not in context"))
    45  			m := models.NewMessageResponse("company number not in request context")
    46  			utils.WriteJSONWithStatus(w, r, m, http.StatusInternalServerError)
    47  			return
    48  		}
    49  
    50  		request.CompanyNumber = strings.ToUpper(companyNumber.(string))
    51  		request.CreatedBy = userDetails.(authentication.AuthUserDetails)
    52  
    53  		// validate that the transactions being requested do exist in E5
    54  		validTransactions, err := validators.TransactionsArePayable(request.CompanyNumber, request.Transactions)
    55  		if err != nil {
    56  			log.ErrorR(r, fmt.Errorf("invalid request - failed matching against e5"))
    57  			m := models.NewMessageResponse("the transactions you want to pay for do not exist or are not payable at this time")
    58  			utils.WriteJSONWithStatus(w, r, m, http.StatusBadRequest)
    59  			return
    60  		}
    61  
    62  		// validTransactions contains extra values that have been added from E5 validation so override request body transactions with validated transactions
    63  		request.Transactions = validTransactions
    64  
    65  		v := validator.New()
    66  		err = v.Struct(request)
    67  
    68  		if err != nil {
    69  			log.ErrorR(r, fmt.Errorf("invalid request - failed validation"))
    70  			m := models.NewMessageResponse("invalid request body")
    71  			utils.WriteJSONWithStatus(w, r, m, http.StatusBadRequest)
    72  			return
    73  		}
    74  
    75  		model := transformers.PayableResourceRequestToDB(&request)
    76  
    77  		err = svc.CreatePayableResource(model)
    78  		if err != nil {
    79  			log.ErrorR(r, fmt.Errorf("failed to create payable request in database"))
    80  			m := models.NewMessageResponse("there was a problem handling your request")
    81  			utils.WriteJSONWithStatus(w, r, m, http.StatusInternalServerError)
    82  			return
    83  		}
    84  
    85  		utils.WriteJSONWithStatus(w, r, transformers.PayableResourceDaoToCreatedResponse(model), http.StatusCreated)
    86  	})
    87  }