Skip to content

API Walkthroughs 6.3 IPT Tornado move

Martyn Whitwell edited this page Jul 28, 2020 · 3 revisions

Moves API Walkthrough

6. Inter-Prison Transfer moves (IPTs)

6.3 "Tornado" moves for one or more unknown people from PrisonA to PrisonB on a specific date (usually at short notice)

  1. [OFFLINE] The supplier is contacted directly (outside of this system) by the prison or PMU and told that urgent move(s) are required from prison-A to prison-B. There are a number of circumstances when this might be required, such as a riot in a prison or a fire in a building requiring an evacuation. The actual prisoners to move will not be determined until the moves are in progress.

  2. The supplier then creates the necesary move records, in a requested state but without linking them to specific profiles.

    In this example, the supplier has been requested to move two unknown people from Prison A to Prison B. Each of these calls will return a new move record, as shown below.

    # create move1 for unknown person1
    curl --request POST \
      --url http://server/api/moves \
      --header 'accept: application/vnd.api+json; version=2' \
      --header 'authorization: Bearer XXX' \
      --header 'content-type: application/json' \
      --header 'idempotency-key: 19c08c7d-366b-45d2-9b80-7cb623e68bc9' \
      --data '{
      "data": {
        "type": "moves",
        "attributes": {
          "date": "2020-07-10",
          "status": "requested",
          "additional_information": "example IPT tornado transfer - person1",
          "move_type": "prison_transfer"
        },
        "relationships": {
          "profile": null,
          "from_location": {
            "data": {
              "type": "locations",
              "id": "067c2855-fa41-493d-9c80-1311a4f7ba45"
            }
          },
          "to_location": {
            "data": {
              "type": "locations",
              "id": "056eed18-772b-45b3-b64a-4d7d563641f7"
            }
          },
          "prison_transfer_reason": {
            "data": {
              "type": "prison_transfer_reasons",
              "id": "1de93692-461f-5355-9e4d-9a0b673daf15"
            }
          }
        }
      }
    }'

    which returns:

    {
      "data": {
        "id": "304b1837-43b3-4913-a852-c52d9b740c29",
        "type": "moves",
        "attributes": {
          "additional_information": "example IPT tornado transfer - person1",
          "cancellation_reason": null,
          "cancellation_reason_comment": null,
          "created_at": "2020-07-16T12:56:40+01:00",
          "date": "2020-07-10",
          "date_from": null,
          "date_to": null,
          "move_agreed": null,
          "move_agreed_by": null,
          "move_type": "prison_transfer",
          "reference": "HAT3421X",
          "rejection_reason": null,
          "status": "requested",
          "time_due": null,
          "updated_at": "2020-07-16T12:56:40+01:00"
        },
        "relationships": {
          "profile": {
            "data": null
          },
          "from_location": {
            "data": {
              "id": "067c2855-fa41-493d-9c80-1311a4f7ba45",
              "type": "locations"
            }
          },
          "to_location": {
            "data": {
              "id": "056eed18-772b-45b3-b64a-4d7d563641f7",
              "type": "locations"
            }
          },
          "prison_transfer_reason": {
            "data": {
              "id": "1de93692-461f-5355-9e4d-9a0b673daf15",
              "type": "prison_transfer_reasons"
            }
          },
          "court_hearings": {
            "data": []
          },
          "allocation": {
            "data": null
          },
          "original_move": {
            "data": null
          }
        }
      }
    }
    # create move2 for unknown person2
    curl --request POST \
      --url http://server/api/moves \
      --header 'accept: application/vnd.api+json; version=2' \
      --header 'authorization: Bearer XXX' \
      --header 'content-type: application/json' \
      --header 'idempotency-key: e9309008-6600-4ffb-8d9a-83aa8d814907' \
      --data '{
      "data": {
        "type": "moves",
        "attributes": {
          "date": "2020-07-10",
          "status": "requested",
          "additional_information": "example IPT tornado transfer - person2",
          "move_type": "prison_transfer"
        },
        "relationships": {
          "profile": null,
          "from_location": {
            "data": {
              "type": "locations",
              "id": "067c2855-fa41-493d-9c80-1311a4f7ba45"
            }
          },
          "to_location": {
            "data": {
              "type": "locations",
              "id": "056eed18-772b-45b3-b64a-4d7d563641f7"
            }
          },
          "prison_transfer_reason": {
            "data": {
              "type": "prison_transfer_reasons",
              "id": "1de93692-461f-5355-9e4d-9a0b673daf15"
            }
          }
        }
      }
    }'

    which returns:

    {
      "data": {
        "id": "3e4cefe8-5a75-4464-8e37-9623cd0e99aa",
        "type": "moves",
        "attributes": {
          "additional_information": "example IPT tornado transfer - person2",
          "cancellation_reason": null,
          "cancellation_reason_comment": null,
          "created_at": "2020-07-16T12:57:38+01:00",
          "date": "2020-07-10",
          "date_from": null,
          "date_to": null,
          "move_agreed": null,
          "move_agreed_by": null,
          "move_type": "prison_transfer",
          "reference": "HMF2184K",
          "rejection_reason": null,
          "status": "requested",
          "time_due": null,
          "updated_at": "2020-07-16T12:57:38+01:00"
        },
        "relationships": {
          "profile": {
            "data": null
          },
          "from_location": {
            "data": {
              "id": "067c2855-fa41-493d-9c80-1311a4f7ba45",
              "type": "locations"
            }
          },
          "to_location": {
            "data": {
              "id": "056eed18-772b-45b3-b64a-4d7d563641f7",
              "type": "locations"
            }
          },
          "prison_transfer_reason": {
            "data": {
              "id": "1de93692-461f-5355-9e4d-9a0b673daf15",
              "type": "prison_transfer_reasons"
            }
          },
          "court_hearings": {
            "data": []
          },
          "allocation": {
            "data": null
          },
          "original_move": {
            "data": null
          }
        }
      }
    }
  3. Sometime later, the people to be transferred are identified and their prison numbers or other identifiers are passed to the supplier. The supplier can then create profiles for them following the usual approach.

    NB: an existing profile record may be re-used across multiple moves. Profiles can be reused over a period of custody. However, we advise that a new profile is created for separate custody periods.

    NB: for people with a prison_number, creating a profile without assessment answers will trigger an initial synchronisation with Nomis. Creating a profile with assessment answers will not trigger a synchronisation with Nomis

    # find person by prison number
    curl --request GET \
      --url 'http://server/api/people?filter%5Bprison_number%5D=G8133UA' \
      --header 'accept: application/vnd.api+json; version=2' \
      --header 'authorization: Bearer XXX'
    
    # create a new profile for person1, synchronised with Nomis alerts
    curl --request POST \
      --url http://server/api/people/747f3914-620a-441a-847f-472c79def26c/profiles \
      --header 'accept: application/vnd.api+json; version=2' \
      --header 'authorization: Bearer XXX' \
      --header 'content-type: application/json' \
      --header 'idempotency-key: 736916a9-adfc-4442-bb4e-f2c71dbd7b11' \
      --data '{ "data": { "type": "profiles" } }'
    
    # create a new profile for person2, synchronised with Nomis alerts
    curl --request POST \
      --url http://server/api/people/fee70079-08c0-4d1c-a125-bfac8caf24c1/profiles \
      --header 'accept: application/vnd.api+json; version=2' \
      --header 'authorization: Bearer XXX' \
      --header 'content-type: application/json' \
      --header 'idempotency-key: 73d506c2-da22-48fb-b065-fb525360bec5' \
      --data '{ "data": { "type": "profiles" } }'

    (see previous API walkthroughs for the typical responses for GET /api/people and POST /api/people/{id}/profiles)

  4. Next, the profiles are attached to the existing moves:

    # set move1 to profile1
    curl --request PATCH \
      --url http://server/api/moves/304b1837-43b3-4913-a852-c52d9b740c29 \
      --header 'accept: application/vnd.api+json; version=2' \
      --header 'authorization: Bearer XXX' \
      --header 'content-type: application/json' \
      --header 'idempotency-key: ecbf34a9-953f-43a1-a4ed-5ec2bfc2bba4' \
      --data '{
      "data": {
        "id": "304b1837-43b3-4913-a852-c52d9b740c29",
        "type": "moves",
        "attributes": {},
        "relationships": {
          "profile": {
            "data": {
              "type": "profiles",
              "id": "d9a7e87e-b031-4da2-ae13-852aab708aac"
            }
          }
        }
      }
    }'

    which returns the updated move1:

    {
      "data": {
        "id": "304b1837-43b3-4913-a852-c52d9b740c29",
        "type": "moves",
        "attributes": {
          "additional_information": "example IPT tornado transfer - person1",
          "cancellation_reason": null,
          "cancellation_reason_comment": null,
          "created_at": "2020-07-16T12:56:40+01:00",
          "date": "2020-07-10",
          "date_from": null,
          "date_to": null,
          "move_agreed": null,
          "move_agreed_by": null,
          "move_type": "prison_transfer",
          "reference": "HAT3421X",
          "rejection_reason": null,
          "status": "requested",
          "time_due": null,
          "updated_at": "2020-07-16T14:45:09+01:00"
        },
        "relationships": {
          "profile": {
            "data": {
              "id": "d9a7e87e-b031-4da2-ae13-852aab708aac",
              "type": "profiles"
            }
          },
          "from_location": {
            "data": {
              "id": "067c2855-fa41-493d-9c80-1311a4f7ba45",
              "type": "locations"
            }
          },
          "to_location": {
            "data": {
              "id": "056eed18-772b-45b3-b64a-4d7d563641f7",
              "type": "locations"
            }
          },
          "prison_transfer_reason": {
            "data": {
              "id": "1de93692-461f-5355-9e4d-9a0b673daf15",
              "type": "prison_transfer_reasons"
            }
          },
          "court_hearings": {
            "data": []
          },
          "allocation": {
            "data": null
          },
          "original_move": {
            "data": null
          }
        }
      }
    }

    Similarly, profile2 is attached to move2:

    curl --request PATCH \
      --url http://server/api/moves/3e4cefe8-5a75-4464-8e37-9623cd0e99aa \
      --header 'accept: application/vnd.api+json; version=2' \
      --header 'authorization: Bearer XXX' \
      --header 'content-type: application/json' \
      --header 'idempotency-key: bcce4f28-18ca-40df-b3b6-58793f8c6b75' \
      --data '{
      "data": {
        "id": "3e4cefe8-5a75-4464-8e37-9623cd0e99aa",
        "type": "moves",
        "attributes": {},
        "relationships": {
          "profile": {
            "data": {
              "type": "profiles",
              "id": "379a14d6-96fc-442f-bf21-cc8d649963b1"
            }
          }
        }
      }
    }'
    

    which returns:

    {
      "data": {
        "id": "3e4cefe8-5a75-4464-8e37-9623cd0e99aa",
        "type": "moves",
        "attributes": {
          "additional_information": "example IPT tornado transfer - person2",
          "cancellation_reason": null,
          "cancellation_reason_comment": null,
          "created_at": "2020-07-16T12:57:38+01:00",
          "date": "2020-07-10",
          "date_from": null,
          "date_to": null,
          "move_agreed": null,
          "move_agreed_by": null,
          "move_type": "prison_transfer",
          "reference": "HMF2184K",
          "rejection_reason": null,
          "status": "requested",
          "time_due": null,
          "updated_at": "2020-07-16T17:08:19+01:00"
        },
        "relationships": {
          "profile": {
            "data": {
              "id": "379a14d6-96fc-442f-bf21-cc8d649963b1",
              "type": "profiles"
            }
          },
          "from_location": {
            "data": {
              "id": "067c2855-fa41-493d-9c80-1311a4f7ba45",
              "type": "locations"
            }
          },
          "to_location": {
            "data": {
              "id": "056eed18-772b-45b3-b64a-4d7d563641f7",
              "type": "locations"
            }
          },
          "prison_transfer_reason": {
            "data": {
              "id": "1de93692-461f-5355-9e4d-9a0b673daf15",
              "type": "prison_transfer_reasons"
            }
          },
          "court_hearings": {
            "data": []
          },
          "allocation": {
            "data": null
          },
          "original_move": {
            "data": null
          }
        }
      }
    }
  5. The new moves can then be accepted changing its status from "requested" to “booked” by calling the accept endpoint on each move:

    # accept move1
    curl --request POST \
      --url http://server/api/moves/304b1837-43b3-4913-a852-c52d9b740c29/accept \
      --header 'accept: application/vnd.api+json; version=2' \
      --header 'authorization: Bearer XXX' \
      --header 'content-type: application/json' \
      --header 'idempotency-key: 2c4493aa-cfd2-45bf-818c-21fe48812209' \
      --data '{
      "data": {
        "type": "accepts",
        "attributes": {
          "timestamp": "2020-07-16T16:12:53.718Z"
        }
      }
    }'
    
    # accept move2
    curl --request POST \
      --url http://server/api/moves/3e4cefe8-5a75-4464-8e37-9623cd0e99aa/accept \
      --header 'accept: application/vnd.api+json; version=2' \
      --header 'authorization: Bearer XXX' \
      --header 'content-type: application/json' \
      --header 'idempotency-key: 416e0565-39a1-4c8a-a158-736577ca26e8' \
      --data '{
      "data": {
        "type": "accepts",
        "attributes": {
          "timestamp": "2020-07-16T16:13:34.706Z"
        }
      }
    }'

    Both calls will return a 204 No Content response.

  6. The supplier can then create journeys, start and then complete the moves, as shown in other walkthroughs.

    # start move1 (NB: repeat for move2)
    curl --request POST \
      --url http://server/api/moves/304b1837-43b3-4913-a852-c52d9b740c29/start \
      --header 'accept: application/vnd.api+json; version=2' \
      --header 'authorization: Bearer XXX' \
      --header 'content-type: application/vnd.api+json' \
      --header 'idempotency-key: 45a97e52-dc12-4ad5-a47f-fd02e888942c' \
      --data '{
      "data": {
        "type": "starts",
        "attributes": {
          "timestamp": "2020-07-167T16:40:46.853Z",
          "notes": "van on the way"
        }
      }
    }'
    
    # complete move1 (NB: repeat for move2)
    curl --request POST \
      --url http://server/api/moves/304b1837-43b3-4913-a852-c52d9b740c29/complete \
      --header 'accept: application/vnd.api+json; version=2' \
      --header 'authorization: Bearer XXX' \
      --header 'content-type: application/vnd.api+json' \
      --header 'idempotency-key: 42d19c1f-a741-4fe8-910d-07ffc832aef8' \
      --data '{
      "data": {
        "type": "completes",
        "attributes": {
          "timestamp": "2020-07-167T16:55:17.163Z",
          "notes": "move completed successfully"
        }
      }
    }'
Clone this wiki locally