# Implementing Sales Intervention

This page provides a guide to the changes you need to make to your integration adapters to implement FX Sale’s Sales Intervention functionality.

## Requirements

Sales Intervention has the following requirements:

* FX Sales 1.18 or greater
* FX Integration API v3.5 or greater
* A User Details Adapter. For more information, see [User Details Service](../fx-integration-api/fxapi-user-details-service.md) in the FX Integration API.

## Overview

Sales Intervention includes a new trade model that works in parallel to the RFS trade model for a trade. Some transitions in the two models are related. For example, when a sales trader picks up a trade for intervention, the Sales Intervention Model transitions to 'PickUpSent' and the RFS Trade Model transitions to 'PickedUp'.

The relationship between the two trade models is not handled automatically by the FX Integration API. It must be coded at the implementation level.

Integrating Sales Intervention into your trading workflow requires you to perform the following tasks:

* Implement the FX Integration API listener interfaces for the Sales Intervention trade model. Where the Sales Intervention specification requires it, raise a transition event on the associated trade’s RFS trade model.
* Edit your implementations of the FX Integration API listener interfaces for the RFS trade model. Where the Sales Intervention specification requires it, raise an event on the associated trade’s Sales Intervention trade model.

You will find the process of integration easier if you can implement listeners for the Sales Intervention trade model in the same integration adapter in which you implement listeners for the RFS trade model.

For an example of a trading adapter with a Sales Intervention implementation, see the Novo Trading Adapter example in the FX Integration API kit (v3.5 or greater).

## Trade-model state diagrams

This section contains state diagrams for the following trade models:

