jbr 3.13.0 → 4.0.0
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 +4 -4
- data/.rubocop.yml +5 -0
- data/CHANGELOG.md +51 -0
- data/README.md +154 -167
- data/lib/graphql/client.rb +2 -6
- data/lib/graphql/throttled.rb +0 -9
- data/lib/jbr/account.rb +44 -15
- data/lib/jbr/authorizing.rb +43 -0
- data/lib/jbr/collection.rb +14 -0
- data/lib/jbr/collections/customers.rb +54 -0
- data/lib/jbr/collections/invoices.rb +18 -0
- data/lib/jbr/{jobs.rb → collections/jobs.rb} +6 -6
- data/lib/jbr/collections/leads.rb +30 -0
- data/lib/jbr/collections/locations.rb +47 -0
- data/lib/jbr/collections/quotes.rb +18 -0
- data/lib/jbr/{visits.rb → collections/visits.rb} +8 -8
- data/lib/jbr/error.rb +1 -1
- data/lib/jbr/errors/throttled.rb +6 -0
- data/lib/jbr/includable.rb +6 -8
- data/lib/jbr/listable.rb +12 -34
- data/lib/jbr/mock/account.rb +25 -7
- data/lib/jbr/mock/invoice.rb +7 -11
- data/lib/jbr/mock/invoices.rb +7 -0
- data/lib/jbr/mock/jobs.rb +10 -6
- data/lib/jbr/mock/leads.rb +7 -0
- data/lib/jbr/mock/quote.rb +3 -8
- data/lib/jbr/mock/quotes.rb +7 -0
- data/lib/jbr/mock/visit.rb +3 -19
- data/lib/jbr/mock/visits.rb +9 -5
- data/lib/jbr/mock.rb +16 -3
- data/lib/jbr/phone.rb +5 -8
- data/lib/jbr/querying.rb +57 -0
- data/lib/jbr/reader.rb +9 -0
- data/lib/jbr/refreshing.rb +0 -8
- data/lib/jbr/resources/customer.rb +23 -0
- data/lib/jbr/resources/invoice.rb +29 -0
- data/lib/jbr/resources/job.rb +20 -0
- data/lib/jbr/resources/lead.rb +7 -0
- data/lib/jbr/resources/line.rb +15 -0
- data/lib/jbr/resources/location.rb +31 -0
- data/lib/jbr/resources/quote.rb +15 -0
- data/lib/jbr/resources/visit.rb +17 -0
- data/lib/jbr/version.rb +1 -1
- data/lib/jbr.rb +37 -46
- metadata +39 -28
- data/lib/jbr/client.rb +0 -98
- data/lib/jbr/cliental.rb +0 -14
- data/lib/jbr/invoice.rb +0 -43
- data/lib/jbr/itemized.rb +0 -9
- data/lib/jbr/job.rb +0 -40
- data/lib/jbr/line_item.rb +0 -44
- data/lib/jbr/mock/client.rb +0 -17
- data/lib/jbr/mock/job.rb +0 -31
- data/lib/jbr/mock/line_item.rb +0 -16
- data/lib/jbr/mock/oauth.rb +0 -22
- data/lib/jbr/mock/property.rb +0 -19
- data/lib/jbr/mock/request.rb +0 -12
- data/lib/jbr/mock/url.rb +0 -9
- data/lib/jbr/mocking.rb +0 -30
- data/lib/jbr/named.rb +0 -9
- data/lib/jbr/oauth.rb +0 -94
- data/lib/jbr/properted.rb +0 -17
- data/lib/jbr/property.rb +0 -93
- data/lib/jbr/quote.rb +0 -25
- data/lib/jbr/request.rb +0 -37
- data/lib/jbr/resource.rb +0 -26
- data/lib/jbr/retriable.rb +0 -20
- data/lib/jbr/url.rb +0 -16
- data/lib/jbr/visit.rb +0 -24
- /data/lib/jbr/{refused.rb → errors/refused.rb} +0 -0
data/lib/jbr/request.rb
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
module Jbr
|
|
2
|
-
# A lead on a Jobber user's board: work someone asked them for.
|
|
3
|
-
class Request < Resource
|
|
4
|
-
# The mutation that opens a request against a client and a property.
|
|
5
|
-
CREATE = <<~GRAPHQL
|
|
6
|
-
mutation($input: RequestCreateInput!) {
|
|
7
|
-
requestCreate(input: $input) { request { id property { id } } userErrors { message } }
|
|
8
|
-
}
|
|
9
|
-
GRAPHQL
|
|
10
|
-
|
|
11
|
-
# @return [String, nil] the client the request was opened against.
|
|
12
|
-
attr_reader :client_id
|
|
13
|
-
|
|
14
|
-
# Create a lead in Jobber associated to a new or existing client, matched by phone.
|
|
15
|
-
# @return [String] the ID of the newly created lead.
|
|
16
|
-
# @param params [Hash] the attributes of the lead
|
|
17
|
-
# @option params [String] :first_name the client’s first name
|
|
18
|
-
# @option params [String] :last_name the client’s last name
|
|
19
|
-
# @option params [String] :phone the client’s phone number
|
|
20
|
-
# @option params [<String, nil>] :email the client’s email address
|
|
21
|
-
# @option params [String] :title the reason why the lead is created
|
|
22
|
-
# @option params [String] :instructions a comment about the lead
|
|
23
|
-
def create(params = {})
|
|
24
|
-
client = @oauth.clients.create_with(params).find_or_create_by(phone: params[:phone])
|
|
25
|
-
@client_id = client.id
|
|
26
|
-
@property_id = client.property_id
|
|
27
|
-
|
|
28
|
-
input = {
|
|
29
|
-
clientId: @client_id, title: params[:title], propertyId: @property_id,
|
|
30
|
-
assessment: { instructions: params[:instructions] },
|
|
31
|
-
}
|
|
32
|
-
output = @oauth.query CREATE, variables: { input: input }
|
|
33
|
-
@id = output.dig 'requestCreate', 'request', 'id'
|
|
34
|
-
self
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|
data/lib/jbr/resource.rb
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
module Jbr
|
|
2
|
-
# What every Jobber resource shares: the node Jobber answered with, the credentials it was
|
|
3
|
-
# read through, and what a list of them was asked and narrowed to.
|
|
4
|
-
class Resource
|
|
5
|
-
# @param oauth [OAuth] the credentials to reach Jobber with, where reaching it is needed.
|
|
6
|
-
# @param node [Hash] the record as Jobber answered it.
|
|
7
|
-
# @param includes [Hash] what a list was asked to bring back beside its records.
|
|
8
|
-
# @param filter [Hash] what a list was narrowed to, in the shape Jobber filters by.
|
|
9
|
-
def initialize(oauth: nil, node: {}, includes: {}, filter: nil)
|
|
10
|
-
@oauth = oauth
|
|
11
|
-
@node = node
|
|
12
|
-
@id = node['id']
|
|
13
|
-
@includes = includes
|
|
14
|
-
@filter = filter
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
# @return [String, nil] the Jobber ID, from the node it came in or once one was created.
|
|
18
|
-
attr_reader :id
|
|
19
|
-
|
|
20
|
-
private
|
|
21
|
-
|
|
22
|
-
# @return [Time, nil] what Jobber answered under a key, as a time. An empty answer is no
|
|
23
|
-
# answer: Time.iso8601 raises on one, where nothing at all it simply has none of.
|
|
24
|
-
def time(key) = (Time.iso8601 @node[key] if @node[key].present?)
|
|
25
|
-
end
|
|
26
|
-
end
|
data/lib/jbr/retriable.rb
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
module Jbr
|
|
2
|
-
# Jobber refusing a query over what it costs rather than over anything about the query. The
|
|
3
|
-
# bucket it is priced against refills, so the same question asked later is answered.
|
|
4
|
-
class Retriable < Error
|
|
5
|
-
# @param message [String] what Jobber said, with the numbers it said it with.
|
|
6
|
-
# @param cost [Hash] the `requestedQueryCost` and the `throttleStatus` beside it.
|
|
7
|
-
def initialize(message, cost = {})
|
|
8
|
-
super message
|
|
9
|
-
status = cost['throttleStatus'].to_h
|
|
10
|
-
@cost = cost['requestedQueryCost']
|
|
11
|
-
@available = status['currentlyAvailable']
|
|
12
|
-
@maximum = status['maximumAvailable']
|
|
13
|
-
@restore_rate = status['restoreRate']
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
# What the query would have cost, the budget it was priced against, and how fast that
|
|
17
|
-
# budget refills. A cost above the maximum is one no waiting will pay for.
|
|
18
|
-
attr_reader :cost, :available, :maximum, :restore_rate
|
|
19
|
-
end
|
|
20
|
-
end
|
data/lib/jbr/url.rb
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
module Jbr
|
|
2
|
-
# The page a Jobber user authorizes the app on.
|
|
3
|
-
class URL
|
|
4
|
-
# @param params [Hash] the +redirect_uri+ and +state+ to come back with.
|
|
5
|
-
# @return [String] the URL to send the user to.
|
|
6
|
-
def self.for(params = {})
|
|
7
|
-
uri = URI 'https://api.getjobber.com/api/oauth/authorize'
|
|
8
|
-
uri.query = URI.encode_www_form params.merge(response_type: 'code', client_id: client_id)
|
|
9
|
-
uri.to_s
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
# @return [String, nil] the client ID of the app being authorized.
|
|
13
|
-
def self.client_id = ENV['JOBBER_CLIENT_ID']
|
|
14
|
-
private_class_method :client_id
|
|
15
|
-
end
|
|
16
|
-
end
|
data/lib/jbr/visit.rb
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
module Jbr
|
|
2
|
-
# One stop at a property: when the work on a job is scheduled to happen.
|
|
3
|
-
class Visit < Resource
|
|
4
|
-
include Cliental, Named, Properted
|
|
5
|
-
|
|
6
|
-
# @return [String, nil] what the visit is called.
|
|
7
|
-
def title = @node['title']
|
|
8
|
-
|
|
9
|
-
# @return [String, nil] the ID of the job the visit belongs to.
|
|
10
|
-
def job_id = @node.dig 'job', 'id'
|
|
11
|
-
|
|
12
|
-
# @return [Boolean, nil] whether the visit takes the whole day rather than an hour of it.
|
|
13
|
-
def all_day? = @node['allDay']
|
|
14
|
-
|
|
15
|
-
# @return [Boolean, nil] whether the client has confirmed the visit.
|
|
16
|
-
def client_confirmed? = @node['clientConfirmed']
|
|
17
|
-
|
|
18
|
-
# @return [Time, nil] the visit start time
|
|
19
|
-
def starts_at = time 'startAt'
|
|
20
|
-
|
|
21
|
-
# @return [Time, nil] the visit end time
|
|
22
|
-
def ends_at = time 'endAt'
|
|
23
|
-
end
|
|
24
|
-
end
|
|
File without changes
|