| POST | /v1/CarConfiguratorStock | Validate and save a car configurator code for a vehicle search | This endpoint calls Agency API to validate and save a car configurator code. The code is validated and saved in the database and returns a response from a third party CCS which provides car configuration details. These get saved to open search and used to perform a vehicle search |
|---|
import datetime
import decimal
from marshmallow.fields import *
from servicestack import *
from typing import *
from dataclasses import dataclass, field
from dataclasses_json import dataclass_json, LetterCase, Undefined, config
from enum import Enum, IntEnum
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class KeyInformation:
b_m7_n_s_t: Optional[str] = None
configuration_date: Optional[str] = None
model_year: Optional[str] = None
half_year: Optional[str] = None
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class EquipmentCache:
code: Optional[str] = None
description: Optional[str] = None
standard_flag: Optional[str] = None
price: Decimal = decimal.Decimal(0)
category: Optional[str] = None
importance: Optional[str] = None
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class OrderingOptions:
interior: Optional[List[str]] = None
exterior: Optional[List[str]] = None
options: Optional[List[str]] = None
wheel_options: List[EquipmentCache] = field(default_factory=list)
trim_options: List[EquipmentCache] = field(default_factory=list)
option_codes: List[EquipmentCache] = field(default_factory=list)
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class CarConfiguratorResponse:
name: Optional[str] = None
key_information: Optional[KeyInformation] = None
ordering_options: Optional[OrderingOptions] = None
response_status: Optional[ResponseStatus] = None
configurator_code: Optional[str] = None
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class BackOrderVehicleDetailsBrand:
description: Optional[str] = None
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class Engine:
id: int = 0
badge: Optional[str] = None
cubic_capacity: int = 0
cyclinders: int = 0
horse_power: Optional[str] = None
kw: Optional[str] = None
selected: bool = False
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class VehicleAuditDetails:
user_id: Optional[str] = None
status: bool = False
notes: Optional[str] = None
creation_date: Optional[str] = None
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class RetailerService:
id: int = 0
description: Optional[str] = None
priority: bool = False
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class RetailerServices:
new: Optional[List[RetailerService]] = None
used: Optional[List[RetailerService]] = None
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class RetailerOpeningTime:
day: Optional[str] = None
open_from: Optional[str] = None
open_to: Optional[str] = None
special: Optional[str] = None
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class RetailerOpeningTimes:
new: List[RetailerOpeningTime] = field(default_factory=list)
used: List[RetailerOpeningTime] = field(default_factory=list)
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class Retailer:
id: int = 0
gssn_id: Optional[str] = None
description: Optional[str] = None
street: Optional[str] = None
city: Optional[str] = None
district: Optional[str] = None
postcode: Optional[str] = None
google_map_postcode: Optional[str] = None
phone: Optional[str] = None
fax: Optional[str] = None
email: Optional[str] = None
website: Optional[str] = None
latitude: float = 0.0
longitude: float = 0.0
retailer_group__id: Optional[int] = None
retailer_group_id: Optional[str] = None
retailer_group_name: Optional[str] = None
distance: float = 0.0
payment_service_guid: Optional[str] = None
is_online: Optional[bool] = None
is_new_car_retailer: Optional[bool] = None
is_used_car_retailer: Optional[bool] = None
is_central_retailer: bool = False
chat_enabled: bool = False
trade_in_enabled: bool = False
display_phone_number_new: Optional[str] = None
display_phone_number_used: Optional[str] = None
services: Optional[RetailerServices] = None
smart: bool = False
smart_description: Optional[str] = None
smart_website: Optional[str] = None
smart_email: Optional[str] = None
smart_phone: Optional[str] = None
additional_information: Optional[str] = None
legacy_id: Optional[str] = None
drive_time: Decimal = decimal.Decimal(0)
agent: bool = False
port: Optional[int] = None
port_name: Optional[str] = None
market_area_id: Optional[int] = None
market_area_name: Optional[str] = None
maintenance_date: Optional[str] = None
maintenance_source: Optional[str] = None
stp_account_numbers: Optional[str] = None
campaign_excluded: Optional[bool] = None
digital_lounge_parent_gssn_id: Optional[str] = None
send_leads_to_digital_lounge_parent: bool = False
is_excluded_from_import: bool = False
opening_times: Optional[RetailerOpeningTimes] = None
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class Media:
image_count: int = 0
main_image_url: Optional[str] = None
main_image_url_mobile: Optional[str] = None
no_image: bool = False
three_sixty_degree_image_urls: Optional[List[str]] = None
three_sixty_degree_mobile_image_urls: Optional[List[str]] = None
vehicle_image_urls: Optional[List[str]] = None
vehicle_mobile_image_urls: Optional[List[str]] = None
class OfferPriceProductType(str, Enum):
LIS_T__P_R_I_C_E = 'LIST_PRICE'
NUMBE_R__P_L_A_T_E__F_E_E = 'NUMBER_PLATE_FEE'
DELIVER_Y__C_H_A_R_G_E = 'DELIVERY_CHARGE'
FUE_L__C_H_A_R_G_E = 'FUEL_CHARGE'
MANUFACTURE_R__O_F_F_E_R = 'MANUFACTURER_OFFER'
PERSONALISE_D__M_O_N_E_Y_O_F_F_E_R = 'PERSONALISED_MONEYOFFER'
PERSONALISE_D__N_O_N_M_O_N_E_Y_O_F_F_E_R = 'PERSONALISED_NONMONEYOFFER'
PERSONALISE_D__N_O_N_M_O_N_E_Y_O_F_F_E_R__N_E_G = 'PERSONALISED_NONMONEYOFFER_NEG'
SERVICE = 'SERVICE'
SERVIC_E__N_E_G = 'SERVICE_NEG'
GOVERNMEN_T__G_R_A_N_T = 'GOVERNMENT_GRANT'
OUTRIGH_T__P_U_R_C_H_A_S_E__D_I_S_C_O_U_N_T = 'OUTRIGHT_PURCHASE_DISCOUNT'
VI_P__O_F_F_E_R = 'VIP_OFFER'
WALLBO_X__O_F_F_E_R = 'WALLBOX_OFFER'
WALLBO_X__O_F_F_E_R__N_E_G = 'WALLBOX_OFFER_NEG'
ROA_D__F_U_N_D__L_I_C_E_N_C_E = 'ROAD_FUND_LICENCE'
FIRS_T__R_E_G_I_S_T_R_A_T_I_O_N__F_E_E = 'FIRST_REGISTRATION_FEE'
NO_T__F_O_U_N_D = 'NOT_FOUND'
ACCESSOR_Y__O_F_F_E_R = 'ACCESSORY_OFFER'
ACCESSOR_Y__O_F_F_E_R__N_E_G = 'ACCESSORY_OFFER_NEG'
MOTABILIT_Y__D_I_S_C_O_U_N_T = 'MOTABILITY_DISCOUNT'
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class Price:
id: Optional[str] = None
description: Optional[str] = None
net: Decimal = decimal.Decimal(0)
vat: Decimal = decimal.Decimal(0)
gross: Decimal = decimal.Decimal(0)
product: Optional[OfferPriceProductType] = None
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class Consumption:
id: int = 0
lkm: Decimal = decimal.Decimal(0)
mpg: Decimal = decimal.Decimal(0)
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class EmissionClass:
colour: Optional[str] = None
rating: Optional[str] = None
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class Equipment:
id: Optional[int] = None
code: Optional[str] = None
description: Optional[str] = None
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class Equipmentv2(Equipment):
importance: int = 0
is_additional: bool = False
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class EquipmentCategoryv2:
order: int = 0
code: Optional[str] = None
description: Optional[str] = None
equipment: Optional[List[Equipmentv2]] = None
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class VehicleAttribute:
description: Optional[str] = None
value: Optional[str] = None
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class IntegratedServiceCareOptions:
option_code: Optional[str] = None
b_m7_n_s_t: Optional[str] = None
full_model_year: Optional[str] = None
integrated_product_type: Optional[str] = None
customer_description: Optional[str] = None
one_agent_product_type: Optional[str] = None
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class BackOrderVehicleDetails(IVehiclePrices, IVehiclePriceCollection, IImageUrl, IVehicleDetails):
vin: Optional[str] = None
commission_number: Optional[str] = None
description: Optional[str] = None
short_description: Optional[str] = None
model_id: int = 0
model: Optional[str] = None
full_model_year_code: Optional[str] = None
brand_id: Optional[int] = None
brand: Optional[BackOrderVehicleDetailsBrand] = None
retailer_id: int = 0
image_url: Optional[str] = None
colour: Optional[str] = None
colour_code: Optional[str] = None
fuel_type: Optional[str] = None
fuel_type_id: int = 0
transmission: Optional[str] = None
transmission_type: Optional[str] = None
engine: Optional[Engine] = None
engine_badge: Optional[str] = None
package: Optional[str] = None
line: Optional[str] = None
upholstery: Optional[str] = None
upholstery_code: Optional[str] = None
usage_code: Optional[str] = None
account: Optional[str] = None
account_type: Optional[str] = None
nst: Optional[str] = None
baumuster: Optional[str] = None
electric_range: Optional[Decimal] = None
electric_consumption: Optional[Decimal] = None
actual_price: Optional[Decimal] = None
otr_price: Decimal = decimal.Decimal(0)
retail_price_ex_vat: Decimal = decimal.Decimal(0)
p11_d: Decimal = decimal.Decimal(0)
vehicle_type: Optional[str] = None
upholstery_description: Optional[str] = None
upholstery_type: Optional[str] = None
body_style: Optional[str] = None
body_style_style_code: Optional[str] = None
body_style_style_code_electric: Optional[str] = None
body_style_style_code_hybrid: Optional[str] = None
available_packages: Optional[List[str]] = None
mapped__line: Optional[int] = None
secured: bool = False
bm7_n_s_t: Optional[str] = None
is_available_online: bool = False
is_specialist_car: bool = False
is_sellable: bool = False
under_offer: bool = False
vehicle_audit_details: Optional[List[VehicleAuditDetails]] = None
retailer: Optional[Retailer] = None
media: Optional[Media] = None
emission: Optional[Decimal] = None
colour_group: Optional[str] = None
vehicle_class: Optional[str] = None
product_range: Optional[str] = None
is_h_o_back_order_account_vehicle: bool = False
is_allocated_to_back_order: bool = False
in_back_order_account: bool = False
delivery_charge: Decimal = decimal.Decimal(0)
delivery_charge_net: Optional[Decimal] = None
delivery_charge_v_a_t: Optional[Decimal] = None
plates: Decimal = decimal.Decimal(0)
plates_net: Optional[Decimal] = None
plates_v_a_t: Optional[Decimal] = None
fuel_charge: Decimal = decimal.Decimal(0)
fuel_charge_net: Optional[Decimal] = None
fuel_charge_v_a_t: Optional[Decimal] = None
retail_price__ex_v_a_t: Decimal = decimal.Decimal(0)
retail_price__inc_v_a_t: Decimal = decimal.Decimal(0)
ve_d__year1: Decimal = decimal.Decimal(0)
ve_d__year2: Decimal = decimal.Decimal(0)
first_reg_fee: Decimal = decimal.Decimal(0)
ot_r__value: Decimal = decimal.Decimal(0)
otr: Decimal = decimal.Decimal(0)
prices: Optional[List[Price]] = None
production_date: Optional[str] = None
port_arrival_date: Optional[datetime.datetime] = None
location: Optional[str] = None
is_display_stock: bool = False
display_retailer_id: Optional[int] = None
display_retailer: Optional[str] = None
display_retailer_gssn_id: Optional[str] = None
display_retailer_market_area_id: Optional[int] = None
is_smart_display_retailer: Optional[bool] = None
colour_description: Optional[str] = None
creation: Optional[datetime.datetime] = None
modified: Optional[datetime.datetime] = None
vat_qualifying_number: Optional[int] = None
vat_qualifying: bool = False
current_retailer_offer_price: Decimal = decimal.Decimal(0)
gssn_id: Optional[str] = None
no_image: bool = False
registration_number: Optional[str] = None
registration_date: Optional[datetime.datetime] = None
mileage: Optional[int] = None
trade_in_date: Optional[datetime.datetime] = None
vid: Optional[str] = None
emission_combined: Optional[str] = None
emission_directive: Optional[str] = None
normalised_emission_directive: Optional[str] = None
has_mild_hybrid_equipment_code: bool = False
acceleration: Optional[Decimal] = None
chassis_number: Optional[str] = None
number_of_doors: Optional[str] = None
number_of_seats: Optional[str] = None
special_info: bool = False
eligible_for_integrated_service_care: bool = False
consumption_combined: Optional[Consumption] = None
consumption_extra_urban: Optional[Consumption] = None
consumption_urban: Optional[Consumption] = None
wltp_fuel_consumption_combined: Optional[Consumption] = None
wltp_fuel_consumption_extra_high: Optional[Consumption] = None
wltp_fuel_consumption_high: Optional[Consumption] = None
wltp_fuel_consumption_low: Optional[Consumption] = None
wltp_fuel_consumption_medium: Optional[Consumption] = None
energy_efficiency_class: Optional[EmissionClass] = None
equipment: Optional[List[Equipmentv2]] = None
equipment_additional: Optional[List[Equipment]] = None
equipment_categories: Optional[List[EquipmentCategoryv2]] = None
vehicle_data: Optional[List[VehicleAttribute]] = None
integrated_service_care_options: Optional[List[IntegratedServiceCareOptions]] = None
isp_vehicle_customer_descriptions: Optional[List[str]] = None
marketing_code: Optional[str] = None
eligible_for_ma_transfer: bool = False
confirmed_production_date: Optional[str] = None
forecasted_arrival_date: Optional[str] = None
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class Package:
id: int = 0
description: Optional[str] = None
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class BackOrderVehicleDetailsWithPackages(BackOrderVehicleDetails, IPackages):
packages: Optional[List[Package]] = None
package_names: Optional[str] = None
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class CarConfiguratorVehicle(BackOrderVehicleDetailsWithPackages):
model_year_code: Optional[str] = None
half_model_year_code: Optional[str] = None
active_offers: List[int] = field(default_factory=list)
eligible_for_motability: bool = False
nearest_port: Optional[bool] = None
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class CarConfiguratorStockMatch:
vehicle: Optional[CarConfiguratorVehicle] = None
is_sellable: bool = False
vehicle_wheels: Optional[str] = None
vehicle_trim: Optional[str] = None
vehicle_additional_option_codes: List[str] = field(default_factory=list)
full_model_year_differences: List[str] = field(default_factory=list)
paint_differences: List[str] = field(default_factory=list)
upholstery_differences: List[str] = field(default_factory=list)
wheel_differences: List[str] = field(default_factory=list)
trim_differences: List[str] = field(default_factory=list)
equipment_differences: List[str] = field(default_factory=list)
differences: List[str] = field(default_factory=list)
exact_match: bool = False
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class CarConfiguratorStockMatches:
sellable_matches: List[CarConfiguratorStockMatch] = field(default_factory=list)
non_sellable_matches: List[CarConfiguratorStockMatch] = field(default_factory=list)
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class CarConfiguratorStockResponse:
total_vehicles: int = 0
car_configurator_response: Optional[CarConfiguratorResponse] = None
exact_matches: Optional[CarConfiguratorStockMatches] = None
close_matches: Optional[CarConfiguratorStockMatches] = None
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class CarConfiguratorStockRequest(IPost):
# @ApiMember(Description="The configurator code to search on", IsRequired=true)
configurator_code: Optional[str] = None
"""
The configurator code to search on
"""
# @ApiMember(Description="Whether to return sellable vehicles")
is_sellable: Optional[bool] = None
"""
Whether to return sellable vehicles
"""
# @ApiMember(Description="Whether to only get exact matches")
exact_match: bool = False
"""
Whether to only get exact matches
"""
# @ApiMember(Description="Whether to restrict vehicles response to a GSSN")
gssn: Optional[str] = None
"""
Whether to restrict vehicles response to a GSSN
"""
Python CarConfiguratorStockRequest DTOs
To override the Content-type in your clients, use the HTTP Accept Header, append the .jsv suffix or ?format=jsv
The following are sample HTTP requests and responses. The placeholders shown need to be replaced with actual values.
POST /v1/CarConfiguratorStock HTTP/1.1
Host: prod-api-agency-orch-mb-dhc.rapp-customers.co.uk
Accept: text/jsv
Content-Type: text/jsv
Content-Length: length
{
ConfiguratorCode: String,
IsSellable: False,
ExactMatch: False,
GSSN: String
}
HTTP/1.1 200 OK
Content-Type: text/jsv
Content-Length: length
{
TotalVehicles: 4,
CarConfiguratorResponse:
{
Name: String,
KeyInformation:
{
BM7NST: String,
ConfigurationDate: String,
ModelYear: String,
HalfYear: String
},
OrderingOptions:
{
Interior:
[
String
],
Exterior:
[
String
],
Options:
[
String
],
WheelOptions:
[
{
Code: String,
Description: String,
StandardFlag: String,
Price: 0,
Category: String,
Importance: String
}
],
TrimOptions:
[
{
Code: String,
Description: String,
StandardFlag: String,
Price: 0,
Category: String,
Importance: String
}
],
OptionCodes:
[
{
Code: String,
Description: String,
StandardFlag: String,
Price: 0,
Category: String,
Importance: String
}
]
},
ResponseStatus:
{
ErrorCode: String,
Message: String,
StackTrace: String,
Errors:
[
{
ErrorCode: String,
FieldName: String,
Message: String,
Meta:
{
String: String
}
}
],
Meta:
{
String: String
}
},
ConfiguratorCode: String
},
ExactMatches:
{
SellableMatches:
[
{
}
],
NonSellableMatches:
[
{
}
]
},
CloseMatches:
{
SellableMatches:
[
{
}
],
NonSellableMatches:
[
{
}
]
}
}