conexa 0.0.7 → 0.0.8

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: 8f797946a06e5b411bab47be327b805494a3baae97afb9faa629d0f5b45318a6
4
- data.tar.gz: a4433c392325e634d6ded5996a809dc124a2e1d75c3239af8050fbf8f3402c47
3
+ metadata.gz: '050626980d9f896ca2c70ed30a27c1cfda7d0d30c89e25c90e86422d122fb1af'
4
+ data.tar.gz: 43134221ca4dd8f38bc3f8a62bfffe2807d1565e949e2adf72d446fa14db01cf
5
5
  SHA512:
6
- metadata.gz: 780a9f5f20b67d1b8a0917b41ff82e06536a79e9f23c29125c7627f2f84efd084e24d6d435d49603b7d3a1df65a5dd3880dea2c3168af653b71ae75800089fda
7
- data.tar.gz: 86bf266d620205ca7d52416775feec983f4d197ade8c241f4812d443b6776c850a12ac66ca3fb517a768f6caa60957843f5bebdb1653e17e590fc40c6338f482
6
+ metadata.gz: 298ef626afb7783dff6d66161e20ff4b28b30b0d81761ce3f5debf187f1d60e0d01814004d3372ad6531b5e40e22e110af471522bbc577e3c0baac63dfb17014
7
+ data.tar.gz: 768fbc470c103074ff5b768bf78ba6ed47385c4d06a7cadba7aed395947da92c73756c8f72c06e66be15520974c7f0c2e8438dfc567181cc83357416cad251d5
data/CHANGELOG.md CHANGED
@@ -7,6 +7,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.0.8] - 2026-02-19
11
+
12
+ ### Fixed
13
+ - `Auth.login` usava `Request.post` (inclui header Authorization) ao invés de `Request.auth`
14
+ - `Model#primary_key_name` retornava nomes incorretos para classes compostas (ex: `creditcard_id` ao invés de `credit_card_id`)
15
+ - `Model.destroy(id)` falhava para resources com `primary_key_attribute` definido
16
+ - `Model#destroy` retornava Hash interno ao invés de `self`
17
+ - `Person` tinha `find`, `all` e `find_by` desnecessariamente desabilitados (a API suporta todos os endpoints CRUD)
18
+
19
+ ### Added
20
+ - Testes de autenticação com cassettes VCR (13 specs)
21
+ - Testes de integração WebMock para Sale, RecurringSale, Plan, Product, Bill, Supplier, Company, CreditCard, Person e InvoicingMethod
22
+ - Total de testes: 407 specs
23
+
24
+ ### Changed
25
+ - `REFERENCE.md` reescrito com documentação completa de todos os endpoints baseada na collection Postman
26
+ - nokogiri atualizado para 1.19.1
27
+
10
28
  ## [0.0.7] - 2026-02-12
11
29
 
12
30
  ### Added
@@ -43,7 +61,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
43
61
  - Charge with settle and PIX methods
44
62
  - Pagination support
45
63
 
46
- [Unreleased]: https://github.com/guilhermegazzinelli/conexa-ruby/compare/v0.0.7...HEAD
64
+ [Unreleased]: https://github.com/guilhermegazzinelli/conexa-ruby/compare/v0.0.8...HEAD
65
+ [0.0.8]: https://github.com/guilhermegazzinelli/conexa-ruby/compare/v0.0.7...v0.0.8
47
66
  [0.0.7]: https://github.com/guilhermegazzinelli/conexa-ruby/compare/v0.0.6...v0.0.7
48
67
  [0.0.6]: https://github.com/guilhermegazzinelli/conexa-ruby/compare/v0.0.5...v0.0.6
49
68
  [0.0.5]: https://github.com/guilhermegazzinelli/conexa-ruby/releases/tag/v0.0.5
data/Gemfile CHANGED
@@ -11,8 +11,6 @@ gem "rspec", "~> 3.0"
11
11
 
12
12
  gem "rubocop", "~> 1.21"
13
13
 
14
- gem "solargraph"
15
-
16
14
  gem "standard"
17
15
 
18
16
  gem "debug"
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- conexa (0.0.6)
4
+ conexa (0.0.8)
5
5
  jwt
6
6
  multi_json
7
7
  rest-client
@@ -23,9 +23,7 @@ GEM
23
23
  addressable (2.8.7)
24
24
  public_suffix (>= 2.0.2, < 7.0)
25
25
  ast (2.4.2)
26
- backport (1.2.0)
27
26
  base64 (0.2.0)
28
- benchmark (0.3.0)
29
27
  bigdecimal (3.1.8)
30
28
  byebug (11.1.3)
31
29
  concurrent-ruby (1.3.4)
@@ -39,7 +37,6 @@ GEM
39
37
  diff-lcs (1.5.1)
40
38
  domain_name (0.6.20240107)
41
39
  drb (2.2.1)
42
- e2mmap (0.1.0)
43
40
  factory_bot (6.5.0)
44
41
  activesupport (>= 5.0.0)
45
42
  faker (3.5.1)
@@ -54,14 +51,9 @@ GEM
54
51
  irb (1.14.1)
55
52
  rdoc (>= 4.0.0)
56
53
  reline (>= 0.4.2)
57
- jaro_winkler (1.6.0)
58
54
  json (2.7.2)
59
55
  jwt (3.1.2)
60
56
  base64
61
- kramdown (2.4.0)
62
- rexml
63
- kramdown-parser-gfm (1.1.0)
64
- kramdown (~> 2.0)
65
57
  language_server-protocol (3.17.0.3)
66
58
  lint_roller (1.1.0)
67
59
  logger (1.6.1)
@@ -72,8 +64,6 @@ GEM
72
64
  minitest (5.25.1)
73
65
  multi_json (1.19.1)
74
66
  netrc (0.11.0)
75
- nokogiri (1.16.7-x86_64-linux)
76
- racc (~> 1.4)
77
67
  parallel (1.26.3)
78
68
  parser (3.3.5.0)
79
69
  ast (~> 2.4.1)
@@ -84,7 +74,6 @@ GEM
84
74
  racc (1.8.1)
85
75
  rainbow (3.1.1)
86
76
  rake (13.2.1)
87
- rbs (2.8.4)
88
77
  rdoc (6.7.0)
89
78
  psych (>= 4.0.0)
90
79
  regexp_parser (2.9.2)
@@ -95,8 +84,6 @@ GEM
95
84
  http-cookie (>= 1.0.2, < 2.0)
96
85
  mime-types (>= 1.16, < 4.0)
97
86
  netrc (~> 0.8)
98
- reverse_markdown (2.1.1)
99
- nokogiri
100
87
  rexml (3.3.8)
101
88
  rspec (3.13.0)
102
89
  rspec-core (~> 3.13.0)
@@ -128,22 +115,6 @@ GEM
128
115
  rubocop-ast (>= 1.31.1, < 2.0)
129
116
  ruby-progressbar (1.13.0)
130
117
  securerandom (0.3.1)
