parking_ticket 1.0.1 → 1.0.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 46eea131e0a69fa49115d452afc9ee575b52a06084eb8a026bf115b33b2d46f6
4
- data.tar.gz: 735ffb052fecb3599af5bf71ec7a28c60e48e8ed2025e8cb7923e7f6bb570851
3
+ metadata.gz: a45be3c94ffccf5e5e1f66abf01a80528a5f9ab95d22b7bbd281996889b3cd5f
4
+ data.tar.gz: 52609368928c5d70bc382619b39bf2962209be2e0456bc90a4e0d89dfb3f0954
5
5
  SHA512:
6
- metadata.gz: 21652de95a323f337d244d5c652a826b5cda0de762c4d3e4f7be31bcf9b62a2e5e7d14eaf7744b48ac9c7aae1de0c03984e1fe3be76cf4cd34b9a4012e785857
7
- data.tar.gz: bfdc6306def10532b510639fe275c7e948f274797e99f4eb314e06a3af98502713e40e57e23756959137f51a0c7b4252caf1e26eaa8f8d6dd738ee02caf6e44a
6
+ metadata.gz: 50c8f9a60ea1f075914e468fbb7057997397a2fd800003321e0f4e03a4e1efbcfc11b6352b6b3d508b1ac95cd5b823738385b8b8c31c298179cb7a7307a9fa02
7
+ data.tar.gz: 5bc40023e17ed5235bccdbddd27d3e78e4cdea6c7e43ecc58397e81e85be5637ce5418106ffb0ab4f8c447660b65e19312a3da7f0d2979c4d14d00eaff2184a8
data/Gemfile CHANGED
@@ -9,6 +9,13 @@ gem 'rake', '~> 13.0'
9
9
 
10
10
  gem 'rspec', '~> 3.0'
11
11
 
12
+ # VCR, save test suite's http requests and replay them
13
+ gem 'vcr', '~> 6.0'
14
+ # Mock web requests in tests
15
+ gem 'webmock', '~> 3.12'
16
+
17
+ gem 'byebug'
18
+
12
19
  gem 'faraday', '~> 2.7', '>= 2.7.2'
13
20
 
14
21
  gem 'json_matchers'
data/Gemfile.lock CHANGED
@@ -1,21 +1,29 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- parking_ticket (1.0.1)
4
+ parking_ticket (1.0.40)
5
5
  faraday
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
+ addressable (2.8.1)
11
+ public_suffix (>= 2.0.2, < 6.0)
12
+ byebug (11.1.3)
13
+ crack (0.4.5)
14
+ rexml
10
15
  diff-lcs (1.5.0)
11
16
  faraday (2.7.2)
12
17
  faraday-net_http (>= 2.0, < 3.1)
13
18
  ruby2_keywords (>= 0.0.4)
14
19
  faraday-net_http (3.0.2)
20
+ hashdiff (1.0.1)
15
21
  json_matchers (0.11.1)
16
22
  json_schema
17
23
  json_schema (0.21.0)
24
+ public_suffix (5.0.1)
18
25
  rake (13.0.6)
26
+ rexml (3.2.5)
19
27
  rspec (3.12.0)
20
28
  rspec-core (~> 3.12.0)
21
29
  rspec-expectations (~> 3.12.0)
@@ -30,17 +38,25 @@ GEM
30
38
  rspec-support (~> 3.12.0)
31
39
  rspec-support (3.12.0)
32
40
  ruby2_keywords (0.0.5)
41
+ vcr (6.1.0)
42
+ webmock (3.18.1)
43
+ addressable (>= 2.8.0)
44
+ crack (>= 0.3.2)
45
+ hashdiff (>= 0.4.0, < 2.0.0)
33
46
 
34
47
  PLATFORMS
35
48
  arm64-darwin-20
36
49
  x86_64-linux
37
50
 
38
51
  DEPENDENCIES
52
+ byebug
39
53
  faraday (~> 2.7, >= 2.7.2)
40
54
  json_matchers
41
55
  parking_ticket!
42
56
  rake (~> 13.0)
43
57
  rspec (~> 3.0)
58
+ vcr (~> 6.0)
59
+ webmock (~> 3.12)
44
60
 
45
61
  BUNDLED WITH
46
62
  2.2.32
