jbr 5.0.0 → 6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a01ddd16fc41518ff9cc7d18b61bdc2c0d9e419959c01fc7dd822473de08bade
4
- data.tar.gz: 3d60fe2c06fd056d0e61d83bca1e40ff6f61954994a061e858a60422b6546e12
3
+ metadata.gz: cabf4447471fd3556e99cc05251c04a201f6329864d98d0650ba8506ff1dcc0a
4
+ data.tar.gz: 8149a10d060f9c265c82a482a53c3eb5646fcb744e41bd8ee136a4eb6b3b3cc5
5
5
  SHA512:
6
- metadata.gz: 71b4e3faacce7acb0ea6d5a3eab5f1beea5f4534a416a16ed663d434299551b94375e3522f0152e6627a22340a7c098eaf464fdcec0012688fa07b0def98c9e8
7
- data.tar.gz: 99828c97615dd6357dd58f167ec05338b6595cbcf5206cbad1088f9e3d3a95665f08698add77b3aeb854d4e10c9a664f8b77467ac064c680ecdd409bc763e96f
6
+ metadata.gz: 770c8fe0d7556995d4484c51953aeb009f06046910d07a7153f1d40a302be2f65a510becbe5bf523375e927367bfe37acde4bc71382e4fe8807f14e0b9cb9c74
7
+ data.tar.gz: 4e479fa10591e9bee8d2cc1c30a79355329d1233410dde79f48a0d094944366ff61bcc6b4e9d582eed4f1bdab27d8b4a2650a8d3f04ac2f2611ad42eca515b56
data/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [6.0.0] - 2026-09-16
4
+
5
+ - [Breaking change] The vocabulary is `company` 3.0: `assigned_to` is `of`, so
6
+ `account.visits.of(technician)` is what `account.visits.assigned_to(technician)` was. Jobber
7
+ still narrows it in the one filter, and it still needs no Users scope. The pin is `~> 3.0`.
8
+
9
+ - [Note] `account.windows` -- the free time of a business -- raises `NotImplementedError` here,
10
+ and will until Jobber exposes the hours a business keeps. It does not today: the schema was
11
+ enumerated looking, and there is no `BusinessHours`, `WorkingHours`, `Shift` or `Weekday` type
12
+ of any kind, while `OnlineBookingConfiguration` is four fields and none of them is an hour.
13
+
14
+ - [Note] Every setting around those hours is there, on `requestSettings`:
15
+ `intervalDurationMinutes` is the grain, `earliestAvailabilityMinutes` the notice,
16
+ `bufferDurationMinutes` the padding either side of a job, `efficientSchedulingType` and
17
+ `maxDriveTimeMinutes` whether travel counts. A caller can work free time out from those and
18
+ the visits. Read them off the form that books, not the one marked default, whose
19
+ `bookingType` may be `NONE`.
20
+
3
21
  ## [5.0.0] - 2026-09-15
4
22
 
5
23
  - [Feature] A scope the app was never granted no longer raises. Jobber answers `An object of
data/README.md CHANGED
@@ -115,7 +115,7 @@ failing. What each reader here needs:
115
115
  | --- | --- |
116
116
  | `account.jobs`, `job.lines` | Jobs |
117
117
  | `job.location`, `location.customer`, `visit.job` | Jobs and Clients |
118
- | `account.visits`, `assigned_to` | Scheduled Items |
118
+ | `account.visits`, `of` | Scheduled Items |
119
119
  | `account.technicians`, `visit.technicians`, `includes(:technicians)` | Users |
120
120
  | `account.quotes` | Quotes |
121
121
  | `account.invoices` | Invoices |
@@ -125,7 +125,7 @@ Jobber files a visit under **Scheduled Items**, which is one object covering vis
125
125
  assessments, tasks and calendar events -- so there is no scope to add for the kinds of booked
126
126
  time this gem does not read yet.
127
127
 
128
- `assigned_to` is the one worth knowing: narrowing to a technician needs no Users, because
128
+ `of` is the one worth knowing: narrowing to a technician needs no Users, because
129
129
  Jobber does the narrowing and no user is ever selected. Reading *who* is on a visit is what
130
130
  needs it.
131
131
 
@@ -325,17 +325,40 @@ One technician's week is the visits in it narrowed to them:
325
325
 
326
326
  ```ruby
