@agnocon/piece-bexio 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. package/LICENSE.MIT-AP +24 -0
  2. package/dist/index.d.ts +2 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +93 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/lib/actions/create-company.d.ts +28 -0
  7. package/dist/lib/actions/create-company.d.ts.map +1 -0
  8. package/dist/lib/actions/create-company.js +461 -0
  9. package/dist/lib/actions/create-company.js.map +1 -0
  10. package/dist/lib/actions/create-file.d.ts +4 -0
  11. package/dist/lib/actions/create-file.d.ts.map +1 -0
  12. package/dist/lib/actions/create-file.js +48 -0
  13. package/dist/lib/actions/create-file.js.map +1 -0
  14. package/dist/lib/actions/create-manual-entry.d.ts +7 -0
  15. package/dist/lib/actions/create-manual-entry.d.ts.map +1 -0
  16. package/dist/lib/actions/create-manual-entry.js +426 -0
  17. package/dist/lib/actions/create-manual-entry.js.map +1 -0
  18. package/dist/lib/actions/create-person.d.ts +30 -0
  19. package/dist/lib/actions/create-person.d.ts.map +1 -0
  20. package/dist/lib/actions/create-person.js +477 -0
  21. package/dist/lib/actions/create-person.js.map +1 -0
  22. package/dist/lib/actions/create-product.d.ts +34 -0
  23. package/dist/lib/actions/create-product.d.ts.map +1 -0
  24. package/dist/lib/actions/create-product.js +527 -0
  25. package/dist/lib/actions/create-product.js.map +1 -0
  26. package/dist/lib/actions/create-project.d.ts +17 -0
  27. package/dist/lib/actions/create-project.d.ts.map +1 -0
  28. package/dist/lib/actions/create-project.js +316 -0
  29. package/dist/lib/actions/create-project.js.map +1 -0
  30. package/dist/lib/actions/create-sales-invoice.d.ts +25 -0
  31. package/dist/lib/actions/create-sales-invoice.d.ts.map +1 -0
  32. package/dist/lib/actions/create-sales-invoice.js +615 -0
  33. package/dist/lib/actions/create-sales-invoice.js.map +1 -0
  34. package/dist/lib/actions/create-sales-order.d.ts +25 -0
  35. package/dist/lib/actions/create-sales-order.d.ts.map +1 -0
  36. package/dist/lib/actions/create-sales-order.js +642 -0
  37. package/dist/lib/actions/create-sales-order.js.map +1 -0
  38. package/dist/lib/actions/create-sales-quote.d.ts +28 -0
  39. package/dist/lib/actions/create-sales-quote.d.ts.map +1 -0
  40. package/dist/lib/actions/create-sales-quote.js +666 -0
  41. package/dist/lib/actions/create-sales-quote.js.map +1 -0
  42. package/dist/lib/actions/create-time-tracking.d.ts +17 -0
  43. package/dist/lib/actions/create-time-tracking.d.ts.map +1 -0
  44. package/dist/lib/actions/create-time-tracking.js +380 -0
  45. package/dist/lib/actions/create-time-tracking.js.map +1 -0
  46. package/dist/lib/actions/export-invoice-pdf.d.ts +5 -0
  47. package/dist/lib/actions/export-invoice-pdf.d.ts.map +1 -0
  48. package/dist/lib/actions/export-invoice-pdf.js +94 -0
  49. package/dist/lib/actions/export-invoice-pdf.js.map +1 -0
  50. package/dist/lib/actions/find-account.d.ts +6 -0
  51. package/dist/lib/actions/find-account.d.ts.map +1 -0
  52. package/dist/lib/actions/find-account.js +107 -0
  53. package/dist/lib/actions/find-account.js.map +1 -0
  54. package/dist/lib/actions/find-company.d.ts +8 -0
  55. package/dist/lib/actions/find-company.d.ts.map +1 -0
  56. package/dist/lib/actions/find-company.js +160 -0
  57. package/dist/lib/actions/find-company.js.map +1 -0
  58. package/dist/lib/actions/find-country.d.ts +7 -0
  59. package/dist/lib/actions/find-country.d.ts.map +1 -0
  60. package/dist/lib/actions/find-country.js +125 -0
  61. package/dist/lib/actions/find-country.js.map +1 -0
  62. package/dist/lib/actions/find-person.d.ts +9 -0
  63. package/dist/lib/actions/find-person.d.ts.map +1 -0
  64. package/dist/lib/actions/find-person.js +175 -0
  65. package/dist/lib/actions/find-person.js.map +1 -0
  66. package/dist/lib/actions/find-product.d.ts +7 -0
  67. package/dist/lib/actions/find-product.d.ts.map +1 -0
  68. package/dist/lib/actions/find-product.js +124 -0
  69. package/dist/lib/actions/find-product.js.map +1 -0
  70. package/dist/lib/actions/search-invoice.d.ts +7 -0
  71. package/dist/lib/actions/search-invoice.d.ts.map +1 -0
  72. package/dist/lib/actions/search-invoice.js +140 -0
  73. package/dist/lib/actions/search-invoice.js.map +1 -0
  74. package/dist/lib/actions/search-order.d.ts +7 -0
  75. package/dist/lib/actions/search-order.d.ts.map +1 -0
  76. package/dist/lib/actions/search-order.js +139 -0
  77. package/dist/lib/actions/search-order.js.map +1 -0
  78. package/dist/lib/actions/search-quote.d.ts +7 -0
  79. package/dist/lib/actions/search-quote.d.ts.map +1 -0
  80. package/dist/lib/actions/search-quote.js +140 -0
  81. package/dist/lib/actions/search-quote.js.map +1 -0
  82. package/dist/lib/actions/send-sales-invoice.d.ts +9 -0
  83. package/dist/lib/actions/send-sales-invoice.d.ts.map +1 -0
  84. package/dist/lib/actions/send-sales-invoice.js +110 -0
  85. package/dist/lib/actions/send-sales-invoice.js.map +1 -0
  86. package/dist/lib/actions/update-company.d.ts +29 -0
  87. package/dist/lib/actions/update-company.d.ts.map +1 -0
  88. package/dist/lib/actions/update-company.js +506 -0
  89. package/dist/lib/actions/update-company.js.map +1 -0
  90. package/dist/lib/actions/update-person.d.ts +31 -0
  91. package/dist/lib/actions/update-person.d.ts.map +1 -0
  92. package/dist/lib/actions/update-person.js +524 -0
  93. package/dist/lib/actions/update-person.js.map +1 -0
  94. package/dist/lib/actions/update-product.d.ts +34 -0
  95. package/dist/lib/actions/update-product.d.ts.map +1 -0
  96. package/dist/lib/actions/update-product.js +556 -0
  97. package/dist/lib/actions/update-product.js.map +1 -0
  98. package/dist/lib/auth.d.ts +2 -0
  99. package/dist/lib/auth.d.ts.map +1 -0
  100. package/dist/lib/auth.js +51 -0
  101. package/dist/lib/auth.js.map +1 -0
  102. package/dist/lib/common/client.d.ts +13 -0
  103. package/dist/lib/common/client.d.ts.map +1 -0
  104. package/dist/lib/common/client.js +64 -0
  105. package/dist/lib/common/client.js.map +1 -0
  106. package/dist/lib/common/index.d.ts +5 -0
  107. package/dist/lib/common/index.d.ts.map +1 -0
  108. package/dist/lib/common/index.js +10 -0
  109. package/dist/lib/common/index.js.map +1 -0
  110. package/dist/lib/common/props.d.ts +14 -0
  111. package/dist/lib/common/props.d.ts.map +1 -0
  112. package/dist/lib/common/props.js +118 -0
  113. package/dist/lib/common/props.js.map +1 -0
  114. package/dist/lib/common/types.d.ts +89 -0
  115. package/dist/lib/common/types.d.ts.map +1 -0
  116. package/dist/lib/common/types.js +6 -0
  117. package/dist/lib/common/types.js.map +1 -0
  118. package/dist/lib/triggers/new-order.d.ts +11 -0
  119. package/dist/lib/triggers/new-order.d.ts.map +1 -0
  120. package/dist/lib/triggers/new-order.js +152 -0
  121. package/dist/lib/triggers/new-order.js.map +1 -0
  122. package/dist/lib/triggers/new-product.d.ts +3 -0
  123. package/dist/lib/triggers/new-product.d.ts.map +1 -0
  124. package/dist/lib/triggers/new-product.js +111 -0
  125. package/dist/lib/triggers/new-product.js.map +1 -0
  126. package/dist/lib/triggers/new-project.d.ts +11 -0
  127. package/dist/lib/triggers/new-project.d.ts.map +1 -0
  128. package/dist/lib/triggers/new-project.js +141 -0
  129. package/dist/lib/triggers/new-project.js.map +1 -0
  130. package/dist/lib/triggers/new-quote.d.ts +11 -0
  131. package/dist/lib/triggers/new-quote.d.ts.map +1 -0
  132. package/dist/lib/triggers/new-quote.js +153 -0
  133. package/dist/lib/triggers/new-quote.js.map +1 -0
  134. package/dist/lib/triggers/new-sales-invoice.d.ts +11 -0
  135. package/dist/lib/triggers/new-sales-invoice.d.ts.map +1 -0
  136. package/dist/lib/triggers/new-sales-invoice.js +153 -0
  137. package/dist/lib/triggers/new-sales-invoice.js.map +1 -0
  138. package/dist/lib/triggers/new-updated-company.d.ts +3 -0
  139. package/dist/lib/triggers/new-updated-company.d.ts.map +1 -0
  140. package/dist/lib/triggers/new-updated-company.js +122 -0
  141. package/dist/lib/triggers/new-updated-company.js.map +1 -0
  142. package/dist/lib/triggers/new-updated-person.d.ts +3 -0
  143. package/dist/lib/triggers/new-updated-person.d.ts.map +1 -0
  144. package/dist/lib/triggers/new-updated-person.js +122 -0
  145. package/dist/lib/triggers/new-updated-person.js.map +1 -0
  146. package/package.json +48 -0
  147. package/src/index.ts +89 -0
  148. package/src/lib/actions/create-company.ts +464 -0
  149. package/src/lib/actions/create-file.ts +62 -0
  150. package/src/lib/actions/create-manual-entry.ts +445 -0
  151. package/src/lib/actions/create-person.ts +481 -0
  152. package/src/lib/actions/create-product.ts +563 -0
  153. package/src/lib/actions/create-project.ts +344 -0
  154. package/src/lib/actions/create-sales-invoice.ts +656 -0
  155. package/src/lib/actions/create-sales-order.ts +689 -0
  156. package/src/lib/actions/create-sales-quote.ts +713 -0
  157. package/src/lib/actions/create-time-tracking.ts +418 -0
  158. package/src/lib/actions/export-invoice-pdf.ts +104 -0
  159. package/src/lib/actions/find-account.ts +114 -0
  160. package/src/lib/actions/find-company.ts +193 -0
  161. package/src/lib/actions/find-country.ts +127 -0
  162. package/src/lib/actions/find-person.ts +208 -0
  163. package/src/lib/actions/find-product.ts +161 -0
  164. package/src/lib/actions/search-invoice.ts +157 -0
  165. package/src/lib/actions/search-order.ts +155 -0
  166. package/src/lib/actions/search-quote.ts +157 -0
  167. package/src/lib/actions/send-sales-invoice.ts +118 -0
  168. package/src/lib/actions/update-company.ts +518 -0
  169. package/src/lib/actions/update-person.ts +536 -0
  170. package/src/lib/actions/update-product.ts +594 -0
  171. package/src/lib/auth.ts +44 -0
  172. package/src/lib/common/client.ts +65 -0
  173. package/src/lib/common/index.ts +5 -0
  174. package/src/lib/common/props.ts +127 -0
  175. package/src/lib/common/types.ts +99 -0
  176. package/src/lib/triggers/new-order.ts +184 -0
  177. package/src/lib/triggers/new-product.ts +154 -0
  178. package/src/lib/triggers/new-project.ts +165 -0
  179. package/src/lib/triggers/new-quote.ts +186 -0
  180. package/src/lib/triggers/new-sales-invoice.ts +186 -0
  181. package/src/lib/triggers/new-updated-company.ts +161 -0
  182. package/src/lib/triggers/new-updated-person.ts +161 -0