@@ -0,0 +1,64 @@
1
+ require 'byebug'
2
+ module ParkingTicket
3
+ module Clients
4
+ class Adapter
5
+ class << self
6
+ def parent_module
7
+ const_get(name.split('::')[0..-2].join('::'))
8
+ end
9
+
10
+ def valid_credentials?(username, password)
11
+ parent_module::Client.auth(username, password).status == 200
12
+ end
13
+ end
14
+ class Error < StandardError
15
+ end
16
+
17
+ def initialize(username, password)
18
+ @username = username
19
+ @password = password
20
+ end
21
+
22
+ def vehicles
23
+ raise_invalid_credentials! unless valid_credentials?
24
+ fetch_and_map_vehicles
25
+ end
26
+
27
+ def rate_options(zipcode, license_plate)
28
+ raise_invalid_credentials! unless valid_credentials?
29
+ fetch_and_map_rate_options(zipcode, license_plate)
30
+ end
31
+
32
+ def running_ticket(license_plate, zipcode)
33
+ raise_invalid_credentials! unless valid_credentials?
34
+ fetch_and_map_running_ticket(license_plate, zipcode)
35
+ end
36
+
37
+ def payment_methods
38
+ raise_invalid_credentials! unless valid_credentials?
39
+ fetch_and_map_payment_methods
40
+ end
41
+
42
+ def new_ticket(license_plate, zipcode, rate_option_id, quantity, time_unit, payment_method_id)
43
+ raise_invalid_credentials! unless valid_credentials?
44
+ return if running_ticket(license_plate, zipcode)
45
+
46
+ request_new_ticket(license_plate, zipcode, rate_option_id, quantity, time_unit, payment_method_id)
47
+ end
48
+
49
+ private
50
+
51
+ def client
52
+ @client ||= self.class.parent_module::Client.new(@username, @password)
53
+ end
54
+
55
+ def valid_credentials?
56
+ @valid_credentials ||= self.class.valid_credentials?(@username, @password)
57
+ end
58
+
59
+ def raise_invalid_credentials!
60
+ raise Error, 'Adapter credentials are not valid'
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,95 @@
1
+ module ParkingTicket
2
+ module Clients
3
+ module PayByPhone
4
+ class Adapter < Clients::Adapter
5
+ ACCEPTED_TIME_UNIT_MAPPER = {
6
+ 'Days' => 'days',
7
+ 'Minutes' => 'minutes',
8
+ 'Hours' => 'hours'
9
+ }.freeze
10
+
11
+ PAYMENT_CARD_TYPE_MAPPER = {
12
+ 'MasterCard' => 'master_card',
13
+ 'Visa' => 'visa'
14
+ }.freeze
15
+
16
+ private
17
+
18
+ def fetch_and_map_vehicles
19
+ client.vehicles.map do |vehicle|
20
+ {
21
+ client_internal_id: vehicle['vehicleId'],
22
+ license_plate: vehicle['licensePlate'],
23
+ type: vehicle['type']
24
+ }
25
+ end
26
+ end
27
+
28
+ def fetch_and_map_rate_options(zipcode, license_plate)
29
+ client.rate_options(zipcode, license_plate).map do |rate_option|
30
+ mapped_time_units = rate_option['acceptedTimeUnits'].map do |accepted_time_unit|
31
+ ACCEPTED_TIME_UNIT_MAPPER[accepted_time_unit]
32
+ end
33
+ {
34
+ client_internal_id: rate_option['rateOptionId'],
35
+ name: rate_option['name'],
36
+ type: rate_option['type'],
37
+ accepted_time_units: mapped_time_units
38
+ }
39
+ end
40
+ end
41
+
42
+ def fetch_and_map_running_ticket(license_plate, zipcode)
43
+ client.running_tickets.filter do |ticket|
44
+ ticket.dig('vehicle', 'licensePlate') == license_plate && ticket['locationId'] == zipcode
45
+ end.map do |ticket|
46
+ {
47
+ client_internal_id: ticket['parkingSessionId'],
48
+ starts_on: DateTime.parse(ticket['startTime']),
49
+ ends_on: DateTime.parse(ticket['expireTime']),
50
+ license_plate: ticket.dig('vehicle', 'licensePlate'),
51
+ cost: ticket.dig('segments', 0, 'cost'),
52
+ client: 'PayByPhone'
53
+ }
54
+ end.first
55
+ end
56
+
57
+ def request_new_ticket(license_plate, zipcode, rate_option_id, quantity, time_unit, payment_method_id)
58
+ mapped_time_unit = ACCEPTED_TIME_UNIT_MAPPER.key(time_unit)
59
+ payment_method = fetch_and_map_payment_methods.find do |payment_method|
60
+ payment_method[:client_internal_id] == payment_method_id
61
+ end
62
+ quote = fetch_and_map_quote(rate_option_id, zipcode, license_plate, quantity, mapped_time_unit)
63
+ client.new_ticket(
64
+ quote[:client_internal_id],
65
+ payment_method[:client_internal_id],
66
+ zipcode,
67
+ license_plate,
68
+ quantity,
69
+ mapped_time_unit,
70
+ quote[:starts_on]
71
+ )
72
+ end
73
+
74
+ def fetch_and_map_payment_methods
75
+ client.payment_methods['items'].map do |payment_method|
76
+ {
77
+ client_internal_id: payment_method['id'],
78
+ anonymised_card_number: payment_method['maskedCardNumber'][-4..],
79
+ payment_card_type: PAYMENT_CARD_TYPE_MAPPER[payment_method['paymentCardType']]
80
+ }
81
+ end
82
+ end
83
+
84
+ def fetch_and_map_quote(rate_option_id, zipcode, license_plate, quantity, time_unit)
85
+ fetched_quote = client.quote(rate_option_id, zipcode, license_plate, quantity, time_unit)
86
+ {
87
+ client_internal_id: fetched_quote['quoteId'],
88
+ starts_on: fetched_quote['parkingStartTime'],
89
+ ends_on: fetched_quote['parkingExpiryTime']
90
+ }
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,157 @@
1
+ require 'faraday'
2
+ module ParkingTicket
3
+ module Clients
4
+ module PayByPhone
5
+ class Client
6
+ class << self
7
+ def rate_options(token, account_id, zipcode, license_plate)
8
+ connection(token).get("/parking/locations/#{zipcode}/rateOptions",
9
+ {
10
+ parkingAccountId: account_id,
11
+ licensePlate: license_plate
12
+ }).body
13
+ end
14
+
15
+ def vehicles(token)
16
+ connection(token).get('/identity/profileservice/v1/members/vehicles/paybyphone').body
17
+ end
18
+
19
+ def auth(username, password)
20
+ conn = Faraday.new('https://auth.paybyphoneapis.com') do |f|
21
+ f.response :json
22
+ end
23
+ conn.post(
24
+ '/token',
25
+ URI.encode_www_form({
26
+ grant_type: 'password',
27
+ username: username,
28
+ password: password,
29
+ client_id: 'paybyphone_web'
30
+ }),
31
+ {
32
+ 'Accept' => 'application/json, text/plain, */*',
33
+ 'X-Pbp-ClientType' => 'WebApp'
34
+ }
35
+ )
36
+ end
37
+
38
+ def account_id(token)
39
+ connection(token).get('/parking/accounts').body.dig(0, 'id')
40
+ end
41
+
42
+ def running_tickets(token, account_id)
43
+ connection(token).get("/parking/accounts/#{account_id}/sessions?periodType=Current").body
44
+ end
45
+
46
+ def quote(token, account_id, rate_option_id, zipcode, license_plate, quantity, time_unit)
47
+ connection(token).get(
48
+ "/parking/accounts/#{account_id}/quote",
49
+ {
50
+ locationId: zipcode,
51
+ licensePlate: license_plate,
52
+ rateOptionId: rate_option_id,
53
+ durationTimeUnit: time_unit,
54
+ durationQuantity: quantity,
55
+ isParkUntil: false,
56
+ parkingAccountId: account_id
57
+ }
58
+ ).body
59
+ end
60
+
61
+ def new_ticket(token, account_id, quote_id, payment_method_id, zipcode, license_plate, quantity, time_unit, start_time)
62
+ connection(token).post(
63
+ "/parking/accounts/#{account_id}/sessions/",
64
+ {
65
+ "expireTime": nil,
66
+ "duration": {
67
+ "quantity": quantity,
68
+ "timeUnit": time_unit
69
+ },
70
+ "licensePlate": license_plate,
71
+ "locationId": zipcode,
72
+ "rateOptionId": '75101',
73
+ "startTime": start_time,
74
+ "quoteId": quote_id,
75
+ "parkingAccountId": account_id,
76
+ "paymentMethod": {
77
+ "paymentMethodType": 'PaymentAccount',
78
+ "payload": {
79
+ "paymentAccountId": payment_method_id,
80
+ "clientBrowserDetails": {
81
+ "browserAcceptHeader": 'text/html',
82
+ "browserColorDepth": '30',
83
+ "browserJavaEnabled": 'false',
84
+ "browserLanguage": 'fr-FR',
85
+ "browserScreenHeight": '900',
86
+ "browserScreenWidth": '1440',
87
+ "browserTimeZone": '-60',
88
+ "browserUserAgent": 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36'
89
+ }
90
+ }
91
+ }
92
+ }.to_json
93
+ ).body
94
+ end
95
+
96
+ def payment_methods(token)
97
+ connection(token).get('/payment/v3/accounts').body
98
+ end
99
+
100
+ private
101
+
102
+ def connection(token)
103
+ Faraday.new(
104
+ url: 'https://consumer.paybyphoneapis.com',
105
+ headers: {
106
+ 'Content-Type' => 'application/json',
107
+ 'Authorization' => "Bearer #{token}"
108
+ }
109
+ ) do |f|
110
+ f.response :json
111
+ end
112
+ end
113
+ end
114
+
115
+ def initialize(username, password)
116
+ @username = username
117
+ @password = password
118
+ end
119
+
120
+ def vehicles
121
+ self.class.vehicles(token)
122
+ end
123
+
124
+ def rate_options(zipcode, license_plate)
125
+ self.class.rate_options(token, account_id, zipcode, license_plate)
126
+ end
127
+
128
+ def running_tickets
129
+ self.class.running_tickets(token, account_id)
130
+ end
131
+
132
+ def payment_methods
133
+ self.class.payment_methods(token)
134
+ end
135
+
136
+ def quote(rate_option_id, zipcode, license_plate, quantity, time_unit)
137
+ self.class.quote(token, account_id, rate_option_id, zipcode, license_plate, quantity, time_unit)
138
+ end
139
+
140
+ def new_ticket(quote_id, payment_method_id, zipcode, license_plate, quantity, time_unit, start_time)
141
+ self.class.new_ticket(token, account_id, quote_id, payment_method_id, zipcode, license_plate, quantity,
142
+ time_unit, start_time)
143
+ end
144
+
145
+ private
146
+
147
+ def token
148
+ @token ||= self.class.auth(@username, @password).body['access_token']
149
+ end
150
+
151
+ def account_id
152
+ @account_id ||= self.class.account_id(token)
153
+ end
154
+ end
155
+ end
156
+ end
157
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ParkingTicket
4
- VERSION = '1.0.1'
4
+ VERSION = '1.0.40'
5
5
  end
