n8n-nodes-ritsa-crm 2.4.0 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,6 +15,8 @@ class RitsaTools {
15
15
  defaults: {
16
16
  name: 'Ritsa CRM',
17
17
  },
18
+ // @ts-ignore
19
+ usableAsTool: true,
18
20
  inputs: ['main'],
19
21
  outputs: ['main'],
20
22
  credentials: [
@@ -35,57 +37,100 @@ class RitsaTools {
35
37
  displayName: 'Modül (Kaynak)',
36
38
  name: 'resource',
37
39
  type: 'options',
38
- noDataExpression: true,
39
40
  options: [
40
- { name: 'Geri Aramalar (Callbacks)', value: 'callback' },
41
- { name: 'Hizmetler', value: 'service' },
42
- { name: 'Kasa ve Satış (POS)', value: 'pos' },
43
- { name: 'Mesajlar', value: 'message' },
44
41
  { name: 'Müşteriler', value: 'customer' },
45
- { name: 'Otomasyonlar', value: 'automation' },
46
- { name: 'Ödemeler', value: 'payment' },
47
42
  { name: 'Randevular', value: 'appointment' },
43
+ { name: 'Mesajlar', value: 'message' },
48
44
  { name: 'Satış Fırsatları (Kanban)', value: 'opportunity' },
45
+ { name: 'Kasa ve Satış (POS)', value: 'pos' },
46
+ { name: 'Ödemeler', value: 'payment' },
47
+ { name: 'Geri Aramalar (Callbacks)', value: 'callback' },
49
48
  { name: 'Stok ve Ürünler', value: 'product' },
49
+ { name: 'Hizmetler', value: 'service' },
50
50
  { name: 'Şube ve Personel', value: 'staff' },
51
+ { name: 'Otomasyonlar', value: 'automation' },
51
52
  { name: 'Özet (Dashboard)', value: 'dashboard' },
52
53
  ],
53
54
  default: 'customer',
54
55
  description: 'İşlem yapmak istediğiniz CRM modülünü seçin',
55
56
  },
56
- // ---------------------------------------------------------------------------
57
- // CUSTOMER OPERATIONS
58
- // ---------------------------------------------------------------------------
59
57
  {
60
- displayName: 'İşlem',
58
+ displayName: 'İşlem (Operation)',
61
59
  name: 'operation',
62
60
  type: 'options',
63
- noDataExpression: true,
64
- displayOptions: { show: { resource: ['customer'] } },
65
61
  options: [
66
- { name: 'Müşteri Detaylarını Getir', value: 'getCustomerDetails', action: 'Müşteri detaylarını getir' },
67
- { name: 'Müşteri Ekle', value: 'createCustomer', action: 'Yeni müşteri oluştur' },
68
- { name: 'Müşteri Güncelle', value: 'updateCustomer', action: 'Müşteri bilgilerini güncelle' },
69
- { name: 'Müşterileri Ara / Listele', value: 'getCustomers', action: 'Müşterileri listele' },
62
+ // Müşteri
63
+ { name: 'Müşterileri Ara / Listele', value: 'getCustomers' },
64
+ { name: 'Müşteri Detaylarını Getir', value: 'getCustomerDetails' },
65
+ { name: 'Müşteri Ekle', value: 'createCustomer' },
66
+ { name: 'Müşteri Güncelle', value: 'updateCustomer' },
67
+ // Randevu
68
+ { name: 'Randevuları Listele', value: 'getAppointments' },
69
+ { name: 'Randevu Oluştur', value: 'createAppointment' },
70
+ { name: 'Randevu Durumunu Güncelle', value: 'updateAppointmentStatus' },
71
+ // Mesaj
72
+ { name: 'Mesaj Gönder', value: 'sendMessage' },
73
+ { name: 'Son Mesajları Oku', value: 'getMessages' },
74
+ // Fırsat
75
+ { name: 'Fırsatları / Leadleri Listele', value: 'getOpportunities' },
76
+ { name: 'Fırsat Aşaması Güncelle', value: 'updateLeadStatus' },
77
+ // POS
78
+ { name: 'Mevcut Kasa Oturumu', value: 'getCurrentSession' },
79
+ { name: 'Kasa Aç / Kapat', value: 'toggleSession' },
80
+ { name: 'Serbest Satış Yap', value: 'makeSale' },
81
+ { name: 'Açık Alacakları Getir', value: 'getReceivables' },
82
+ { name: 'Alacak Tahsilatı Gir', value: 'collectReceivable' },
83
+ // Otomasyon
84
+ { name: 'Otomasyon Kurallarını Listele', value: 'getAutomationRules' },
85
+ { name: 'Otomasyonu Aç / Kapat', value: 'toggleAutomation' },
86
+ { name: 'Otomasyonu Manuel Çalıştır', value: 'runAutomation' },
87
+ // Ödeme
88
+ { name: 'Günlük Ciro / Kasa Özeti', value: 'getDailySummary' },
89
+ { name: 'Ödeme Oluştur', value: 'createPayment' },
90
+ { name: 'Ödeme İade / İptal Et', value: 'refundPayment' },
91
+ // Callback
92
+ { name: 'Geri Aramaları Listele', value: 'getCallbacks' },
93
+ { name: 'Geri Arama Görevi Oluştur', value: 'createCallback' },
94
+ { name: 'Tamamlandı (Arandı) İşaretle', value: 'markAsCalled' },
95
+ // Dashboard
96
+ { name: 'Ana Özet Verilerini Getir', value: 'getDashboardSummary' },
97
+ { name: 'Menü Bildirim Sayılarını Getir', value: 'getNavBadges' },
98
+ // Stok
99
+ { name: 'Stok ve Fiyat Sorgula', value: 'checkStock' },
100
+ // Hizmet
101
+ { name: 'Hizmetleri ve Fiyatları Listele', value: 'getServices' },
102
+ // Personel
103
+ { name: 'Personelleri Getir', value: 'getStaff' },
104
+ { name: 'Şubeleri Getir', value: 'getBranches' },
70
105
  ],
71
106
  default: 'getCustomers',
107
+ description: 'Yapılacak işlemi seçin',
72
108
  },
109
+ {
110
+ displayName: 'Parametreler (JSON)',
111
+ name: 'parameters',
112
+ type: 'json',
113
+ default: '{}',
114
+ description: 'Yapay zeka veya dinamik çağrılar için gönderilecek parametreler (JSON objesi). Örn: { "searchQuery": "Ahmet" }',
115
+ },
116
+ // ---------------------------------------------------------------------------
117
+ // PARAMETERS (SHOW CONDITIONALLY ON GLOBAL OPERATION FIELD)
118
+ // ---------------------------------------------------------------------------
73
119
  {
74
120
  displayName: 'Arama Sorgusu',
75
121
  name: 'searchQuery',
76
122
  type: 'string',
77
123
  default: '',
78
124
  description: 'Örn: "Ahmet", "+905551234567" veya e-posta adresi ile müşteri arayın',
79
- displayOptions: { show: { resource: ['customer'], operation: ['getCustomers'] } },
125
+ displayOptions: { show: { operation: ['getCustomers'] } },
80
126
  },
81
127
  {
82
128
  displayName: 'Müşteri ID',
83
129
  name: 'customerId',
84
130
  type: 'string',
85
- required: true,
86
131
  default: '',
87
- description: 'Örn: "15" (CRM üzerindeki müşteri numarası)',
88
- displayOptions: { show: { resource: ['customer'], operation: ['getCustomerDetails', 'updateCustomer'] } },
132
+ description: 'Örn: "15"',
133
+ displayOptions: { show: { operation: ['getCustomerDetails', 'updateCustomer', 'createAppointment', 'sendMessage', 'getMessages'] } },
89
134
  },
90
135
  {
91
136
  displayName: 'Ad (First Name)',
@@ -93,7 +138,7 @@ class RitsaTools {
93
138
  type: 'string',
94
139
  default: '',
95
140
  description: 'Örn: "Ayşe"',
96
- displayOptions: { show: { resource: ['customer'], operation: ['createCustomer', 'updateCustomer'] } },
141
+ displayOptions: { show: { operation: ['createCustomer', 'updateCustomer'] } },
97
142
  },
98
143
  {
99
144
  displayName: 'Soyad (Last Name)',
@@ -101,31 +146,15 @@ class RitsaTools {
101
146
  type: 'string',
102
147
  default: '',
103
148
  description: 'Örn: "Yılmaz"',
104
- displayOptions: { show: { resource: ['customer'], operation: ['createCustomer', 'updateCustomer'] } },
149
+ displayOptions: { show: { operation: ['createCustomer', 'updateCustomer'] } },
105
150
  },
106
151
  {
107
152
  displayName: 'Telefon',
108
153
  name: 'phone',
109
154
  type: 'string',
110
155
  default: '',
111
- description: 'Örn: "+905551234567" (Ülke koduyla birlikte)',
112
- displayOptions: { show: { resource: ['customer'], operation: ['createCustomer', 'updateCustomer'] } },
113
- },
114
- // ---------------------------------------------------------------------------
115
- // APPOINTMENT OPERATIONS
116
- // ---------------------------------------------------------------------------
117
- {
118
- displayName: 'İşlem',
119
- name: 'operation',
120
- type: 'options',
121
- noDataExpression: true,
122
- displayOptions: { show: { resource: ['appointment'] } },
123
- options: [
124
- { name: 'Randevu Durumunu Güncelle', value: 'updateAppointmentStatus', action: 'Randevu iptal / onay' },
125
- { name: 'Randevu Oluştur', value: 'createAppointment', action: 'Yeni randevu oluştur' },
126
- { name: 'Randevuları Listele', value: 'getAppointments', action: 'Randevuları getir' },
127
- ],
128
- default: 'getAppointments',
156
+ description: 'Örn: "+905551234567"',
157
+ displayOptions: { show: { operation: ['createCustomer', 'updateCustomer'] } },
129
158
  },
130
159
  {
131
160
  displayName: 'Tarih (Yıl-Ay-Gün)',
@@ -133,7 +162,7 @@ class RitsaTools {
133
162
  type: 'string',
134
163
  default: '',
135
164
  description: 'Örn: "2026-06-25". Boş bırakılırsa bugünün randevuları gelir.',
136
- displayOptions: { show: { resource: ['appointment'], operation: ['getAppointments', 'createAppointment'] } },
165
+ displayOptions: { show: { operation: ['getAppointments', 'createAppointment'] } },
137
166
  },
138
167
  {
139
168
  displayName: 'Saat (Saat:Dakika)',
@@ -141,23 +170,15 @@ class RitsaTools {
141
170
  type: 'string',
142
171
  default: '',
143
172
  description: 'Örn: "14:30" veya "09:00"',
144
- displayOptions: { show: { resource: ['appointment'], operation: ['createAppointment'] } },
145
- },
146
- {
147
- displayName: 'Müşteri ID',
148
- name: 'customerId',
149
- type: 'string',
150
- default: '',
151
- description: 'Randevu alınacak müşterinin ID numarası. Örn: "42"',
152
- displayOptions: { show: { resource: ['appointment'], operation: ['createAppointment'] } },
173
+ displayOptions: { show: { operation: ['createAppointment'] } },
153
174
  },
154
175
  {
155
176
  displayName: 'Randevu ID',
156
177
  name: 'appointmentId',
157
178
  type: 'string',
158
179
  default: '',
159
- description: 'Güncellenecek randevunun ID numarası. Örn: "105"',
160
- displayOptions: { show: { resource: ['appointment'], operation: ['updateAppointmentStatus'] } },
180
+ description: 'Örn: "105"',
181
+ displayOptions: { show: { operation: ['updateAppointmentStatus'] } },
161
182
  },
162
183
  {
163
184
  displayName: 'Yeni Durum',
@@ -170,31 +191,7 @@ class RitsaTools {
170
191
  { name: 'Tamamlandı (Completed)', value: 'completed' },
171
192
  ],
172
193
  default: 'confirmed',
173
- displayOptions: { show: { resource: ['appointment'], operation: ['updateAppointmentStatus'] } },
174
- },
175
- // ---------------------------------------------------------------------------
176
- // MESSAGE OPERATIONS
177
- // ---------------------------------------------------------------------------
178
- {
179
- displayName: 'İşlem',
180
- name: 'operation',
181
- type: 'options',
182
- noDataExpression: true,
183
- displayOptions: { show: { resource: ['message'] } },
184
- options: [
185
- { name: 'Mesaj Gönder', value: 'sendMessage', action: 'Mesaj gönder' },
186
- { name: 'Son Mesajları Oku', value: 'getMessages', action: 'Mesajları getir' },
187
- ],
188
- default: 'sendMessage',
189
- },
190
- {
191
- displayName: 'Müşteri Telefonu veya ID',
192
- name: 'customerId',
193
- type: 'string',
194
- required: true,
195
- default: '',
196
- description: 'Örn: "+905551234567" veya CRM Müşteri ID "15"',
197
- displayOptions: { show: { resource: ['message'], operation: ['sendMessage', 'getMessages'] } },
194
+ displayOptions: { show: { operation: ['updateAppointmentStatus'] } },
198
195
  },
199
196
  {
200
197
  displayName: 'Gönderilecek Mesaj',
@@ -203,53 +200,23 @@ class RitsaTools {
203
200
  typeOptions: { alwaysOpenEditWindow: true },
204
201
  default: '',
205
202
  description: 'Müşteriye iletilecek WhatsApp / SMS mesajı metni',
206
- displayOptions: { show: { resource: ['message'], operation: ['sendMessage'] } },
207
- },
208
- // ---------------------------------------------------------------------------
209
- // OPPORTUNITY / KANBAN OPERATIONS
210
- // ---------------------------------------------------------------------------
211
- {
212
- displayName: 'İşlem',
213
- name: 'operation',
214
- type: 'options',
215
- noDataExpression: true,
216
- displayOptions: { show: { resource: ['opportunity'] } },
217
- options: [
218
- { name: 'Fırsat Aşaması Güncelle', value: 'updateLeadStatus', action: 'Pipeline aşaması güncelle' },
219
- { name: 'Fırsat Ekle', value: 'createOpportunity', action: 'Yeni fırsat oluştur' },
220
- { name: 'Fırsatları / Leadleri Listele', value: 'getOpportunities', action: 'Aktif fırsatları listele' },
221
- ],
222
- default: 'getOpportunities',
203
+ displayOptions: { show: { operation: ['sendMessage'] } },
223
204
  },
224
205
  {
225
206
  displayName: 'Fırsat (Lead) ID',
226
207
  name: 'leadId',
227
208
  type: 'string',
228
209
  default: '',
229
- description: 'Örn: "7". Kanban panosundaki kartın numarası.',
230
- displayOptions: { show: { resource: ['opportunity'], operation: ['updateLeadStatus'] } },
210
+ description: 'Örn: "7"',
211
+ displayOptions: { show: { operation: ['updateLeadStatus'] } },
231
212
  },
232
213
  {
233
214
  displayName: 'Yeni Aşama (Durum)',
234
- name: 'newStatus',
215
+ name: 'newStatusText',
235
216
  type: 'string',
236
217
  default: '',
237
218
  description: 'Örn: "Ön Görüşme Yapıldı" veya "Satışa Döndü"',
238
- displayOptions: { show: { resource: ['opportunity'], operation: ['updateLeadStatus'] } },
239
- },
240
- // ---------------------------------------------------------------------------
241
- // INVENTORY / PRODUCT OPERATIONS
242
- // ---------------------------------------------------------------------------
243
- {
244
- displayName: 'İşlem',
245
- name: 'operation',
246
- type: 'options',
247
- noDataExpression: true,
248
- displayOptions: { show: { resource: ['product'] } },
249
- options: [
250
- { name: 'Stok ve Fiyat Sorgula', value: 'checkStock', action: 'Stok ve fiyat bilgisi çek' },
251
- ],
252
- default: 'checkStock',
219
+ displayOptions: { show: { operation: ['updateLeadStatus'] } },
253
220
  },
254
221
  {
255
222
  displayName: 'Ürün Adı / Barkodu',
@@ -257,39 +224,7 @@ class RitsaTools {
257
224
  type: 'string',
258
225
  default: '',
259
226
  description: 'Örn: "Lazer Başlığı" veya "869123456"',
260
- displayOptions: { show: { resource: ['product'], operation: ['checkStock'] } },
261
- },
262
- // ---------------------------------------------------------------------------
263
- // SERVICE OPERATIONS
264
- // ---------------------------------------------------------------------------
265
- {
266
- displayName: 'İşlem',
267
- name: 'operation',
268
- type: 'options',
269
- noDataExpression: true,
270
- displayOptions: { show: { resource: ['service'] } },
271
- options: [
272
- { name: 'Hizmetleri ve Fiyatları Listele', value: 'getServices', action: 'Hizmetleri getir' },
273
- ],
274
- default: 'getServices',
275
- },
276
- // ---------------------------------------------------------------------------
277
- // POS / SALES OPERATIONS
278
- // ---------------------------------------------------------------------------
279
- {
280
- displayName: 'İşlem',
281
- name: 'operation',
282
- type: 'options',
283
- noDataExpression: true,
284
- displayOptions: { show: { resource: ['pos'] } },
285
- options: [
286
- { name: 'Açık Alacakları Getir', value: 'getReceivables' },
287
- { name: 'Alacak Tahsilatı Gir', value: 'collectReceivable' },
288
- { name: 'Kasa Aç / Kapat', value: 'toggleSession' },
289
- { name: 'Mevcut Kasa Oturumu', value: 'getCurrentSession' },
290
- { name: 'Serbest Satış Yap', value: 'makeSale' },
291
- ],
292
- default: 'getCurrentSession',
227
+ displayOptions: { show: { operation: ['checkStock'] } },
293
228
  },
294
229
  {
295
230
  displayName: 'Kasa Aksiyonu',
@@ -300,7 +235,7 @@ class RitsaTools {
300
235
  { name: 'Kasayı Kapat', value: 'close' },
301
236
  ],
302
237
  default: 'open',
303
- displayOptions: { show: { resource: ['pos'], operation: ['toggleSession'] } },
238
+ displayOptions: { show: { operation: ['toggleSession'] } },
304
239
  },
305
240
  {
306
241
  displayName: 'Satış Kalemleri (JSON Array)',
@@ -308,119 +243,39 @@ class RitsaTools {
308
243
  type: 'json',
309
244
  default: '[{ "name": "Örnek Hizmet", "quantity": 1, "unit_price": 200 }]',
310
245
  description: 'Sepete eklenecek ürün/hizmetleri JSON dizisi olarak girin.',
311
- displayOptions: { show: { resource: ['pos'], operation: ['makeSale'] } },
246
+ displayOptions: { show: { operation: ['makeSale'] } },
312
247
  },
313
248
  {
314
249
  displayName: 'Alacak (Receivable) ID',
315
250
  name: 'receivableId',
316
251
  type: 'string',
317
252
  default: '',
318
- description: 'Örn: "15". Tahsilatı yapılacak açık hesabın numarası.',
319
- displayOptions: { show: { resource: ['pos'], operation: ['collectReceivable'] } },
320
- },
321
- // ---------------------------------------------------------------------------
322
- // AUTOMATION OPERATIONS
323
- // ---------------------------------------------------------------------------
324
- {
325
- displayName: 'İşlem',
326
- name: 'operation',
327
- type: 'options',
328
- noDataExpression: true,
329
- displayOptions: { show: { resource: ['automation'] } },
330
- options: [
331
- { name: 'Otomasyon Kurallarını Listele', value: 'getAutomationRules' },
332
- { name: 'Otomasyonu Aç / Kapat', value: 'toggleAutomation' },
333
- { name: 'Otomasyonu Manuel Çalıştır (Tetikle)', value: 'runAutomation' },
334
- ],
335
- default: 'getAutomationRules',
253
+ description: 'Örn: "15"',
254
+ displayOptions: { show: { operation: ['collectReceivable'] } },
336
255
  },
337
256
  {
338
257
  displayName: 'Kural (Rule) ID',
339
258
  name: 'ruleId',
340
259
  type: 'string',
341
260
  default: '',
342
- description: 'Örn: "1". Tetiklenecek veya ayarlanacak otomasyon ID numarası.',
343
- displayOptions: { show: { resource: ['automation'], operation: ['toggleAutomation', 'runAutomation'] } },
344
- },
345
- // ---------------------------------------------------------------------------
346
- // PAYMENT OPERATIONS
347
- // ---------------------------------------------------------------------------
348
- {
349
- displayName: 'İşlem',
350
- name: 'operation',
351
- type: 'options',
352
- noDataExpression: true,
353
- displayOptions: { show: { resource: ['payment'] } },
354
- options: [
355
- { name: 'Günlük Ciro / Kasa Özeti', value: 'getDailySummary' },
356
- { name: 'Ödeme (Tahsilat) Oluştur', value: 'createPayment' },
357
- { name: 'Ödeme İade / İptal Et', value: 'refundPayment' },
358
- ],
359
- default: 'getDailySummary',
261
+ description: 'Örn: "1"',
262
+ displayOptions: { show: { operation: ['toggleAutomation', 'runAutomation'] } },
360
263
  },
361
264
  {
362
265
  displayName: 'Ödeme ID',
363
266
  name: 'paymentId',
364
267
  type: 'string',
365
268
  default: '',
366
- description: 'Örn: "55". İade edilecek ödemenin numarası.',
367
- displayOptions: { show: { resource: ['payment'], operation: ['refundPayment'] } },
368
- },
369
- // ---------------------------------------------------------------------------
370
- // CALLBACK OPERATIONS
371
- // ---------------------------------------------------------------------------
372
- {
373
- displayName: 'İşlem',
374
- name: 'operation',
375
- type: 'options',
376
- noDataExpression: true,
377
- displayOptions: { show: { resource: ['callback'] } },
378
- options: [
379
- { name: 'Geri Arama Görevi Oluştur', value: 'createCallback' },
380
- { name: 'Geri Aramaları Listele', value: 'getCallbacks' },
381
- { name: 'Tamamlandı (Arandı) İşaretle', value: 'markAsCalled' },
382
- ],
383
- default: 'getCallbacks',
269
+ description: 'Örn: "55"',
270
+ displayOptions: { show: { operation: ['refundPayment'] } },
384
271
  },
385
272
  {
386
273
  displayName: 'Arama (Callback) ID',
387
274
  name: 'callbackId',
388
275
  type: 'string',
389
276
  default: '',
390
- description: 'Örn: "3". Arandı olarak işaretlenecek görevin numarası.',
391
- displayOptions: { show: { resource: ['callback'], operation: ['markAsCalled'] } },
392
- },
393
- // ---------------------------------------------------------------------------
394
- // DASHBOARD OPERATIONS
395
- // ---------------------------------------------------------------------------
396
- {
397
- displayName: 'İşlem',
398
- name: 'operation',
399
- type: 'options',
400
- noDataExpression: true,
401
- displayOptions: { show: { resource: ['dashboard'] } },
402
- options: [
403
- { name: 'Ana Özet Verilerini Getir', value: 'getDashboardSummary' },
404
- { name: 'Menü Bildirim Sayılarını Getir', value: 'getNavBadges' },
405
- ],
406
- default: 'getDashboardSummary',
407
- },
408
- // ---------------------------------------------------------------------------
409
- // STAFF & BRANCH OPERATIONS
410
- // ---------------------------------------------------------------------------
411
- {
412
- displayName: 'İşlem',
413
- name: 'operation',
414
- type: 'options',
415
- noDataExpression: true,
416
- displayOptions: { show: { resource: ['staff'] } },
417
- options: [
418
- { name: 'Personelleri Getir', value: 'getStaff' },
419
- { name: 'Personel Ekle', value: 'createStaff' },
420
- { name: 'Şubeleri Getir', value: 'getBranches' },
421
- { name: 'Şube Ekle', value: 'createBranch' },
422
- ],
423
- default: 'getStaff',
277
+ description: 'Örn: "3"',
278
+ displayOptions: { show: { operation: ['markAsCalled'] } },
424
279
  },
425
280
  ],
426
281
  };
@@ -438,6 +293,27 @@ class RitsaTools {
438
293
  // Resolve branch ID from node parameter, fallback to credentials
439
294
  const nodeBranchId = this.getNodeParameter('branchId', i, '');
440
295
  const resolvedBranchId = nodeBranchId ? parseInt(nodeBranchId, 10) : branchId;
296
+ // Parse JSON parameters if supplied (for AI agent dynamic calls)
297
+ const nodeParamsStr = this.getNodeParameter('parameters', i, '{}');
298
+ let nodeParams = {};
299
+ try {
300
+ nodeParams = JSON.parse(nodeParamsStr);
301
+ }
302
+ catch (e) {
303
+ nodeParams = {};
304
+ }
305
+ // Helper to resolve parameters from JSON body or from standard node inputs
306
+ const getParam = (name, defaultValue = '') => {
307
+ if (nodeParams && nodeParams[name] !== undefined) {
308
+ return nodeParams[name];
309
+ }
310
+ try {
311
+ return this.getNodeParameter(name, i, defaultValue);
312
+ }
313
+ catch (e) {
314
+ return defaultValue;
315
+ }
316
+ };
441
317
  try {
442
318
  let responseData;
443
319
  let method = 'GET';
@@ -448,32 +324,32 @@ class RitsaTools {
448
324
  if (operation === 'getCustomers') {
449
325
  method = 'GET';
450
326
  path = '/customers';
451
- const searchQuery = this.getNodeParameter('searchQuery', i, '');
327
+ const searchQuery = getParam('searchQuery');
452
328
  if (searchQuery)
453
329
  qs.search = searchQuery;
454
330
  }
455
331
  else if (operation === 'getCustomerDetails') {
456
332
  method = 'GET';
457
- const customerId = this.getNodeParameter('customerId', i);
333
+ const customerId = getParam('customerId');
458
334
  path = `/customers/${customerId}`;
459
335
  }
460
336
  else if (operation === 'createCustomer') {
461
337
  method = 'POST';
462
338
  path = '/customers';
463
339
  body = {
464
- first_name: this.getNodeParameter('firstName', i, ''),
465
- last_name: this.getNodeParameter('lastName', i, ''),
466
- phone: this.getNodeParameter('phone', i, ''),
340
+ first_name: getParam('firstName'),
341
+ last_name: getParam('lastName'),
342
+ phone: getParam('phone'),
467
343
  };
468
344
  }
469
345
  else if (operation === 'updateCustomer') {
470
- const customerId = this.getNodeParameter('customerId', i);
346
+ const customerId = getParam('customerId');
471
347
  method = 'PUT';
472
348
  path = `/customers/${customerId}`;
473
349
  body = {
474
- first_name: this.getNodeParameter('firstName', i, ''),
475
- last_name: this.getNodeParameter('lastName', i, ''),
476
- phone: this.getNodeParameter('phone', i, ''),
350
+ first_name: getParam('firstName'),
351
+ last_name: getParam('lastName'),
352
+ phone: getParam('phone'),
477
353
  };
478
354
  }
479
355
  }
@@ -481,7 +357,7 @@ class RitsaTools {
481
357
  if (operation === 'getAppointments') {
482
358
  method = 'GET';
483
359
  path = '/appointments';
484
- const date = this.getNodeParameter('date', i, '');
360
+ const date = getParam('date');
485
361
  if (date)
486
362
  qs.date = date;
487
363
  }
@@ -489,16 +365,16 @@ class RitsaTools {
489
365
  method = 'POST';
490
366
  path = '/appointments';
491
367
  body = {
492
- customer_id: this.getNodeParameter('customerId', i),
493
- scheduled_at: `${this.getNodeParameter('date', i)}T${this.getNodeParameter('time', i)}:00`,
368
+ customer_id: getParam('customerId'),
369
+ scheduled_at: `${getParam('date')}T${getParam('time')}:00`,
494
370
  };
495
371
  }
496
372
  else if (operation === 'updateAppointmentStatus') {
497
- const appointmentId = this.getNodeParameter('appointmentId', i);
373
+ const appointmentId = getParam('appointmentId');
498
374
  method = 'PUT';
499
375
  path = `/appointments/${appointmentId}`;
500
376
  body = {
501
- status: this.getNodeParameter('newStatus', i),
377
+ status: getParam('newStatus'),
502
378
  };
503
379
  }
504
380
  }
@@ -510,10 +386,10 @@ class RitsaTools {
510
386
  else if (operation === 'sendMessage') {
511
387
  method = 'POST';
512
388
  path = '/opportunities/send-bulk-message';
513
- const customerId = this.getNodeParameter('customerId', i);
389
+ const customerId = getParam('customerId');
514
390
  body = {
515
391
  customer_ids: [parseInt(customerId, 10)],
516
- message: this.getNodeParameter('messageContent', i),
392
+ message: getParam('messageContent'),
517
393
  };
518
394
  }
519
395
  }
@@ -522,6 +398,14 @@ class RitsaTools {
522
398
  method = 'GET';
523
399
  path = '/opportunities';
524
400
  }
401
+ else if (operation === 'updateLeadStatus') {
402
+ const leadId = getParam('leadId');
403
+ method = 'PUT';
404
+ path = `/opportunities/${leadId}`; // Fallback implementation
405
+ body = {
406
+ status: getParam('newStatusText'),
407
+ };
408
+ }
525
409
  }
526
410
  else if (resource === 'pos') {
527
411
  if (operation === 'getCurrentSession') {
@@ -529,21 +413,35 @@ class RitsaTools {
529
413
  path = '/pos/sessions/current';
530
414
  }
531
415
  else if (operation === 'toggleSession') {
532
- const action = this.getNodeParameter('sessionAction', i);
416
+ const action = getParam('sessionAction');
533
417
  method = 'POST';
534
418
  path = `/pos/sessions/${action}`;
535
419
  }
536
420
  else if (operation === 'makeSale') {
537
421
  method = 'POST';
538
422
  path = '/pos/sale';
539
- const saleItemsStr = this.getNodeParameter('saleItems', i, '[]');
540
- try {
541
- body = JSON.parse(saleItemsStr);
423
+ const saleItemsVal = getParam('saleItems');
424
+ if (typeof saleItemsVal === 'string') {
425
+ try {
426
+ body = JSON.parse(saleItemsVal);
427
+ }
428
+ catch (e) {
429
+ body = {};
430
+ }
542
431
  }
543
- catch (e) {
544
- body = {};
432
+ else {
433
+ body = saleItemsVal;
545
434
  }
546
435
  }
436
+ else if (operation === 'getReceivables') {
437
+ method = 'GET';
438
+ path = '/pos/receivables';
439
+ }
440
+ else if (operation === 'collectReceivable') {
441
+ const receivableId = getParam('receivableId');
442
+ method = 'POST';
443
+ path = `/pos/receivables/${receivableId}/collect`;
444
+ }
547
445
  }
548
446
  else if (resource === 'automation') {
549
447
  if (operation === 'getAutomationRules') {
@@ -551,14 +449,14 @@ class RitsaTools {
551
449
  path = '/automations';
552
450
  }
553
451
  else if (operation === 'toggleAutomation') {
554
- const ruleId = this.getNodeParameter('ruleId', i);
452
+ const ruleId = getParam('ruleId');
555
453
  method = 'POST';
556
454
  path = `/automations/${ruleId}/toggle`;
557
455
  }
558
456
  else if (operation === 'runAutomation') {
559
457
  method = 'POST';
560
458
  path = `/automations/run-now`;
561
- const ruleId = this.getNodeParameter('ruleId', i);
459
+ const ruleId = getParam('ruleId');
562
460
  body = { rule_id: parseInt(ruleId, 10) };
563
461
  }
564
462
  }
@@ -572,7 +470,7 @@ class RitsaTools {
572
470
  path = '/payments';
573
471
  }
574
472
  else if (operation === 'refundPayment') {
575
- const paymentId = this.getNodeParameter('paymentId', i);
473
+ const paymentId = getParam('paymentId');
576
474
  method = 'POST';
577
475
  path = `/payments/${paymentId}/refund`;
578
476
  }
@@ -587,7 +485,7 @@ class RitsaTools {
587
485
  path = '/callbacks';
588
486
  }
589
487
  else if (operation === 'markAsCalled') {
590
- const callbackId = this.getNodeParameter('callbackId', i);
488
+ const callbackId = getParam('callbackId');
591
489
  method = 'POST';
592
490
  path = `/callbacks/${callbackId}/mark-called`;
593
491
  }
@@ -606,7 +504,7 @@ class RitsaTools {
606
504
  if (operation === 'checkStock') {
607
505
  method = 'GET';
608
506
  path = '/products';
609
- const productQuery = this.getNodeParameter('productQuery', i, '');
507
+ const productQuery = getParam('productQuery');
610
508
  if (productQuery)
611
509
  qs.search = productQuery;
612
510
  }