cashctrl 0.0.1 → 0.1.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.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +21 -0
  3. data/README.md +549 -14
  4. data/lib/cashctrl/client.rb +216 -0
  5. data/lib/cashctrl/collection.rb +77 -0
  6. data/lib/cashctrl/configuration.rb +30 -0
  7. data/lib/cashctrl/error.rb +27 -0
  8. data/lib/cashctrl/localized_string.rb +115 -0
  9. data/lib/cashctrl/models/account.rb +35 -0
  10. data/lib/cashctrl/models/article.rb +40 -0
  11. data/lib/cashctrl/models/asset.rb +32 -0
  12. data/lib/cashctrl/models/bank.rb +16 -0
  13. data/lib/cashctrl/models/category.rb +13 -0
  14. data/lib/cashctrl/models/certificate_document.rb +14 -0
  15. data/lib/cashctrl/models/certificate_template.rb +13 -0
  16. data/lib/cashctrl/models/cost_center.rb +15 -0
  17. data/lib/cashctrl/models/currency.rb +18 -0
  18. data/lib/cashctrl/models/custom_field.rb +18 -0
  19. data/lib/cashctrl/models/custom_field_group.rb +12 -0
  20. data/lib/cashctrl/models/file.rb +19 -0
  21. data/lib/cashctrl/models/fiscal_period.rb +16 -0
  22. data/lib/cashctrl/models/fiscal_period_task.rb +14 -0
  23. data/lib/cashctrl/models/history.rb +19 -0
  24. data/lib/cashctrl/models/insurance_type.rb +13 -0
  25. data/lib/cashctrl/models/journal.rb +56 -0
  26. data/lib/cashctrl/models/journal_import.rb +18 -0
  27. data/lib/cashctrl/models/journal_import_entry.rb +20 -0
  28. data/lib/cashctrl/models/loader.rb +52 -0
  29. data/lib/cashctrl/models/location.rb +22 -0
  30. data/lib/cashctrl/models/order.rb +46 -0
  31. data/lib/cashctrl/models/order_book_entry.rb +17 -0
  32. data/lib/cashctrl/models/order_document.rb +15 -0
  33. data/lib/cashctrl/models/order_layout.rb +18 -0
  34. data/lib/cashctrl/models/order_payment.rb +16 -0
  35. data/lib/cashctrl/models/person.rb +72 -0
  36. data/lib/cashctrl/models/report.rb +15 -0
  37. data/lib/cashctrl/models/report_collection.rb +13 -0
  38. data/lib/cashctrl/models/report_element.rb +16 -0
  39. data/lib/cashctrl/models/rounding.rb +15 -0
  40. data/lib/cashctrl/models/salary_book_entry.rb +16 -0
  41. data/lib/cashctrl/models/salary_certificate.rb +15 -0
  42. data/lib/cashctrl/models/salary_document.rb +15 -0
  43. data/lib/cashctrl/models/salary_field.rb +16 -0
  44. data/lib/cashctrl/models/salary_layout.rb +13 -0
  45. data/lib/cashctrl/models/salary_payment.rb +16 -0
  46. data/lib/cashctrl/models/salary_setting.rb +12 -0
  47. data/lib/cashctrl/models/salary_statement.rb +17 -0
  48. data/lib/cashctrl/models/salary_status.rb +12 -0
  49. data/lib/cashctrl/models/salary_sum.rb +14 -0
  50. data/lib/cashctrl/models/salary_template.rb +12 -0
  51. data/lib/cashctrl/models/salary_type.rb +14 -0
  52. data/lib/cashctrl/models/sequence_number.rb +13 -0
  53. data/lib/cashctrl/models/setting.rb +33 -0
  54. data/lib/cashctrl/models/tax.rb +17 -0
  55. data/lib/cashctrl/models/text.rb +13 -0
  56. data/lib/cashctrl/models/title.rb +13 -0
  57. data/lib/cashctrl/models/unit.rb +11 -0
  58. data/lib/cashctrl/resource.rb +190 -0
  59. data/lib/cashctrl/resources/account/bank.rb +24 -0
  60. data/lib/cashctrl/resources/account/category.rb +22 -0
  61. data/lib/cashctrl/resources/account/cost_center/category.rb +24 -0
  62. data/lib/cashctrl/resources/account/cost_center.rb +48 -0
  63. data/lib/cashctrl/resources/account.rb +54 -0
  64. data/lib/cashctrl/resources/base.rb +161 -0
  65. data/lib/cashctrl/resources/currency.rb +26 -0
  66. data/lib/cashctrl/resources/custom_field/group.rb +24 -0
  67. data/lib/cashctrl/resources/custom_field.rb +30 -0
  68. data/lib/cashctrl/resources/file/category.rb +22 -0
  69. data/lib/cashctrl/resources/file.rb +66 -0
  70. data/lib/cashctrl/resources/fiscal_period/task.rb +30 -0
  71. data/lib/cashctrl/resources/fiscal_period.rb +96 -0
  72. data/lib/cashctrl/resources/history.rb +44 -0
  73. data/lib/cashctrl/resources/inventory/article/category.rb +24 -0
  74. data/lib/cashctrl/resources/inventory/article.rb +34 -0
  75. data/lib/cashctrl/resources/inventory/asset/category.rb +24 -0
  76. data/lib/cashctrl/resources/inventory/asset.rb +34 -0
  77. data/lib/cashctrl/resources/inventory/unit.rb +12 -0
  78. data/lib/cashctrl/resources/journal/import/entry.rb +54 -0
  79. data/lib/cashctrl/resources/journal/import.rb +22 -0
  80. data/lib/cashctrl/resources/journal.rb +94 -0
  81. data/lib/cashctrl/resources/location.rb +10 -0
  82. data/lib/cashctrl/resources/order/book_entry.rb +12 -0
  83. data/lib/cashctrl/resources/order/category.rb +32 -0
  84. data/lib/cashctrl/resources/order/document.rb +38 -0
  85. data/lib/cashctrl/resources/order/layout.rb +12 -0
  86. data/lib/cashctrl/resources/order/payment.rb +56 -0
  87. data/lib/cashctrl/resources/order.rb +94 -0
  88. data/lib/cashctrl/resources/person/category.rb +22 -0
  89. data/lib/cashctrl/resources/person/title.rb +12 -0
  90. data/lib/cashctrl/resources/person.rb +40 -0
  91. data/lib/cashctrl/resources/report/collection.rb +72 -0
  92. data/lib/cashctrl/resources/report/element.rb +80 -0
  93. data/lib/cashctrl/resources/report.rb +60 -0
  94. data/lib/cashctrl/resources/rounding.rb +10 -0
  95. data/lib/cashctrl/resources/salary/book_entry.rb +12 -0
  96. data/lib/cashctrl/resources/salary/category.rb +22 -0
  97. data/lib/cashctrl/resources/salary/certificate/document.rb +72 -0
  98. data/lib/cashctrl/resources/salary/certificate/template.rb +24 -0
  99. data/lib/cashctrl/resources/salary/certificate.rb +30 -0
  100. data/lib/cashctrl/resources/salary/document.rb +62 -0
  101. data/lib/cashctrl/resources/salary/field.rb +38 -0
  102. data/lib/cashctrl/resources/salary/insurance/type.rb +14 -0
  103. data/lib/cashctrl/resources/salary/layout.rb +12 -0
  104. data/lib/cashctrl/resources/salary/payment.rb +56 -0
  105. data/lib/cashctrl/resources/salary/setting.rb +12 -0
  106. data/lib/cashctrl/resources/salary/statement.rb +77 -0
  107. data/lib/cashctrl/resources/salary/status.rb +24 -0
  108. data/lib/cashctrl/resources/salary/sum.rb +12 -0
  109. data/lib/cashctrl/resources/salary/template.rb +22 -0
  110. data/lib/cashctrl/resources/salary/type.rb +24 -0
  111. data/lib/cashctrl/resources/sequence_number.rb +20 -0
  112. data/lib/cashctrl/resources/setting.rb +52 -0
  113. data/lib/cashctrl/resources/tax.rb +10 -0
  114. data/lib/cashctrl/resources/text.rb +10 -0
  115. data/lib/cashctrl/schema.yml +601 -0
  116. data/lib/cashctrl/version.rb +1 -1
  117. data/lib/cashctrl.rb +114 -2
  118. data/lib/generators/model_generator.rb +92 -0
  119. metadata +115 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2a3babb2af59d87a65c8320a5b88625fec3c98bb8c07b601e8fa454f4490f649
