Plan Modification

Clients can always change their portfolio strategy and select a different investment model. Keep in mind that if the risk associated with the new portfolio model does not match the client's risk profile, you must provide the reason to change proposal response ID(s).

Attention

Plan modification is possible only when the plan creation order has been accepted.

Selecting proposal

The following describes how to retrieve all alternative investment proposals for plan modification.

								
  var clientPortfolio = await httpClient.GetFromJsonAsync<PortfolioOutputModel>($"api/v1/user-portfolios/portfolio-id/{portfolioId}?portfolio-view-as=Snapshot");

  var url = $"api/v1/proposals/investment-category-id/{clientPortfolio.InvestmentCategoryId}";
  var proposals = await httpClient.GetFromJsonAsync<List<ProposalOutputModel>>(url);
  var alternativeProposals = proposals.Where(x => x.Id != clientPortfolio.ProposalId).ToList();


									
								
		HttpRequest portfolioRequest = HttpRequest.newBuilder()
			.timeout(Duration.ofMinutes(1))
			.uri(URI.create(Settings.BASE_WMS_URL + "user-portfolios/portfolio-id/" + portfolioId))
			.header("Accept-Language", "de-DE")
			.header("Authorization", "Bearer " + Settings.ADMIN_TOKEN)
			.header("Content-Type", "application/json")
			.build();
					
		var response = httpClient.send(portfolioRequest, BodyHandlers.ofString());
		PortfolioOutputModel clientPortfolio = new Gson().fromJson(response.body().toString(), PortfolioOutputModel.class);
		
		// Alternative proposals list
		HttpRequest proposalsRequest = HttpRequest.newBuilder()
			.timeout(Duration.ofMinutes(1))
			.uri(URI.create(Settings.BASE_WMS_URL + "proposals/investment-category-id/" + clientPortfolio.InvestmentCategoryId))
			.header("Accept-Language", "de-DE")
			.header("Authorization", "Bearer " + Settings.ADMIN_TOKEN)
			.header("Content-Type", "application/json")
			.build();
				
		response = httpClient.send(proposalsRequest, BodyHandlers.ofString());		
		Type listType = new TypeToken<ArrayList<ProposalOutputModel>>(){}.getType();
		List<ProposalOutputModel> proposalObjs = new Gson().fromJson(response.body().toString(), listType);


Preparing the contract

See the Preparing the contract chapter regarding plan creation, as the steps are the same.

Submitting the order

In the following code snippet, we submit a plan change, passing the new Proposal ID selected by the user/client. This will change the investment strategy.

								
  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Please note:
  //   1.a new PDF document is needed for plan change. For this example we simply use an empty PDF.
  //   2.reason to change proposal is hard-coded while should be chosen by client
  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

  var clientPortfolio = await httpClient.GetFromJsonAsync<PortfolioOutputModel>($"api/v1/user-portfolios/portfolio-id/{portfolioId}");

  var reasonToChangeProposalUrl = $"api/v1/reason-to-change-proposed-proposal/investment-category-id/{clientPortfolio.InvestmentCategoryId}/active";
  var reasonToChangeProposal = await httpClient.GetFromJsonAsync<ReasonToChangeProposalOutputModel>(reasonToChangeProposalUrl);

  var orderPortfolioModificationInputModel = new
  {
	PortfolioId = portfolioId,
	// Assume this is the new portfolio model selected by client
	ProposalId = alternativeProposals.First().Id,
	// Assume this is reason to change proposal selected by client
	ReasonToChangeProposalResponsesIds = new List<long>{ reasonToChangeProposal.Responses.First().Id }
  };

  // For simplicity, use an empty PDF contract template
  var byteArray = FileContentHelper.GetFileContent(this.GetType(), "Contract-3A.pdf");

  var httpContent = HttpHelper.CreateMultipartFormDataHttpContent(orderPortfolioModificationInputModel, byteArray);
  var httpResponseMessage = await httpClient.PostAsync("api/v1/user-portfolio-orders/modification", httpContent);
  if (httpResponseMessage.IsSuccessStatusCode == false)
  {
	// Manage the error
  }
									
								
		//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// Please note:
		//   1.a new PDF document is needed for plan change. For this example we simply use an empty PDF.
		//   2.reason to change proposal is hard-coded while should be chosen by client
		//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		HttpRequest reasonToChangeRequest = HttpRequest.newBuilder()
				.timeout(Duration.ofMinutes(1))
				.uri(URI.create(Settings.BASE_WMS_URL + "reason-to-change-proposed-proposal/investment-category-id/" + clientPortfolio.InvestmentCategoryId + "/active"))
				.header("Accept-Language", "de-DE")
				.header("Authorization", "Bearer " + Settings.ADMIN_TOKEN)
				.header("Content-Type", "application/json")
				.build();
		
		response = httpClient.send(reasonToChangeRequest, BodyHandlers.ofString());
		ReasonToChangeProposalOutputModel reasonToChangeProposalObj = new Gson().fromJson(response.body().toString(), ReasonToChangeProposalOutputModel.class);
		var reasonToChangeProposalId = reasonToChangeProposalObj.Responses.get(1).Id;
				
		StringBuilder orderPortfolioModificationInputModel = new StringBuilder("{");
		orderPortfolioModificationInputModel.append("'PortfolioId': " + portfolioId + ",");
		// Assume this is the new portfolio model selected by client
		orderPortfolioModificationInputModel.append("'ProposalId': " + alternativeProposalObjs.getFirst().Id + ",");
		// Assume this is reason to change proposal selected by client
		orderPortfolioModificationInputModel.append("'ReasonToChangeProposalResponsesIds': [ " + reasonToChangeProposalId + " ]");				
		orderPortfolioModificationInputModel.append("}");
				
		// For simplicity, use an empty PDF contract template
		var inputStream = Files.newInputStream(Paths.get("c:\\Temp\\Contract-DIR-3A.pdf"));
		
		MultiPartBodyPublisher multipartBody = new MultiPartBodyPublisher()
			    .addPart("jsonPayload", orderPortfolioModificationInputModel.toString())
			    .addPart("userContracts", () -> inputStream, "Contract.pdf", "application/pdf");
		
		HttpRequest planChangeRequest = HttpRequest.newBuilder()
				.timeout(Duration.ofMinutes(1))
				.uri(URI.create(Settings.BASE_WMS_URL + "user-portfolio-orders/modification"))
				.header("Accept-Language", "de-DE")
				.header("Authorization", "Bearer " + Settings.ADMIN_TOKEN)
				.header("Content-Type", "multipart/form-data; boundary=" + multipartBody.getBoundary())
				.POST(multipartBody.build())
				.build();
		
		response = httpClient.send(planChangeRequest, BodyHandlers.ofString());
		if (response.statusCode() != 200 && response.statusCode() != 201) {
			//System.out.println(response.body());
			throw new Exception("pdf-service/fill-pdf-with-data ==> response.statusCode() = " + response.statusCode());
		}


After the order is submitted, the Portfolio.HasPendingOrder will be TRUE.

When "PendingOrder" is TRUE, no plan modification is allowed.

Once the order is accepted, this value will change to FALSE and a new plan change will be possible.