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 +4 -4
- data/CHANGELOG.md +20 -1
- data/Gemfile +0 -2
- data/Gemfile.lock +3 -35
- data/REFERENCE.md +685 -89
- data/lib/conexa/model.rb +5 -2
- data/lib/conexa/resources/auth.rb +1 -3
- data/lib/conexa/resources/person.rb +0 -14
- data/lib/conexa/version.rb +1 -1
- metadata +3 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '050626980d9f896ca2c70ed30a27c1cfda7d0d30c89e25c90e86422d122fb1af'
|
|
4
|
+
data.tar.gz: 43134221ca4dd8f38bc3f8a62bfffe2807d1565e949e2adf72d446fa14db01cf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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.
|
|
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
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
conexa (0.0.
|
|
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
|
-
|
|
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** -
|
|
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.
|
|
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
|
-
#
|
|
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
|
-
#
|
|
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
|
|
115
|
+
Manages clients (pessoas fisicas ou juridicas).
|
|
73
116
|
|
|
74
117
|
```ruby
|
|
75
|
-
# Create customer (Pessoa
|
|
118
|
+
# Create customer (Pessoa Juridica)
|
|
76
119
|
customer = Conexa::Customer.create(
|
|
77
120
|
company_id: 3,
|
|
78
121
|
name: 'Empresa ABC Ltda',
|
|
79
|
-
|
|
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
|
-
|
|
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 (
|
|
171
|
+
# Create customer (Estrangeiro)
|
|
85
172
|
customer = Conexa::Customer.create(
|
|
86
173
|
company_id: 3,
|
|
87
|
-
name: '
|
|
88
|
-
|
|
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
|
-
**
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
- `
|
|
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
|
-
- `
|
|
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
|
-
|
|
148
|
-
|
|
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.
|
|
166
|
-
contract.
|
|
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(
|
|
311
|
+
contract.end_contract(date: '2024-12-31', reason_id: 1, unlink_customer: false)
|
|
176
312
|
# or
|
|
177
|
-
Conexa::Contract.end_contract(456,
|
|
313
|
+
Conexa::Contract.end_contract(456, date: '2024-12-31')
|
|
178
314
|
|
|
179
315
|
# Update
|
|
180
|
-
contract.
|
|
316
|
+
contract.due_day = 15
|
|
181
317
|
contract.save
|
|
318
|
+
|
|
319
|
+
# Delete
|
|
320
|
+
contract.destroy
|
|
182
321
|
```
|
|
183
322
|
|
|
184
|
-
**
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
- `
|
|
188
|
-
- `
|
|
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 (
|
|
191
|
-
- `
|
|
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(
|
|
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,
|
|
404
|
+
Conexa::Charge.settle(789, settlement_date: '2024-02-05')
|
|
218
405
|
|
|
219
406
|
# Get PIX QR Code
|
|
220
407
|
pix = charge.pix
|
|
221
|
-
|
|
222
|
-
pix
|
|
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
|
-
**
|
|
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` -
|
|
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
|
-
**
|
|
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
|
|
268
|
-
sale.amount
|
|
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(
|
|
571
|
+
rs.end_recurring_sale(date: '2024-12-31')
|
|
314
572
|
# or
|
|
315
|
-
Conexa::RecurringSale.end_recurring_sale(555,
|
|
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
|
-
|
|
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
|
|
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
|
-
**
|
|
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
|
-
**
|
|
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
|
-
|
|
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
|
-
#
|
|
395
|
-
supplier =
|
|
396
|
-
|
|
397
|
-
|
|
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
|
-
#
|
|
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
|
-
|
|
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)
|
|
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
|
-
|
|
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 (
|
|
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::
|
|
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
|
-
|
|
|
533
|
-
|
|
|
534
|
-
|
|
|
535
|
-
|
|
|
536
|
-
|
|
|
537
|
-
|
|
|
538
|
-
|
|
|
539
|
-
|
|
|
540
|
-
|
|
|
541
|
-
|
|
|
542
|
-
|
|
|
543
|
-
|
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
data/lib/conexa/version.rb
CHANGED
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.
|
|
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:
|
|
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.
|
|
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: []
|