327
327
  monday = Date.today.beginning_of_week.in_time_zone
328
- account.visits.between(monday, monday + 1.week).assigned_to(technician).each do |visit|
328
+ account.visits.between(monday, monday + 1.week).of(technician).each do |visit|
329
329
  visit.starts_at, visit.ends_at, visit.job.id
330
330
  end
331
331
  ```
332
332
 
333
- Jobber narrows a list of visits by who is on it, so `assigned_to` puts the technician into the
333
+ Jobber narrows a list of visits by who is on it, so `of` puts the technician into the
334
334
  same filter as the window: nobody else's visits are answered, paged or paid for, and the crew
335
335
  is not read at all unless `includes(:technicians)` asks. The two narrowings land in the one
336
336
  filter, so a caller may ask for the week and the technician in either order.
337
337
 
338
- `assigned_to` therefore needs no Users scope. Reading *who* is on a visit does.
338
+ `of` therefore needs no Users scope. Reading *who* is on a visit does.
339
+
340
+ ## What Jobber cannot say
341
+
342
+ `account.windows` -- the free time of a business, which the vocabulary names -- raises
343
+ `NotImplementedError` here, and will go on doing so until Jobber exposes the hours a business
344
+ keeps.
345
+
346
+ It does not today. The whole schema was enumerated looking for it: there is no `BusinessHours`,
347
+ `WorkingHours`, `OperatingHours`, `Shift`, `Weekday` or `DayOfWeek` type of any kind, and
348
+ `OnlineBookingConfiguration` is four fields -- whether bookings are on, the URL, the embed
349
+ script, the id. Jobber's own booking page must know the hours; the API does not say them.
350
+
351
+ What it does say is every setting around them, on `requestSettings`:
352
+ `intervalDurationMinutes` is the grain an offer is cut to, `earliestAvailabilityMinutes` the
353
+ notice the business needs, `bufferDurationMinutes` the padding left either side of a job, and
354
+ `efficientSchedulingType` with `maxDriveTimeMinutes` whether travel is counted as well. Read
355
+ those beside the visits and a caller can work free time out for itself -- which is what the
356
+ missing reader would have done. Take the settings from the form that books, not the one marked
357
+ default: the default form may be a request form, whose `bookingType` is `NONE`.
358
+
359
+ Raising is deliberate rather than answering with none. An empty week and a fully booked one are
360
+ the same shape, so a caller reading none as none would quietly stop offering the business
361
+ altogether, with nothing in a log and no page looking wrong.
339
362
 
340
363
  A visit is still not all Jobber schedules. A task, an event and the two kinds of reminder sit
341
364
  on the same calendar and are read past unread, because Jobber's filter takes one kind and not
@@ -24,7 +24,7 @@ module Jbr
24
24
  # @param technician [Company::Technician] whoever the work is booked for.
25
25
  # @return [Visits] the same list, narrowed to what they are booked for.
26
26
  # @note Needs no Users scope: Jobber narrows, and no user is selected to do it.
27
- def assigned_to(technician) = narrowed(assignedTo: [ technician.id ])
27
+ def of(technician) = narrowed(assignedTo: [ technician.id ])
28
28
 
29
29
  # @return [Visits] the same list, narrowed to the stops of jobs, by Jobber rather than here.
30
30
  def for_jobs = narrowed(scheduleItemType: 'VISIT')
data/lib/jbr/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # A Ruby client for the Jobber API.
2
2
  module Jbr
3
3
  # The version of this gem.
4
- VERSION = '5.0.0'
4
+ VERSION = '6.0.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jbr
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.0
4
+ version: 6.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Claudio Baccigalupo
@@ -29,14 +29,14 @@ dependencies:
29
29
  requirements:
30
30
  - - "~>"
31
31
  - !ruby/object:Gem::Version
32
- version: '2.1'
32
+ version: '3.0'
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: '2.1'
39
+ version: '3.0'
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: minitest
42
42
  requirement: !ruby/object:Gem::Requirement