131
- solargraph (0.50.0)
132
- backport (~> 1.2)
133
- benchmark
134
- bundler (~> 2.0)
135
- diff-lcs (~> 1.4)
136
- e2mmap
137
- jaro_winkler (~> 1.5)
138
- kramdown (~> 2.3)
139
- kramdown-parser-gfm (~> 1.1)
140
- parser (~> 3.0)
141
- rbs (~> 2.0)
142
- reverse_markdown (~> 2.0)
143
- rubocop (~> 1.38)
144
- thor (~> 1.0)
145
- tilt (~> 2.0)
146
- yard (~> 0.9, >= 0.9.24)
147
118
  standard (1.41.1)
148
119
  language_server-protocol (~> 3.17.0.2)
149
120
  lint_roller (~> 1.0)
@@ -157,8 +128,6 @@ GEM
157
128
  lint_roller (~> 1.1)
158
129
  rubocop-performance (~> 1.22.0)
159
130
  stringio (3.1.1)
160
- thor (1.3.2)
161
- tilt (2.4.0)
162
131
  tzinfo (2.0.6)
163
132
  concurrent-ruby (~> 1.0)
164
133
  unicode-display_width (2.6.0)
@@ -168,10 +137,10 @@ GEM
168
137
  addressable (>= 2.8.0)
169
138
  crack (>= 0.3.2)
170
139
  hashdiff (>= 0.4.0, < 2.0.0)
171
- yard (0.9.37)
172
140
 
173
141
  PLATFORMS
174
- x86_64-linux
142
+ ruby
143
+ x86_64-linux-gnu
175
144
 
176
145
  DEPENDENCIES
177
146
  byebug
@@ -182,7 +151,6 @@ DEPENDENCIES
182
151
  rake (~> 13.0)
183
152
  rspec (~> 3.0)
184
153
  rubocop (~> 1.21)
185
- solargraph
186
154
  standard
187
155
  vcr
188
156
  webmock
data/REFERENCE.md CHANGED
@@ -7,19 +7,24 @@
7
7
  Conexa is a Brazilian SaaS platform for **recurring billing**, **subscription management**, and **financial operations**. This gem provides a Ruby interface to their REST API v2.
8
8
 
9
9
  **Key concepts:**
10
+ - **Auth** - Username/password authentication (JWT)
10
11
  - **Customer** - Client (PF or PJ) who receives invoices
11
12
  - **Contract** - Recurring billing agreement with a plan
12
13
  - **Charge** - Individual invoice/boleto generated for payment
13
14
  - **Sale** - One-time sale (not recurring)
14
15
  - **RecurringSale** - Recurring sale item within a contract
15
- - **Plan** - Predefined pricing plan with products
16
+ - **Plan** - Pricing plan with products and periodicities
16
17
  - **Product** - Billable item/service
18
+ - **InvoicingMethod** - Payment method configuration (boleto, PIX, credit card)
19
+ - **Person** - Requester (solicitante) linked to a customer
20
+ - **Bill** - Financial bill (conta a pagar)
21
+ - **Supplier** - Supplier with PF/PJ data
17
22
 
18
23
  ## Installation
19
24
 
20
25
  ```ruby
21
26
  # Gemfile
22
- gem 'conexa', '~> 0.0.6'
27
+ gem 'conexa', '~> 0.0.7'
23
28
 
24
29
  # Or install directly
25
30
  gem install conexa
@@ -43,13 +48,13 @@ rails generate conexa:install
43
48
  This gem follows Ruby/Rails conventions. Use **snake_case** for all parameters - the gem automatically converts to camelCase for the API.
44
49
 
45
50
  ```ruby
46
- # Correct - snake_case
51
+ # Correct - snake_case
47
52
  Conexa::Customer.create(
48
53
  company_id: 3,
49
54
  legal_person: { cnpj: '99.557.155/0001-90' }
50
55
  )
51
56
 