@@ -4,33 +4,70 @@ require 'parking_ticket/configuration'
4
4
  require 'parking_ticket/version'
5
5
 
6
6
  # PayByPhone wrapper
7
- require 'client/pay_by_phone/configuration'
8
- require 'client/pay_by_phone/adapter'
9
- require 'client/pay_by_phone/request'
7
+ require 'clients/adapter'
8
+ require 'clients/pay_by_phone/adapter'
9
+ require 'clients/pay_by_phone/client'
10
10
 
11
11
  module ParkingTicket
12
12
  class Base
13
+ class << self
14
+ def valid_credentials?(adapter_name, username, password)
15
+ adapter = Clients::PayByPhone::Adapter if adapter_name == 'pay_by_phone'
16
+ raise Error, 'EasyPark will be handled in the next major release' if adapter_name == 'easy_park'
17
+ raise Error, "Unhandled adapter : #{adapter_name}" unless adapter
18
+
19
+ adapter.valid_credentials?(username, password)
20
+ end
21
+
22
+ def config
23
+ yield(self)
24
+ end
25
+
26
+ attr_accessor :ticket_format
27
+
28
+ def format_ticket(ticket)
29
+ return unless ticket_format
30
+
31
+ ticket_format.each_with_object({}) do |element, acumulator|
32
+ if element.is_a?(Hash)
33
+ original_key = element.keys.first
34
+ target_key = element.values.first
35
+ acumulator[target_key] = ticket[original_key]
36
+ else
37
+ acumulator[element] = ticket[element]
38
+ end
39
+ end
40
+ end
41
+ end
13
42
  attr_reader :configuration
