fiscalrail 0.4.0 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d2a0b93b946f75e4d2733bafaea87dee185f6b7abf5db7c60b7d73864472d63f
4
- data.tar.gz: 40ec395e28ee22197bdeb479517022bdf4894c3b89b721fd80a9db8c693309cf
3
+ metadata.gz: 686707319e3f84edc7570df96ecde4325051ced614c1d7afb0706fb490730fbe
4
+ data.tar.gz: 9b72d4865f113b5d9e1d18668a390ec8d6900b1ab05d06ca9ef12cf933a47c90
5
5
  SHA512:
6
- metadata.gz: c4b48066bb84842295979af02f44e7e002fadf22c88bb73252684f748bb71ac82ec3867673bc8c3227a2b18ac7e1b22df98f0ded6c180bf824550e6bb745f5ff
7
- data.tar.gz: 8fff2a61e27c474e4ae2c43fb688d3c5aac67212dda270ac332b6c112a256fb0844a248117801798700804c1236437cbaeeb0229fce437f2c13b95cb1b9fbf38
6
+ metadata.gz: 7b72ea35beff00c975ccb4dcb1f4953b56805cd64b330dee8cd4d39086158043574a4f10e51d28eac3639bea26cde7dbd0bfdcf068cbf66a8bd4d1838e5b4836
7
+ data.tar.gz: aae2526ccbe70ba3872c6859861cb972f743e72b1fc653fd28006d8236b49275583f48651e034fae59f6dbd109e36e841fec16d842efb0d8770dfd88dc9e0d04
data/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.6.0
4
+
5
+ - Add ES-scoped issuer certificate file uploads, representation verification,
6
+ submission-verification retries and pending-change cancellation.
7
+ - Expose active submission readiness and pending verification results from the
8
+ deployed API contract (47 operations).
9
+ - Keep certificate uploads as native multipart requests without automatic retries.
10
+
11
+
12
+ ## 0.5.0 — 2026-09-28
13
+
14
+ - Match the deployed current-account API routes and split invoicing settings into a dedicated resource.
15
+ - Use `/tax-ids/{id}` for tax ID retrieval.
16
+ - Regenerate response and request types from the updated FiscalRail OpenAPI contract.
17
+
3
18
  ## 0.4.0 — 2026-09-07
4
19
 
5
20
  - Start at 0.4.0 to match the Python SDK release with full resource coverage.
data/README.md CHANGED
@@ -5,7 +5,7 @@ A Ruby client for issuing immutable invoices through FiscalRail. Ruby 3.3 or lat
5
5
  Install with Bundler:
6
6
 
7
7
  ```ruby
8
- gem "fiscalrail", "~> 0.4.0"
8
+ gem "fiscalrail", "~> 0.6.0"
9
9
  ```
10
10
 
11
11
  ## Issue an invoice
@@ -83,9 +83,10 @@ By default, the SDK makes at most two retries for connection failures, timeouts,
83
83
 
84
84
  | Resource | Methods |
85
85
  | --- | --- |
86
- | `accounts` | `list`, `retrieve`, `update` |
87
- | `balances` | `retrieve(account_id)` |
88
- | `account_tax_regimes` | `retrieve(account_id)` |
86
+ | `accounts` | `retrieve`, `update` |
87
+ | `account_invoicing` | `retrieve`, `update` |
88
+ | `balances` | `retrieve` |
89
+ | `account_tax_regimes` | `retrieve` |
89
90
  | `api_keys` | `list`, `create`, `retrieve`, `delete` |
90
91
  | `customers` | `list`, `create`, `retrieve`, `update`, `delete` |
91
92
  | `event_destinations` | `list`, `create`, `retrieve`, `update`, `delete`, `enable`, `disable` |
@@ -114,7 +115,7 @@ end
114
115
  first_ten = client.customers.auto_paging_each.lazy.take(10).to_a