4
- data.tar.gz: e61d18fe574d86ddba6453c87cbd6b2bce55817b03cfc65aedc68e66b0c8bbbf
3
+ metadata.gz: '019f213f238694c48c7204599a63e13e4f8fcea1a0eb337c649544bfa7b8172e'
4
+ data.tar.gz: bfb12a268305a238032dce7d0c8fd3f7a314f6a7df0b86629f560f8179275001
5
5
  SHA512:
6
- metadata.gz: 6c80bba5143a5b62aeb333925cf1e4ae444afb53e60833ffd94330b8ee9e209fced19104a845b72275025555a0b609201baf931a8b6472632204e3ff7ff1dc04
7
- data.tar.gz: f7bcfb1277d2e0883da53b155b69114755dd558bf4e7ec2a6dbc19e27fb55bbc027764bc37b036ab79d460c05cbcb561613da4e31f8949176fb642d653835d7d
6
+ metadata.gz: df078461cff3447464efd49e7867c363a6244170902fd9953b10056007e0640e03c5314011cef577f4aec1107383790e86d8d535807601de500e0199b4bd4e03
7
+ data.tar.gz: 32e23fc1a02ac10951e242145fc4c75f151ee7df572b34d97834df508bd80f7562c1cc0a4f035b0fc0cc9f71500955f9567ec5406bc08cb74a32148e552c0bf8
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2025 Marco Roth
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md CHANGED
@@ -1,39 +1,574 @@
1
- # Cashctrl
1
+ # CashCtrl Ruby
2
2
 