14
43
 
15
44
  class Error < StandardError
16
45
  end
17
46
 
18
- def initialize(adapter_name, configuration_attributes)
47
+ def initialize(adapter_name, username, password)
19
48
  @adapter_name = adapter_name
20
- @configuration_attributes = configuration_attributes
21
- @result = {}
49
+ @username = username
50
+ @password = password
22
51
  end
23
52
 
24
- def adapter
25
- @adapter ||= load_adapter!
53
+ def vehicles
54
+ adapter.vehicles
26
55
  end
27
56
 
28
- def renew
29
- adapter.renew unless current_ticket
57
+ def rate_options(zipcode, license_plate)
58
+ adapter.rate_options(zipcode, license_plate)
30
59
  end
31
60
 
32
- def current_ticket
33
- adapter.current_ticket
61
+ def running_ticket(license_plate, zipcode)
62
+ adapter.running_ticket(license_plate, zipcode)
63
+ end
64
+
65
+ def payment_methods
66
+ adapter.payment_methods
67
+ end
68
+
69
+ def new_ticket(license_plate, zipcode, rate_option_id, quantity, time_unit, payment_method_id)
70
+ adapter.new_ticket(license_plate, zipcode, rate_option_id, quantity, time_unit, payment_method_id)
34
71
  end