115
116
  ```
116
117
 
117
- Automatic iteration proceeds forward and preserves filters. Use `list(starting_after: ...)` or `list(ending_before: ...)` to manage cursors yourself. Accounts and tax regimes return single lists and do not expose automatic pagination.
118
+ Automatic iteration proceeds forward and preserves filters. Use `list(starting_after: ...)` or `list(ending_before: ...)` to manage cursors yourself. Account, account invoicing, balance, and account tax regime resources return single objects.
118
119
 
119
120
  ## Payment instructions
120
121
 
@@ -129,7 +130,7 @@ instruction = client.payment_instructions.create(
129
130
  }
130
131
  )
131
132
 
132
- client.accounts.update("acct_...", default_payment_instructions: [instruction.id])
133
+ client.account_invoicing.update(default_payment_instructions: [instruction.id])
133
134
 
134
135
  invoice = client.invoices.issue(
135
136
  payment_terms: { due_date: Date.new(2026, 9, 30) },
@@ -182,7 +183,7 @@ FiscalRail::Client.open(
182
183
  write_timeout: 30,
183
184
  max_retries: 2
184
185
  ) do |client|
185
- client.accounts.list
186
+ client.accounts.retrieve
186
187
  end
187
188
  ```
188
189
 
@@ -229,3 +230,32 @@ FISCALRAIL_APP_ROOT="$PWD" bundle exec ruby /absolute/path/to/ruby/test/rails_in
229
230
  It creates a Test account inside a test transaction and checks customer creation, null clearing, payment defaults, issuance/replay, pagination, PDF download and amendment. Set `FISCALRAIL_SDK_PDF=/tmp/sdk-invoice.pdf` to retain the rendered PDF for inspection. This test is optional and is not part of the standalone gem CI.
230
231
 
231
232
  See [RELEASING.md](RELEASING.md) for the release checklist.
233
+
234
+
235
+ ## Spanish AEAT submission
236
+
237
+ Use a Live Spanish account key. Upload a `.p12`/`.pfx` file (up to 128 KiB),
238
+ including its private key, using native multipart upload. Omit the password for
239
+ an unprotected bundle. The certificate's issuer NIF must match the account.
240
+
241
+ ```ruby
242
+ File.open("issuer.p12", "rb") do |certificate|
243
+ setup = client.account_tax_regimes.es.upload_certificate(
244
+ certificate_file: certificate,
245
+ certificate_password: ENV.fetch("CERTIFICATE_PASSWORD")
246
+ )
247
+ end
248
+ setup = client.account_tax_regimes.retrieve
249
+ # Inspect setup.es.pending_submission.status / error_code and setup.es.submission.ready.
250
+ client.account_tax_regimes.es.verify_submission # retry the pending or active check
251
+ client.account_tax_regimes.es.cancel_submission_change
252
+ client.account_tax_regimes.es.verify_representation # after granting AEAT authority
253
+ ```
254
+
255
+ Each mutation above is a separate operation; choose the one needed. Upload and
256
+ verification return the account setup while AEAT checks run asynchronously.
257
+ Poll the generic account tax-regime resource for pending verification status,
258
+ error code and the active setup's readiness. A working setup remains active until
259
+ a replacement verifies; failed checks retain the pending certificate for retry.
260
+ Cancelling removes only the pending change. Uploads are not automatically retried.
261
+ The ES mutations use `/account/tax-regime/es/...`; reads use `/account/tax-regime`.
@@ -2,7 +2,7 @@
2
2
 
3
3
  module FiscalRail
4
4
  class Client
5
- attr_reader :accounts, :balances, :account_tax_regimes, :api_keys, :customers,
5
+ attr_reader :accounts, :account_invoicing, :balances, :account_tax_regimes, :api_keys, :customers,
6
6
  :event_destinations, :events, :invoice_series, :invoices, :invoice_pdfs,
7
7
  :payment_instructions, :tax_ids, :tax_regimes
8
8
 
@@ -20,6 +20,7 @@ module FiscalRail
20
20
  @adapter = adapter || NetHTTPAdapter.new(open_timeout: open_timeout, read_timeout: read_timeout, write_timeout: write_timeout)
21
21
  transport = Transport.new(api_key: api_key, base_url: base_url, max_retries: max_retries, adapter: @adapter)
22
22
  @accounts = Resources::Accounts.new(transport)
23
+ @account_invoicing = Resources::AccountInvoicing.new(transport)
23
24
  @balances = Resources::Balances.new(transport)
24
25
  @account_tax_regimes = Resources::AccountTaxRegimes.new(transport)
25
26
  @api_keys = Resources::ApiKeys.new(transport)
@@ -19,15 +19,6 @@ module FiscalRail
19
19
  "format": "date-time",
20
20
  "type": "string"
21
21
  },
