feat(inventory): Be able to handle both type of tesla response
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Matthieu 'JP' DERASSE 2023-08-13 12:09:47 +00:00
parent 73aa82a79b
commit 5277672f1e
Signed by: mderasse
GPG Key ID: 55141C777B16A705
3 changed files with 79 additions and 29 deletions

View File

@ -80,7 +80,6 @@ steps:
``` {{commit.message}} ``` ``` {{commit.message}} ```
🌐 {{ build.link }} 🌐 {{ build.link }}
format: markdown
when: when:
status: status:
- failure - failure

View File

@ -5,8 +5,41 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/url" "net/url"
"strconv"
"strings"
) )
// UnmarshalJSON come overide default unmarshal on availabilitiesReponse to handle both type of response sent by Tesla Inventory API.
func (a *AvailabilitiesResponse) UnmarshalJSON(data []byte) error {
if !strings.Contains(string(data), "\"total_matches_found\":\"") {
type TmpJson AvailabilitiesResponse
var tmpJson TmpJson
err := json.Unmarshal(data, &tmpJson)
if err != nil {
return err
}
*a = AvailabilitiesResponse(tmpJson)
return nil
}
var exactAvailabilities AvailabilitiesExactResponse
err := json.Unmarshal(data, &exactAvailabilities)
if err != nil {
return err
}
amount, err := strconv.Atoi(exactAvailabilities.TotalMatchesFound)
if err != nil {
return err
}
a.TotalMatchesFound = amount
a.Results.Exact = exactAvailabilities.Results
return nil
}
// GetAvailabilities return the car availabilities matching with the provided characteristics. // GetAvailabilities return the car availabilities matching with the provided characteristics.
func (c *Client) GetAvailabilities(ctx context.Context, params AvailabilityParams, headers map[string]string) (*AvailabilitiesResponse, error) { func (c *Client) GetAvailabilities(ctx context.Context, params AvailabilityParams, headers map[string]string) (*AvailabilitiesResponse, error) {
b, err := json.Marshal(params) b, err := json.Marshal(params)

View File

@ -131,40 +131,40 @@ const (
// AvailabilityParams is the params accepted by the API. // AvailabilityParams is the params accepted by the API.
type AvailabilityParams struct { type AvailabilityParams struct {
Query AvailabilityQueryParams `json:"query"` Query AvailabilityQueryParams `json:"query"`
Offset int `json:"offset"` Offset *int `json:"offset,omitempty"`
Count int `json:"count"` Count *int `json:"count,omitempty"`
OutsideOffset int `json:"outsideOffset"` OutsideOffset *int `json:"outsideOffset,omitempty"`
OutsideSearch bool `json:"outsideSearch"` OutsideSearch *bool `json:"outsideSearch,omitempty"`
} }
// AvailabilityQueryParams are the params to filter results. // AvailabilityQueryParams are the params to filter results.
type AvailabilityQueryParams struct { type AvailabilityQueryParams struct {
Arrangeby arrangeByEnum `json:"arrangeby"` Arrangeby *arrangeByEnum `json:"arrangeby,omitempty"`
Condition conditionEnum `json:"condition"` Condition *conditionEnum `json:"condition,omitempty"`
Language string `json:"language"` Language *string `json:"language,omitempty"`
Lat float64 `json:"lat"` Lat *float64 `json:"lat,omitempty"`
Lng float64 `json:"lng"` Lng *float64 `json:"lng,omitempty"`
Market string `json:"market"` Market *string `json:"market,omitempty"`
Model modelEnum `json:"model"` Model *modelEnum `json:"model,omitempty"`
Options OptionsParams `json:"options"` Options *OptionsParams `json:"options,omitempty"`
Order orderByEnum `json:"order"` Order *orderByEnum `json:"order,omitempty"`
Range int `json:"range"` Range *int `json:"range,omitempty"`
Region string `json:"region"` Region *string `json:"region,omitempty"`
SuperRegion string `json:"super_region"` SuperRegion *string `json:"super_region,omitempty"`
Zip string `json:"zip"` Zip *string `json:"zip,omitempty"`
} }
// OptionsParams contain the car option. // OptionsParams contain the car option.
type OptionsParams struct { type OptionsParams struct {
AdditionalOptions []string `json:"ADL_OPTS"` AdditionalOptions []string `json:"ADL_OPTS,omitempty"`
Autopilot []autopilotEnum `json:"AUTOPILOT"` Autopilot []autopilotEnum `json:"AUTOPILOT,omitempty"`
CabinConfig []cabinConfigEnum `json:"CABIN_CONFIG"` CabinConfig []cabinConfigEnum `json:"CABIN_CONFIG,omitempty"`
Interior []interiorEnum `json:"INTERIOR"` Interior []interiorEnum `json:"INTERIOR,omitempty"`
Paint []paintEnum `json:"PAINT"` Paint []paintEnum `json:"PAINT,omitempty"`
SteeringWheel []steeringWheelEnum `json:"STEERING_WHEEL"` SteeringWheel []steeringWheelEnum `json:"STEERING_WHEEL,omitempty"`
Trim []trimEnum `json:"TRIM"` Trim []trimEnum `json:"TRIM,omitempty"`
Wheels []wheelsEnum `json:"WHEELS"` Wheels []wheelsEnum `json:"WHEELS,omitempty"`
Year []string `json:"Year"` Year []string `json:"Year,omitempty"`
} }
/** /**
@ -438,8 +438,26 @@ type Availability struct {
FirstRegistrationDate any `json:"FirstRegistrationDate,omitempty"` FirstRegistrationDate any `json:"FirstRegistrationDate,omitempty"`
} }
/**
* Tesla inventory API have to kind of response by on the result.
* Either you have a exact response (most of the case)
* Either you have a multiple availability based on the level of match with your filters
*
* I have decided to use the 2nd format in the inventory SDK as it can handle both cases
**/
// AvailabilitiesExactResponse contain the a list of car availability.
type AvailabilitiesExactResponse struct {
Results []Availability `json:"results"`
TotalMatchesFound string `json:"total_matches_found"`
}
// AvailabilitiesResponse contain the a list of car availability. // AvailabilitiesResponse contain the a list of car availability.
type AvailabilitiesResponse struct { type AvailabilitiesResponse struct {
Results []Availability `json:"results,omitempty"` Results struct {
TotalMatchesFound string `json:"total_matches_found,omitempty"` Approximate []Availability `json:"approximate"`
ApproximateOutside []Availability `json:"approximateOutside"`
Exact []Availability `json:"exact"`
} `json:"results"`
TotalMatchesFound int `json:"total_matches_found"`
} }