3
- TODO: Delete this and the text below, and describe your gem
4
-
5
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/cashctrl`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ A Ruby gem to interact with the [CashCtrl](https://cashctrl.com) Swiss accounting software API.
6
4
 
7
5
  ## Installation
8
6
 
9
- TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem "cashctrl"
11
+ ```
10
12
 
11
- Install the gem and add to the application's Gemfile by executing:
13
+ And then execute:
12
14
 
13
15
  ```bash
14
- bundle add UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
16
+ bundle install
15
17
  ```
16
18
 
17
- If bundler is not being used to manage dependencies, install the gem by executing:
19
+ Or install it yourself as:
18
20
 
19
21
  ```bash
20
- gem install UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
22
+ gem install cashctrl
23
+ ```
24
+
25
+ ## Configuration
26
+
27
+ ### Global Configuration
28
+
29
+ ```ruby
30
+ Cashctrl.configure do |config|
31
+ config.org = "your-organization"
32
+ config.api_key = ENV["CASHCTRL_API_KEY"]
33
+ config.language = "en"
34
+ end
35
+ ```
36
+
37
+ - `org` - Your CashCtrl subdomain
38
+ - `api_key` - Your API key
39
+ - `language` - Optional: `en`, `de`, `fr`, `it` (default: `en`)
40
+
41
+ ### Per-Client Configuration
42
+
43
+ For multi-tenant applications or testing:
44
+
45
+ ```ruby
46
+ client = Cashctrl::Client.new(
47
+ org: "other-organization",
48
+ api_key: "different-api-key",
49
+ language: "de"
50
+ )
21
51
  ```
22
52
 
23
53
  ## Usage
24
54
 
