| POST | /order | Provide waypoints for a route and place an order. This will bill the order to your account. |
|---|
import Foundation
import ServiceStack
public class PlaceOrder : ApiServiceRequest, ILogRequest
{
/**
* Optionally provide your own reference identifier
*/
// @ApiMember(Description="Optionally provide your own reference identifier")
public var clientReference:String
/**
* Optionally provide a reference for the customer/business
*/
// @ApiMember(Description="Optionally provide a reference for the customer/business")
public var customerReference:String
/**
* Array of waypoints
*/
// @ApiMember(Description="Array of waypoints", IsRequired=true)
public var waypoints:[RequestQuoteWaypoint] = []
/**
* Is this a scheduled order?
*/
// @ApiMember(Description="Is this a scheduled order?", IsRequired=true)
public var isScheduled:Bool
/**
* Specify the scheduling type, required if IsScheduled is true
*/
// @ApiMember(Description="Specify the scheduling type, required if IsScheduled is true")
public var scheduleType:ScheduleType
/**
* Specify the scheduled date for this delivery in ISO 8601 string format, required if IsScheduled is true and ScheduleType is SpecificTime
*/
// @ApiMember(Description="Specify the scheduled date for this delivery in ISO 8601 string format, required if IsScheduled is true and ScheduleType is SpecificTime")
public var scheduledDate:String
/**
* Set this to true to prevent creating an order and billing for it
*/
// @ApiMember(Description="Set this to true to prevent creating an order and billing for it", IsRequired=true)
public var test:Bool
/**
* Is your account allows Urgent Orders, you can use this flag to indicate when an Order is urgent.
*/
// @ApiMember(Description="Is your account allows Urgent Orders, you can use this flag to indicate when an Order is urgent.")
public var isUrgent:Bool
required public init(){ super.init() }
private enum CodingKeys : String, CodingKey {
case clientReference
case customerReference
case waypoints
case isScheduled
case scheduleType
case scheduledDate
case test
case isUrgent
}
required public init(from decoder: Decoder) throws {
try super.init(from: decoder)
let container = try decoder.container(keyedBy: CodingKeys.self)
clientReference = try container.decodeIfPresent(String.self, forKey: .clientReference)
customerReference = try container.decodeIfPresent(String.self, forKey: .customerReference)
waypoints = try container.decodeIfPresent([RequestQuoteWaypoint].self, forKey: .waypoints) ?? []
isScheduled = try container.decodeIfPresent(Bool.self, forKey: .isScheduled)
scheduleType = try container.decodeIfPresent(ScheduleType.self, forKey: .scheduleType)
scheduledDate = try container.decodeIfPresent(String.self, forKey: .scheduledDate)
test = try container.decodeIfPresent(Bool.self, forKey: .test)
isUrgent = try container.decodeIfPresent(Bool.self, forKey: .isUrgent)
}
public override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self)
if clientReference != nil { try container.encode(clientReference, forKey: .clientReference) }
if customerReference != nil { try container.encode(customerReference, forKey: .customerReference) }
if waypoints.count > 0 { try container.encode(waypoints, forKey: .waypoints) }
if isScheduled != nil { try container.encode(isScheduled, forKey: .isScheduled) }
if scheduleType != nil { try container.encode(scheduleType, forKey: .scheduleType) }
if scheduledDate != nil { try container.encode(scheduledDate, forKey: .scheduledDate) }
if test != nil { try container.encode(test, forKey: .test) }
if isUrgent != nil { try container.encode(isUrgent, forKey: .isUrgent) }
}
}
public class ApiServiceRequest : IServiceRequest, IHasApiKey, Codable
{
/**
* The API Key required for authentication
*/
// @ApiMember(DataType="string", Description="The API Key required for authentication", IsRequired=true)
public var apiKey:String
required public init(){}
}
public class RequestQuoteWaypoint : IRequestWaypoint, Codable
{
/**
* Number of waypoint for ordering
*/
// @ApiMember(Description="Number of waypoint for ordering", IsRequired=true)
public var waypointNumber:Int
/**
* Waypoint Latitude
*/
// @ApiMember(Description="Waypoint Latitude", IsRequired=true)
public var latitude:Double
/**
* Waypoint Longitude
*/
// @ApiMember(Description="Waypoint Longitude", IsRequired=true)
public var longitude:Double
/**
* Name of contact person at waypoint
*/
// @ApiMember(Description="Name of contact person at waypoint", IsRequired=true)
public var contactName:String
/**
* Telephone number of contact person at waypoint
*/
// @ApiMember(Description="Telephone number of contact person at waypoint", IsRequired=true)
public var contactNumber:String
/**
* Instructions for driver to follow at waypoint
*/
// @ApiMember(Description="Instructions for driver to follow at waypoint", IsRequired=true)
public var deliveryInstructions:String
/**
* Waypoint address
*/
// @ApiMember(Description="Waypoint address", IsRequired=true)
public var address:String
required public init(){}
}
public enum ScheduleType : Int, Codable
{
case NextAvailable = 0
case SpecificTime = 1
}
public class PlaceOrderResponse : ApiServiceResponse
{
/**
* The ID of the order.
*/
// @ApiMember(Description="The ID of the order.")
public var orderId:String
/**
* Were there any validation issues for any waypoints
*/
// @ApiMember(Description="Were there any validation issues for any waypoints")
public var waypointIssue:Bool
/**
* The total distance for the order
*/
// @ApiMember(Description="The total distance for the order")
public var totalDistance:Double
/**
* The total distance for the order, formatted as a string
*/
// @ApiMember(Description="The total distance for the order, formatted as a string")
public var totalDistanceValue:String
/**
* The date and time the order is scheduled for in ISO 8601 string format, will be set if IsScheduled is true
*/
// @ApiMember(Description="The date and time the order is scheduled for in ISO 8601 string format, will be set if IsScheduled is true")
public var scheduledDate:String
/**
* The subtotal of the order before VAT
*/
// @ApiMember(Description="The subtotal of the order before VAT")
public var subTotal:String
/**
* The total of the order after VAT
*/
// @ApiMember(Description="The total of the order after VAT")
public var finalPrice:String
/**
* The amount of VAT
*/
// @ApiMember(Description="The amount of VAT ")
public var vatValue:String
/**
* Will contain a message if there a problem with a scheduled order
*/
// @ApiMember(Description="Will contain a message if there a problem with a scheduled order")
public var schedulingNotice:String
/**
* Will contain a message if there is a problem with a scheduled quote, if the order is scheduled to soon to opening times
*/
// @ApiMember(Description="Will contain a message if there is a problem with a scheduled quote, if the order is scheduled to soon to opening times")
public var schedulingError:String
/**
* User friendly waybill number
*/
// @ApiMember(Description="User friendly waybill number")
public var wayBill:String
/**
* List of order information for pricing etc between each waypoint
*/
// @ApiMember(Description="List of order information for pricing etc between each waypoint")
public var waypoints:[WaypointQuoteInformation] = []
/**
* List with validation information for each waypoint
*/
// @ApiMember(Description="List with validation information for each waypoint")
public var waypointValidations:[WaypointValidationInformation] = []
required public init(){ super.init() }
private enum CodingKeys : String, CodingKey {
case orderId
case waypointIssue
case totalDistance
case totalDistanceValue
case scheduledDate
case subTotal
case finalPrice
case vatValue
case schedulingNotice
case schedulingError
case wayBill
case waypoints
case waypointValidations
}
required public init(from decoder: Decoder) throws {
try super.init(from: decoder)
let container = try decoder.container(keyedBy: CodingKeys.self)
orderId = try container.decodeIfPresent(String.self, forKey: .orderId)
waypointIssue = try container.decodeIfPresent(Bool.self, forKey: .waypointIssue)
totalDistance = try container.decodeIfPresent(Double.self, forKey: .totalDistance)
totalDistanceValue = try container.decodeIfPresent(String.self, forKey: .totalDistanceValue)
scheduledDate = try container.decodeIfPresent(String.self, forKey: .scheduledDate)
subTotal = try container.decodeIfPresent(String.self, forKey: .subTotal)
finalPrice = try container.decodeIfPresent(String.self, forKey: .finalPrice)
vatValue = try container.decodeIfPresent(String.self, forKey: .vatValue)
schedulingNotice = try container.decodeIfPresent(String.self, forKey: .schedulingNotice)
schedulingError = try container.decodeIfPresent(String.self, forKey: .schedulingError)
wayBill = try container.decodeIfPresent(String.self, forKey: .wayBill)
waypoints = try container.decodeIfPresent([WaypointQuoteInformation].self, forKey: .waypoints) ?? []
waypointValidations = try container.decodeIfPresent([WaypointValidationInformation].self, forKey: .waypointValidations) ?? []
}
public override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self)
if orderId != nil { try container.encode(orderId, forKey: .orderId) }
if waypointIssue != nil { try container.encode(waypointIssue, forKey: .waypointIssue) }
if totalDistance != nil { try container.encode(totalDistance, forKey: .totalDistance) }
if totalDistanceValue != nil { try container.encode(totalDistanceValue, forKey: .totalDistanceValue) }
if scheduledDate != nil { try container.encode(scheduledDate, forKey: .scheduledDate) }
if subTotal != nil { try container.encode(subTotal, forKey: .subTotal) }
if finalPrice != nil { try container.encode(finalPrice, forKey: .finalPrice) }
if vatValue != nil { try container.encode(vatValue, forKey: .vatValue) }
if schedulingNotice != nil { try container.encode(schedulingNotice, forKey: .schedulingNotice) }
if schedulingError != nil { try container.encode(schedulingError, forKey: .schedulingError) }
if wayBill != nil { try container.encode(wayBill, forKey: .wayBill) }
if waypoints.count > 0 { try container.encode(waypoints, forKey: .waypoints) }
if waypointValidations.count > 0 { try container.encode(waypointValidations, forKey: .waypointValidations) }
}
}
public class ApiServiceResponse : IServiceResponse, Codable
{
/**
* Information about the response.
*/
// @ApiMember(Description="Information about the response.", IsRequired=true)
public var Description:String
/**
* Heading or summary of the response.
*/
// @ApiMember(Description="Heading or summary of the response.", IsRequired=true)
public var heading:String
/**
* Did the intended operation for this response complete successfully?
*/
// @ApiMember(DataType="boolean", Description="Did the intended operation for this response complete successfully?", IsRequired=true)
public var wasSuccessful:Bool
required public init(){}
}
public class WaypointQuoteInformation : LinkedWaypoint
{
/**
* Distance between waypoints as a number
*/
// @ApiMember(Description="Distance between waypoints as a number")
public var distance:Double
/**
* String formatted distance
*/
// @ApiMember(Description="String formatted distance")
public var distanceValue:String
public var waypointValid:Bool
public var message:String
public var errorDetails:[String] = []
/**
* Caculated price between waypoints excluding vat
*/
// @ApiMember(Description="Caculated price between waypoints excluding vat")
public var price:Double
/**
* Price excluding vat formatted as a string rand value
*/
// @ApiMember(Description="Price excluding vat formatted as a string rand value")
public var priceValue:String
/**
* The price between waypoints including vat
*/
// @ApiMember(Description="The price between waypoints including vat")
public var priceWithVAT:Double
/**
* The price including vat formatted as a rand value string
*/
// @ApiMember(Description="The price including vat formatted as a rand value string")
public var priceValueWithVAT:String
required public init(){ super.init() }
private enum CodingKeys : String, CodingKey {
case distance
case distanceValue
case waypointValid
case message
case errorDetails
case price
case priceValue
case priceWithVAT
case priceValueWithVAT
}
required public init(from decoder: Decoder) throws {
try super.init(from: decoder)
let container = try decoder.container(keyedBy: CodingKeys.self)
distance = try container.decodeIfPresent(Double.self, forKey: .distance)
distanceValue = try container.decodeIfPresent(String.self, forKey: .distanceValue)
waypointValid = try container.decodeIfPresent(Bool.self, forKey: .waypointValid)
message = try container.decodeIfPresent(String.self, forKey: .message)
errorDetails = try container.decodeIfPresent([String].self, forKey: .errorDetails) ?? []
price = try container.decodeIfPresent(Double.self, forKey: .price)
priceValue = try container.decodeIfPresent(String.self, forKey: .priceValue)
priceWithVAT = try container.decodeIfPresent(Double.self, forKey: .priceWithVAT)
priceValueWithVAT = try container.decodeIfPresent(String.self, forKey: .priceValueWithVAT)
}
public override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self)
if distance != nil { try container.encode(distance, forKey: .distance) }
if distanceValue != nil { try container.encode(distanceValue, forKey: .distanceValue) }
if waypointValid != nil { try container.encode(waypointValid, forKey: .waypointValid) }
if message != nil { try container.encode(message, forKey: .message) }
if errorDetails.count > 0 { try container.encode(errorDetails, forKey: .errorDetails) }
if price != nil { try container.encode(price, forKey: .price) }
if priceValue != nil { try container.encode(priceValue, forKey: .priceValue) }
if priceWithVAT != nil { try container.encode(priceWithVAT, forKey: .priceWithVAT) }
if priceValueWithVAT != nil { try container.encode(priceValueWithVAT, forKey: .priceValueWithVAT) }
}
}
public class LinkedWaypoint : Codable
{
public var fromWaypointNumber:Int
public var toWaypointNumber:Int
public var fromLatitude:Double
public var fromLongitude:Double
public var toLatitude:Double
public var toLongitude:Double
required public init(){}
}
public class WaypointValidationInformation : Codable
{
public var waypointNumber:Int
public var isValid:Bool
public var errorMessages:[String] = []
required public init(){}
}
To override the Content-type in your clients, use the HTTP Accept Header, append the .other suffix or ?format=other
The following are sample HTTP requests and responses. The placeholders shown need to be replaced with actual values.
POST /order HTTP/1.1
Host: 1fetch.api.client.prod.86degrees.com
Accept: text/jsonl
Content-Type: text/jsonl
Content-Length: length
{"ClientReference":"String","CustomerReference":"String","Waypoints":[{"WaypointNumber":0,"Latitude":0,"Longitude":0,"ContactName":"String","ContactNumber":"String","DeliveryInstructions":"String","Address":"String"}],"IsScheduled":false,"ScheduleType":0,"ScheduledDate":"String","Test":false,"IsUrgent":false,"ApiKey":"String"}
HTTP/1.1 200 OK
Content-Type: text/jsonl
Content-Length: length
{"OrderId":"00000000-0000-0000-0000-000000000000","WaypointIssue":false,"TotalDistance":0,"TotalDistanceValue":"0","ScheduledDate":"String","SubTotal":"String","FinalPrice":"String","VATValue":"String","SchedulingNotice":"String","SchedulingError":"String","WayBill":"String","Waypoints":[{}],"WaypointValidations":[{}],"Description":"String","Heading":"String","WasSuccessful":false}