bukku_rails 0.1.6 → 0.2.2

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: 155357b4ca282d160dcb92f22b77c6ceed853d4df539470838b02846809af42a
4
- data.tar.gz: e59657c28be7b60904edb9dda405435d7b8216a61610f0c3f5603b0fcd02137f
3
+ metadata.gz: ae7834af9fb6e0e658c7983ec8470965dd05895d5e9fb812287abf2138b7cf0b
4
+ data.tar.gz: 372206b437586da2dc52d54ecf05c9c3e20df6129115551bb5d537c6fa2ba121
5
5
  SHA512:
6
- metadata.gz: 27e5a345e5dd38ba2e2a5d05d5d52d6f3fd83ac9815be509df718ee08ecba3cd14227f8fc09d818985171f6b23c8d98b02f3201a930b392dfdc59399ca12c1a0
7
- data.tar.gz: 41a28319db712943fb2181c7793d7eb674414b071cf7632a04cfae617603605b09467608864f19b3f1820db8e42041187c6b21dd714d25658f2060a4a31c42f7
6
+ metadata.gz: 34272757719187e556d86f660a2079ea01b2727740fefa86dad212189f0e58557238d141e6ecb8e27dbe4d15665ae83b5210cca645788a7a9263c7bf109a4716
7
+ data.tar.gz: 2439395811ac766fe33cac66a6c7632c50fadea7f50322f477510c415847ec8653e075aa9dbb75a5d9afaae1bd57d8254da30e9e577bc41c43aa69d62c0cfca3
data/README.md CHANGED
@@ -4,7 +4,7 @@ Use Rails methods to interact with your data in [Bukku](https://bukku.my/) accou
4
4
 
5
5
  Take a look at [Bukku's API](https://developers.bukku.my) to know what data you can extract from Bukku.
6
6
 
7
- > As of December 2, 2025, the gem only handles **GET** request. If you require other request, fork the gem and write it and then send us a Pull Request.
7
+ > As of February 2026, the gem handles **GET**, **POST**, and **file upload** requests.
8
8
 
9
9
  ## Installation
10
10
 
@@ -50,18 +50,25 @@ Just like in Rails the methods follow the singular and plural expression. Method
50
50
  |------------|-------------|----------|
51
51
  | GET | `get_sales_quotes(query-parameters)` | `/sales/quotes` |
52
52
  | GET | `get_sales_quote(id)` | `/sales/quotes/:id` |
53
+ | POST | `create_quote(body:)` | `/sales/quotes` |
53
54
  | GET | `get_sales_orders(query-parameters)` | `/sales/orders` |
54
55
  | GET | `get_sales_order(id)` | `/sales/orders/:id` |
56
+ | POST | `create_sales_order(body:)` | `/sales/orders` |
55
57
  | GET | `get_delivery_orders(query-parameters)` | `/sales/delivery_orders` |
56
58
  | GET | `get_delivery_order(id)` | `/sales/delivery_orders/:id` |
59
+ | POST | `create_delivery_order(body:)` | `/sales/delivery_orders` |
57
60
  | GET | `get_invoices(query-parameters)` | `/sales/invoices` |
58
61
  | GET | `get_invoice(id)` | `/sales/invoices/:id` |
62
+ | POST | `create_invoice(body:)` | `/sales/invoices` |
59
63
  | GET | `get_sales_credit_notes(query-parameters)` | `/sales/credit_notes` |
60
64
  | GET | `get_sales_credit_note(id)` | `/sales/credit_notes/:id` |
65
+ | POST | `create_credit_note(body:)` | `/sales/credit_notes` |
61
66
  | GET | `get_sales_payments(query-parameters)` | `/sales/payments` |
62
67
  | GET | `get_sales_payment(id)` | `/sales/payments/:id` |
68
+ | POST | `create_payment(body:)` | `/sales/payments` |
63
69
  | GET | `get_sales_refunds(query-parameters)` | `/sales/refunds` |
64
70
  | GET | `get_sales_refund(id)` | `/sales/refunds/:id` |
71
+ | POST | `create_refund(body:)` | `/sales/refunds` |
65
72
 
66
73
  #### Purchases
67
74
 
@@ -69,16 +76,22 @@ Just like in Rails the methods follow the singular and plural expression. Method
69
76
  |------------|-------------|----------|
70
77
  | GET | `get_purchase_orders(query-parameters)` | `/purchases/orders` |
71
78
  | GET | `get_purchase_order(id)` | `/purchases/orders/:id` |
79
+ | POST | `create_purchase_order(body:)` | `/purchases/orders` |
72
80
  | GET | `get_received_notes(query-parameters)` | `/purchases/goods_received_notes` |
73
81
  | GET | `get_received_note(id)` | `/purchases/goods_received_notes/:id` |
82
+ | POST | `create_received_note(body:)` | `/purchases/goods_received_notes` |
74
83
  | GET | `get_bills(query-parameters)` | `/purchases/bills` |
75
84
  | GET | `get_bill(id)` | `/purchases/bills/:id` |
85
+ | POST | `create_bill(body:)` | `/purchases/bills` |
76
86
  | GET | `get_purchases_credit_notes(query-parameters)` | `/purchases/credit_notes` |
77
87
  | GET | `get_purchases_credit_note(id)` | `/purchases/credit_notes/:id` |
88
+ | POST | `create_purchase_credit_note(body:)` | `/purchases/credit_note` |
78
89
  | GET | `get_purchases_payments(query-parameters)` | `/purchases/payments` |
79
- | GET | `get_purchases_payments(id)` | `/purchases/payments/:id` |
90
+ | GET | `get_purchases_payment(id)` | `/purchases/payments/:id` |
91
+ | POST | `create_purchases_payment(body:)` | `/purchases/payments` |
80
92
  | GET | `get_purchases_refunds(query-parameters)` | `/purchases/refunds` |
81
93
  | GET | `get_purchases_refund(id)` | `/purchases/refunds/:id` |
94
+ | POST | `create_purchases_refund(body:)` | `/purchases/refunds` |
82
95
 
83
96
  #### Banking
84
97
 
@@ -86,10 +99,13 @@ Just like in Rails the methods follow the singular and plural expression. Method
86
99
  |------------|-------------|----------|
87
100
  | GET | `get_banking_incomes(query-parameters)` | `/banking/incomes` |
88
101
  | GET | `get_banking_income(id)` | `/banking/incomes/:id` |
102
+ | POST | `create_banking_income(body:)` | `/banking/incomes` |
89
103
  | GET | `get_banking_expenses(query-parameters)` | `/banking/expenses` |
90
104
  | GET | `get_banking_expense(id)` | `/banking/expenses/:id` |
105
+ | POST | `create_expense(body:)` | `/banking/expenses` |
91
106
  | GET | `get_transfers(query-parameters)` | `/banking/transfers` |
92
107
  | GET | `get_transfer(id)` | `/banking/transfers/:id` |
108
+ | POST | `create_transfer(body:)` | `/banking/transfer` |
93
109
 
94
110
  #### Contacts
95
111
 
@@ -97,8 +113,10 @@ Just like in Rails the methods follow the singular and plural expression. Method
97
113
  |------------|-------------|----------|
98
114
  | GET | `get_contacts(query-parameters)` | `/contacts` |
99
115
  | GET | `get_contact(id)` | `/contacts/:id` |
116
+ | POST | `create_contact(body:)` | `/contacts` |
100
117
  | GET | `get_contact_groups(query-parameters)` | `/contacts/groups` |
101
118
  | GET | `get_contact_group(id)` | `/contacts/groups/:id` |
119
+ | POST | `create_group(body:)` | `/contacts/groups` |
102
120
 
103
121
  #### Products
104
122
 
@@ -106,8 +124,12 @@ Just like in Rails the methods follow the singular and plural expression. Method
106
124
  |------------|-------------|----------|
107
125
  | GET | `get_products(query-parameters)` | `/products` |
108
126
  | GET | `get_product(id)` | `/products/:id` |
127
+ | POST | `create_product(body:)` | `/products` |
128
+ | GET | `get_bundle(id)` | `/products/bundles/:id` |
129
+ | POST | `create_bundle(body:)` | `/products/bundles` |
109
130
  | GET | `get_product_groups(query-parameters)` | `/products/groups` |
110
131
  | GET | `get_product_group(id)` | `/products/groups/:id` |
132
+ | POST | `create_product_group(body:)` | `/products/groups` |
111
133
 
112
134
  #### Accounting
113
135
 
@@ -115,8 +137,16 @@ Just like in Rails the methods follow the singular and plural expression. Method
115
137
  |------------|-------------|----------|
116
138
  | GET | `get_journal_entries(query-parameters)` | `/journal_entries` |
117
139
  | GET | `get_journal_entry(id)` | `/journal_entries/:id` |
140
+ | POST | `create_journal_entry(body:)` | `/journal_entries` |
118
141
  | GET | `get_accounts(query-parameters)` | `/accounts` |
119
142
  | GET | `get_account(id)` | `/accounts/:id` |
143
+ | POST | `create_account(body:)` | `/accounts` |
144
+
145
+ #### Files
146
+
147
+ | HTTP Method | Ruby Method | Endpoint |
148
+ |------------|-------------|----------|
149
+ | POST | `upload_file(file_data:, filename:, mime_type:)` | `/files` |
120
150
 
121
151
  ### Examples
122
152
 
@@ -159,10 +189,34 @@ invoices = client.get_invoices(date_from: "2025-11-01", date_to: "2025-11-30")
159
189
  invoice = client.get_invoice(123)
160
190
  ```
161
191
 
192
+ **Creating a new contact (or supplier)**:
193
+
194
+ ```ruby
195
+ body = {
196
+ entity_type: "MALAYSIAN_COMPANY",
197
+ legal_name: invoice.supplier_name,
198
+ types: ["supplier"]
199
+ }
200
+
201
+ contact = client.create_contact(body: body)
202
+ ```
203
+
204
+ **File upload:**
205
+
206
+ ```ruby
207
+
208
+ file_data = File.read("invoice.pdf")
209
+ filename = "invoice.pdf"
210
+ mime_type = "application/pdf"
211
+
212
+ client.upload_file(file_data: file_data, filename: filename, mime_type: mime_type)
213
+
214
+ ```
215
+
162
216
  ## Contributing
163
217
 
164
218
  Bug reports and pull requests are welcome on GitHub at <https://github.com/stopar/bukku_rails>.
165
219
 
166
220
  ## License
167
221
 
168
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
222
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT)
data/lib/bukku.rb CHANGED
@@ -1,9 +1,9 @@
1
1
  class Bukku < Client
2
2
  # Usage of this integration as follows:
3
- # access = Bukku.new(token: "bukku_token_key", domain: "domain")
4
- # respond = access.<method>(parameters)
5
- # Example: respond = access.get_sales_invoices(date_from: "2025-11-25", date_to: "2025-11-30")
3
+ # access = BukkuTest.new(token: "bukku_token_key", domain: "domain")
4
+ # respond = access.<method>
6
5
 
6
+ # Testing URL
7
7
  BASE_URI = 'https://api.bukku.my'
8
8
 
9
9
  ## SALES
@@ -16,6 +16,10 @@ class Bukku < Client
16
16
  get "/sales/quotes/#{id}"
17
17
  end
18
18
 
19
+ def create_quote(body:)
20
+ post '/sales/quotes', body: body
21
+ end
22
+
19
23
  # Sales Order
20
24
  def get_sales_orders(**kwargs)
21
25
  get '/sales/orders', query: kwargs
@@ -25,6 +29,10 @@ class Bukku < Client
25
29
  get "/sales/orders/#{id}"
26
30
  end
27
31
 
32
+ def create_sales_order(body:)
33
+ post '/sales/orders', body: body
34
+ end
35
+
28
36
  # Delivery Order
29
37
  def get_delivery_orders(**kwargs)
30
38
  get '/sales/delivery_orders', query: kwargs
@@ -34,6 +42,10 @@ class Bukku < Client
34
42
  get "/sales/delivery_orders/#{id}"
35
43
  end
36
44
 
45
+ def create_delivery_order(body:)
46
+ post '/sales/delivery_orders', body: body
47
+ end
48
+
37
49
  # Invoice
38
50
  def get_invoices(**kwargs)
39
51
  get '/sales/invoices', query: kwargs
@@ -43,6 +55,10 @@ class Bukku < Client
43
55
  get "/sales/invoices/#{id}"
44
56
  end
45
57
 
58
+ def create_invoice(body:)
59
+ post '/sales/invoices', body: body
60
+ end
61
+
46
62
  # Credit Note
47
63
  def get_sales_credit_notes(**kwargs)
48
64
  get '/sales/credit_notes', query: kwargs
@@ -52,6 +68,10 @@ class Bukku < Client
52
68
  get "/sales/credit_notes/#{id}"
53
69
  end
54
70
 
71
+ def create_credit_note(body:)
72
+ post '/sales/credit_notes', body: body
73
+ end
74
+
55
75
  # Payment
56
76
  def get_sales_payments(**kwargs)
57
77
  get '/sales/payments', query: kwargs
@@ -61,7 +81,11 @@ class Bukku < Client
61
81
  get "/sales/payments/#{id}"
62
82
  end
63
83
 
64
- # Redund
84
+ def create_payment(body:)
85
+ post '/sales/payments', body: body
86
+ end
87
+
88
+ # Refund
65
89
  def get_sales_refunds(**kwargs)
66
90
  get '/sales/refunds', query: kwargs
67
91
  end
@@ -70,6 +94,10 @@ class Bukku < Client
70
94
  get "/sales/refunds/#{id}"
71
95
  end
72
96
 
97
+ def create_refund(body:)
98
+ post '/sales/refunds', body: body
99
+ end
100
+
73
101
  ## PURCHASE
74
102
  # Purchase Order
75
103
  def get_purchase_orders(**kwargs)
@@ -80,6 +108,10 @@ class Bukku < Client
80
108
  get "/purchases/orders/#{id}"
81
109
  end
82
110
 
111
+ def create_purchase_order(body:)
112
+ post '/purchases/orders', body: body
113
+ end
114
+
83
115
  ## Goods Received Note
84
116
  def get_received_notes(**kwargs)
85
117
  get '/purchases/goods_received_notes', query: kwargs
@@ -89,6 +121,10 @@ class Bukku < Client
89
121
  get "/purchases/goods_received_notes/#{id}"
90
122
  end
91
123
 
124
+ def create_received_note(body:)
125
+ post '/purchases/goods_received_notes', body: body
126
+ end
127
+
92
128
  # Bill
93
129
  def get_bills(**kwargs)
94
130
  get '/purchases/bills', query: kwargs
@@ -98,6 +134,10 @@ class Bukku < Client
98
134
  get "/purchases/bills/#{id}"
99
135
  end
100
136
 
137
+ def create_bill(body:)
138
+ post '/purchases/bills', body: body
139
+ end
140
+
101
141
  # Credit Note
102
142
  def get_purchases_credit_notes(**kwargs)
103
143
  get '/purchases/credit_notes', query: kwargs
@@ -107,6 +147,10 @@ class Bukku < Client
107
147
  get "/purchases/credit_notes/#{id}"
108
148
  end
109
149
 
150
+ def create_purchase_credit_note(body:)
151
+ post '/purchases/credit_note', body: body
152
+ end
153
+
110
154
  # Payment
111
155
  def get_purchases_payments(**kwargs)
112
156
  get '/purchases/payments', query: kwargs
@@ -116,6 +160,10 @@ class Bukku < Client
116
160
  get "/purchases/payments/#{id}"
117
161
  end
118
162
 
163
+ def create_purchases_payment(body:)
164
+ post '/purchases/payments', body: body
165
+ end
166
+
119
167
  # Refund
120
168
  def get_purchases_refunds(**kwargs)
121
169
  get '/purchases/refunds', query: kwargs
@@ -125,6 +173,10 @@ class Bukku < Client
125
173
  get "/purchases/refunds/#{id}"
126
174
  end
127
175
 
176
+ def create_purchases_refund(body:)
177
+ post '/purchases/refunds', body: body
178
+ end
179
+
128
180
  ## BANK
129
181
  # Money In
130
182
  def get_banking_incomes(**kwargs)
@@ -135,6 +187,10 @@ class Bukku < Client
135
187
  get "/banking/incomes/#{id}"
136
188
  end
137
189
 
190
+ def create_banking_income(body:)
191
+ post '/banking/incomes', body: body
192
+ end
193
+
138
194
  # Money Out
139
195
  def get_banking_expenses(**kwargs)
140
196
  get '/banking/expenses', query: kwargs
@@ -144,6 +200,10 @@ class Bukku < Client
144
200
  get "/banking/expenses/#{id}"
145
201
  end
146
202
 
203
+ def create_expense(body:)
204
+ post '/banking/expenses', body: body
205
+ end
206
+
147
207
  # Transfers
148
208
  def get_transfers(**kwargs)
149
209
  get '/banking/transfers', query: kwargs
@@ -153,6 +213,10 @@ class Bukku < Client
153
213
  get "/banking/transfers/#{id}"
154
214
  end
155
215
 
216
+ def create_transfer(body:)
217
+ post '/banking/transfer', body: body
218
+ end
219
+
156
220
  ## CONTACT
157
221
  # Contacts
158
222
  def get_contacts(**kwargs)
@@ -163,6 +227,10 @@ class Bukku < Client
163
227
  get "/contacts/#{id}"
164
228
  end
165
229
 
230
+ def create_contact(body:)
231
+ post '/contacts', body: body
232
+ end
233
+
166
234
  # Groups
167
235
  def get_contact_groups(**kwargs)
168
236
  get '/contacts/groups', query: kwargs
@@ -172,6 +240,10 @@ class Bukku < Client
172
240
  get "/contacts/groups/#{id}"
173
241
  end
174
242
 
243
+ def create_group(body:)
244
+ post '/contacts/groups', body: body
245
+ end
246
+
175
247
  ## PRODUCT
176
248
  # Product
177
249
  def get_products(**kwargs)
@@ -182,6 +254,19 @@ class Bukku < Client
182
254
  get "/products/#{id}"
183
255
  end
184
256
 
257
+ def create_product(body:)
258
+ post '/products', body: body
259
+ end
260
+
261
+ # Bundles
262
+ def get_bundle(id)
263
+ get "/products/bundles/#{id}"
264
+ end
265
+
266
+ def create_bundle(body:)
267
+ post '/products/bundles', body: body
268
+ end
269
+
185
270
  # Groups
186
271
  def get_product_groups(**kwargs)
187
272
  get '/products/groups', query: kwargs
@@ -191,6 +276,10 @@ class Bukku < Client
191
276
  get "/products/groups/#{id}"
192
277
  end
193
278
 
279
+ def create_product_group(body:)
280
+ post '/products/groups', body: body
281
+ end
282
+
194
283
  ## ACCOUNTING
195
284
  # Journal Entries
196
285
  def get_journal_entries(**kwargs)
@@ -201,6 +290,10 @@ class Bukku < Client
201
290
  get "/journal_entries/#{id}"
202
291
  end
203
292
 
293
+ def create_journal_entry(body:)
294
+ post '/journal_entries', body: body
295
+ end
296
+
204
297
  # Account
205
298
  def get_accounts(**kwargs)
206
299
  get '/accounts', query: kwargs
@@ -209,4 +302,13 @@ class Bukku < Client
209
302
  def get_account(id)
210
303
  get "/accounts/#{id}"
211
304
  end
305
+
306
+ def create_account(body:)
307
+ post '/accounts', body: body
308
+ end
309
+
310
+ # Files
311
+ def upload_file(file_data:, filename:, mime_type:)
312
+ upload '/files', file_data: file_data, filename: filename, mime_type: mime_type
313
+ end
212
314
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BukkuRails
4
- VERSION = '0.1.6'
4
+ VERSION = '0.2.2'
5
5
  end
data/lib/bukku_test.rb CHANGED
@@ -16,6 +16,10 @@ class BukkuTest < Client
16
16
  get "/sales/quotes/#{id}"
17
17
  end
18
18
 
19
+ def create_quote(body:)
20
+ post '/sales/quotes', body: body
21
+ end
22
+
19
23
  # Sales Order
20
24
  def get_sales_orders(**kwargs)
21
25
  get '/sales/orders', query: kwargs
@@ -25,6 +29,10 @@ class BukkuTest < Client
25
29
  get "/sales/orders/#{id}"
26
30
  end
27
31
 
32
+ def create_sales_order(body:)
33
+ post '/sales/orders', body: body
34
+ end
35
+
28
36
  # Delivery Order
29
37
  def get_delivery_orders(**kwargs)
30
38
  get '/sales/delivery_orders', query: kwargs
@@ -34,6 +42,10 @@ class BukkuTest < Client
34
42
  get "/sales/delivery_orders/#{id}"
35
43
  end
36
44
 
45
+ def create_delivery_order(body:)
46
+ post '/sales/delivery_orders', body: body
47
+ end
48
+
37
49
  # Invoice
38
50
  def get_invoices(**kwargs)
39
51
  get '/sales/invoices', query: kwargs
@@ -43,6 +55,10 @@ class BukkuTest < Client
43
55
  get "/sales/invoices/#{id}"
44
56
  end
45
57
 
58
+ def create_invoice(body:)
59
+ post '/sales/invoices', body: body
60
+ end
61
+
46
62
  # Credit Note
47
63
  def get_sales_credit_notes(**kwargs)
48
64
  get '/sales/credit_notes', query: kwargs
@@ -52,6 +68,10 @@ class BukkuTest < Client
52
68
  get "/sales/credit_notes/#{id}"
53
69
  end
54
70
 
71
+ def create_credit_note(body:)
72
+ post '/sales/credit_notes', body: body
73
+ end
74
+
55
75
  # Payment
56
76
  def get_sales_payments(**kwargs)
57
77
  get '/sales/payments', query: kwargs
@@ -61,7 +81,11 @@ class BukkuTest < Client
61
81
  get "/sales/payments/#{id}"
62
82
  end
63
83
 
64
- # Redund
84
+ def create_payment(body:)
85
+ post '/sales/payments', body: body
86
+ end
87
+
88
+ # Refund
65
89
  def get_sales_refunds(**kwargs)
66
90
  get '/sales/refunds', query: kwargs
67
91
  end
@@ -70,6 +94,10 @@ class BukkuTest < Client
70
94
  get "/sales/refunds/#{id}"
71
95
  end
72
96
 
97
+ def create_refund(body:)
98
+ post '/sales/refunds', body: body
99
+ end
100
+
73
101
  ## PURCHASE
74
102
  # Purchase Order
75
103
  def get_purchase_orders(**kwargs)
@@ -80,6 +108,10 @@ class BukkuTest < Client
80
108
  get "/purchases/orders/#{id}"
81
109
  end
82
110
 
111
+ def create_purchase_order(body:)
112
+ post '/purchases/orders', body: body
113
+ end
114
+
83
115
  ## Goods Received Note
84
116
  def get_received_notes(**kwargs)
85
117
  get '/purchases/goods_received_notes', query: kwargs
@@ -89,6 +121,10 @@ class BukkuTest < Client
89
121
  get "/purchases/goods_received_notes/#{id}"
90
122
  end
91
123
 
124
+ def create_received_note(body:)
125
+ post '/purchases/goods_received_notes', body: body
126
+ end
127
+
92
128
  # Bill
93
129
  def get_bills(**kwargs)
94
130
  get '/purchases/bills', query: kwargs
@@ -98,6 +134,10 @@ class BukkuTest < Client
98
134
  get "/purchases/bills/#{id}"
99
135
  end
100
136
 
137
+ def create_bill(body:)
138
+ post '/purchases/bills', body: body
139
+ end
140
+
101
141
  # Credit Note
102
142
  def get_purchases_credit_notes(**kwargs)
103
143
  get '/purchases/credit_notes', query: kwargs
@@ -107,6 +147,10 @@ class BukkuTest < Client
107
147
  get "/purchases/credit_notes/#{id}"
108
148
  end
109
149
 
150
+ def create_purchase_credit_note(body:)
151
+ post '/purchases/credit_note', body: body
152
+ end
153
+
110
154
  # Payment
111
155
  def get_purchases_payments(**kwargs)
112
156
  get '/purchases/payments', query: kwargs
@@ -116,6 +160,10 @@ class BukkuTest < Client
116
160
  get "/purchases/payments/#{id}"
117
161
  end
118
162
 
163
+ def create_purchases_payment(body:)
164
+ post '/purchases/payments', body: body
165
+ end
166
+
119
167
  # Refund
120
168
  def get_purchases_refunds(**kwargs)
121
169
  get '/purchases/refunds', query: kwargs
@@ -125,6 +173,10 @@ class BukkuTest < Client
125
173
  get "/purchases/refunds/#{id}"
126
174
  end
127
175
 
176
+ def create_purchases_refund(body:)
177
+ post '/purchases/refunds', body: body
178
+ end
179
+
128
180
  ## BANK
129
181
  # Money In
130
182
  def get_banking_incomes(**kwargs)
@@ -135,6 +187,10 @@ class BukkuTest < Client
135
187
  get "/banking/incomes/#{id}"
136
188
  end
137
189
 
190
+ def create_banking_income(body:)
191
+ post '/banking/incomes', body: body
192
+ end
193
+
138
194
  # Money Out
139
195
  def get_banking_expenses(**kwargs)
140
196
  get '/banking/expenses', query: kwargs
@@ -144,6 +200,10 @@ class BukkuTest < Client
144
200
  get "/banking/expenses/#{id}"
145
201
  end
146
202
 
203
+ def create_expense(body:)
204
+ post '/banking/expenses', body: body
205
+ end
206
+
147
207
  # Transfers
148
208
  def get_transfers(**kwargs)
149
209
  get '/banking/transfers', query: kwargs
@@ -153,6 +213,10 @@ class BukkuTest < Client
153
213
  get "/banking/transfers/#{id}"
154
214
  end
155
215
 
216
+ def create_transfer(body:)
217
+ post '/banking/transfer', body: body
218
+ end
219
+
156
220
  ## CONTACT
157
221
  # Contacts
158
222
  def get_contacts(**kwargs)
@@ -163,6 +227,10 @@ class BukkuTest < Client
163
227
  get "/contacts/#{id}"
164
228
  end
165
229
 
230
+ def create_contact(body:)
231
+ post '/contacts', body: body
232
+ end
233
+
166
234
  # Groups
167
235
  def get_contact_groups(**kwargs)
168
236
  get '/contacts/groups', query: kwargs
@@ -172,6 +240,10 @@ class BukkuTest < Client
172
240
  get "/contacts/groups/#{id}"
173
241
  end
174
242
 
243
+ def create_group(body:)
244
+ post '/contacts/groups', body: body
245
+ end
246
+
175
247
  ## PRODUCT
176
248
  # Product
177
249
  def get_products(**kwargs)
@@ -182,6 +254,19 @@ class BukkuTest < Client
182
254
  get "/products/#{id}"
183
255
  end
184
256
 
257
+ def create_product(body:)
258
+ post '/products', body: body
259
+ end
260
+
261
+ # Bundles
262
+ def get_bundle(id)
263
+ get "/products/bundles/#{id}"
264
+ end
265
+
266
+ def create_bundle(body:)
267
+ post '/products/bundles', body: body
268
+ end
269
+
185
270
  # Groups
186
271
  def get_product_groups(**kwargs)
187
272
  get '/products/groups', query: kwargs
@@ -191,6 +276,10 @@ class BukkuTest < Client
191
276
  get "/products/groups/#{id}"
192
277
  end
193
278
 
279
+ def create_product_group(body:)
280
+ post '/products/groups', body: body
281
+ end
282
+
194
283
  ## ACCOUNTING
195
284
  # Journal Entries
196
285
  def get_journal_entries(**kwargs)
@@ -201,6 +290,10 @@ class BukkuTest < Client
201
290
  get "/journal_entries/#{id}"
202
291
  end
203
292
 
293
+ def create_journal_entry(body:)
294
+ post '/journal_entries', body: body
295
+ end
296
+
204
297
  # Account
205
298
  def get_accounts(**kwargs)
206
299
  get '/accounts', query: kwargs
@@ -209,4 +302,13 @@ class BukkuTest < Client
209
302
  def get_account(id)
210
303
  get "/accounts/#{id}"
211
304
  end
305
+
306
+ def create_account(body:)
307
+ post '/accounts', body: body
308
+ end
309
+
310
+ # Files
311
+ def upload_file(file_data:, filename:, mime_type:)
312
+ upload '/files', file_data: file_data, filename: filename, mime_type: mime_type
313
+ end
212
314
  end
data/lib/client.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  class Client
2
2
  # The BASE_URI below is there to facilitate test only
3
- BASE_URI = "https://rekon.org"
3
+ BASE_URI = 'https://rekon.org'
4
4
 
5
5
  attr_reader :token, :domain
6
6
 
@@ -16,6 +16,15 @@ class Client
16
16
  end
17
17
 
18
18
  def default_headers
19
+ {
20
+ 'Authorization' => "Bearer #{@token}",
21
+ 'Company-Subdomain' => "#{@domain}",
22
+ 'Accept' => 'application/json',
23
+ 'Content-Type' => 'application/json'
24
+ }
25
+ end
26
+
27
+ def upload_headers
19
28
  {
20
29
  'Authorization' => "Bearer #{@token}",
21
30
  'Company-Subdomain' => "#{@domain}",
@@ -31,36 +40,55 @@ class Client
31
40
  make_request Net::HTTP::Post, path, query: query, body: body
32
41
  end
33
42
 
34
- def make_request(klass, path, query: {}, body: {})
35
- uri = URI("#{base_uri}#{path}")
36
- uri.query = URI.encode_www_form(query) if query
43
+ def upload(path, file_data:, filename:, mime_type:)
44
+ upload_request Net::HTTP::Post, path, file_data: file_data, filename: filename, mime_type: mime_type
45
+ end
37
46
 
47
+ def build_http(uri)
38
48
  http = Net::HTTP.new(uri.host, uri.port)
39
49
  http.use_ssl = uri.instance_of?(URI::HTTPS)
40
-
50
+
41
51
  # Add the 2 lines below because development keeps on failing SSL CRL checks
42
- # Check this article for explanation: https://dev.to/madhuhari188/how-we-solved-unable-to-get-certificate-crl-in-rails-a-debugging-story-2pna
52
+ # Check this article for explanation:
53
+ # https://dev.to/madhuhari188/how-we-solved-unable-to-get-certificate-crl-in-rails-a-debugging-story-2pna
43
54
  http.verify_mode = OpenSSL::SSL::VERIFY_PEER
44
55
  http.verify_callback = ->(_preverify_ok, _store_ctx) { true }
45
56
 
57
+ http
58
+ end
59
+
60
+ def make_request(klass, path, query: {}, body: {})
46
61
  # Uncomment below for debuging purpose to see the payload that was sent.
47
- # http.set_debug_output($stdout)
62
+ # build_http(uri).set_debug_output($stdout)
63
+
64
+ uri = URI("#{base_uri}#{path}")
65
+ uri.query = URI.encode_www_form(query) if query
48
66
 
49
67
  request = klass.new(uri.request_uri, default_headers)
50
- if body && !body.empty?
51
- request.body = body.to_json
52
- end
68
+ request.body = body.to_json if body && !body.empty?
69
+
70
+ execute_request(build_http(uri), request)
71
+ end
72
+
73
+ def upload_request(klass, path, file_data:, filename:, mime_type:)
74
+ uri = URI("#{base_uri}#{path}")
75
+ request = klass.new(uri.request_uri, upload_headers)
76
+ request.set_form(
77
+ [['file', StringIO.new(file_data), { filename: filename, content_type: mime_type }]], 'multipart/form-data'
78
+ )
53
79
 
80
+ execute_request(build_http(uri), request)
81
+ end
82
+
83
+ def execute_request(http, request)
54
84
  response = http.request(request)
55
85
 
56
86
  case response.code.to_i
57
87
  when 200, 201, 202, 203, 204
58
- # JSON.parse(response.body) if response.body.present?
59
88
  JSON.parse(response.body) if response.body && !response.body.empty?
60
89
  else
61
90
  raise Error, "#{response.code}: #{response.body}"
62
91
  end
63
92
  end
64
-
65
93
  class Error < StandardError; end
66
94
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bukku_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Muzaffar Ariff
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-01-19 00:00:00.000000000 Z
11
+ date: 2026-02-27 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Use Rails conventions to call Bukku API requests.
14
14
  email:
@@ -50,5 +50,6 @@ requirements: []
50
50
  rubygems_version: 3.2.32
51
51
  signing_key:
52
52
  specification_version: 4
53
- summary: Bukku Cloud accounting API implementation in Rails
53
+ summary: Bukku Cloud accounting API implementation in Ruby and usage mostly for Rails
54
+ apps
54
55
  test_files: []