* [RFS Trade Model](#rfs-trade-model)
* [Sales Intervention Trade Model](#sales-intervention-trade-model)

### RFS trade model

The state model for the RFS trade model is illustrated below. For more information on this trade model, see [RFS Trade Messages](../fx-integration-api/fxapi-trade-model-rfs.md).

State changes that are initiated by the FX Professional or FX Mobile client are in blue, and state changes that are initiated by the server are in green.

```plantuml
@startuml
[*] --> Initial<<Terminator>>
Initial -[#ECAF28]-> Submitted : [[/developer/fx-integration-api/fxapi-trade-model-rfs#submit Submit]]
Submitted --> Queued : [[/developer/fx-integration-api/fxapi-trade-model-rfs#submitack SubmitAck]]

Queued --> PickedUp : [[/developer/fx-integration-api/fxapi-trade-model-rfs#pickup PickUp]]
PickedUp --> Queued : [[/developer/fx-integration-api/fxapi-trade-model-rfs#hold Hold]]

PickedUp --> Executable : [[/developer/fx-integration-api/fxapi-trade-model-rfs#spotquote PriceUpdate]]
Executable --> PickedUp : [[/developer/fx-integration-api/fxapi-trade-model-rfs#withdraw Withdraw]]
Executable --> Executable : [[/developer/fx-integration-api/fxapi-trade-model-rfs#spotquote PriceUpdate]]

Executable -[#ECAF28]-> ExecuteSent : [[/developer/fx-integration-api/fxapi-trade-model-rfs#execute Execute]]
ExecuteSent --> Executed : [[/developer/fx-integration-api/fxapi-trade-model-rfs#executeack ExecuteAck]]
ExecuteSent --> ExecuteSent : [[/developer/fx-integration-api/fxapi-trade-model-rfs#spotquote PriceUpdate]]
ExecuteSent --> WarningSent : Warning

Executed --> TradeConfirmed<<Terminator>> : [[/developer/fx-integration-api/fxapi-trade-model-rfs#ticketspottradeconfirmation TradeConfirmation]]

WarningSent -[#ECAF28]-> AcceptWarningSent : [[/developer/fx-integration-api/fxapi-trade-model-rfs#acceptwarning AcceptWarning]]
WarningSent -[#ECAF28]-> Executable : [[/developer/fx-integration-api/fxapi-trade-model-rfs#rejectwarning RejectWarning]]
WarningSent -[#ECAF28]-> ClientCloseSent : [[/developer/fx-integration-api/fxapi-trade-model-rfs#clientclose ClientClose]]
WarningSent --> Expired : [[/developer/fx-integration-api/fxapi-trade-model-rfs#expire Expire]]

AcceptWarningSent --> Executed : [[/developer/fx-integration-api/fxapi-trade-model-rfs#acceptwarningack AcceptWarningAck]]

Submitted -[#ECAF28]-> ClientCloseSent : [[/developer/fx-integration-api/fxapi-trade-model-rfs#clientclose ClientClose]]
Queued -[#ECAF28]-> ClientCloseSent : [[/developer/fx-integration-api/fxapi-trade-model-rfs#clientclose ClientClose]]
PickedUp -[#ECAF28]-> ClientCloseSent : [[/developer/fx-integration-api/fxapi-trade-model-rfs#clientclose ClientClose]]
Executable -[#ECAF28]-> ClientCloseSent : [[/developer/fx-integration-api/fxapi-trade-model-rfs#clientclose ClientClose]]
ClientCloseSent --> ClientClosed<<Terminator>> : [[/developer/fx-integration-api/fxapi-trade-model-rfs#clientcloseack ClientCloseAck]]

Queued --> Expired<<Terminator>> : [[/developer/fx-integration-api/fxapi-trade-model-rfs#expire Expire]]
Executable --> Expired : [[/developer/fx-integration-api/fxapi-trade-model-rfs#expire Expire]]
Executed --> Expired : [[/developer/fx-integration-api/fxapi-trade-model-rfs#expire Expire]]

Expired --> [*]
ClientClosed --> [*]
TradeConfirmed --> [*]

legend left
**__Legend__**
Transitions initiated by the client are in <color:#ECAF28><b>yellow</b></color>.
Transitions initiated by the server are in <color:#003E67><b>blue</b></color>.
end legend

@enduml
```

### Sales Intervention trade model

**📌 NOTE**\
This documentation applies to the trade model in the FX Integration API 2. For documentation on trade models in the FX Integration API 3, see [FX Integration API](../fx-integration-api/index.md).

The Sales Intervention model is illustrated below.

State changes that are initiated by the FX Sales client are in blue, and state changes that are initiated by the server are in green.

```plantuml
@startuml
[*] --> Initial
Initial -[#ECAF28]-> PickUpSent : [[/developer/fx-integration-api/fxapi-trade-model-salesintervention#pickup PickUp]]
PickUpSent --> PickUpPending : [[/developer/fx-integration-api/fxapi-trade-model-salesintervention#blocktradedetails PickUpAck]]
PickUpSent --> ClientRejected : [[/developer/fx-integration-api/fxapi-trade-model-salesintervention#pickuprejected PickUpRejected]]
PickUpPending --> PickedUp : PriceUnavailable
PickUpPending --> PickedUp : [[/developer/fx-integration-api/fxapi-trade-model-salesintervention#salesblockquote PriceUpdate]]
PickUpPending -[#ECAF28]-> TraderAccepted : [[/developer/fx-integration-api/fxapi-trade-model-salesintervention#accept Accept]]
PickUpPending -[#ECAF28]-> HoldSent : [[/developer/fx-integration-api/fxapi-trade-model-salesintervention#hold Hold]]
PickUpPending -[#ECAF28]-> RejectSent : [[/developer/fx-integration-api/fxapi-trade-model-salesintervention#reject Reject]]
PickUpPending --> ClientRejected : [[/developer/fx-integration-api/fxapi-trade-model-salesintervention#clientreject ClientReject]]
PickedUp -[#ECAF28]-> QuoteSent : [[/developer/fx-integration-api/fxapi-trade-model-salesintervention#quote Quote]]
PickedUp --> PickedUp : [[/developer/fx-integration-api/fxapi-trade-model-salesintervention#salesblockquote PriceUpdate]]
PickedUp -[#ECAF28]-> HoldSent : [[/developer/fx-integration-api/fxapi-trade-model-salesintervention#hold Hold]]
PickedUp -[#ECAF28]-> RejectSent : [[/developer/fx-integration-api/fxapi-trade-model-salesintervention#reject Reject]]
PickedUp --> ClientRejected : [[/developer/fx-integration-api/fxapi-trade-model-salesintervention#clientreject ClientReject]]
QuoteSent --> QuoteSent : [[/developer/fx-integration-api/fxapi-trade-model-salesintervention#salesblockquote PriceUpdate]]
QuoteSent --> ClientRejected : [[/developer/fx-integration-api/fxapi-trade-model-salesintervention#clientreject ClientReject]]
QuoteSent -[#ECAF28]-> RejectSent : [[/developer/fx-integration-api/fxapi-trade-model-salesintervention#reject Reject]]
QuoteSent -[#ECAF28]-> WithdrawSent : [[/developer/fx-integration-api/fxapi-trade-model-salesintervention#withdraw Withdraw]]
QuoteSent --> Quoted : [[/developer/fx-integration-api/fxapi-trade-model-salesintervention#quoteack QuoteAck]]
ClientRejected<<Terminator>> --> [*]
RejectSent --> TraderRejected : [[/developer/fx-integration-api/fxapi-trade-model-salesintervention#rejectack RejectAck]]
TraderRejected<<Terminator>> --> [*]
WithdrawSent --> PickedUp : [[/developer/fx-integration-api/fxapi-trade-model-salesintervention#withdrawack WithdrawAck]]
WithdrawSent --> WithdrawSent : [[/developer/fx-integration-api/fxapi-trade-model-salesintervention#salesblockquote PriceUpdate]]
WithdrawSent -[#ECAF28]-> RejectSent : [[/developer/fx-integration-api/fxapi-trade-model-salesintervention#reject Reject]]
Quoted --> TradeConfirmation : [[/developer/fx-integration-api/fxapi-trade-model-salesintervention#blocksalestradeconfirmation TradeConfirmed]]
Quoted --> Quoted : [[/developer/fx-integration-api/fxapi-trade-model-salesintervention#salesblockquote PriceUpdate]]
Quoted -[#ECAF28]-> WithdrawSent : [[/developer/fx-integration-api/fxapi-trade-model-salesintervention#withdraw Withdraw]]
Quoted --> ClientRejected : [[/developer/fx-integration-api/fxapi-trade-model-salesintervention#clientreject ClientReject]]
Quoted -[#ECAF28]-> RejectSent : [[/developer/fx-integration-api/fxapi-trade-model-salesintervention#reject Reject]]
Quoted -[#ECAF28]-> QuoteSent : [[/developer/fx-integration-api/fxapi-trade-model-salesintervention#quote Quote]]
TradeConfirmation<<Terminator>> --> [*]
HoldSent --> Held : [[/developer/fx-integration-api/fxapi-trade-model-salesintervention#holdack HoldAck]]
Held<<Terminator>> --> [*]
TraderAccepted<<Terminator>> --> [*]

legend left
**__Legend__**
Transitions initiated by the client (the sales trader) are in <color:#ECAF28><b>yellow</b></color>.
Transitions initiated by the server are in <color:#003E67><b>blue</b></color>.
end legend

@enduml

```

## Implementation

A typical intervention handler needs to perform the following tasks:

* [Handle the failure of a quote to pass risk assessment](#handle-the-failure-of-a-quote-to-pass-risk-assessment)
* [Handle the pickup of a quote by a sales trader](#handle-the-pickup-of-a-quote-by-a-sales-trader)
* [Handle the sending of a price by a sales trader](#handle-the-sending-of-a-price-by-a-sales-trader)
* [Handle the withdrawal of a price by a sales trader](#handle-the-withdrawal-of-a-price-by-a-sales-trader)
* [Handle the rejection of a quote request by a sales trader](#handle-the-rejection-of-a-quote-request-by-a-sales-trader)
* [Handle the release of a quote by a sales trader](#handle-the-release-of-a-quote-by-a-sales-trader)
* [Handle quote request timeout](#handle-timeout-of-a-quote)
* [Handle rejection of a price by a client](#handle-rejection-of-a-price-by-a-client)
* [Handle acceptance of a price by a client](#handle-acceptance-of-a-price-by-a-client)

### Handle the failure of a quote to pass risk assessment

In the `onSubmit` handler in your `RFSTradeListener` implementation, if the quote request submitted by the client fails risk assessment, then perform the following actions:

1. Leave the quote in the Queued state (do not raise a Reject event on the RFS trade model).
2. Store the quote request in a Sales Intervention queue.
3. Add the quote request to the container subscribed to by the Active Deals Blotter in FX Sales: /PRIVATE/FX/SALES/BLOTTER/ACTIVEDEALS

   Records in the Active Deals Blotter container must have the following fields:
   * **TradeRequestId**: used to identify a quote that requires sales intervention
   * **Dealable**: determines whether a quote has yet to be picked up by a sales trader. When a quote is picked up by a sales trader, the Dealable field is set to false, and cannot be picked up by other sales traders.

### Handle the pickup of a quote by a sales trader

In the `onPickup` handler in your `SalesInterventionTradeListener` implementation, perform the following tasks.

**If the quote request is dealable (can be picked up):**

1. Raise a PickUp event on the RFS trade model.
2. Raise a PickUpAckEvent on the Sales Intervention trade model.
3. Raise a PriceUpdateEvent on the Sales Intervention trade model.

**If the quote request is not dealable (cannot be picked up):**

1. Raise a PickupRejectedEvent on the Sales Intervention trade model.

### Handle the sending of a price by a sales trader

In the `onQuote` handler in your `SalesInterventionTradeListener` implementation, perform the following tasks:

1. Raise a QuoteAck event on the Sales Intervention trade model.
2. Raise a PriceUpdate event on the RFS trade model.

When your integration code receives a price update from the backend, raise a PriceUpdate event on both the RFS trade model and the Sales Intervention trade model.

### Handle the withdrawal of a price by a sales trader

In the `onWithdraw` handler in your `SalesInterventionTradeListener` implementation, perform the following tasks:

1. Raise a Withdraw event on the RFS trade model.
2. Raise a WithdrawAck event on the Sales Intervention trade model.

### Handle the rejection of a quote request by a sales trader

In the `onReject` handler in your `SalesInterventionTradeListener` implementation, perform the following tasks:

1. Raise a Reject event on the RFS trade model.
2. Raise a RejectAck event on the Sales Intervention trade model.
3. Schedule the removal of the quote’s record from the Active Deals Blotter.

### Handle the release of a quote by a sales trader

In the `onHold` handler in your `SalesInterventionTradeListener` implementation, perform the following tasks:

1. Raise a Hold event on the RFS trade model.
2. Raise a HoldAck event on the Sales Intervention trade model.

### Handle timeout of a quote

In the `onTradeClose` handler in your `RFSTradeListener` implementation, perform the following tasks:

1. Raise a ClientReject event on the Sales Intervention trade model.

### Handle rejection of a price by a client

In the `onClientClose` handlers in your `RFSTradeListener` implementation, perform the following tasks:

1. Raise a ClientReject event on the Sales Intervention trade model.

### Handle acceptance of a price by a client

In the `onExecute` handler in your `RFSTradeListener` impementation, perform the following tasks:

1. Raise an ExecuteAck event on the RFS trade model
2. Execute the trade on the backend trading system.
   1. If the trade executes successfully, then raise a TradeConfirmed event on both the RFS trade model and the Sales Intervention trade model.
   2. If the trade does not execute successfully, then raise a Reject event on both the RFS trade model and the Sales Intervention trade model.

## Permissions

To grant a sales trader permission to use Sales Intervention, grant them permission for the FX-SALES-INTERVENTION action in the FX_SALES_INTERVENTION namespace.

---

**See also**:

* [Sales Intervention](st-sales-intervention.md)
* [Sales Intervention architecture](st-sales-intervention-architecture.md)
* [Sales Intervention user interface](st-sales-intervention-user-interface.md)