35
72
 
36
73
  private
@@ -43,24 +80,15 @@ module ParkingTicket
43
80
  end
44
81
 
45
82
  def prepare_pay_by_phone_adapter!
46
- configuration = pay_by_phone_configuration
47
- return Client::PayByPhone::Adapter.new(configuration) if configuration.completed?
48
-
49
- raise Error, 'Uncompleted configuration'
50
- end
51
-
52
- def pay_by_phone_configuration
53
- Client::PayByPhone::Configuration.new do |config|
54
- config.username = @configuration_attributes[:username]
55
- config.password = @configuration_attributes[:password]
56
- config.license_plate = @configuration_attributes[:license_plate]
57
- config.zipcode = @configuration_attributes[:zipcode]
58
- config.card_number = @configuration_attributes[:card_number]
59
- end
83
+ Clients::PayByPhone::Adapter.new(@username, @password)
60
84
  end
61
85
 
62
86
  def prepare_easy_park_adapter!
63
87
  raise Error, 'EasyPark will be handled in the next major release'
64
88
  end
89
+
90
+ def adapter
91
+ @adapter ||= load_adapter!
92
+ end
65
93
  end
66
94
  end
Binary file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parking_ticket
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.40
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Ecrepont
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-01-16 00:00:00.000000000 Z
11
+ date: 2023-02-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -40,13 +40,14 @@ files:
40
40
  - Rakefile
41
41
  - bin/console
42
42
  - bin/setup
43
- - lib/client/pay_by_phone/adapter.rb
44
- - lib/client/pay_by_phone/configuration.rb
45
- - lib/client/pay_by_phone/request.rb
43
+ - lib/clients/adapter.rb
44
+ - lib/clients/pay_by_phone/adapter.rb
45
+ - lib/clients/pay_by_phone/client.rb
46
46
  - lib/parking_ticket.rb
47
47
  - lib/parking_ticket/configuration.rb
48
48
  - lib/parking_ticket/version.rb
49
49
  - parking_ticket-1.0.0.gem
50
+ - parking_ticket-1.0.1.gem
50
51
  homepage: https://github.com/troptropcontent/parking_ticket
51
52
  licenses:
52
53
  - MIT