25
- TODO: Write usage instructions here
55
+ ### Two API Styles
56
+
57
+ The gem supports two usage patterns:
58
+
59
+ #### 1. Class Methods (uses global configuration)
60
+
61
+ **List all accounts:**
62
+
63
+ ```ruby
64
+ Cashctrl::Account.list
65
+ ```
66
+
67
+ **Read a specific account:**
68
+
69
+ ```ruby
70
+ Cashctrl::Account.read(id: 1)
71
+ ```
72
+
73
+ **Create an account:**
74
+
75
+ ```ruby
76
+ Cashctrl::Account.create(number: "1000", name: "Cash", categoryId: 1)
77
+ ```
78
+
79
+ **Update an account:**
80
+
81
+ ```ruby
82
+ Cashctrl::Account.update(id: 1, name: "Updated Name")
83
+ ```
84
+
85
+ **Delete accounts:**
86
+
87
+ ```ruby
88
+ Cashctrl::Account.delete(ids: [1, 2, 3])
89
+ ```
90
+
91
+ #### 2. Client Instance (custom configuration)
92
+
93
+ ```ruby
94
+ client = Cashctrl::Client.new(org: "myorg", api_key: "key")
95
+
96
+ client.accounts.list
97
+ client.accounts.read(id: 1)
98
+ client.accounts.create(number: "1000", name: "Cash", categoryId: 1)
99
+ client.persons.list
100
+ client.orders.list
101
+ ```
102
+
103
+ #### Convenience Methods
104
+
105
+ All resources support these shortcuts and aliases:
106
+
107
+ ```ruby
108
+ Cashctrl::Account.all # alias for .list
109
+ Cashctrl::Account.find(1) # alias for .read(id: 1)
110
+
111
+ Cashctrl::Account.first # alias for .list.first
112
+ Cashctrl::Account.last # alias for .list.last
113
+
114
+ client.accounts.all
115
+ client.accounts.find(1)
116
+ client.orders.first
117
+ ```
118
+
119
+ ### Core Resources
120
+
121
+ #### Accounts
122
+
123
+ **List accounts:**
124
+
125
+ ```ruby
126
+ Cashctrl::Account.list
127
+ ```
128
+
129
+ **Get first or last account:**
130
+
131
+ ```ruby
132
+ Cashctrl::Account.first
133
+ Cashctrl::Account.last
134
+ ```
135
+
136
+ **Find account by number:**
137
+
138
+ ```ruby
139
+ Cashctrl::Account.find_by_number("1000")
140
+ ```
141
+
142
+ **Get account balance:**
143
+
144
+ ```ruby
145
+ Cashctrl::Account.balance(id: 1, date: "2024-12-31")
146
+ ```
147
+
148
+ **Account categories:**
149
+
150
+ ```ruby
151
+ Cashctrl::Account::Category.list
152
+ Cashctrl::Account::Category.tree
153
+ ```
154
+
155
+ **Bank accounts:**
156
+
157
+ ```ruby
158
+ Cashctrl::Account::Bank.list
159
+ Cashctrl::Account::Bank.create(name: "Main Bank", accountId: 1)
160
+ ```
161
+
162
+ **Cost centers:**
163
+
164
+ ```ruby
165
+ Cashctrl::Account::CostCenter.list
166
+ Cashctrl::Account::CostCenter.balance(id: 1)
167
+ ```
168
+
169
+ #### Persons (Contacts)
170
+
171
+ ```ruby
172
+ Cashctrl::Person.list
173
+ Cashctrl::Person.read(id: 1)
174
+ Cashctrl::Person.create(firstName: "John", lastName: "Doe", isCustomer: true)
175
+ Cashctrl::Person.categorize(ids: [1, 2], target: 5)
176
+ ```
177
+
178
+ **Person categories:**
179
+
180
+ ```ruby
181
+ Cashctrl::Person::Category.list
182
+ Cashctrl::Person::Category.tree
183
+ ```
184
+
185
+ **Titles (Mr., Mrs., etc.):**
186
+
187
+ ```ruby
188
+ Cashctrl::Person::Title.list
189
+ ```
190
+
191
+ #### Orders (Invoices, Quotes, etc.)
192
+
193
+ ```ruby
194
+ Cashctrl::Order.list
195
+ Cashctrl::Order.read(id: 1)
196
+ Cashctrl::Order.create(
197
+ associateId: 1,
198
+ categoryId: 1,
199
+ items: [{ accountId: 100, name: "Service", unitPrice: 100 }].to_json
200
+ )
201
+ Cashctrl::Order.update_status(id: 1, status: "S")
202
+ ```
203
+
204
+ **Order documents (PDF generation):**
205
+
206
+ ```ruby
207
+ Cashctrl::Order::Document.read(id: 1)
208
+ Cashctrl::Order::Document.read_pdf(id: 1)
209
+ Cashctrl::Order::Document.mail(id: 1, recipientEmail: "client@example.com")
210
+ ```
211
+
212
+ **Order categories:**
213
+
214
+ ```ruby
215
+ Cashctrl::Order::Category.list
216
+ ```
217
+
218
+ #### Journal Entries
219
+
220
+ ```ruby
221
+ Cashctrl::Journal.list
222
+ Cashctrl::Journal.read(id: 1)
223
+ ```
224
+
225
+ **Create with account IDs:**
226
+
227
+ ```ruby
228
+ Cashctrl::Journal.create(
229
+ debitId: 1,
230
+ creditId: 2,
231
+ amount: 100.00,
232
+ dateAdded: "2024-01-15",
233
+ title: "Payment received"
234
+ )
235
+ ```
236
+
237
+ **Create with account numbers:**
238
+
239
+ ```ruby
240
+ Cashctrl::Journal.create(
241
+ debit: "1000",
242
+ credit: "2000",
243
+ amount: 100.00,
244
+ dateAdded: "2024-01-15",
245
+ title: "Payment received"
246
+ )
247
+ ```
248
+
249
+ **Create with Account objects:**
250
+
251
+ ```ruby
252
+ cash_account = Cashctrl::Account.find_by_number("1000")
253
+ bank_account = Cashctrl::Account.find_by_number("1020")
254
+
255
+ Cashctrl::Journal.create(
256
+ debit: cash_account,
257
+ credit: bank_account,
258
+ amount: 500.00,
259
+ dateAdded: "2024-01-15",
260
+ title: "Cash deposit"
261
+ )
262
+ ```
263
+
264
+ #### Currencies
265
+
266
+ ```ruby
267
+ Cashctrl::Currency.list
268
+ Cashctrl::Currency.read(id: 1)
269
+ Cashctrl::Currency.exchange_rate(from: "CHF", to: "EUR", date: "2024-01-15")
270
+ ```
271
+
272
+ #### Tax Rates
273
+
274
+ ```ruby
275
+ Cashctrl::Tax.list
276
+ Cashctrl::Tax.read(id: 1)
277
+ Cashctrl::Tax.create(name: "VAT 8.1%", percentage: 8.1)
278
+ ```
279
+
280
+ #### Fiscal Periods
281
+
282
+ ```ruby
283
+ Cashctrl::FiscalPeriod.list
284
+ Cashctrl::FiscalPeriod.result(id: 1)
285
+ Cashctrl::FiscalPeriod.switch(id: 2)
286
+ Cashctrl::FiscalPeriod.complete(id: 1)
287
+ Cashctrl::FiscalPeriod.book_depreciations(id: 1)
288
+ ```
289
+
290
+ #### Reports
291
+
292
+ ```ruby
293
+ Cashctrl::Report.tree
294
+ ```
295
+
296
+ **Report collections:**
297
+
298
+ ```ruby
299
+ Cashctrl::Report::Collection.read(id: 1)
300
+ Cashctrl::Report::Collection.download_pdf(id: 1)
301
+ Cashctrl::Report::Collection.download_annual_report(id: 1)
302
+ ```
303
+
304
+ **Report elements:**
305
+
306
+ ```ruby
307
+ Cashctrl::Report::Element.read(id: 1)
308
+ Cashctrl::Report::Element.data(id: 1)
309
+ Cashctrl::Report::Element.download_xlsx(id: 1)
310
+ ```
311
+
312
+ #### Inventory
313
+
314
+ **Articles:**
315
+
316
+ ```ruby
317
+ Cashctrl::Resources::Inventory::Article.list
318
+ Cashctrl::Resources::Inventory::Article.create(name: "Product", unitPrice: 50.00)
319
+ ```
320
+
321
+ **Fixed assets:**
322
+
323
+ ```ruby
324
+ Cashctrl::Resources::Inventory::Asset.list
325
+ ```
326
+
327
+ **Units:**
328
+
329
+ ```ruby
330
+ Cashctrl::Resources::Inventory::Unit.list
331
+ ```
332
+
333
+ #### Files
334
+
335
+ ```ruby
336
+ client.files.list
337
+ client.files.get(id: 1)
338
+ client.files.prepare(mime_type: "application/pdf", name: "invoice.pdf")
339
+ client.files.persist(ids: [1])
340
+ ```
341
+
342
+ ### Typed Models & Collections
343
+
344
+ API responses are automatically converted to typed Ruby objects.
345
+
346
+ **List returns a Collection:**
347
+
348
+ ```ruby
349
+ accounts = Cashctrl::Account.list
350
+ accounts.class
351
+ accounts.total
352
+ accounts.each { |a| puts a.name }
353
+ ```
354
+
355
+ **Individual records are typed models:**
356
+
357
+ ```ruby
358
+ account = accounts.first
359
+ account.class
360
+ account.id
361
+ account.name
362
+ account.number
363
+ ```
364
+
365
+ **Read also returns typed models:**
366
+
367
+ ```ruby
368
+ account = Cashctrl::Account.read(id: 1)
369
+ account.class
370
+ ```
371
+
372
+ #### Type Coercion
373
+
374
+ Fields are automatically converted to appropriate Ruby types.
375
+
376
+ **DateTime fields:**
377
+
378
+ ```ruby
379
+ account = Cashctrl::Account.read(id: 1)
380
+ account.created
381
+ account.last_updated
382
+ ```
383
+
384
+ **BigDecimal for monetary values:**
385
+
386
+ ```ruby
387
+ account.opening_amount
388
+ account.end_amount
389
+ ```
390
+
391
+ **Booleans:**
392
+
393
+ ```ruby
394
+ account.is_inactive
395
+ ```
396
+
397
+ **Date fields:**
398
+
399
+ ```ruby
400
+ person = Cashctrl::Person.read(id: 1)
401
+ person.date_birth
402
+ ```
403
+
404
+ #### Accessing Raw API Response
405
+
406
+ The original API response is always available:
407
+
408
+ ```ruby
409
+ account = Cashctrl::Account.read(id: 1)
410
+ account.raw_data
411
+ ```
412
+
413
+ ### Localized Strings (i18n)
414
+
415
+ CashCtrl returns multi-language strings in XML format. These are automatically parsed into `LocalizedString` objects.
416
+
417
+ **Localized fields return LocalizedString objects:**
418
+
419
+ ```ruby
420
+ account = Cashctrl::Account.read(id: 1)
421
+ account.category_display.class
422
+ ```
423
+
424
+ **Access specific languages:**
425
+
426
+ ```ruby
427
+ account.category_display.de
428
+ account.category_display.en
429
+ account.category_display.fr
430
+ account.category_display.it
431
+ ```
432
+
433
+ **`to_s` returns the value for the current locale:**
434
+
435
+ ```ruby
436
+ account.category_display.to_s
437
+ ```
438
+
439
+ **Get all translations as a hash:**
440
+
441
+ ```ruby
442
+ account.category_display.to_h
443
+ ```
444
+
445
+ The locale is determined by (in order of priority):
446
+ 1. `I18n.locale` if I18n is available
447
+ 2. `Cashctrl.configuration.language`
448
+ 3. Falls back to `"en"`
449
+
450
+ ### Export Formats
451
+
452
+ Many list endpoints support CSV, Excel, and PDF exports:
453
+
454
+ ```ruby
455
+ client.accounts.list_csv
456
+ client.accounts.list_xlsx
457
+ client.accounts.list_pdf
458
+ ```
459
+
460
+ ### Error Handling
461
+
462
+ ```ruby
463
+ begin
464
+ Cashctrl::Account.read(id: 999999)
465
+ rescue Cashctrl::AuthenticationError => e
466
+ puts "Invalid API key"
467
+ rescue Cashctrl::NotFoundError => e
468
+ puts "Resource not found"
469
+ rescue Cashctrl::ValidationError => e
470
+ puts "Validation failed"
471
+ puts e.errors
472
+ rescue Cashctrl::RateLimitError => e
473
+ puts "Too many requests"
474
+ rescue Cashctrl::ServerError => e
475
+ puts "Server error (5xx)"
476
+ rescue Cashctrl::Error => e
477
+ puts "Generic error"
478
+ end
479
+ ```
480
+
481
+ ### All Available Resources
482
+
483
+ | Resource | Class |
484
+ |----------|-------|
485
+ | Accounts | `Cashctrl::Account` |
486
+ | Account Banks | `Cashctrl::Account::Bank` |
487
+ | Account Categories | `Cashctrl::Account::Category` |
488
+ | Cost Centers | `Cashctrl::Account::CostCenter` |
489
+ | Currencies | `Cashctrl::Currency` |
490
+ | Custom Fields | `Cashctrl::CustomField` |
491
+ | Files | `Cashctrl::Resources::CashctrlFile` |
492
+ | Fiscal Periods | `Cashctrl::FiscalPeriod` |
493
+ | History | `Cashctrl::Resources::History` |
494
+ | Inventory Articles | `Cashctrl::Resources::Inventory::Article` |
495
+ | Inventory Assets | `Cashctrl::Resources::Inventory::Asset` |
496
+ | Inventory Units | `Cashctrl::Resources::Inventory::Unit` |
497
+ | Journal | `Cashctrl::Journal` |
498
+ | Locations | `Cashctrl::Location` |
499
+ | Orders | `Cashctrl::Order` |
500
+ | Order Categories | `Cashctrl::Order::Category` |
501
+ | Order Documents | `Cashctrl::Order::Document` |
502
+ | Persons | `Cashctrl::Person` |
503
+ | Person Categories | `Cashctrl::Person::Category` |
504
+ | Person Titles | `Cashctrl::Person::Title` |
505
+ | Reports | `Cashctrl::Report` |
506
+ | Report Collections | `Cashctrl::Report::Collection` |
507
+ | Report Elements | `Cashctrl::Report::Element` |
508
+ | Roundings | `Cashctrl::Rounding` |
509
+ | Salary (all sub-resources) | `Cashctrl::Resources::Salary::*` |
510
+ | Sequence Numbers | `Cashctrl::SequenceNumber` |
511
+ | Settings | `Cashctrl::Setting` |
512
+ | Tax Rates | `Cashctrl::Tax` |
513
+ | Text Templates | `Cashctrl::Text` |
514
+
515
+ ## API Documentation
516
+
517
+ For full API documentation, see the [CashCtrl API Reference](https://app.cashctrl.com/static/help/en/api/index.html).
26
518
 
27
519
  ## Development
28
520
 
29
521
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
522
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
523
+ To install this gem onto your local machine, run `bundle exec rake install`.
524
+
525
+ ### Model Generator
526
+
527
+ Model classes are auto-generated from `lib/cashctrl/schema.yml`. The schema defines attributes and their types for each resource.
528
+
529
+ **Schema format:**
530
+
531
+ ```yaml
532
+ account:
533
+ attributes:
534
+ id:
535
+ type: integer
536
+ readonly: true
537
+ number:
538
+ type: string
539
+ name:
540
+ type: string
541
+ opening_amount:
542
+ type: decimal
543
+ created:
544
+ type: datetime
545
+ readonly: true
546
+ is_inactive:
547
+ type: boolean
548
+ ```
549
+
550
+ **Supported types:**
551
+
552
+ - `string` - Plain strings (auto-detects localized XML strings)
553
+ - `integer` - Integer values
554
+ - `decimal` - BigDecimal for monetary values
555
+ - `boolean` - Boolean values
556
+ - `date` - Date objects
557
+ - `datetime` - DateTime objects
558
+ - `json` - JSON parsed objects
559
+
560
+ **Regenerate models after schema changes:**
561
+
562
+ ```bash
563
+ ruby lib/generators/model_generator.rb
564
+ ```
565
+
566
+ This generates model classes in `lib/cashctrl/models/` with proper type coercion.
32
567
 
33
568
  ## Contributing
34
569
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/marcoroth/cashctrl. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/marcoroth/cashctrl/blob/main/CODE_OF_CONDUCT.md).
570
+ Bug reports and pull requests are welcome on GitHub at https://github.com/marcoroth/cashctrl-ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/marcoroth/cashctrl-ruby/blob/main/CODE_OF_CONDUCT.md).
36
571
 
37
- ## Code of Conduct
572
+ ## License
38
573
 
39
- Everyone interacting in the Cashctrl project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/marcoroth/cashctrl/blob/main/CODE_OF_CONDUCT.md).
574
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).