52
- # Avoid - camelCase (works but not idiomatic)
57
+ # Avoid - camelCase (works but not idiomatic)
53
58
  Conexa::Customer.create(
54
59
  companyId: 3,
55
60
  legalPerson: { cnpj: '99.557.155/0001-90' }
@@ -67,25 +72,111 @@ customer.legal_person # => { cnpj: '...' }
67
72
 
68
73
  ## Resources
69
74
 
75
+ ### Auth
76
+
77
+ Authenticates with username/password and returns a JWT token. Does not require a pre-configured `api_token`.
78
+
79
+ ```ruby
80
+ # Authenticate
81
+ auth = Conexa::Auth.login(username: 'admin', password: 'secret')
82
+ # or
83
+ auth = Conexa::Auth.authenticate(username: 'admin', password: 'secret')
84
+
85
+ auth.access_token # => "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
86
+ auth.token_type # => "Bearer"
87
+ auth.expires_in # => 28800 (8 hours in seconds)
88
+ auth.user.id # => 1
89
+ auth.user.type # => "admin" or "employee"
90
+ auth.user.name # => "Luke Skywalker"
91
+
92
+ # Use the token for subsequent requests
93
+ Conexa.configure { |c| c.api_token = auth.access_token }
94
+ ```
95
+
96
+ **API endpoint:** `POST /auth`
97
+
98
+ **Request body:**
99
+ - `username` - Login username (admin login or employee email)
100
+ - `password` - Password
101
+
102
+ **Response attributes:**
103
+ - `user` - User object with `id`, `type`, `name`
104
+ - `token_type` - Always "Bearer"
105
+ - `access_token` - JWT token for subsequent requests
106
+ - `expires_in` - Token expiration in seconds (28800 = 8 hours)
107
+
108
+ **Errors:**
109
+ - `Conexa::ResponseError` - Invalid credentials (401), validation errors (400)
110
+
111
+ ---
112
+
70
113
  ### Customer
71
114
 
72
- Manages clients (pessoas físicas ou jurídicas).
115
+ Manages clients (pessoas fisicas ou juridicas).
73
116
 
74
117
  ```ruby
75
- # Create customer (Pessoa Jurídica)
118
+ # Create customer (Pessoa Juridica)
76
119
  customer = Conexa::Customer.create(
77
120
  company_id: 3,
78
121
  name: 'Empresa ABC Ltda',
79
- legal_person: { cnpj: '99.557.155/0001-90' },
122
+ trade_name: 'ABC',
123
+ field_of_activity: 'Tecnologia',
124
+ notes: 'Cliente VIP',
125
+ cell_number: '31999998888',
126
+ phones: ['3133334444', '3144445555'],
127
+ website: 'https://www.abc.com.br',
128
+ has_login_access: true,
129
+ login: 'empresa@abc.com.br',
130
+ password: 'SecurePass123',
131
+ legal_person: {
132
+ cnpj: '99.557.155/0001-90',
133
+ foundation_date: '2020-01-15',
134
+ state_inscription: '123456789',
135
+ municipal_inscription: '98765432'
136
+ },
137
+ address: {
138
+ zip_code: '30130000',
139
+ state: 'MG',
140
+ city: 'Belo Horizonte',
141
+ street: 'Av. Afonso Pena',
142
+ number: '1000',
143
+ neighborhood: 'Centro',
144
+ additional_details: 'Sala 501'
145
+ },
80
146
  emails_message: ['contato@abc.com.br'],
81
- phones: ['31999998888']
147
+ emails_financial_messages: ['financeiro@abc.com.br'],
148
+ default_due_day: 10,
149
+ tax_deductions: {
150
+ iss: 0, ir: 0, pis: 0, inss: 0, csll: 0, cofins: 0
151
+ },
152
+ extra_fields: [
153
+ { id: 1, value: 'Valor 1' }
154
+ ]
155
+ )
156
+
157
+ # Create customer (Pessoa Fisica)
158
+ customer = Conexa::Customer.create(
159
+ company_id: 3,
160
+ name: 'Joao Silva',
161
+ natural_person: {
162
+ cpf: '123.456.789-00',
163
+ rg: '123456789',
164
+ birth_date: '1990-05-15',
165
+ issuing_authority: 'SSP/MG',
166
+ profession: 'Desenvolvedor',
167
+ marital_status: 'single' # single, married, divorced, widowed, not informed
168
+ }
82
169
  )
83
170
 
84
- # Create customer (Pessoa Física)
171
+ # Create customer (Estrangeiro)
85
172
  customer = Conexa::Customer.create(
86
173
  company_id: 3,
87
- name: 'João Silva',
88
- natural_person: { cpf: '123.456.789-00' }
174
+ name: 'John Smith',
175
+ foreign: {
176
+ document: 'ABC123456',
177
+ birth_date: '1985-03-20',
178
+ profession: 'Engineer'
179
+ }
89
180
  )
90
181
 
91
182
  # Find by ID
@@ -111,25 +202,49 @@ customer.save
111
202
  customer.destroy
112
203
  # or
113
204
  Conexa::Customer.destroy(127)
205
+
206
+ # Sub-resources
207
+ Conexa::Customer.persons(127) # List persons for customer
208
+ Conexa::Customer.contracts(127) # List contracts for customer
209
+ Conexa::Customer.charges(127) # List charges for customer
114
210
  ```
115
211
 
116
- **Customer attributes:**
117
- - `customer_id` - ID
118
- - `company_id` - Unit/company ID
119
- - `name` - Full name
212
+ **API endpoints:** `POST /customer`, `GET /customer/:id`, `PATCH /customer/:id`, `DELETE /customer/:id`, `GET /customers`
213
+
214
+ **Create/update attributes:**
215
+ - `company_id` - Unit/company ID (required on create)
216
+ - `name` - Full name (required on create)
120
217
  - `trade_name` - Trade name (optional)
121
- - `has_login_access` - Has portal access
218
+ - `pronunciation` - Name pronunciation (optional)
219
+ - `field_of_activity` - Field of activity
220
+ - `notes` - General notes
221
+ - `cell_number` - Cell phone number
222
+ - `phones` - Array of phone numbers
223
+ - `website` - Website URL
224
+ - `has_login_access` - Has portal access (boolean)
225
+ - `login` - Login email (when has_login_access is true)
226
+ - `password` - Login password (when has_login_access is true)
227
+ - `legal_person` - PJ data: `cnpj`, `foundation_date`, `state_inscription`, `municipal_inscription`
228
+ - `natural_person` - PF data: `cpf`, `rg`, `birth_date`, `issuing_authority`, `profession`, `marital_status`
229
+ - `foreign` - Foreign data: `document`, `birth_date`, `profession`
230
+ - `address` - Address: `zip_code`, `state`, `city`, `street`, `number`, `neighborhood`, `additional_details`
231
+ - `mailing_address` - Mailing address (same structure as address)
232
+ - `emails_message` - Array of general emails
233
+ - `emails_financial_messages` - Array of financial emails
234
+ - `tags_id` - Array of tag IDs
235
+ - `default_due_day` - Default due day for charges
236
+ - `tax_deductions` - Tax deductions: `iss`, `ir`, `pis`, `inss`, `csll`, `cofins`
237
+ - `extra_fields` - Array of `{ id, value }` for custom fields
238
+ - `automatically_issue_nfse` - Auto-generate NFSe (boolean)
239
+ - `notes_nfse` - NFSe notes
240
+ - `extension_numbers` - Extension numbers
241
+
242
+ **Read-only attributes:**
243
+ - `customer_id` - ID
122
244
  - `is_active` - Active status
123
245
  - `is_blocked` - Blocked status
124
246
  - `is_juridical_person` - Is PJ (legal person)
125
247
  - `is_foreign` - Is foreigner
126
- - `address` - Address object
127
- - `legal_person` - PJ data (cnpj, etc)
128
- - `natural_person` - PF data (cpf, etc)
129
- - `phones` - Array of phones
130
- - `emails_message` - General emails
131
- - `emails_financial_messages` - Financial emails
132
- - `tags_id` - Tag IDs
133
248
  - `created_at` - Creation timestamp
134
249
 
135
250
  ---
@@ -139,13 +254,34 @@ Conexa::Customer.destroy(127)
139
254
  Manages recurring billing contracts.
140
255
 
141
256
  ```ruby
142
- # Create contract
257
+ # Create contract with plan
143
258
  contract = Conexa::Contract.create(
144
259
  customer_id: 127,
145
260
  plan_id: 5,
146
261
  start_date: '2024-01-01',
147
- payment_day: 10,
148
- invoicing_method_id: 1
262
+ due_day: 10,
263
+ payment_frequency: 'monthly',
264
+ amount: 500.00,
265
+ seller_id: 1,
266
+ contract_summary: 'Contrato mensal',
267
+ notes: 'Observacoes',
268
+ membership_fee: 100.00,
269
+ generate_sales: true,
270
+ prorata_type: 'proportional',
271
+ nfse_description: 'Servicos de coworking',
272
+ refund: {
273
+ amount: 1000.00,
274
+ date_limit: '2025-01-01',
275
+ is_to_generate_refund_billet: false
276
+ },
277
+ complementary_services: [
278
+ { product_or_service_id: 100, quantity: 1, amount: 50.00, notes: 'Servico extra' }
279
+ ],
280
+ service_correspondence_quotas: {
281
+ limited: true,
282
+ messages_limit: 100,
283
+ price_additional_message: 2.50
284
+ }
149
285
  )
150
286
 
151
287
  # Create with custom products (no plan)
@@ -162,8 +298,8 @@ contract = Conexa::Contract.create_with_products(
162
298
  # Find contract
163
299
  contract = Conexa::Contract.find(456)
164
300
  contract.status # => "active"
165
- contract.plan_id # => 5
166
- contract.payment_day # => 10
301
+ contract.active? # => true
302
+ contract.ended? # => false
167
303
 
168
304
  # List contracts
169
305
  contracts = Conexa::Contract.all(
@@ -172,36 +308,81 @@ contracts = Conexa::Contract.all(
172
308
  )
173
309
 
174
310
  # End/terminate contract
175
- contract.end_contract(end_date: '2024-12-31', reason: 'Cliente solicitou')
311
+ contract.end_contract(date: '2024-12-31', reason_id: 1, unlink_customer: false)
176
312
  # or
177
- Conexa::Contract.end_contract(456, end_date: '2024-12-31')
313
+ Conexa::Contract.end_contract(456, date: '2024-12-31')
178
314
 
179
315
  # Update
180
- contract.payment_day = 15
316
+ contract.due_day = 15
181
317
  contract.save
318
+
319
+ # Delete
320
+ contract.destroy
182
321
  ```
183
322
 
184
- **Contract attributes:**
185
- - `contract_id` - ID
186
- - `customer_id` - Customer ID
187
- - `plan_id` - Plan ID (optional)
188
- - `status` - Status (active, ended, cancelled)
323
+ **API endpoints:** `POST /contract`, `GET /contract/:id`, `PATCH /contract/:id`, `DELETE /contract/:id`, `PATCH /contract/end/:id`, `GET /contracts`
324
+
325
+ **Create attributes:**
326
+ - `customer_id` - Customer ID (required)
327
+ - `plan_id` - Plan ID (optional, alternative to items)
328
+ - `payment_frequency` - monthly, bimonthly, quarterly, semester, yearly
189
329
  - `start_date` - Start date
190
- - `end_date` - End date (if terminated)
191
- - `payment_day` - Day of month for billing (1-28)
330
+ - `end_date` - End date (optional)
331
+ - `due_day` - Day of month for billing (1-28)
332
+ - `fidelity_date` - Fidelity end date
333
+ - `amount` - Contract value
334
+ - `discount_value` - Discount value
335
+ - `seller_id` - Seller user ID
336
+ - `contract_summary` - Summary text
337
+ - `notes` - Notes
338
+ - `membership_fee` - Membership fee
339
+ - `generate_sales` - Auto-generate sales (boolean)
340
+ - `prorata_type` - Prorata type
341
+ - `nfse_description` - NFSe description
342
+ - `discount_on_rooms` - Room discount percentage
343
+ - `discount_on_workstation` - Workstation discount percentage
344
+ - `private_space_id` - Private space ID
345
+ - `is_sms_enabled` - SMS notifications (boolean)
346
+ - `refund` - Refund config: `amount`, `date_limit`, `is_to_generate_refund_billet`
347
+ - `complementary_services` - Array of: `product_or_service_id`, `quantity`, `amount`, `notes`
348
+ - `service_correspondence_quotas` - Quotas: `limited`, `messages_limit`, `price_additional_message`
349
+
350
+ **End contract params:**
351
+ - `date` - End date
352
+ - `reason_id` - Reason ID
353
+ - `unlink_customer` - Unlink customer (boolean)
354
+
355
+ **Read-only attributes:**
356
+ - `contract_id` - ID
357
+ - `status` - active, ended, cancelled
358
+
359
+ **Helper methods:**
360
+ - `active?` - Check if active
361
+ - `ended?` - Check if ended or cancelled
192
362
 
193
363
  ---
194
364
 
195
365
  ### Charge
196
366
 
197
- Manages invoices/boletos.
367
+ Manages invoices/boletos. Charges are created from sales.
198
368
 
199
369
  ```ruby
370
+ # Create charge from sales
371
+ charge = Conexa::Charge.create(
372
+ sales_ids: [1234, 1235],
373
+ invoicing_method_id: 1,
374
+ due_date: '2024-02-10',
375
+ notes: 'Cobranca mensal'
376
+ )
377
+
200
378
  # Find charge
201
379
  charge = Conexa::Charge.find(789)
202
380
  charge.status # => "pending"
203
381
  charge.amount # => 199.90
204
382
  charge.due_date # => "2024-02-10"
383
+ charge.paid? # => false
384
+ charge.pending? # => true
385
+ charge.overdue? # => false
205
386
 
206
387
  # List charges
207
388
  charges = Conexa::Charge.all(
@@ -212,14 +393,20 @@ charges = Conexa::Charge.all(
212
393
  )
213
394
 
214
395
  # Settle (mark as paid)
215
- charge.settle(payment_date: '2024-02-05', payment_value: 199.90)
396
+ charge.settle(
397
+ settlement_date: '2024-02-05',
398
+ paid_amount: 199.90,
399
+ account_id: 1,
400
+ send_email: true,
401
+ receiving_method: { id: 1, installments_quantity: 1 }
402
+ )
216
403
  # or
217
- Conexa::Charge.settle(789, payment_date: '2024-02-05')
404
+ Conexa::Charge.settle(789, settlement_date: '2024-02-05')
218
405
 
219
406
  # Get PIX QR Code
220
407
  pix = charge.pix
221
- pix.qr_code # => "00020126..."
222
- pix.qr_code_image # => Base64 image
408
+ # or
409
+ pix = Conexa::Charge.pix(789)
223
410
 
224
411
  # Send email notification
225
412
  charge.send_email
@@ -232,18 +419,39 @@ charge.cancel
232
419
  Conexa::Charge.cancel(789)
233
420
  ```
234
421
 
235
- **Charge attributes:**
422
+ **API endpoints:** `POST /charge`, `GET /charge/:id`, `GET /charges`, `PATCH /charge/settle/:id`, `GET /charge/pix/:id`
423
+
424
+ **Create attributes:**
425
+ - `sales_ids` - Array of sale IDs to include in charge
426
+ - `invoicing_method_id` - Payment method ID
427
+ - `due_date` - Due date
428
+ - `notes` - Notes
429
+
430
+ **Settle attributes:**
431
+ - `settlement_date` - Payment date
432
+ - `paid_amount` - Amount paid
433
+ - `account_id` - Bank account ID
434
+ - `send_email` - Send confirmation email (boolean)
435
+ - `receiving_method` - Payment method: `id`, `installments_quantity`
436
+
437
+ **Read-only attributes:**
236
438
  - `charge_id` - ID
237
439
  - `customer_id` - Customer ID
238
- - `status` - Status (pending, paid, overdue, cancelled)
440
+ - `status` - pending, paid, overdue, cancelled
239
441
  - `amount` - Amount due
240
442
  - `due_date` - Due date
443
+ - `paid_at` - Payment date
444
+
445
+ **Helper methods:**
446
+ - `paid?` - Check if paid
447
+ - `pending?` - Check if pending
448
+ - `overdue?` - Check if overdue
241
449
 
242
- **Methods:**
243
- - `settle(params)` - Mark as paid
244
- - `pix` - Get PIX payment data
245
- - `send_email` - Send notification
246
- - `cancel` - Cancel charge
450
+ **Special methods:**
451
+ - `settle(params)` / `Charge.settle(id, params)` - Mark as paid
452
+ - `pix` / `Charge.pix(id)` - Get PIX payment data
453
+ - `send_email` / `Charge.send_email(id)` - Send notification
454
+ - `cancel` / `Charge.cancel(id)` - Cancel charge
247
455
 
248
456
  ---
249
457
 
@@ -256,6 +464,8 @@ Manages one-time sales.
256
464
  sale = Conexa::Sale.create(
257
465
  customer_id: 450,
258
466
  product_id: 2521,
467
+ requester_id: 10,
468
+ seller_id: 1,
259
469
  quantity: 1,
260
470
  amount: 80.99,
261
471
  reference_date: '2024-01-15',
@@ -264,8 +474,11 @@ sale = Conexa::Sale.create(
264
474
 
265
475
  # Find sale
266
476
  sale = Conexa::Sale.find(1234)
267
- sale.status # => "notBilled"
268
- sale.amount # => 80.99
477
+ sale.status # => "notBilled"
478
+ sale.amount # => 80.99
479
+ sale.editable? # => true
480
+ sale.billed? # => false
481
+ sale.paid? # => false
269
482
 
270
483
  # List sales
271
484
  sales = Conexa::Sale.all(
@@ -283,6 +496,26 @@ sale.save
283
496
  sale.destroy
284
497
  ```
285
498
 
499
+ **API endpoints:** `POST /sale`, `GET /sale/:id`, `PATCH /sale/:id`, `DELETE /sale/:id`, `GET /sales`
500
+
501
+ **Create/update attributes:**
502
+ - `customer_id` - Customer ID (required)
503
+ - `product_id` - Product ID (required)
504
+ - `requester_id` - Requester (person) ID
505
+ - `seller_id` - Seller (user) ID
506
+ - `quantity` - Quantity (required)
507
+ - `amount` - Amount (required)
508
+ - `reference_date` - Reference date
509
+ - `notes` - Notes
510
+
511
+ **Read-only attributes:**
512
+ - `sale_id` - ID
513
+ - `status` - Status string
514
+ - `original_amount` - Original amount before discount
515
+ - `discount_value` - Discount value
516
+ - `created_at` - Creation timestamp
517
+ - `updated_at` - Update timestamp
518
+
286
519
  **Sale statuses:**
287
520
  - `notBilled` - Not yet billed (editable)
288
521
  - `billed` - Included in a charge
@@ -293,6 +526,11 @@ sale.destroy
293
526
  - `billedNegociated` - Negotiated
294
527
  - `partiallyPaid` - Partially paid
295
528
 
529
+ **Helper methods:**
530
+ - `editable?` - Check if status is notBilled
531
+ - `billed?` - Check if billed
532
+ - `paid?` - Check if paid
533
+
296
534
  ---
297
535
 
298
536
  ### RecurringSale
@@ -300,6 +538,22 @@ sale.destroy
300
538
  Manages recurring items within contracts.
301
539
 
302
540
  ```ruby
541
+ # Create recurring sale
542
+ rs = Conexa::RecurringSale.create(
543
+ customer_id: 127,
544
+ type: 'product', # 'package' or 'product'
545
+ reference_id: 100, # product or package ID
546
+ requester_id: 10,
547
+ seller_id: 1,
548
+ is_repeat: true,
549
+ occurrence_quantity: 12,
550
+ frequency: 'monthly',
551
+ start_date: '2024-01-01',
552
+ quantity: 1,
553
+ amount: 99.90,
554
+ notes: 'Venda recorrente'
555
+ )
556
+
303
557
  # Find recurring sale
304
558
  rs = Conexa::RecurringSale.find(555)
305
559
 
@@ -309,29 +563,124 @@ recurring = Conexa::RecurringSale.all(
309
563
  status: 'active'
310
564
  )
311
565
 
566
+ # Update
567
+ rs.amount = 109.90
568
+ rs.save
569
+
312
570
  # End recurring sale
313
- rs.end_recurring_sale(end_date: '2024-12-31')
571
+ rs.end_recurring_sale(date: '2024-12-31')
314
572
  # or
315
- Conexa::RecurringSale.end_recurring_sale(555, end_date: '2024-12-31')
573
+ Conexa::RecurringSale.end_recurring_sale(555, date: '2024-12-31')
574
+
575
+ # Delete
576
+ rs.destroy
316
577
  ```
317
578
 
579
+ **API endpoints:** `POST /recurringSale`, `GET /recurringSale/:id`, `PATCH /recurringSale/:id`, `DELETE /recurringSale/:id`, `PATCH /recurringSale/end/:id`, `GET /recurringSales`
580
+
581
+ **Create attributes:**
582
+ - `customer_id` - Customer ID
583
+ - `type` - 'package' or 'product'
584
+ - `reference_id` - Product or package ID
585
+ - `requester_id` - Requester ID
586
+ - `seller_id` - Seller ID
587
+ - `is_repeat` - Is repeating (boolean)
588
+ - `occurrence_quantity` - Number of occurrences
589
+ - `frequency` - Frequency string
590
+ - `start_date` - Start date
591
+ - `last_adjustment_date` - Last price adjustment date
592
+ - `quantity` - Quantity
593
+ - `amount` - Amount
594
+ - `notes` - Notes
595
+ - `is_discount_previous_reservations` - Discount previous reservations (boolean)
596
+ - `is_calculate_pro_rata` - Calculate pro rata (boolean)
597
+
598
+ **Update attributes:**
599
+ - `requester_id`, `amount`, `quantity`, `last_adjustment_date`, `notes`
600
+
318
601
  ---
319
602
 
320
603
  ### Plan
321
604
 
322
- Read-only resource for pricing plans.
605
+ Pricing plans with products and periodicities.
323
606
 
324
607
  ```ruby
608
+ # Create plan
609
+ plan = Conexa::Plan.create(
610
+ company_id: 1,
611
+ name: 'Plano Basico',
612
+ service_category_id: 1,
613
+ cost_center_id: 10,
614
+ description: 'Plano com todos os recursos',
615
+ membership_fee: 200.00,
616
+ refund_value: 1500.00,
617
+ fidelity_months: 12,
618
+ due_day: 10,
619
+ nfse_description: 'Servicos de coworking',
620
+ receipt_description: 'Recibo mensal',
621
+ discount_on_rooms: 15.5,
622
+ discount_on_workstation: 10.0,
623
+ is_sms_enabled: true,
624
+ payment_periodicities: [
625
+ { periodicity: 'monthly', amount: 500.00 },
626
+ { periodicity: 'quarterly', amount: 1400.00 },
627
+ { periodicity: 'yearly', amount: 5000.00 }
628
+ ],
629
+ product_quotas: [
630
+ { product_id: 100, quantity: 10 },
631
+ { product_id: 101, quantity: 5 }
632
+ ],
633
+ service_correspondence_quotas: {
634
+ limited: true,
635
+ messages_limit: 100,
636
+ price_additional_message: 2.50
637
+ },
638
+ booking_models: [
639
+ { id: 1, stations: 2 }
640
+ ],
641
+ private_space_ids: [10, 11, 12],
642
+ hour_quotas: [
643
+ { hours: 10, periodicity: 'daily', space_id: 5 },
644
+ { hours: 40, periodicity: 'weekly', group_id: 3 }
645
+ ]
646
+ )
647
+
325
648
  # Find plan
326
649
  plan = Conexa::Plan.find(5)
327
- plan.name # => "Plano Básico"
328
- plan.amount # => 99.90
650
+ plan.name # => "Plano Basico"
329
651
 
330
652
  # List plans
331
653
  plans = Conexa::Plan.all(company_id: [3])
654
+
655
+ # Delete
656
+ plan.destroy
332
657
  ```
333
658
 
334
- **Note:** Plans cannot be created/updated via API. Use Conexa dashboard.
659
+ **API endpoints:** `POST /plan`, `GET /plan/:id`, `PATCH /plan/:id`, `DELETE /plan/:id`, `GET /plans`
660
+
661
+ **Note:** `save` (update) raises `NoMethodError` in the gem. Use `Conexa::Request` directly if needed.
662
+
663
+ **Create attributes:**
664
+ - `company_id` - Company ID (required)
665
+ - `name` - Plan name (required, must be unique)
666
+ - `service_category_id` - Service category ID (required)
667
+ - `cost_center_id` - Cost center ID
668
+ - `description` - Description
669
+ - `membership_fee` - Membership fee
670
+ - `refund_value` - Refund value
671
+ - `fidelity_months` - Fidelity period in months
672
+ - `due_day` - Default due day
673
+ - `nfse_description` - NFSe description
674
+ - `receipt_description` - Receipt description
675
+ - `discount_on_rooms` - Room discount percentage
676
+ - `discount_on_workstation` - Workstation discount percentage
677
+ - `is_sms_enabled` - SMS enabled (boolean)
678
+ - `payment_periodicities` - Array of: `periodicity` (monthly, bimonthly, quarterly, semester, yearly), `amount`
679
+ - `product_quotas` - Array of: `product_id`, `quantity`
680
+ - `service_correspondence_quotas` - `limited`, `messages_limit`, `price_additional_message`
681
+ - `booking_models` - Array of: `id`, `stations`
682
+ - `private_space_ids` - Array of space IDs
683
+ - `hour_quotas` - Array of: `hours`, `periodicity`, `group_id`, `space_id`
335
684
 
336
685
  ---
337
686
 
@@ -348,15 +697,64 @@ product.name # => "Mensalidade"
348
697
  products = Conexa::Product.all(company_id: [3])
349
698
  ```
350
699
 
351
- **Note:** Products cannot be created/updated via API. Use Conexa dashboard.
700
+ **API endpoints:** `GET /product/:id`, `GET /products`
701
+
702
+ **Note:** Products cannot be created/updated via this gem. `save` raises `NoMethodError`.
703
+
704
+ ---
705
+
706
+ ### InvoicingMethod
707
+
708
+ Manages payment method configurations (boleto, PIX, credit card, etc.).
709
+
710
+ ```ruby
711
+ # Find invoicing method
712
+ method = Conexa::InvoicingMethod.find(1)
713
+ method.invoicing_method_id # => 1
714
+
715
+ # List invoicing methods
716
+ methods = Conexa::InvoicingMethod.all
717
+
718
+ # Create
719
+ method = Conexa::InvoicingMethod.create(
720
+ name: 'Boleto Bancario'
721
+ )
722
+
723
+ # Update
724
+ method.save
725
+
726
+ # Delete
727
+ method.destroy
728
+ ```
729
+
730
+ **API endpoints:** `GET /invoicingMethod/:id`, `GET /invoicingMethods`, `POST /invoicingMethod`, `PATCH /invoicingMethod/:id`, `DELETE /invoicingMethod/:id`
352
731
 
353
732
  ---
354
733
 
355
734
  ### Bill
356
735
 
357
- Read-only resource for financial bills (contas a pagar).
736
+ Financial bills (contas a pagar).
358
737
 
359
738
  ```ruby
739
+ # Create bill
740
+ bill = Conexa::Bill.create(
741
+ company_id: 1,
742
+ due_date: '2024-03-15',
743
+ amount: 500.00,
744
+ subcategory_id: 1,
745
+ supplier_id: 50,
746
+ description: 'Aluguel escritorio',
747
+ account_id: 1,
748
+ document_date: '2024-03-01',
749
+ competence_date: '2024-03-01',
750
+ document_number: 'NF-001',
751
+ digitable_line: '23793.38128 60000.000003 00000.000400 1 84340000050000',
752
+ cost_centers: [
753
+ { id: 1, percentage: 100 }
754
+ ],
755
+ cac: { is_included: true, percentage: 5.0 }
756
+ )
757
+
360
758
  # Find bill
361
759
  bill = Conexa::Bill.find(321)
362
760
 
@@ -364,6 +762,25 @@ bill = Conexa::Bill.find(321)
364
762
  bills = Conexa::Bill.all(company_id: [3])
365
763
  ```
366
764
 
765
+ **API endpoints:** `POST /bill`, `GET /bill/:id`, `GET /bills`
766
+
767
+ **Note:** `save` (update) raises `NoMethodError` in the gem.
768
+
769
+ **Create attributes:**
770
+ - `company_id` - Company ID
771
+ - `due_date` - Due date
772
+ - `amount` - Amount
773
+ - `subcategory_id` - Subcategory ID
774
+ - `supplier_id` - Supplier ID
775
+ - `description` - Description
776
+ - `account_id` - Bank account ID
777
+ - `document_date` - Document date
778
+ - `competence_date` - Competence date
779
+ - `document_number` - Document number
780
+ - `digitable_line` - Barcode digitable line
781
+ - `cost_centers` - Array of: `id`, `percentage`
782
+ - `cac` - CAC config: `is_included`, `percentage`
783
+
367
784
  ---
368
785
 
369
786
  ### Company
@@ -378,26 +795,81 @@ company = Conexa::Company.find(3)
378
795
  companies = Conexa::Company.all
379
796
  ```
380
797
 
798
+ **API endpoints:** `GET /company/:id`, `GET /companies`
799
+
381
800
  ---
382
801
 
383
802
  ### Supplier
384
803
 
385
- Manages suppliers (fornecedores).
804
+ Manages suppliers (fornecedores) with PF/PJ data.
386
805
 
387
806
  ```ruby
807
+ # Create supplier (PJ)
808
+ supplier = Conexa::Supplier.create(
809
+ name: 'Fornecedor XYZ Ltda',
810
+ field_of_activity: 'Servicos',
811
+ notes: 'Fornecedor principal',
812
+ cell_number: '31999998888',
813
+ phones: ['3133334444'],
814
+ emails: ['contato@xyz.com.br'],
815
+ website: 'https://www.xyz.com.br',
816
+ contact_person_names: ['Joao', 'Maria'],
817
+ legal_person: {
818
+ legal_name: 'Fornecedor XYZ Servicos Ltda',
819
+ cnpj: '12.345.678/0001-90',
820
+ state_inscription: '123456789',
821
+ municipal_inscription: '98765432'
822
+ },
823
+ address: {
824
+ zip_code: '30130000',
825
+ state: 'MG',
826
+ city: 'Belo Horizonte',
827
+ street: 'Rua da Bahia',
828
+ number: '500',
829
+ neighborhood: 'Centro',
830
+ additional_details: 'Sala 10'
831
+ }
832
+ )
833
+
834
+ # Create supplier (PF)
835
+ supplier = Conexa::Supplier.create(
836
+ name: 'Joao Fornecedor',
837
+ natural_person: {
838
+ cpf: '123.456.789-00',
839
+ rg: '123456789',
840
+ issuing_authority: 'SSP/MG'
841
+ }
842
+ )
843
+
388
844
  # Find supplier
389
845
  supplier = Conexa::Supplier.find(50)
390
846
 
391
847
  # List suppliers
392
848
  suppliers = Conexa::Supplier.all(company_id: [3])
393
849
 
394
- # Create supplier
395
- supplier = Conexa::Supplier.create(
396
- company_id: 3,
397
- name: 'Fornecedor XYZ'
398
- )
850
+ # Update
851
+ supplier.name = 'Novo Nome'
852
+ supplier.save
853
+
854
+ # Delete
855
+ supplier.destroy
399
856
  ```
400
857
 
858
+ **API endpoints:** `POST /supplier`, `GET /supplier/:id`, `PATCH /supplier/:id`, `DELETE /supplier/:id`, `GET /supplier` (list)
859
+
860
+ **Create attributes:**
861
+ - `name` - Supplier name (required)
862
+ - `field_of_activity` - Field of activity
863
+ - `notes` - Notes
864
+ - `cell_number` - Cell phone
865
+ - `phones` - Array of phones
866
+ - `emails` - Array of emails
867
+ - `website` - Website URL
868
+ - `contact_person_names` - Array of contact names
869
+ - `legal_person` - PJ data: `legal_name`, `cnpj`, `state_inscription`, `municipal_inscription`
870
+ - `natural_person` - PF data: `cpf`, `rg`, `issuing_authority`
871
+ - `address` - Address: `zip_code`, `state`, `city`, `street`, `number`, `neighborhood`, `additional_details`
872
+
401
873
  ---
402
874
 
403
875
  ### CreditCard
@@ -405,31 +877,143 @@ supplier = Conexa::Supplier.create(
405
877
  Manages customer credit cards.
406
878
 
407
879
  ```ruby
408
- # Find credit card
409
- card = Conexa::CreditCard.find(99)
410
-
411
- # Create (tokenized)
880
+ # Create credit card
412
881
  card = Conexa::CreditCard.create(
413
882
  customer_id: 127,
414
- token: 'card_token_from_gateway'
883
+ number: '4111111111111111',
884
+ name: 'JOAO DA SILVA',
885
+ expiration_date: '12/2026',
886
+ cvc: '123',
887
+ brand: 'visa',
888
+ default: true,
889
+ enable_recurring: true
415
890
  )
891
+
892
+ # Find credit card
893
+ card = Conexa::CreditCard.find(99)
894
+
895
+ # Update
896
+ card.default = true
897
+ card.save
898
+
899
+ # Delete
900
+ card.destroy
416
901
  ```
417
902
 
903
+ **API endpoints:** `POST /creditCard`, `GET /creditCard/:id`, `PATCH /creditCard/:id`, `DELETE /creditCard/:id`
904
+
905
+ **Note:** `all` (listing) is not available for credit cards.
906
+
907
+ **Create attributes:**
908
+ - `customer_id` - Customer ID (required)
909
+ - `number` - Card number
910
+ - `name` - Cardholder name
911
+ - `expiration_date` - Expiration date (MM/YYYY)
912
+ - `cvc` - CVC code
913
+ - `brand` - Card brand
914
+ - `default` - Set as default (boolean)
915
+ - `enable_recurring` - Enable for recurring charges (boolean)
916
+
418
917
  ---
419
918
 
420
919
  ### Person
421
920
 
422
- Manages requesters (solicitantes) for a customer. Limited API access.
921
+ Manages requesters (solicitantes) linked to a customer. The API supports full CRUD.
423
922
 
424
923
  ```ruby
425
924
  # Create person for customer
426
925
  person = Conexa::Person.create(
427
926
  customer_id: 127,
428
927
  name: 'Maria Solicitante',
429
- email: 'maria@empresa.com'
928
+ nationality: 'Brasileira',
929
+ place_of_birth: 'Belo Horizonte',
930
+ marital_status: 'single',
931
+ is_foreign: false,
932
+ is_company_partner: true,
933
+ is_guarantor: false,
934
+ cpf: '123.456.789-00',
935
+ rg: '123456789',
936
+ issuing_authority: 'SSP/MG',
937
+ birth_date: '1990-05-15',
938
+ cell_number: '31999998888',
939
+ phones: ['3133334444'],
940
+ emails: ['maria@empresa.com'],
941
+ sex: 'female',
942
+ job_title: 'Gerente',
943
+ profession: 'Administradora',
944
+ resume: 'Profissional experiente',
945
+ notes: 'Contato principal',
946
+ address: {
947
+ zip_code: '30130000',
948
+ state: 'MG',
949
+ city: 'Belo Horizonte',
950
+ street: 'Av. Afonso Pena',
951
+ number: '1000',
952
+ neighborhood: 'Centro',
953
+ additional_details: 'Sala 501'
954
+ },
955
+ devices: [
956
+ { nickname: 'Notebook', mac_address: 'AA:BB:CC:DD:EE:FF' }
957
+ ],
958
+ has_login_access: true,
959
+ login: 'maria@empresa.com',
960
+ password: 'SecurePass123',
961
+ permissions: ['finance', 'orders', 'rooms'],
962
+ can_receive_mail: true,
963
+ color: '#FF5733',
964
+ url_linkedin: 'https://linkedin.com/in/maria',
965
+ url_instagram: '@maria',
966
+ url_facebook: 'maria.fb',
967
+ url_twitter: '@maria'
430
968
  )
969
+
970
+ # Update
971
+ person.name = 'Maria Silva'
972
+ person.save
973
+
974
+ # Delete
975
+ person.destroy
431
976
  ```
432
977
 
978
+ **API endpoints:** `POST /person`, `GET /person/:id`, `PATCH /person/:id`, `DELETE /person/:id`, `GET /persons`
979
+
980
+ **Note:** In the gem, `find`, `all`, and `find_by` raise `NoMethodError`. Use `Conexa::Request` directly if you need to retrieve or list persons.
981
+
982
+ **Create/update attributes:**
983
+ - `customer_id` - Customer ID (required)
984
+ - `name` - Full name (required)
985
+ - `nationality` - Nationality
986
+ - `place_of_birth` - Place of birth
987
+ - `marital_status` - Marital status
988
+ - `is_foreign` - Is foreigner (boolean)
989
+ - `foreign_data` - Foreign data object
990
+ - `is_company_partner` - Is company partner (boolean)
991
+ - `is_guarantor` - Is guarantor (boolean)
992
+ - `cpf` - CPF number
993
+ - `rg` - RG number
994
+ - `issuing_authority` - RG issuing authority
995
+ - `birth_date` - Birth date
996
+ - `cell_number` - Cell phone
997
+ - `phones` - Array of phones
998
+ - `emails` - Array of emails
999
+ - `sex` - Gender (male, female)
1000
+ - `job_title` - Job title
1001
+ - `profession` - Profession
1002
+ - `resume` - Resume/bio
1003
+ - `notes` - Notes
1004
+ - `address` - Address object
1005
+ - `devices` - Array of: `nickname`, `mac_address`
1006
+ - `has_login_access` - Has portal access (boolean)
1007
+ - `login` - Login email
1008
+ - `password` - Login password
1009
+ - `permissions` - Array of: finance, orders, rooms, shared_spaces, assistance, correspondences, printing
1010
+ - `access_id` - Access ID
1011
+ - `can_receive_mail` - Can receive mail (boolean)
1012
+ - `color` - Color code
1013
+ - `print_fee_id` - Print fee ID
1014
+ - `extension_numbers` - Extension numbers
1015
+ - `url_linkedin`, `url_instagram`, `url_facebook`, `url_twitter` - Social URLs
1016
+
433
1017
  ---
434
1018
 
435
1019
  ## Common Patterns
@@ -451,7 +1035,7 @@ page = 1
451
1035
  loop do
452
1036
  result = Conexa::Customer.all(page: page, size: 100)
453
1037
  break if result.empty?
454
-
1038
+
455
1039
  result.each { |customer| process(customer) }
456
1040
  page += 1
457
1041
  end
@@ -489,10 +1073,10 @@ end
489
1073
 
490
1074
  **Error classes:**
491
1075
  - `Conexa::NotFound` - Resource not found (404)
492
- - `Conexa::ValidationError` - Validation failed (422)
1076
+ - `Conexa::ValidationError` - Validation failed (response without `message` key)
1077
+ - `Conexa::ResponseError` - API error with `message` key (400, 401, 422, 500)
493
1078
  - `Conexa::ConnectionError` - Network error
494
- - `Conexa::ResponseError` - Generic API error
495
- - `Conexa::RequestError` - Invalid request parameters
1079
+ - `Conexa::RequestError` - Invalid request parameters (e.g., nil ID)
496
1080
  - `Conexa::MissingCredentialsError` - Token not configured
497
1081
 
498
1082
  ### Filters
@@ -523,29 +1107,41 @@ Conexa::Charge.all(
523
1107
  )
524
1108
  ```
525
1109
 
1110
+ ### Rate Limiting
1111
+
1112
+ The API enforces a limit of 100 requests per minute. Response headers:
1113
+ - `X-Rate-Limit-Limit` - Maximum requests per minute
1114
+ - `X-Rate-Limit-Remaining` - Remaining requests
1115
+ - `X-Rate-Limit-Reset` - Seconds until limit resets
1116
+
526
1117
  ---
527
1118
 
528
1119
  ## Model Methods Summary
529
1120
 
530
1121
  | Resource | find | all | create | save | destroy | Special Methods |
531
1122
  |----------|------|-----|--------|------|---------|-----------------|
532
- | Customer | | | | | | - |
533
- | Contract | | | | | | end_contract |
534
- | Charge | | | | | | settle, pix, cancel, send_email |
535
- | Sale | | | | | | - |
536
- | RecurringSale | | | | | | end_recurring_sale |
537
- | Plan | | | | | | - |
538
- | Product | | | | | | - |
539
- | Bill | | | | | | - |
540
- | Company | | | | | | - |
541
- | Supplier | | | | | | - |
542
- | CreditCard | | | | | | - |
543
- | Person | | | | | | - |
1123
+ | Auth | - | - | - | - | - | login, authenticate |
1124
+ | Customer | yes | yes | yes | yes | yes | persons, contracts, charges |
1125
+ | Contract | yes | yes | yes | yes | yes | end_contract, create_with_products |
1126
+ | Charge | yes | yes | yes | - | - | settle, pix, cancel, send_email |
1127
+ | Sale | yes | yes | yes | yes | yes | billed?, paid?, editable? |
1128
+ | RecurringSale | yes | yes | yes | yes | yes | end_recurring_sale |
1129
+ | Plan | yes | yes | yes | - | yes | - |
1130
+ | Product | yes | yes | - | - | - | - |
1131
+ | InvoicingMethod | yes | yes | yes | yes | yes | - |
1132
+ | Bill | yes | yes | yes | - | - | - |
1133
+ | Company | yes | yes | yes | yes | yes | - |
1134
+ | Supplier | yes | yes | yes | yes | yes | - |
1135
+ | CreditCard | yes | - | yes | yes | yes | - |
1136
+ | Person | - | - | yes | yes | yes | - |
1137
+
1138
+ **Legend:** `yes` = available, `-` = not available (raises NoMethodError or not implemented)
544
1139
 
545
1140
  ---
546
1141
 
547
1142
  ## Version History
548
1143
 
1144
+ - **v0.0.7** - Add Auth resource, fix Auth.login, add test suite with VCR
549
1145
  - **v0.0.6** - Fix nil guard in camelize_hash, fix Result#empty? delegation
550
1146
  - **v0.0.5** - Initial public release
551
1147
 
data/lib/conexa/model.rb CHANGED
@@ -77,7 +77,7 @@ module Conexa
77
77
  end
78
78
 
79
79
  def primary_key_name
80
- class_name.downcase + "_id"
80
+ Util.to_snake_case(class_name) + "_id"
81
81
  end
82
82
 
83
83
  def class_name
@@ -87,6 +87,7 @@ module Conexa
87
87
  def destroy
88
88
  raise RequestError.new('Invalid ID') unless id.present?
89
89
  update Conexa::Request.delete( self.class.show_url(primary_key) ).call(class_name)
90
+ self
90
91
  end
91
92
 
92
93
  class << self
@@ -116,7 +117,9 @@ module Conexa
116
117
  alias :where :all
117
118
 
118
119
  def destroy id
119
- self.new(id: id).destroy
120
+ instance = self.new
121
+ instance.set_primary_key(id)
122
+ instance.destroy
120
123
  end
121
124
 
122
125
  def url(*params)
@@ -23,12 +23,10 @@ module Conexa
23
23
  # # Use the token for subsequent requests
24
24
  # Conexa.configure { |c| c.api_token = auth.access_token }
25
25
  def login(username:, password:)
26
- response = Conexa::Request.post('/auth', params: {
26
+ Conexa::Request.auth('/auth', params: {
27
27
  username: username,
28
28
  password: password
29
29
  }).call('auth')
30
-
31
- new(response.to_h)
32
30
  end
33
31
 
34
32
  alias_method :authenticate, :login
@@ -1,18 +1,4 @@
1
1
  module Conexa
2
2
  class Person < Model
3
- class << self
4
- def all(*args, **params)
5
- raise NoMethodError
6
- end
7
-
8
- def find_by_id(id, **options)
9
- raise NoMethodError
10
- end
11
-
12
-
13
- def find_by(params = Hash.new, page = nil, size = nil)
14
- raise NoMethodError
15
- end
16
- end
17
3
  end
18
4
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Conexa
4
- VERSION = "0.0.7"
4
+ VERSION = "0.0.8"
5
5
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: conexa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Guilherme Gazzinelli
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2026-02-12 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: jwt
@@ -185,7 +184,6 @@ metadata:
185
184
  homepage_uri: https://github.com/guilhermegazzinelli/conexa-ruby
186
185
  source_code_uri: https://github.com/guilhermegazzinelli/conexa-ruby
187
186
  changelog_uri: https://github.com/guilhermegazzinelli/conexa-ruby/blob/main/CHANGELOG.md
188
- post_install_message:
189
187
  rdoc_options: []
190
188
  require_paths:
191
189
  - lib
@@ -200,8 +198,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
200
198
  - !ruby/object:Gem::Version
201
199
  version: '0'
202
200
  requirements: []
203
- rubygems_version: 3.5.22
204
- signing_key:
201
+ rubygems_version: 3.6.9
205
202
  specification_version: 4
206
203
  summary: Gem para integração com a Api da Conexa
207
204
  test_files: []