@@ -1,61 +0,0 @@
1
- module ParkingTicket
2
- module Client
3
- module PayByPhone
4
- class Adapter
5
- def initialize(configuration)
6
- @configuration = configuration
7
- end
8
-
9
- def covered?
10
- !!current_ticket
11
- end
12
-
13
- def current_ticket
14
- ticket = request.tickets(account_id).find do |ticket|
15
- ticket.dig('vehicle', 'licensePlate') == @configuration.license_plate
16
- end
17
-
18
- return unless ticket
19
-
20
- {
21
- starts_on: DateTime.parse(ticket['startTime']),
22
- ends_on: DateTime.parse(ticket['expireTime']),
23
- license_plate: ticket.dig('vehicle', 'licensePlate'),
24
- cost: ticket.dig('segments', 0, 'cost'),
25
- client: 'PayByPhone',
26
- client_ticket_id: ticket['parkingSessionId']
27
- }
28
- end
29
-
30
- def renew
31
- return if covered?
32
-
33
- quote = request.new_quote(rate_option_id, account_id)
34
- request.new_ticket(account_id, quote['parkingStartTime'], quote['quoteId'], payment_method_id)
35
- end
36
-
37
- private
38
-
39
- def request
40
- @request ||= Request.new(@configuration)
41
- end
42
-
43
- def account_id
44
- @account_id ||= request.accounts.dig(0, 'id')
45
- end
46
-
47
- def payment_method_id
48
- request.payment_methods['items'].find do |payment_method|
49
- payment_method['maskedCardNumber'] == @configuration.card_number
50
- end['id']
51
- end
52
-
53
- def rate_option_id
54
- request.rate_options(account_id).find do |rate_option|
55
- rate_option['type'] == 'RES' && rate_option['licensePlate'] == @configuration.license_plate
56
- end['rateOptionId']
57
- end
58
- end
59
- end
60
- end
61
- end
@@ -1,9 +0,0 @@
1
- module ParkingTicket
2
- module Client
3
- module PayByPhone
4
- class Configuration < ParkingTicket::Configuration
5
- attr_required :username, :password, :license_plate, :zipcode, :card_number
6
- end
7
- end
8
- end
9
- end
@@ -1,121 +0,0 @@
1
- require 'faraday'
2
- module ParkingTicket
3
- module Client
4
- module PayByPhone
5
- class Request
6
- def initialize(configuration)
7
- @configuration = configuration
8
- end
9
-
10
- def tickets(account_id)
11
- connection.get("/parking/accounts/#{account_id}/sessions?periodType=Current").body
12
- end
13
-
14
- def new_ticket(account_id, parking_start_time, quote_id, payment_method_id)
15
- connection.post(
16
- "/parking/accounts/#{account_id}/sessions/",
17
- {
18
- "expireTime": nil,
19
- "duration": {
20
- "quantity": '1',
21
- "timeUnit": 'days'
22
- },
23
- "licensePlate": @configuration.license_plate,
24
- "locationId": @configuration.zipcode,
25
- "rateOptionId": '75101',
26
- "startTime": parking_start_time,
27
- "quoteId": quote_id,
28
- "parkingAccountId": account_id,
29
- "paymentMethod": {
30
- "paymentMethodType": 'PaymentAccount',
31
- "payload": {
32
- "paymentAccountId": payment_method_id,
33
- "clientBrowserDetails": {
34
- "browserAcceptHeader": 'text/html',
35
- "browserColorDepth": '30',
36
- "browserJavaEnabled": 'false',
37
- "browserLanguage": 'fr-FR',
38
- "browserScreenHeight": '900',
39
- "browserScreenWidth": '1440',
40
- "browserTimeZone": '-60',
41
- "browserUserAgent": 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36'
42
- }
43
- }
44
- }
45
- }.to_json
46
- ).body
47
- end
48
-
49
- def accounts
50
- connection.get('/parking/accounts').body
51
- end
52
-
53
- def vehicles
54
- connection.get('/identity/profileservice/v1/members/vehicles/paybyphone').body
55
- end
56
-
57
- def rate_options(account_id)
58
- connection.get("/parking/locations/#{@configuration.zipcode}/rateOptions",
59
- {
60
- parkingAccountId: account_id,
61
- licensePlate: @configuration.license_plate
62
- }).body
63
- end
64
-
65
- def new_quote(rate_option_id, account_id)
66
- connection.get(
67
- "/parking/accounts/#{account_id}/quote",
68
- {
69
- locationId: @configuration.zipcode,
70
- licensePlate: @configuration.license_plate,
71
- rateOptionId: rate_option_id,
72
- durationTimeUnit: 'Days',
73
- durationQuantity: 1,
74
- isParkUntil: false,
75
- parkingAccountId: account_id
76
- }
77
- ).body
78
- end
79
-
80
- def member
81
- connection.get('/identity/profileservice/v1/members').body
82
- end
83
-
84
- def payment_methods
85
- connection.get('/payment/v3/accounts').body
86
- end
87
-
88
- def connection
89
- @connection ||= Faraday.new(
90
- url: 'https://consumer.paybyphoneapis.com',
91
- headers: {
92
- 'Content-Type' => 'application/json',
93
- 'Authorization' => "Bearer #{token}"
94
- }
95
- ) do |f|
96
- f.response :json
97
- end
98
- end
99
-
100
- def token
101
- conn = Faraday.new('https://auth.paybyphoneapis.com') do |f|
102
- f.response :json
103
- end
104
- conn.post(
105
- '/token',
106
- URI.encode_www_form({
107
- grant_type: 'password',
108
- username: @configuration.username,
109
- password: @configuration.password,
110
- client_id: 'paybyphone_web'
111
- }),
112
- {
113
- 'Accept' => 'application/json, text/plain, */*',
114
- 'X-Pbp-ClientType' => 'WebApp'
115
- }
116
- ).body['access_token']
117
- end
118
- end
119
- end
120
- end
121
- end