22
- "default_payment_instructions": {
23
- "items": {
24
- "$ref": "#/components/schemas/PaymentInstructionId"
25
- },
26
- "type": "array"
27
- },
28
- "default_series": {
29
- "$ref": "#/components/schemas/AccountDefaultSeries"
30
- },
31
22
  "email": {
32
23
  "type": [
33
24
  "string",
@@ -37,12 +28,6 @@ module FiscalRail
37
28
  "id": {
38
29
  "$ref": "#/components/schemas/AccountId"
39
30
  },
40
- "invoice_locale": {
41
- "type": "string"
42
- },
43
- "invoice_numbering_scope": {
44
- "$ref": "#/components/schemas/AccountInvoiceNumberingScope"
45
- },
46
31
  "live": {
47
32
  "$ref": "#/components/schemas/Live"
48
33
  },
@@ -84,10 +69,6 @@ module FiscalRail
84
69
  "address",
85
70
  "tax_regime",
86
71
  "timezone",
87
- "invoice_locale",
88
- "invoice_numbering_scope",
89
- "default_series",
90
- "default_payment_instructions",
91
72
  "created_at",
92
73
  "updated_at"
93
74
  ],
@@ -133,30 +114,72 @@ module FiscalRail
133
114
  "AccountInvoiceNumberingScope": {
134
115
  "type": "string"
135
116
  },
136
- "AccountList": {
137
- "model": "AccountList",
117
+ "AccountInvoicing": {
118
+ "model": "AccountInvoicing",
138
119
  "properties": {
139
- "data": {
120
+ "default_payment_instructions": {
140
121
  "items": {
141
- "$ref": "#/components/schemas/Account"
122
+ "$ref": "#/components/schemas/PaymentInstructionId"
142
123
  },
143
124
  "type": "array"
144
125
  },
145
- "has_more": {
146
- "type": "boolean"
126
+ "default_series": {
127
+ "$ref": "#/components/schemas/AccountDefaultSeries"
128
+ },
129
+ "footer": {
130
+ "type": [
131
+ "string",
132
+ "null"
133
+ ]
134
+ },
135
+ "locale": {
136
+ "type": "string"
137
+ },
138
+ "numbering_scope": {
139
+ "$ref": "#/components/schemas/AccountInvoiceNumberingScope"
147
140
  },
148
141
  "object": {
149
- "const": "list",
142
+ "const": "account_invoicing",
150
143
  "type": "string"
151
144
  }
152
145
  },
153
146
  "required": [
154
147
  "object",
155
- "has_more",
156
- "data"
148
+ "locale",
149
+ "footer",
150
+ "numbering_scope",
151
+ "default_series",
152
+ "default_payment_instructions"
157
153
  ],
158
154
  "type": "object"
159
155
  },
156
+ "AccountInvoicingUpdate": {
157
+ "model": "AccountInvoicingUpdate",
158
+ "properties": {
159
+ "default_payment_instructions": {
160
+ "items": {
161
+ "$ref": "#/components/schemas/PaymentInstructionId"
162
+ },
163
+ "type": "array"
164
+ },
165
+ "default_series": {
166
+ "$ref": "#/components/schemas/AccountDefaultSeries"
167
+ },
168
+ "footer": {
169
+ "type": [
170
+ "string",
171
+ "null"
172
+ ]
173
+ },
174
+ "locale": {
175
+ "type": "string"
176
+ },
177
+ "numbering_scope": {
178
+ "$ref": "#/components/schemas/AccountInvoiceNumberingScope"
179
+ }
180
+ },
181
+ "type": "object"
182
+ },
160
183
  "AccountNotConfiguredErrorResponse": {
161
184
  "model": "AccountNotConfiguredErrorResponse",
162
185
  "properties": {
@@ -206,17 +229,20 @@ module FiscalRail
206
229
  "address": {
207
230
  "$ref": "#/components/schemas/AddressUpdate"
208
231
  },
209
- "default_payment_instructions": {
210
- "items": {
211
- "$ref": "#/components/schemas/PaymentInstructionId"
212
- },
213
- "type": "array"
232
+ "email": {
233
+ "type": [
234
+ "string",
235
+ "null"
236
+ ]
214
237
  },
215
- "default_series": {
216
- "$ref": "#/components/schemas/AccountDefaultSeries"
238
+ "name": {
239
+ "type": "string"
217
240
  },
218
- "invoice_numbering_scope": {
219
- "$ref": "#/components/schemas/AccountInvoiceNumberingScope"
241
+ "phone": {
242
+ "type": [
243
+ "string",
244
+ "null"
245
+ ]
220
246
  }
221
247
  },
222
248
  "type": "object"
@@ -2339,6 +2365,49 @@ module FiscalRail
2339
2365
  ],
2340
2366
  "type": "object"
2341
2367
  },
2368
+ "SpanishAccountSubmission": {
2369
+ "model": "SpanishAccountSubmission",
2370
+ "properties": {
2371
+ "certificate_expires_at": {
2372
+ "format": "date-time",
2373
+ "type": [
2374
+ "string",
2375
+ "null"
2376
+ ]
2377
+ },
2378
+ "error_code": {
2379
+ "type": [
2380
+ "string",
2381
+ "null"
2382
+ ]
2383
+ },
2384
+ "kind": {
2385
+ "type": "string"
2386
+ },
2387
+ "last_checked_at": {
2388
+ "format": "date-time",
2389
+ "type": [
2390
+ "string",
2391
+ "null"
2392
+ ]
2393
+ },
2394
+ "ready": {
2395
+ "type": "boolean"
2396
+ },
2397
+ "status": {
2398
+ "type": "string"
2399
+ }
2400
+ },
2401
+ "required": [
2402
+ "kind",
2403
+ "ready",
2404
+ "certificate_expires_at",
2405
+ "status",
2406
+ "error_code",
2407
+ "last_checked_at"
2408
+ ],
2409
+ "type": "object"
2410
+ },
2342
2411
  "SpanishAccountTaxRegime": {
2343
2412
  "model": "SpanishAccountTaxRegime",
2344
2413
  "properties": {
@@ -2368,6 +2437,16 @@ module FiscalRail
2368
2437
  "SpanishAccountTaxRegimeDetails": {
2369
2438
  "model": "SpanishAccountTaxRegimeDetails",
2370
2439
  "properties": {
2440
+ "pending_submission": {
2441
+ "oneOf": [
2442
+ {
2443
+ "$ref": "#/components/schemas/SpanishPendingSubmission"
2444
+ },
2445
+ {
2446
+ "type": "null"
2447
+ }
2448
+ ]
2449
+ },
2371
2450
  "representation": {
2372
2451
  "oneOf": [
2373
2452
  {
@@ -2377,10 +2456,22 @@ module FiscalRail
2377
2456
  "type": "null"
2378
2457
  }
2379
2458
  ]
2459
+ },
2460
+ "submission": {
2461
+ "oneOf": [
2462
+ {
2463
+ "$ref": "#/components/schemas/SpanishAccountSubmission"
2464
+ },
2465
+ {
2466
+ "type": "null"
2467
+ }
2468
+ ]
2380
2469
  }
2381
2470
  },
2382
2471
  "required": [
2383
- "representation"
2472
+ "representation",
2473
+ "submission",
2474
+ "pending_submission"
2384
2475
  ],
2385
2476
  "type": "object"
2386
2477
  },
@@ -2434,6 +2525,89 @@ module FiscalRail
2434
2525
  ],
2435
2526
  "type": "object"
2436
2527
  },
2528
+ "SpanishPendingSubmission": {
2529
+ "model": "SpanishPendingSubmission",
2530
+ "properties": {
2531
+ "certificate_expires_at": {
2532
+ "format": "date-time",
2533
+ "type": [
2534
+ "string",
2535
+ "null"
2536
+ ]
2537
+ },
2538
+ "error_code": {
2539
+ "type": [
2540
+ "string",
2541
+ "null"
2542
+ ]
2543
+ },
2544
+ "kind": {
2545
+ "type": "string"
2546
+ },
2547
+ "last_checked_at": {
2548
+ "format": "date-time",
2549
+ "type": [
2550
+ "string",
2551
+ "null"
2552
+ ]
2553
+ },
2554
+ "status": {
2555
+ "type": "string"
2556
+ }
2557
+ },
2558
+ "required": [
2559
+ "kind",
2560
+ "status",
2561
+ "error_code",
2562
+ "last_checked_at",
2563
+ "certificate_expires_at"
2564
+ ],
2565
+ "type": "object"
2566
+ },
2567
+ "SubmissionConfigurationErrorResponse": {
2568
+ "model": "SubmissionConfigurationErrorResponse",
2569
+ "properties": {
2570
+ "error": {
2571
+ "model": "SubmissionConfigurationError",
2572
+ "properties": {
2573
+ "code": {
2574
+ "type": "string"
2575
+ },
2576
+ "details": {
2577
+ "items": {
2578
+ "model": "SubmissionConfigurationValidationDetail",
2579
+ "properties": {
2580
+ "field": {
2581
+ "type": "string"
2582
+ },
2583
+ "message": {
2584
+ "type": "string"
2585
+ }
2586
+ },
2587
+ "required": [
2588
+ "field",
2589
+ "message"
2590
+ ],
2591
+ "type": "object"
2592
+ },
2593
+ "type": "array"
2594
+ },
2595
+ "message": {
2596
+ "type": "string"
2597
+ }
2598
+ },
2599
+ "required": [
2600
+ "code",
2601
+ "message"
2602
+ ],
2603
+ "type": "object"
2604
+ }
2605
+ },
2606
+ "required": [
2607
+ "error"
2608
+ ],
2609
+ "type": "object"
2610
+ },
2437
2611
  "TaxId": {
2438
2612
  "model": "TaxId",
2439
2613
  "properties": {
@@ -2888,6 +3062,16 @@ module FiscalRail
2888
3062
  }
2889
3063
  }
2890
3064
  },
3065
+ "cancelAccountSubmissionChange": {
3066
+ "method": "DELETE",
3067
+ "path": "/account/tax-regime/es/submission/pending",
3068
+ "parameters": [],
3069
+ "responses": {
3070
+ "200": {
3071
+ "$ref": "#/components/schemas/AccountTaxRegime"
3072
+ }
3073
+ }
3074
+ },
2891
3075
  "createApiKey": {
2892
3076
  "method": "POST",
2893
3077
  "path": "/api-keys",
@@ -3056,16 +3240,6 @@ module FiscalRail
3056
3240
  }
3057
3241
  }
3058
3242
  },
3059
- "listAccounts": {
3060
- "method": "GET",
3061
- "path": "/accounts",
3062
- "parameters": [],
3063
- "responses": {
3064
- "200": {
3065
- "$ref": "#/components/schemas/AccountList"
3066
- }
3067
- }
3068
- },
3069
3243
  "listApiKeys": {
3070
3244
  "method": "GET",
3071
3245
  "path": "/api-keys",
@@ -3290,30 +3464,28 @@ module FiscalRail
3290
3464
  },
3291
3465
  "retrieveAccount": {
3292
3466
  "method": "GET",
3293
- "path": "/accounts/{id}",
3294
- "parameters": [
3295
- {
3296
- "name": "id",
3297
- "in": "path",
3298
- "required": true
3299
- }
3300
- ],
3467
+ "path": "/account",
3468
+ "parameters": [],
3301
3469
  "responses": {
3302
3470
  "200": {
3303
3471
  "$ref": "#/components/schemas/Account"
3304
3472
  }
3305
3473
  }
3306
3474
  },
3307
- "retrieveAccountTaxRegime": {
3475
+ "retrieveAccountInvoicing": {
3308
3476
  "method": "GET",
3309
- "path": "/accounts/{account_id}/tax-regime",
3310
- "parameters": [
3311
- {
3312
- "name": "account_id",
3313
- "in": "path",
3314
- "required": true
3477
+ "path": "/account/invoicing",
3478
+ "parameters": [],
3479
+ "responses": {
3480
+ "200": {
3481
+ "$ref": "#/components/schemas/AccountInvoicing"
3315
3482
  }
3316
- ],
3483
+ }
3484
+ },
3485
+ "retrieveAccountTaxRegime": {
3486
+ "method": "GET",
3487
+ "path": "/account/tax-regime",
3488
+ "parameters": [],
3317
3489
  "responses": {
3318
3490
  "200": {
3319
3491
  "$ref": "#/components/schemas/AccountTaxRegime"
@@ -3338,14 +3510,8 @@ module FiscalRail
3338
3510
  },
3339
3511
  "retrieveBalance": {
3340
3512
  "method": "GET",
3341
- "path": "/accounts/{account_id}/balance",
3342
- "parameters": [
3343
- {
3344
- "name": "account_id",
3345
- "in": "path",
3346
- "required": true
3347
- }
3348
- ],
3513
+ "path": "/account/balance",
3514
+ "parameters": [],
3349
3515
  "responses": {
3350
3516
  "200": {
3351
3517
  "$ref": "#/components/schemas/Balance"
@@ -3466,7 +3632,7 @@ module FiscalRail
3466
3632
  },
3467
3633
  "retrieveTaxId": {
3468
3634
  "method": "GET",
3469
- "path": "/tax_ids/{id}",
3635
+ "path": "/tax-ids/{id}",
3470
3636
  "parameters": [
3471
3637
  {
3472
3638
  "name": "id",
@@ -3498,20 +3664,24 @@ module FiscalRail
3498
3664
  },
3499
3665
  "updateAccount": {
3500
3666
  "method": "PATCH",
3501
- "path": "/accounts/{id}",
3502
- "parameters": [
3503
- {
3504
- "name": "id",
3505
- "in": "path",
3506
- "required": true
3507
- }
3508
- ],
3667
+ "path": "/account",
3668
+ "parameters": [],
3509
3669
  "responses": {
3510
3670
  "200": {
3511
3671
  "$ref": "#/components/schemas/Account"
3512
3672
  }
3513
3673
  }
3514
3674
  },
3675
+ "updateAccountInvoicing": {
3676
+ "method": "PATCH",
3677
+ "path": "/account/invoicing",
3678
+ "parameters": [],
3679
+ "responses": {
3680
+ "200": {
3681
+ "$ref": "#/components/schemas/AccountInvoicing"
3682
+ }
3683
+ }
3684
+ },
3515
3685
  "updateCustomer": {
3516
3686
  "method": "PATCH",
3517
3687
  "path": "/customers/{id}",
@@ -3575,6 +3745,36 @@ module FiscalRail
3575
3745
  "$ref": "#/components/schemas/PaymentInstruction"
3576
3746
  }
3577
3747
  }
3748
+ },
3749
+ "uploadAccountCertificate": {
3750
+ "method": "POST",
3751
+ "path": "/account/tax-regime/es/certificate",
3752
+ "parameters": [],
3753
+ "responses": {
3754
+ "202": {
3755
+ "$ref": "#/components/schemas/AccountTaxRegime"
3756
+ }
3757
+ }
3758
+ },
3759
+ "verifyAccountRepresentation": {
3760
+ "method": "POST",
3761
+ "path": "/account/tax-regime/es/representation/verify",
3762
+ "parameters": [],
3763
+ "responses": {
3764
+ "202": {
3765
+ "$ref": "#/components/schemas/AccountTaxRegime"
3766
+ }
3767
+ }
3768
+ },
3769
+ "verifyAccountSubmission": {
3770
+ "method": "POST",
3771
+ "path": "/account/tax-regime/es/submission/verify",
3772
+ "parameters": [],
3773
+ "responses": {
3774
+ "202": {
3775
+ "$ref": "#/components/schemas/AccountTaxRegime"
3776
+ }
3777
+ }
3578
3778
  }
3579
3779
  }
3580
3780
  }
@@ -6,12 +6,8 @@ module FiscalRail
6
6
  class Account < Model
7
7
  def address = self["address"]
8
8
  def created_at = self["created_at"]
9
- def default_payment_instructions = self["default_payment_instructions"]
10
- def default_series = self["default_series"]
11
9
  def email = self["email"]
12
10
  def id = self["id"]
13
- def invoice_locale = self["invoice_locale"]
14
- def invoice_numbering_scope = self["invoice_numbering_scope"]
15
11
  def live = self["live"]
16
12
  def name = self["name"]
17
13
  def object = self["object"]
@@ -28,12 +24,23 @@ module FiscalRail
28
24
  def invoice = self["invoice"]
29
25
  end
30
26
 
31
- class AccountList < Page
32
- def data = self["data"]
33
- def has_more = self["has_more"]
27
+ class AccountInvoicing < Model
28
+ def default_payment_instructions = self["default_payment_instructions"]
29
+ def default_series = self["default_series"]
30
+ def footer = self["footer"]
31
+ def locale = self["locale"]
32
+ def numbering_scope = self["numbering_scope"]
34
33
  def object = self["object"]
35
34
  end
36
35
 
36
+ class AccountInvoicingUpdate < Model
37
+ def default_payment_instructions = self["default_payment_instructions"]
38
+ def default_series = self["default_series"]
39
+ def footer = self["footer"]
40
+ def locale = self["locale"]
41
+ def numbering_scope = self["numbering_scope"]
42
+ end
43
+
37
44
  class AccountNotConfiguredError < Model
38
45
  def code = self["code"]
39
46
  def message = self["message"]
@@ -45,9 +52,9 @@ module FiscalRail
45
52
 
46
53
  class AccountUpdate < Model
47
54
  def address = self["address"]
48
- def default_payment_instructions = self["default_payment_instructions"]
49
- def default_series = self["default_series"]
50
- def invoice_numbering_scope = self["invoice_numbering_scope"]
55
+ def email = self["email"]
56
+ def name = self["name"]
57
+ def phone = self["phone"]
51
58
  end
52
59
 
53
60
  class Address < Model
@@ -586,6 +593,15 @@ module FiscalRail
586
593
  def verified_at = self["verified_at"]
587
594
  end
588
595
 
596
+ class SpanishAccountSubmission < Model
597
+ def certificate_expires_at = self["certificate_expires_at"]
598
+ def error_code = self["error_code"]
599
+ def kind = self["kind"]
600
+ def last_checked_at = self["last_checked_at"]
601
+ def ready = self["ready"]
602
+ def status = self["status"]
603
+ end
604
+
589
605
  class SpanishAccountTaxRegime < Model
590
606
  def account = self["account"]
591
607
  def es = self["es"]
@@ -594,7 +610,9 @@ module FiscalRail
594
610
  end
595
611
 
596
612
  class SpanishAccountTaxRegimeDetails < Model
613
+ def pending_submission = self["pending_submission"]
597
614
  def representation = self["representation"]
615
+ def submission = self["submission"]
598
616
  end
599
617
 
600
618
  class SpanishInvoiceQr < Model
@@ -612,6 +630,29 @@ module FiscalRail
612
630
  def verifactu = self["verifactu"]
613
631
  end
614
632
 
633
+ class SpanishPendingSubmission < Model
634
+ def certificate_expires_at = self["certificate_expires_at"]
635
+ def error_code = self["error_code"]
636
+ def kind = self["kind"]
637
+ def last_checked_at = self["last_checked_at"]
638
+ def status = self["status"]
639
+ end
640
+
641
+ class SubmissionConfigurationError < Model
642
+ def code = self["code"]
643
+ def details = self["details"]
644
+ def message = self["message"]
645
+ end
646
+
647
+ class SubmissionConfigurationErrorResponse < Model
648
+ def error = self["error"]
649
+ end
650
+
651
+ class SubmissionConfigurationValidationDetail < Model
652
+ def field = self["field"]
653
+ def message = self["message"]
654
+ end
655
+
615
656
  class TaxId < Model
616
657
  def country = self["country"]
617
658
  def id = self["id"]
@@ -10,7 +10,7 @@ module FiscalRail
10
10
 
11
11
  private
12
12
 
13
- def request(operation_id, path: {}, params: {}, body: nil, retry_safe: false, idempotency_key: nil, headers: {}, binary: false)
13
+ def request(operation_id, path: {}, params: {}, body: nil, multipart: nil, retry_safe: false, idempotency_key: nil, headers: {}, binary: false)
14
14
  operation = Generated::OPERATIONS.fetch(operation_id)
15
15
  route = operation.fetch("path").gsub(/\{([^}]+)\}/) do
16
16
  value = path.fetch(Regexp.last_match(1).to_sym)
@@ -20,7 +20,7 @@ module FiscalRail
20
20
  end
21
21
  headers = headers.merge("Accept" => "application/pdf") if binary
22
22
  response = @transport.request(method: operation.fetch("method"), path: route, params: params,
23
- body: body, retry_safe: retry_safe, idempotency_key: idempotency_key, headers: headers)
23
+ body: body, multipart: multipart, retry_safe: retry_safe, idempotency_key: idempotency_key, headers: headers)
24
24
  metadata = { request_id: response.headers["request-id"], idempotent_replayed: response.headers["idempotent-replayed"], idempotency_key: idempotency_key }
25
25
  unless operation.fetch("responses").key?(response.status.to_s)
26
26
  raise ResponseParseError.new("unexpected HTTP #{response.status}", model: operation_id, field: "$", **metadata.slice(:request_id, :idempotency_key))
@@ -3,28 +3,58 @@
3
3
  module FiscalRail
4
4
  module Resources
5
5
  class Accounts < Resource
6
- def list
7
- request("listAccounts", retry_safe: true)
6
+ def retrieve
7
+ request("retrieveAccount", retry_safe: true)
8
8
  end
9
9
 
10
- def retrieve(account_id)
11
- request("retrieveAccount", path: { id: account_id }, retry_safe: true)
10
+ def update(**params)
11
+ request("updateAccount", body: params)
12
+ end
13
+ end
14
+
15
+ class AccountInvoicing < Resource
16
+ def retrieve
17
+ request("retrieveAccountInvoicing", retry_safe: true)
12
18
  end
13
19
 
14
- def update(account_id, **params)
15
- request("updateAccount", path: { id: account_id }, body: params)
20
+ def update(**params)
21
+ request("updateAccountInvoicing", body: params)
16
22
  end
17
23
  end
18
24
 
19
25
  class Balances < Resource
20
- def retrieve(account_id)
21
- request("retrieveBalance", path: { account_id: account_id }, retry_safe: true)
26
+ def retrieve
27
+ request("retrieveBalance", retry_safe: true)
22
28
  end
23
29
  end
24
30
 
25
31
  class AccountTaxRegimes < Resource
26
- def retrieve(account_id)
27
- request("retrieveAccountTaxRegime", path: { account_id: account_id }, retry_safe: true)
32
+ def es
33
+ @es ||= SpanishSubmission.new(@transport)
34
+ end
35
+
36
+ def retrieve
37
+ request("retrieveAccountTaxRegime", retry_safe: true)
38
+ end
39
+ end
40
+ class SpanishSubmission < Resource
41
+ def upload_certificate(certificate_file:, certificate_password: nil)
42
+ content = certificate_file.read(128 * 1024 + 1) || ""
43
+ raise ArgumentError, "certificate_file must be at most 128 KiB" if content.bytesize > 128 * 1024
44
+
45
+ request("uploadAccountCertificate", multipart: { certificate_file: content, certificate_password: certificate_password })
46
+ end
47
+
48
+ def verify_representation
49
+ request("verifyAccountRepresentation")
50
+ end
51
+
52
+ def verify_submission
53
+ request("verifyAccountSubmission")
54
+ end
55
+
56
+ def cancel_submission_change
57
+ request("cancelAccountSubmissionChange")
28
58
  end
29
59
  end
30
60
  end
@@ -4,6 +4,7 @@ require "net/http"
4
4
  require "json"
5
5
  require "uri"
6
6
  require "thread"
7
+ require "securerandom"
7
8
 
8
9
  module FiscalRail
9
10
  # The adapter boundary also makes custom proxy/TLS/instrumentation possible.
@@ -63,7 +64,7 @@ module FiscalRail
63
64
  @api_key, @base_url, @max_retries, @adapter, @sleeper = api_key, base_url.sub(%r{/+\z}, ""), max_retries, adapter, sleeper
64
65
  end
65
66
 
66
- def request(method:, path:, body: nil, params: {}, headers: {}, retry_safe:, idempotency_key: nil)
67
+ def request(method:, path:, body: nil, multipart: nil, params: {}, headers: {}, retry_safe:, idempotency_key: nil)
67
68
  uri = URI("#{@base_url}#{path}")
68
69
  query = Serialization.json_value(params.reject { |_, value| value.nil? })
69
70
  uri.query = URI.encode_www_form(query) unless query.empty?
@@ -74,6 +75,17 @@ module FiscalRail
74
75
  request_headers["Idempotency-Key"] = idempotency_key if idempotency_key
75
76
  request_headers["Content-Type"] = "application/json" unless body.nil?
76
77
  encoded = body.nil? ? nil : JSON.generate(Serialization.json_value(body))
78
+ if multipart
79
+ boundary = "fiscalrail-#{SecureRandom.hex(24)}"
80
+ request_headers["Content-Type"] = "multipart/form-data; boundary=#{boundary}"
81
+ encoded = "--#{boundary}\r\nContent-Disposition: form-data; name=\"certificate_file\"; filename=\"certificate.p12\"\r\nContent-Type: application/x-pkcs12\r\n\r\n".b
82
+ encoded << multipart.fetch(:certificate_file).b << "\r\n".b
83
+ unless multipart[:certificate_password].nil?
84
+ encoded << "--#{boundary}\r\nContent-Disposition: form-data; name=\"certificate_password\"\r\n\r\n".b
85
+ encoded << multipart.fetch(:certificate_password).b << "\r\n".b
86
+ end
87
+ encoded << "--#{boundary}--\r\n".b
88
+ end
77
89
  attempt = 0
78
90
  loop do
79
91
  begin
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FiscalRail
4
- VERSION = "0.4.0"
4
+ VERSION = "0.6.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fiscalrail
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - FiscalRail