printavo-ruby 0.5.2 → 0.6.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/docs/CHANGELOG.md +25 -0
- data/docs/TODO.md +207 -44
- data/lib/printavo/client.rb +12 -0
- data/lib/printavo/models/account.rb +14 -0
- data/lib/printavo/models/contact.rb +17 -0
- data/lib/printavo/models/invoice.rb +42 -0
- data/lib/printavo/resources/account.rb +25 -0
- data/lib/printavo/resources/contacts.rb +57 -0
- data/lib/printavo/resources/invoices.rb +61 -0
- data/lib/printavo/version.rb +1 -1
- data/lib/printavo.rb +6 -0
- metadata +8 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3563777c538165a00ca4888be9d489c6a0e9b14542dac6d02a18b60894826f7d
|
|
4
|
+
data.tar.gz: ceb47bf69ff0dc7f48888d4fee3f601aa621015f8028e6dd0af31e2037b36749
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b266887065b5f727b6f9660557ce37d7ab64b53f23033f5c64c678cae919f00cd21e169fee17177bce7e873fdcc9d978307a3254e20de0224aab4b8e9c462d97
|
|
7
|
+
data.tar.gz: 4d1c944ca7283bab4e45dfe3cde0ddc6acf3ea35a167ee7b49574b6f7e367fff77a833253976605e2f8219aea932d5056b04004fcb55553cd4975bdfe853b3fe
|
data/docs/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,31 @@ All notable changes to this project will be documented in this file.
|
|
|
6
6
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
7
7
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
8
8
|
|
|
9
|
+
## [0.6.0] - 2026-03-30
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- `Printavo::Contact` model (`id`, `first_name`, `last_name`, `full_name`, `email`, `phone`, `fax`)
|
|
13
|
+
- `Contacts` resource: `find(id)`, `create(**input)`, `contactCreate` mutation,
|
|
14
|
+
`update(id, **input)`, `contactUpdate` mutation
|
|
15
|
+
- `Printavo::Invoice` model (`id`, `nickname`, `total`, `amount_paid`,
|
|
16
|
+
`amount_outstanding`, `paid_in_full?`, `invoice_at`, `payment_due_at`,
|
|
17
|
+
`status`, `status_key`, `status?`, `contact`)
|
|
18
|
+
- `Invoices` resource: `all`, `find(id)`, `update(id, **input)` (`invoiceUpdate` mutation);
|
|
19
|
+
note: invoices are promoted from quotes, so no `create` — use `client.orders.create`
|
|
20
|
+
- `Printavo::Account` model (`id`, `company_name`, `company_email`, `phone`,
|
|
21
|
+
`website`, `logo_url`, `locale`)
|
|
22
|
+
- `Account` resource: singleton `find` — no ID argument, returns the account
|
|
23
|
+
associated with the current API credentials
|
|
24
|
+
- `client.contacts`, `client.invoices`, `client.account` entry points on `Printavo::Client`
|
|
25
|
+
- 10 new `.graphql` files under `lib/printavo/graphql/` (contacts/find, create, update;
|
|
26
|
+
invoices/all, find, update; account/find)
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
- `spec/support/factories.rb` split into 9 domain files under `spec/support/factories/`
|
|
30
|
+
(`account`, `contact`, `customer`, `graphql`, `inquiry`, `invoice`, `job`, `order`, `status`)
|
|
31
|
+
- `spec/spec_helper.rb` loads factory files via `Dir` glob; `config.include Factories` moved here
|
|
32
|
+
- Removed `Metrics/ModuleLength` exclusion from `.rubocop.yml` — no longer needed
|
|
33
|
+
|
|
9
34
|
## [0.5.2] - 2026-03-30
|
|
10
35
|
|
|
11
36
|
### Changed
|
data/docs/TODO.md
CHANGED
|
@@ -69,6 +69,7 @@ Full task list for `printavo-ruby` across all versions. Checked items are shippe
|
|
|
69
69
|
- [x] Extract 17 GraphQL heredocs into external `.graphql` files (`lib/printavo/graphql/<resource>/<op>.graphql`)
|
|
70
70
|
- [x] `docs/` consolidation — `CHANGELOG.md`, `CONTRIBUTING.md`, `FUTURE.md`, `CACHING.md`
|
|
71
71
|
- [x] `docs/CACHING.md` — nine caching strategy patterns for rate-limit-aware consumers
|
|
72
|
+
- [x] Split `spec/support/factories.rb` monolith into 9 domain files under `spec/support/factories/`
|
|
72
73
|
|
|
73
74
|
---
|
|
74
75
|
|
|
@@ -86,38 +87,166 @@ Resources and mutations present in the Printavo V2 GraphQL API that are not yet
|
|
|
86
87
|
wrapped by a resource class. Raw GraphQL access works for all of these today via
|
|
87
88
|
`client.graphql.query(...)` — these tasks add first-class resource support.
|
|
88
89
|
|
|
89
|
-
###
|
|
90
|
+
### Embedded / Infrastructure Types (no standalone resource needed)
|
|
91
|
+
|
|
92
|
+
These types appear in the schema but are sub-objects, pagination wrappers, or
|
|
93
|
+
return values — they are exposed via model field accessors, not separate resources.
|
|
94
|
+
|
|
95
|
+
- `*Connection` / `*Edge` (all variants) — GraphQL pagination wrappers; handled by `Printavo::Page`
|
|
96
|
+
- `Address`, `BillingAddress`, `CustomerAddress`, `MerchAddress`, `CustomAddress` — embedded address shapes
|
|
97
|
+
- `Avatar` — embedded in `User`
|
|
98
|
+
- `CatalogInformation`, `InvoiceInformation` — embedded in `Account`
|
|
99
|
+
- `DeletedID` — return type for delete mutations
|
|
100
|
+
- `EmailMessage`, `TextMessage` — message subtypes under `Thread`
|
|
101
|
+
- `Feature`, `FeatureRestriction` — embedded in `Account.features`
|
|
102
|
+
- `LineItemEnabledColumns`, `LineItemGroupSize`, `LineItemPriceReceipt`, `LineItemSizeCount` — embedded in `LineItemGroup` / `LineItem`
|
|
103
|
+
- `LoggedIn` — auth response type
|
|
104
|
+
- `MerchOrderDelivery`, `MerchStoreSummary` — embedded in `MerchOrder` / `MerchStore`
|
|
105
|
+
- `MessageAttachment` — embedded in `Thread` messages
|
|
106
|
+
- `ObjectTimestamps` — `createdAt` / `updatedAt` on all objects
|
|
107
|
+
- `OrderUnionConnection` / `OrderUnionEdge` — union pagination for `Quote | Invoice`; handled via inline fragments
|
|
108
|
+
- `PageInfo` — cursor pagination metadata; handled by `Printavo::Page`
|
|
109
|
+
- `PaymentRequestDetail` — embedded in `PaymentRequest`
|
|
110
|
+
- `Permission` — embedded in `User`
|
|
111
|
+
- `Personalization` — size/color breakdown embedded in `LineItem` / `Imprint`
|
|
112
|
+
- `PricingMatrixCell`, `PricingMatrixColumn` — sub-objects of `PricingMatrix`
|
|
113
|
+
- `ProductCatalog` — configuration embedded in `Account`
|
|
114
|
+
- `Social` — social media links embedded in `Account`
|
|
115
|
+
- `ThreadSummary` — preview summary embedded on orders; not a standalone query
|
|
116
|
+
- `TransactionDetails`, `TransactionUnionConnection`, `TransactionUnionEdge` — embedded / pagination wrappers
|
|
90
117
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
### Account ✅
|
|
121
|
+
|
|
122
|
+
- [x] `Printavo::Account` model (shop-level info: name, address, phone, logo)
|
|
123
|
+
- [x] `Account` resource: `find` (singleton — no ID needed)
|
|
124
|
+
- [x] `account` query
|
|
125
|
+
|
|
126
|
+
### Contacts ✅
|
|
127
|
+
|
|
128
|
+
- [x] `Printavo::Contact` model (`id`, `firstName`, `lastName`, `email`, `phone`)
|
|
129
|
+
- [x] `Contacts` resource: `find(id)`, `create`, `update`
|
|
130
|
+
- [x] `contact` query (contacts are distinct from the customer's `primaryContact`)
|
|
131
|
+
|
|
132
|
+
### Invoices ✅
|
|
133
|
+
|
|
134
|
+
- [x] `Printavo::Invoice` model (mirrors Order; has `amountPaid`, `amountOutstanding`, `paidInFull?`)
|
|
135
|
+
- [x] `Invoices` resource: `all`, `find(id)`, `update`
|
|
136
|
+
- [x] `client.invoices` entry point on `Printavo::Client`
|
|
137
|
+
|
|
138
|
+
### Approvals
|
|
94
139
|
|
|
95
|
-
|
|
140
|
+
- [ ] `Printavo::Approval` model (`id`, `status`, `approvedAt`, `contact`)
|
|
141
|
+
- [ ] `Printavo::ApprovalRequest` model (`id`, `sentAt`, `expiresAt`, `approval`)
|
|
142
|
+
- [ ] `Approvals` resource: `all(order_id:)`, `find(id)`
|
|
143
|
+
- [ ] `approvalCreate`, `approvalUpdate` mutations
|
|
96
144
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
- [ ] `
|
|
145
|
+
### Categories
|
|
146
|
+
|
|
147
|
+
- [ ] `Printavo::Category` model (`id`, `name`)
|
|
148
|
+
- [ ] `Categories` resource: `all`, `find(id)` — reference data for products/line items
|
|
149
|
+
|
|
150
|
+
### Contractor Profiles
|
|
151
|
+
|
|
152
|
+
- [ ] `Printavo::ContractorProfile` model (`id`, `name`, `email`)
|
|
153
|
+
- [ ] `ContractorProfiles` resource: `all`, `find(id)` — contractors assignable to invoices
|
|
154
|
+
|
|
155
|
+
### Delivery Methods
|
|
156
|
+
|
|
157
|
+
- [ ] `Printavo::DeliveryMethod` model (`id`, `name`)
|
|
158
|
+
- [ ] `DeliveryMethods` resource: `all` — reference data (pickup, ship, etc.)
|
|
159
|
+
|
|
160
|
+
### Delete Mutations
|
|
161
|
+
|
|
162
|
+
- [ ] `contactDelete(id:)`
|
|
163
|
+
- [ ] `customerDelete(id:)`
|
|
164
|
+
- [ ] `quoteDelete(id:)` / `invoiceDelete(id:)`
|
|
165
|
+
- [ ] `lineItemDelete(id:)`
|
|
166
|
+
- [ ] `taskDelete(id:)`
|
|
167
|
+
|
|
168
|
+
### Email Templates
|
|
169
|
+
|
|
170
|
+
- [ ] `Printavo::EmailTemplate` model (`id`, `name`, `subject`, `body`)
|
|
171
|
+
- [ ] `EmailTemplates` resource: `all`, `find(id)`
|
|
172
|
+
|
|
173
|
+
### Expenses
|
|
174
|
+
|
|
175
|
+
- [ ] `Printavo::Expense` model (`id`, `name`, `amount`, `category`)
|
|
176
|
+
- [ ] `Expenses` resource: `all(order_id:)`, `find(id)`, `create`, `update`
|
|
177
|
+
- [ ] `expenseCreate`, `expenseUpdate` mutations
|
|
178
|
+
|
|
179
|
+
### Fees
|
|
180
|
+
|
|
181
|
+
- [ ] `Printavo::Fee` model (`id`, `name`, `amount`, `taxable`)
|
|
182
|
+
- [ ] `Fees` resource: `all(order_id:)`, `find(id)`, `create`, `update`
|
|
183
|
+
- [ ] `feeCreate`, `feeUpdate` mutations
|
|
184
|
+
|
|
185
|
+
### Imprints
|
|
186
|
+
|
|
187
|
+
- [ ] `Printavo::Imprint` model (`id`, `name`, `position`, `colors`, `personalization`)
|
|
188
|
+
- [ ] `Imprints` resource: `all(line_item_group_id:)`, `find(id)`, `create`, `update`
|
|
189
|
+
- [ ] `imprintCreate`, `imprintUpdate` mutations
|
|
100
190
|
|
|
101
191
|
### Line Item Groups
|
|
102
192
|
|
|
103
|
-
- [ ] `Printavo::LineItemGroup` model (`id`, `name`, `description`)
|
|
104
|
-
- [ ] `LineItemGroups` resource: `all(order_id:)`, `find(id)`
|
|
105
|
-
- [ ] `
|
|
193
|
+
- [ ] `Printavo::LineItemGroup` model (`id`, `name`, `description`, `sizes`, `enabled_columns`)
|
|
194
|
+
- [ ] `LineItemGroups` resource: `all(order_id:)`, `find(id)`, `create`, `update`
|
|
195
|
+
- [ ] `lineItemGroupCreate`, `lineItemGroupUpdate` mutations
|
|
106
196
|
|
|
107
197
|
### Merch
|
|
108
198
|
|
|
109
|
-
- [ ] `Printavo::MerchStore` model
|
|
110
|
-
- [ ] `Printavo::MerchOrder` model
|
|
199
|
+
- [ ] `Printavo::MerchStore` model (`id`, `name`, `url`, `summary`)
|
|
200
|
+
- [ ] `Printavo::MerchOrder` model (`id`, `status`, `delivery`, `contact`)
|
|
111
201
|
- [ ] `MerchStores` resource: `all`, `find(id)`
|
|
112
202
|
- [ ] `MerchOrders` resource: `all`, `find(id)`
|
|
113
203
|
- [ ] `client.merch_stores` / `client.merch_orders` entry points
|
|
114
204
|
|
|
115
|
-
###
|
|
205
|
+
### Mockups & Production Files
|
|
116
206
|
|
|
117
|
-
- [ ] `Printavo::
|
|
118
|
-
- [ ] `
|
|
119
|
-
- [ ]
|
|
120
|
-
- [ ]
|
|
207
|
+
- [ ] `Printavo::Mockup` model (`id`, `url`, `position`, `createdAt`)
|
|
208
|
+
- [ ] `Printavo::ProductionFile` model (`id`, `url`, `filename`, `createdAt`)
|
|
209
|
+
- [ ] `Mockups` resource: `all(order_id:)`, `find(id)`, `create`
|
|
210
|
+
- [ ] `ProductionFiles` resource: `all(order_id:)`, `find(id)`, `create`
|
|
211
|
+
|
|
212
|
+
### Payments
|
|
213
|
+
|
|
214
|
+
- [ ] `Printavo::Payment` model (`id`, `amount`, `method`, `paidAt`)
|
|
215
|
+
- [ ] `Printavo::PaymentDispute` model (`id`, `amount`, `reason`, `status`)
|
|
216
|
+
- [ ] `Printavo::PaymentRequest` model (`id`, `amount`, `sentAt`, `paidAt`, `details`)
|
|
217
|
+
- [ ] `Printavo::PaymentTerm` model (`id`, `name`, `netDays`) — reference data
|
|
218
|
+
- [ ] `Payments` resource: `all(order_id:)`, `find(id)`
|
|
219
|
+
- [ ] `PaymentRequests` resource: `all(order_id:)`, `find(id)`, `create`
|
|
220
|
+
- [ ] `PaymentTerms` resource: `all` — reference data
|
|
221
|
+
- [ ] `paymentRequestCreate` mutation
|
|
222
|
+
|
|
223
|
+
### Preset Tasks
|
|
224
|
+
|
|
225
|
+
- [ ] `Printavo::PresetTask` model (`id`, `body`, `dueOffsetDays`, `assignee`)
|
|
226
|
+
- [ ] `Printavo::PresetTaskGroup` model (`id`, `name`, `tasks`)
|
|
227
|
+
- [ ] `PresetTaskGroups` resource: `all`, `find(id)`, `create`, `update`
|
|
228
|
+
- [ ] `presetTaskGroupCreate`, `presetTaskGroupUpdate` mutations
|
|
229
|
+
|
|
230
|
+
### Product Catalog & Pricing
|
|
231
|
+
|
|
232
|
+
- [ ] `Printavo::Product` model (`id`, `name`, `sku`, `description`)
|
|
233
|
+
- [ ] `Printavo::PricingMatrix` model (`id`, `name`, `cells`, `columns`)
|
|
234
|
+
- [ ] `Products` resource: `all`, `find(id)`
|
|
235
|
+
- [ ] `PricingMatrices` resource: `all`, `find(id)`
|
|
236
|
+
|
|
237
|
+
### Purchase Orders
|
|
238
|
+
|
|
239
|
+
- [ ] `Printavo::PurchaseOrder` model (`id`, `vendorName`, `total`, `sentAt`)
|
|
240
|
+
- [ ] `Printavo::PoLineItem` model (`id`, `name`, `quantity`, `price`)
|
|
241
|
+
- [ ] `PurchaseOrders` resource: `all`, `find(id)`, `create`, `update`
|
|
242
|
+
- [ ] `purchaseOrderCreate`, `purchaseOrderUpdate` mutations
|
|
243
|
+
|
|
244
|
+
### Refunds & Returns
|
|
245
|
+
|
|
246
|
+
- [ ] `Printavo::Refund` model (`id`, `amount`, `reason`, `createdAt`)
|
|
247
|
+
- [ ] `Printavo::Return` model (`id`, `quantity`, `reason`, `createdAt`)
|
|
248
|
+
- [ ] `Refunds` resource: `all(order_id:)`, `find(id)`, `create`
|
|
249
|
+
- [ ] `refundCreate` mutation
|
|
121
250
|
|
|
122
251
|
### Tasks
|
|
123
252
|
|
|
@@ -127,62 +256,96 @@ wrapped by a resource class. Raw GraphQL access works for all of these today via
|
|
|
127
256
|
|
|
128
257
|
### Threads (Messages)
|
|
129
258
|
|
|
130
|
-
- [ ] `Printavo::Thread` model (`id`, `body`, `author`, `createdAt`)
|
|
259
|
+
- [ ] `Printavo::Thread` model (`id`, `body`, `author`, `createdAt`, `attachments`)
|
|
131
260
|
- [ ] `Threads` resource: `all(order_id:)`, `find(id)`, `create`
|
|
132
261
|
- [ ] `threadCreate` mutation
|
|
133
262
|
|
|
134
|
-
###
|
|
263
|
+
### Transactions
|
|
135
264
|
|
|
136
|
-
- [ ] `Printavo::
|
|
137
|
-
- [ ] `
|
|
138
|
-
- [ ] `account` query
|
|
265
|
+
- [ ] `Printavo::Transaction` model (`id`, `amount`, `kind`, `createdAt`, `details`)
|
|
266
|
+
- [ ] `Transactions` resource: `all(order_id:)`, `find(id)`
|
|
139
267
|
|
|
140
|
-
###
|
|
268
|
+
### Types of Work
|
|
141
269
|
|
|
142
|
-
- [ ] `
|
|
143
|
-
- [ ] `
|
|
144
|
-
- [ ] `lineItemDelete(id:)`
|
|
145
|
-
- [ ] `taskDelete(id:)`
|
|
270
|
+
- [ ] `Printavo::TypeOfWork` model (`id`, `name`)
|
|
271
|
+
- [ ] `TypesOfWork` resource: `all` — reference data for order categorization
|
|
146
272
|
|
|
147
|
-
###
|
|
273
|
+
### Users
|
|
148
274
|
|
|
149
|
-
- [ ] `Printavo::
|
|
150
|
-
- [ ] `
|
|
151
|
-
|
|
275
|
+
- [ ] `Printavo::User` model (`id`, `firstName`, `lastName`, `email`, `avatar`, `permissions`)
|
|
276
|
+
- [ ] `Users` resource: `all`, `find(id)` — shop staff members
|
|
277
|
+
|
|
278
|
+
### Vendors
|
|
279
|
+
|
|
280
|
+
- [ ] `Printavo::Vendor` model (`id`, `name`, `email`, `phone`)
|
|
281
|
+
- [ ] `Vendors` resource: `all`, `find(id)`, `create`, `update`
|
|
282
|
+
- [ ] `vendorCreate`, `vendorUpdate` mutations
|
|
152
283
|
|
|
153
284
|
---
|
|
154
285
|
|
|
155
286
|
## Planned Versions
|
|
156
287
|
|
|
157
|
-
### v0.6.0 — Invoices, Contacts &
|
|
288
|
+
### v0.6.0 — Invoices, Contacts & Account ✅
|
|
158
289
|
|
|
159
|
-
- [
|
|
160
|
-
- [
|
|
161
|
-
- [
|
|
162
|
-
- [ ] Analytics/Reporting resource: revenue, job counts, customer activity, turnaround times
|
|
163
|
-
- [ ] Community burn-in — gather feedback on 0.5.x API surface
|
|
290
|
+
- [x] `Invoices` resource (`all`, `find`, `update`)
|
|
291
|
+
- [x] `Contacts` resource (`find`, `create`, `update`)
|
|
292
|
+
- [x] `Account` resource (singleton `find`)
|
|
164
293
|
|
|
165
294
|
### v0.7.0 — Transactions, Tasks & Threads
|
|
166
295
|
|
|
167
296
|
- [ ] `Transactions` resource (`all`, `find`)
|
|
168
297
|
- [ ] `Tasks` resource (`all`, `find`, `create`, `update`, `complete`)
|
|
169
298
|
- [ ] `Threads` resource (`all`, `find`, `create`)
|
|
170
|
-
- [ ] Delete mutations
|
|
299
|
+
- [ ] Delete mutations: `contactDelete`, `customerDelete`, `quoteDelete`, `invoiceDelete`, `lineItemDelete`, `taskDelete`
|
|
300
|
+
|
|
301
|
+
### v0.8.0 — Order Structure: Line Item Groups, Imprints & Fees
|
|
171
302
|
|
|
172
|
-
|
|
303
|
+
- [ ] `LineItemGroups` resource (`all`, `find`, `create`, `update`)
|
|
304
|
+
- [ ] `Imprints` resource (`all`, `find`, `create`, `update`)
|
|
305
|
+
- [ ] `Fees` resource (`all`, `find`, `create`, `update`)
|
|
306
|
+
- [ ] `Expenses` resource (`all`, `find`, `create`, `update`)
|
|
307
|
+
|
|
308
|
+
### v0.9.0 — Merch, Products & Pricing
|
|
173
309
|
|
|
174
310
|
- [ ] `MerchStores` + `MerchOrders` resources
|
|
175
|
-
- [ ] `
|
|
176
|
-
- [ ] `
|
|
311
|
+
- [ ] `Products` resource + `PricingMatrices` resource
|
|
312
|
+
- [ ] `Categories` resource (reference data)
|
|
313
|
+
|
|
314
|
+
### v0.10.0 — Financial: Payments, Purchase Orders & Refunds
|
|
315
|
+
|
|
316
|
+
- [ ] `Payments` resource (`all`, `find`)
|
|
317
|
+
- [ ] `PaymentRequests` resource (`all`, `find`, `create`)
|
|
318
|
+
- [ ] `PaymentTerms` resource (`all`) — reference data
|
|
319
|
+
- [ ] `PurchaseOrders` + `PoLineItems` resources
|
|
320
|
+
- [ ] `Refunds` + `Returns` resources
|
|
321
|
+
|
|
322
|
+
### v0.11.0 — Workflow: Approvals & Preset Tasks
|
|
323
|
+
|
|
324
|
+
- [ ] `Approvals` resource (`all`, `find`, `create`)
|
|
325
|
+
- [ ] `PresetTaskGroups` resource (`all`, `find`, `create`, `update`)
|
|
326
|
+
|
|
327
|
+
### v0.12.0 — Files, Media & Communication
|
|
328
|
+
|
|
329
|
+
- [ ] `ProductionFiles` resource (`all`, `find`, `create`)
|
|
330
|
+
- [ ] `Mockups` resource (`all`, `find`, `create`)
|
|
331
|
+
- [ ] `EmailTemplates` resource (`all`, `find`)
|
|
332
|
+
|
|
333
|
+
### v0.13.0 — People, Orgs & Reference Data
|
|
334
|
+
|
|
335
|
+
- [ ] `Users` resource (`all`, `find`)
|
|
336
|
+
- [ ] `Vendors` resource (`all`, `find`, `create`, `update`)
|
|
337
|
+
- [ ] `ContractorProfiles` resource (`all`, `find`)
|
|
338
|
+
- [ ] `DeliveryMethods` resource (`all`) — reference data
|
|
339
|
+
- [ ] `TypesOfWork` resource (`all`) — reference data
|
|
177
340
|
|
|
178
|
-
### v0.
|
|
341
|
+
### v0.14.0 — Retry / Backoff & CLI
|
|
179
342
|
|
|
180
343
|
- [ ] Configurable `max_retries` on `Printavo::Client`
|
|
181
344
|
- [ ] Exponential backoff with jitter on 429 responses
|
|
182
345
|
- [ ] `retry_on_rate_limit: true/false` client option
|
|
183
346
|
- [ ] Thor-based `printavo` CLI (`customers`, `orders`, `orders find <id>`)
|
|
184
347
|
|
|
185
|
-
### v0.
|
|
348
|
+
### v0.99.0 — API Freeze
|
|
186
349
|
|
|
187
350
|
- [ ] Community feedback integration
|
|
188
351
|
- [ ] Deprecation notices for any renamed methods
|
data/lib/printavo/client.rb
CHANGED
|
@@ -25,10 +25,22 @@ module Printavo
|
|
|
25
25
|
@graphql = GraphqlClient.new(connection)
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
+
def account
|
|
29
|
+
Resources::Account.new(@graphql)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def contacts
|
|
33
|
+
Resources::Contacts.new(@graphql)
|
|
34
|
+
end
|
|
35
|
+
|
|
28
36
|
def customers
|
|
29
37
|
Resources::Customers.new(@graphql)
|
|
30
38
|
end
|
|
31
39
|
|
|
40
|
+
def invoices
|
|
41
|
+
Resources::Invoices.new(@graphql)
|
|
42
|
+
end
|
|
43
|
+
|
|
32
44
|
def statuses
|
|
33
45
|
Resources::Statuses.new(@graphql)
|
|
34
46
|
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# lib/printavo/models/account.rb
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Printavo
|
|
5
|
+
class Account < Models::Base
|
|
6
|
+
def id = self['id']
|
|
7
|
+
def company_name = self['companyName']
|
|
8
|
+
def company_email = self['companyEmail']
|
|
9
|
+
def phone = self['phone']
|
|
10
|
+
def website = self['website']
|
|
11
|
+
def logo_url = self['logoUrl']
|
|
12
|
+
def locale = self['locale']
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# lib/printavo/models/contact.rb
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Printavo
|
|
5
|
+
class Contact < Models::Base
|
|
6
|
+
def id = self['id']
|
|
7
|
+
def first_name = self['firstName']
|
|
8
|
+
def last_name = self['lastName']
|
|
9
|
+
def email = self['email']
|
|
10
|
+
def phone = self['phone']
|
|
11
|
+
def fax = self['fax']
|
|
12
|
+
|
|
13
|
+
def full_name
|
|
14
|
+
self['fullName'] || [first_name, last_name].compact.join(' ').strip
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# lib/printavo/models/invoice.rb
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Printavo
|
|
5
|
+
class Invoice < Models::Base
|
|
6
|
+
def id = self['id']
|
|
7
|
+
def nickname = self['nickname']
|
|
8
|
+
def total = self['total']
|
|
9
|
+
def amount_paid = self['amountPaid']
|
|
10
|
+
def amount_outstanding = self['amountOutstanding']
|
|
11
|
+
def paid_in_full? = self['paidInFull']
|
|
12
|
+
def invoice_at = self['invoiceAt']
|
|
13
|
+
def payment_due_at = self['paymentDueAt']
|
|
14
|
+
|
|
15
|
+
def status
|
|
16
|
+
dig('status', 'name')
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def status_id
|
|
20
|
+
dig('status', 'id')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def status_color
|
|
24
|
+
dig('status', 'color')
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def status_key
|
|
28
|
+
return nil if status.nil?
|
|
29
|
+
|
|
30
|
+
status.downcase.gsub(/\s+/, '_').to_sym
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def status?(key)
|
|
34
|
+
status_key == key.to_sym
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def contact
|
|
38
|
+
attrs = self['contact']
|
|
39
|
+
Contact.new(attrs) if attrs
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# lib/printavo/resources/account.rb
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Printavo
|
|
5
|
+
module Resources
|
|
6
|
+
# Singleton resource — Printavo exposes one account per API credential.
|
|
7
|
+
# Use +client.account.find+ (no ID argument required).
|
|
8
|
+
class Account < Base
|
|
9
|
+
FIND_QUERY = File.read(File.join(__dir__, '../graphql/account/find.graphql')).freeze
|
|
10
|
+
|
|
11
|
+
# Returns the account associated with the current API credentials.
|
|
12
|
+
#
|
|
13
|
+
# @return [Printavo::Account]
|
|
14
|
+
#
|
|
15
|
+
# @example
|
|
16
|
+
# account = client.account.find
|
|
17
|
+
# puts account.company_name # => "Texas Embroidery Ranch"
|
|
18
|
+
# puts account.locale # => "en-US"
|
|
19
|
+
def find
|
|
20
|
+
data = @graphql.query(FIND_QUERY)
|
|
21
|
+
Printavo::Account.new(data['account'])
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# lib/printavo/resources/contacts.rb
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Printavo
|
|
5
|
+
module Resources
|
|
6
|
+
class Contacts < Base
|
|
7
|
+
FIND_QUERY = File.read(File.join(__dir__, '../graphql/contacts/find.graphql')).freeze
|
|
8
|
+
CREATE_MUTATION = File.read(File.join(__dir__, '../graphql/contacts/create.graphql')).freeze
|
|
9
|
+
UPDATE_MUTATION = File.read(File.join(__dir__, '../graphql/contacts/update.graphql')).freeze
|
|
10
|
+
|
|
11
|
+
# Finds a contact by ID.
|
|
12
|
+
#
|
|
13
|
+
# @param id [String, Integer]
|
|
14
|
+
# @return [Printavo::Contact]
|
|
15
|
+
#
|
|
16
|
+
# @example
|
|
17
|
+
# client.contacts.find("123")
|
|
18
|
+
def find(id)
|
|
19
|
+
data = @graphql.query(FIND_QUERY, variables: { id: id.to_s })
|
|
20
|
+
Printavo::Contact.new(data['contact'])
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Creates a new contact. Requires at minimum +email:+.
|
|
24
|
+
#
|
|
25
|
+
# @return [Printavo::Contact]
|
|
26
|
+
#
|
|
27
|
+
# @example
|
|
28
|
+
# client.contacts.create(first_name: "Jane", last_name: "Smith",
|
|
29
|
+
# email: "jane@example.com", phone: "555-867-5309")
|
|
30
|
+
def create(**input)
|
|
31
|
+
data = @graphql.mutate(CREATE_MUTATION, variables: { input: camelize_keys(input) })
|
|
32
|
+
Printavo::Contact.new(data['contactCreate'])
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Updates an existing contact by ID.
|
|
36
|
+
#
|
|
37
|
+
# @param id [String, Integer]
|
|
38
|
+
# @return [Printavo::Contact]
|
|
39
|
+
#
|
|
40
|
+
# @example
|
|
41
|
+
# client.contacts.update("123", phone: "555-999-0000")
|
|
42
|
+
def update(id, **input)
|
|
43
|
+
data = @graphql.mutate(UPDATE_MUTATION,
|
|
44
|
+
variables: { id: id.to_s, input: camelize_keys(input) })
|
|
45
|
+
Printavo::Contact.new(data['contactUpdate'])
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def camelize_keys(hash)
|
|
51
|
+
hash.transform_keys do |key|
|
|
52
|
+
key.to_s.gsub(/_([a-z])/) { ::Regexp.last_match(1).upcase }
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# lib/printavo/resources/invoices.rb
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Printavo
|
|
5
|
+
module Resources
|
|
6
|
+
class Invoices < Base
|
|
7
|
+
ALL_QUERY = File.read(File.join(__dir__, '../graphql/invoices/all.graphql')).freeze
|
|
8
|
+
FIND_QUERY = File.read(File.join(__dir__, '../graphql/invoices/find.graphql')).freeze
|
|
9
|
+
UPDATE_MUTATION = File.read(File.join(__dir__, '../graphql/invoices/update.graphql')).freeze
|
|
10
|
+
|
|
11
|
+
def all(first: 25, after: nil)
|
|
12
|
+
fetch_page(first: first, after: after).records
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Finds an invoice by ID.
|
|
16
|
+
#
|
|
17
|
+
# @param id [String, Integer]
|
|
18
|
+
# @return [Printavo::Invoice]
|
|
19
|
+
#
|
|
20
|
+
# @example
|
|
21
|
+
# client.invoices.find("456")
|
|
22
|
+
def find(id)
|
|
23
|
+
data = @graphql.query(FIND_QUERY, variables: { id: id.to_s })
|
|
24
|
+
Printavo::Invoice.new(data['invoice'])
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Updates an existing invoice by ID.
|
|
28
|
+
# Note: invoices are promoted from quotes — use +client.orders.create+ to originate.
|
|
29
|
+
#
|
|
30
|
+
# @param id [String, Integer]
|
|
31
|
+
# @return [Printavo::Invoice]
|
|
32
|
+
#
|
|
33
|
+
# @example
|
|
34
|
+
# client.invoices.update("456", nickname: "Final Invoice", payment_due_at: "2026-05-01")
|
|
35
|
+
def update(id, **input)
|
|
36
|
+
data = @graphql.mutate(UPDATE_MUTATION,
|
|
37
|
+
variables: { id: id.to_s, input: camelize_keys(input) })
|
|
38
|
+
Printavo::Invoice.new(data['invoiceUpdate'])
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def fetch_page(first: 25, after: nil, **)
|
|
44
|
+
data = @graphql.query(ALL_QUERY, variables: { first: first, after: after })
|
|
45
|
+
nodes = data['invoices']['nodes'].map { |attrs| Printavo::Invoice.new(attrs) }
|
|
46
|
+
page_info = data['invoices']['pageInfo']
|
|
47
|
+
Printavo::Page.new(
|
|
48
|
+
records: nodes,
|
|
49
|
+
has_next_page: page_info['hasNextPage'],
|
|
50
|
+
end_cursor: page_info['endCursor']
|
|
51
|
+
)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def camelize_keys(hash)
|
|
55
|
+
hash.transform_keys do |key|
|
|
56
|
+
key.to_s.gsub(/_([a-z])/) { ::Regexp.last_match(1).upcase }
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
data/lib/printavo/version.rb
CHANGED
data/lib/printavo.rb
CHANGED
|
@@ -12,13 +12,19 @@ require_relative 'printavo/connection'
|
|
|
12
12
|
require_relative 'printavo/graphql_client'
|
|
13
13
|
require_relative 'printavo/page'
|
|
14
14
|
require_relative 'printavo/models/base'
|
|
15
|
+
require_relative 'printavo/models/account'
|
|
16
|
+
require_relative 'printavo/models/contact'
|
|
15
17
|
require_relative 'printavo/models/customer'
|
|
18
|
+
require_relative 'printavo/models/invoice'
|
|
16
19
|
require_relative 'printavo/models/status'
|
|
17
20
|
require_relative 'printavo/models/order'
|
|
18
21
|
require_relative 'printavo/models/job'
|
|
19
22
|
require_relative 'printavo/models/inquiry'
|
|
20
23
|
require_relative 'printavo/resources/base'
|
|
24
|
+
require_relative 'printavo/resources/account'
|
|
25
|
+
require_relative 'printavo/resources/contacts'
|
|
21
26
|
require_relative 'printavo/resources/customers'
|
|
27
|
+
require_relative 'printavo/resources/invoices'
|
|
22
28
|
require_relative 'printavo/resources/statuses'
|
|
23
29
|
require_relative 'printavo/resources/orders'
|
|
24
30
|
require_relative 'printavo/resources/jobs'
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: printavo-ruby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Stan Carver II
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-03-
|
|
11
|
+
date: 2026-03-31 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|
|
@@ -272,16 +272,22 @@ files:
|
|
|
272
272
|
- lib/printavo/connection.rb
|
|
273
273
|
- lib/printavo/errors.rb
|
|
274
274
|
- lib/printavo/graphql_client.rb
|
|
275
|
+
- lib/printavo/models/account.rb
|
|
275
276
|
- lib/printavo/models/base.rb
|
|
277
|
+
- lib/printavo/models/contact.rb
|
|
276
278
|
- lib/printavo/models/customer.rb
|
|
277
279
|
- lib/printavo/models/inquiry.rb
|
|
280
|
+
- lib/printavo/models/invoice.rb
|
|
278
281
|
- lib/printavo/models/job.rb
|
|
279
282
|
- lib/printavo/models/order.rb
|
|
280
283
|
- lib/printavo/models/status.rb
|
|
281
284
|
- lib/printavo/page.rb
|
|
285
|
+
- lib/printavo/resources/account.rb
|
|
282
286
|
- lib/printavo/resources/base.rb
|
|
287
|
+
- lib/printavo/resources/contacts.rb
|
|
283
288
|
- lib/printavo/resources/customers.rb
|
|
284
289
|
- lib/printavo/resources/inquiries.rb
|
|
290
|
+
- lib/printavo/resources/invoices.rb
|
|
285
291
|
- lib/printavo/resources/jobs.rb
|
|
286
292
|
- lib/printavo/resources/orders.rb
|
|
287
293
|
- lib/printavo/resources/statuses.rb
|