@@ -0,0 +1,563 @@
1
+ import { createAction, Property, OAuth2PropertyValue } from '@agnocon/pieces-framework';
2
+ import { bexioAuth } from '../auth';
3
+ import { BexioClient } from '../common/client';
4
+ import { bexioCommonProps } from '../common/props';
5
+
6
+ export const createProductAction = createAction({
7
+ auth: bexioAuth,
8
+ name: 'create_product',
9
+ displayName: 'Create Product',
10
+ description: 'Create a new product or service',
11
+ audience: 'both',
12
+ aiMetadata: { description: 'Create a new Bexio article (a physical product or a service) with internal code and name, plus optional pricing, taxes, unit, currency, supplier, stock, and dimension details. Not idempotent: each call adds a separate article even if the code repeats, so check for an existing product first to avoid duplicates. Stock-item fields require the stock_edit scope.', idempotent: false },
13
+ props: {
14
+ user_id: Property.Dropdown({
15
+ auth: bexioAuth,
16
+ displayName: 'User',
17
+ description: 'User associated with this product',
18
+ required: true,
19
+ refreshers: [],
20
+ options: async ({ auth }) => {
21
+ if (!auth) {
22
+ return {
23
+ disabled: true,
24
+ placeholder: 'Connect your Bexio account first',
25
+ options: [],
26
+ };
27
+ }
28
+
29
+ try {
30
+ const client = new BexioClient(auth);
31
+ const users = await client.get<Array<{
32
+ id: number;
33
+ firstname?: string | null;
34
+ lastname?: string | null;
35
+ email: string;
36
+ }>>('/3.0/users');
37
+
38
+ return {
39
+ disabled: false,
40
+ options: users.map((user) => {
41
+ const name = user.firstname && user.lastname
42
+ ? `${user.firstname} ${user.lastname}`
43
+ : user.email;
44
+ return {
45
+ label: name,
46
+ value: user.id,
47
+ };
48
+ }),
49
+ };
50
+ } catch (error) {
51
+ return {
52
+ disabled: true,
53
+ placeholder: 'Failed to load users',
54
+ options: [],
55
+ };
56
+ }
57
+ },
58
+ }),
59
+ article_type_id: Property.StaticDropdown({
60
+ displayName: 'Product Type',
61
+ description: 'Type of product',
62
+ required: true,
63
+ defaultValue: 1,
64
+ options: {
65
+ disabled: false,
66
+ options: [
67
+ { label: 'Physical Product', value: 1 },
68
+ { label: 'Service', value: 2 },
69
+ ],
70
+ },
71
+ }),
72
+ intern_code: Property.ShortText({
73
+ displayName: 'Internal Code',
74
+ description: 'Internal product code',
75
+ required: true,
76
+ }),
77
+ intern_name: Property.ShortText({
78
+ displayName: 'Internal Name',
79
+ description: 'Internal product name',
80
+ required: true,
81
+ }),
82
+ intern_description: Property.LongText({
83
+ displayName: 'Internal Description',
84
+ description: 'Internal product description',
85
+ required: false,
86
+ }),
87
+ contact_id: Property.Dropdown({
88
+ auth: bexioAuth,
89
+ displayName: 'Contact',
90
+ description: 'Contact associated with this product',
91
+ required: false,
92
+ refreshers: [],
93
+ options: async ({ auth }) => {
94
+ if (!auth) {
95
+ return {
96
+ disabled: true,
97
+ placeholder: 'Connect your Bexio account first',
98
+ options: [],
99
+ };
100
+ }
101
+
102
+ try {
103
+ const client = new BexioClient(auth);
104
+ const contacts = await client.get<Array<{
105
+ id: number;
106
+ contact_type_id: number;
107
+ name_1: string;
108
+ name_2?: string | null;
109
+ nr?: string | null;
110
+ }>>('/2.0/contact');
111
+
112
+ return {
113
+ disabled: false,
114
+ options: contacts.map((contact) => {
115
+ const name = contact.name_2
116
+ ? `${contact.name_2} ${contact.name_1}`
117
+ : contact.name_1;
118
+ const label = contact.nr ? `${name} (#${contact.nr})` : name;
119
+ return {
120
+ label,
121
+ value: contact.id,
122
+ };
123
+ }),
124
+ };
125
+ } catch (error) {
126
+ return {
127
+ disabled: true,
128
+ placeholder: 'Failed to load contacts',
129
+ options: [],
130
+ };
131
+ }
132
+ },
133
+ }),
134
+ deliverer_code: Property.ShortText({
135
+ displayName: 'Supplier Code',
136
+ description: 'Supplier product code',
137
+ required: false,
138
+ }),
139
+ deliverer_name: Property.ShortText({
140
+ displayName: 'Supplier Name',
141
+ description: 'Supplier product name',
142
+ required: false,
143
+ }),
144
+ deliverer_description: Property.LongText({
145
+ displayName: 'Supplier Description',
146
+ description: 'Supplier product description',
147
+ required: false,
148
+ }),
149
+ purchase_price: Property.ShortText({
150
+ displayName: 'Purchase Price',
151
+ description: 'Purchase price',
152
+ required: false,
153
+ }),
154
+ sale_price: Property.ShortText({
155
+ displayName: 'Sale Price',
156
+ description: 'Sale price',
157
+ required: false,
158
+ }),
159
+ purchase_total: Property.Number({
160
+ displayName: 'Purchase Total',
161
+ description: 'Total purchase amount',
162
+ required: false,
163
+ }),
164
+ sale_total: Property.Number({
165
+ displayName: 'Sale Total',
166
+ description: 'Total sale amount',
167
+ required: false,
168
+ }),
169
+ currency_id: bexioCommonProps.currency({
170
+ displayName: 'Currency',
171
+ required: false,
172
+ }),
173
+ tax_income_id: Property.Dropdown({
174
+ auth: bexioAuth,
175
+ displayName: 'Income Tax',
176
+ description: 'Tax for income/sales',
177
+ required: false,
178
+ refreshers: [],
179
+ options: async ({ auth }) => {
180
+ if (!auth) {
181
+ return {
182
+ disabled: true,
183
+ placeholder: 'Connect your Bexio account first',
184
+ options: [],
185
+ };
186
+ }
187
+
188
+ try {
189
+ const client = new BexioClient(auth);
190
+ const taxes = await client.get<Array<{
191
+ id: number;
192
+ name: string;
193
+ value: number;
194
+ display_name?: string;
195
+ type?: string;
196
+ }>>('/3.0/taxes');
197
+
198
+ return {
199
+ disabled: false,
200
+ options: taxes
201
+ .filter((tax) => tax.type === 'sales_tax' || !tax.type)
202
+ .map((tax) => ({
203
+ label: tax.display_name || tax.name,
204
+ value: tax.id,
205
+ })),
206
+ };
207
+ } catch (error) {
208
+ return {
209
+ disabled: true,
210
+ placeholder: 'Failed to load taxes',
211
+ options: [],
212
+ };
213
+ }
214
+ },
215
+ }),
216
+ tax_expense_id: Property.Dropdown({
217
+ auth: bexioAuth,
218
+ displayName: 'Expense Tax',
219
+ description: 'Tax for expenses/purchases',
220
+ required: false,
221
+ refreshers: [],
222
+ options: async ({ auth }) => {
223
+ if (!auth) {
224
+ return {
225
+ disabled: true,
226
+ placeholder: 'Connect your Bexio account first',
227
+ options: [],
228
+ };
229
+ }
230
+
231
+ try {
232
+ const client = new BexioClient(auth);
233
+ const taxes = await client.get<Array<{
234
+ id: number;
235
+ name: string;
236
+ value: number;
237
+ display_name?: string;
238
+ type?: string;
239
+ }>>('/3.0/taxes');
240
+
241
+ return {
242
+ disabled: false,
243
+ options: taxes
244
+ .filter((tax) => tax.type === 'pre_tax' || !tax.type)
245
+ .map((tax) => ({
246
+ label: tax.display_name || tax.name,
247
+ value: tax.id,
248
+ })),
249
+ };
250
+ } catch (error) {
251
+ return {
252
+ disabled: true,
253
+ placeholder: 'Failed to load taxes',
254
+ options: [],
255
+ };
256
+ }
257
+ },
258
+ }),
259
+ unit_id: Property.Dropdown({
260
+ auth: bexioAuth,
261
+ displayName: 'Unit',
262
+ description: 'Unit of measurement',
263
+ required: false,
264
+ refreshers: [],
265
+ options: async ({ auth }) => {
266
+ if (!auth) {
267
+ return {
268
+ disabled: true,
269
+ placeholder: 'Connect your Bexio account first',
270
+ options: [],
271
+ };
272
+ }
273
+
274
+ try {
275
+ const client = new BexioClient(auth);
276
+ const units = await client.get<Array<{ id: number; name: string }>>('/2.0/unit');
277
+
278
+ return {
279
+ disabled: false,
280
+ options: units.map((unit) => ({
281
+ label: unit.name,
282
+ value: unit.id,
283
+ })),
284
+ };
285
+ } catch (error) {
286
+ return {
287
+ disabled: true,
288
+ placeholder: 'Failed to load units',
289
+ options: [],
290
+ };
291
+ }
292
+ },
293
+ }),
294
+ is_stock: Property.Checkbox({
295
+ displayName: 'Is Stock Item',
296
+ description: 'Whether this is a stock item (requires stock_edit scope)',
297
+ required: false,
298
+ defaultValue: false,
299
+ }),
300
+ stock_id: Property.Dropdown({
301
+ auth: bexioAuth,
302
+ displayName: 'Stock Location',
303
+ description: 'Stock location',
304
+ required: false,
305
+ refreshers: [],
306
+ options: async ({ auth }) => {
307
+ if (!auth) {
308
+ return {
309
+ disabled: true,
310
+ placeholder: 'Connect your Bexio account first',
311
+ options: [],
312
+ };
313
+ }
314
+
315
+ try {
316
+ const client = new BexioClient(auth);
317
+ // TODO: Need to confirm endpoint - assuming /2.0/stock or /2.0/stock_location
318
+ const stocks = await client.get<Array<{ id: number; name: string }>>('/2.0/stock').catch(() => []);
319
+
320
+ return {
321
+ disabled: false,
322
+ options: stocks.map((stock) => ({
323
+ label: stock.name,
324
+ value: stock.id,
325
+ })),
326
+ };
327
+ } catch (error) {
328
+ return {
329
+ disabled: true,
330
+ placeholder: 'Failed to load stock locations',
331
+ options: [],
332
+ };
333
+ }
334
+ },
335
+ }),
336
+ stock_place_id: Property.Dropdown({
337
+ auth: bexioAuth,
338
+ displayName: 'Stock Area',
339
+ description: 'Stock area/place',
340
+ required: false,
341
+ refreshers: [],
342
+ options: async ({ auth }) => {
343
+ if (!auth) {
344
+ return {
345
+ disabled: true,
346
+ placeholder: 'Connect your Bexio account first',
347
+ options: [],
348
+ };
349
+ }
350
+
351
+ try {
352
+ const client = new BexioClient(auth);
353
+ // TODO: Need to confirm endpoint - assuming /2.0/stock_place or /2.0/stock_area
354
+ const stockPlaces = await client.get<Array<{ id: number; name: string }>>('/2.0/stock_place').catch(() => []);
355
+
356
+ return {
357
+ disabled: false,
358
+ options: stockPlaces.map((place) => ({
359
+ label: place.name,
360
+ value: place.id,
361
+ })),
362
+ };
363
+ } catch (error) {
364
+ return {
365
+ disabled: true,
366
+ placeholder: 'Failed to load stock areas',
367
+ options: [],
368
+ };
369
+ }
370
+ },
371
+ }),
372
+ stock_nr: Property.Number({
373
+ displayName: 'Stock Number',
374
+ description: 'Current stock quantity',
375
+ required: true,
376
+ defaultValue: 0,
377
+ }),
378
+ stock_min_nr: Property.Number({
379
+ displayName: 'Minimum Stock',
380
+ description: 'Minimum stock quantity',
381
+ required: true,
382
+ defaultValue: 0,
383
+ }),
384
+ width: Property.Number({
385
+ displayName: 'Width',
386
+ description: 'Product width',
387
+ required: false,
388
+ }),
389
+ height: Property.Number({
390
+ displayName: 'Height',
391
+ description: 'Product height',
392
+ required: false,
393
+ }),
394
+ weight: Property.Number({
395
+ displayName: 'Weight',
396
+ description: 'Product weight',
397
+ required: false,
398
+ }),
399
+ volume: Property.Number({
400
+ displayName: 'Volume',
401
+ description: 'Product volume',
402
+ required: false,
403
+ }),
404
+ remarks: Property.LongText({
405
+ displayName: 'Remarks',
406
+ description: 'Additional remarks',
407
+ required: false,
408
+ }),
409
+ delivery_price: Property.Number({
410
+ displayName: 'Delivery Price',
411
+ description: 'Delivery price',
412
+ required: false,
413
+ }),
414
+ article_group_id: Property.Dropdown({
415
+ auth: bexioAuth,
416
+ displayName: 'Article Group',
417
+ description: 'Product group/category',
418
+ required: false,
419
+ refreshers: [],
420
+ options: async ({ auth }) => {
421
+ if (!auth) {
422
+ return {
423
+ disabled: true,
424
+ placeholder: 'Connect your Bexio account first',
425
+ options: [],
426
+ };
427
+ }
428
+
429
+ try {
430
+ const client = new BexioClient(auth);
431
+ // TODO: Need to confirm endpoint - assuming /2.0/article_group
432
+ const groups = await client.get<Array<{ id: number; name: string }>>('/2.0/article_group').catch(() => []);
433
+
434
+ return {
435
+ disabled: false,
436
+ options: groups.map((group) => ({
437
+ label: group.name,
438
+ value: group.id,
439
+ })),
440
+ };
441
+ } catch (error) {
442
+ return {
443
+ disabled: true,
444
+ placeholder: 'Failed to load article groups',
445
+ options: [],
446
+ };
447
+ }
448
+ },
449
+ }),
450
+ account_id: bexioCommonProps.account({
451
+ displayName: 'Account',
452
+ description: 'Account for this product',
453
+ required: false,
454
+ }),
455
+ expense_account_id: bexioCommonProps.account({
456
+ displayName: 'Expense Account',
457
+ description: 'Expense account for this product',
458
+ required: false,
459
+ }),
460
+ },
461
+ async run({ auth, propsValue }) {
462
+ const client = new BexioClient(auth);
463
+ const props = propsValue;
464
+
465
+ const requestBody: Record<string, unknown> = {
466
+ user_id: props['user_id'],
467
+ article_type_id: props['article_type_id'],
468
+ intern_code: props['intern_code'],
469
+ intern_name: props['intern_name'],
470
+ stock_nr: props['stock_nr'] || 0,
471
+ stock_min_nr: props['stock_min_nr'] || 0,
472
+ };
473
+
474
+ if (props['intern_description']) {
475
+ requestBody['intern_description'] = props['intern_description'];
476
+ }
477
+ if (props['contact_id']) {
478
+ requestBody['contact_id'] = props['contact_id'];
479
+ }
480
+ if (props['deliverer_code']) {
481
+ requestBody['deliverer_code'] = props['deliverer_code'];
482
+ }
483
+ if (props['deliverer_name']) {
484
+ requestBody['deliverer_name'] = props['deliverer_name'];
485
+ }
486
+ if (props['deliverer_description']) {
487
+ requestBody['deliverer_description'] = props['deliverer_description'];
488
+ }
489
+ if (props['purchase_price']) {
490
+ requestBody['purchase_price'] = props['purchase_price'];
491
+ }
492
+ if (props['sale_price']) {
493
+ requestBody['sale_price'] = props['sale_price'];
494
+ }
495
+ if (props['purchase_total']) {
496
+ requestBody['purchase_total'] = props['purchase_total'];
497
+ }
498
+ if (props['sale_total']) {
499
+ requestBody['sale_total'] = props['sale_total'];
500
+ }
501
+ if (props['currency_id']) {
502
+ requestBody['currency_id'] = props['currency_id'];
503
+ }
504
+ if (props['tax_income_id']) {
505
+ requestBody['tax_income_id'] = props['tax_income_id'];
506
+ }
507
+ if (props['tax_expense_id']) {
508
+ requestBody['tax_expense_id'] = props['tax_expense_id'];
509
+ }
510
+ if (props['unit_id']) {
511
+ requestBody['unit_id'] = props['unit_id'];
512
+ }
513
+ if (props['is_stock'] !== undefined) {
514
+ requestBody['is_stock'] = props['is_stock'];
515
+ }
516
+ if (props['stock_id']) {
517
+ requestBody['stock_id'] = props['stock_id'];
518
+ }
519
+ if (props['stock_place_id']) {
520
+ requestBody['stock_place_id'] = props['stock_place_id'];
521
+ }
522
+ if (props['width']) {
523
+ requestBody['width'] = props['width'];
524
+ }
525
+ if (props['height']) {
526
+ requestBody['height'] = props['height'];
527
+ }
528
+ if (props['weight']) {
529
+ requestBody['weight'] = props['weight'];
530
+ }
531
+ if (props['volume']) {
532
+ requestBody['volume'] = props['volume'];
533
+ }
534
+ if (props['remarks']) {
535
+ requestBody['remarks'] = props['remarks'];
536
+ }
537
+ if (props['delivery_price']) {
538
+ requestBody['delivery_price'] = props['delivery_price'];
539
+ }
540
+ if (props['article_group_id']) {
541
+ requestBody['article_group_id'] = props['article_group_id'];
542
+ }
543
+ if (props['account_id']) {
544
+ requestBody['account_id'] = props['account_id'];
545
+ }
546
+ if (props['expense_account_id']) {
547
+ requestBody['expense_account_id'] = props['expense_account_id'];
548
+ }
549
+
550
+ const response = await client.post<{
551
+ id: number;
552
+ user_id: number;
553
+ article_type_id: number;
554
+ intern_code: string;
555
+ intern_name: string;
556
+ stock_nr: number;
557
+ stock_min_nr: number;
558
+ }>('/2.0/article', requestBody);
559
+
560
+ return response;
561
+ },
562
+ });
563
+