n8n-nodes-aivencerealtycrm 2.0.2 → 2.0.4

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.
@@ -64,6 +64,10 @@ class AivenceRealty {
64
64
  name: 'Calculator',
65
65
  value: 'calculator',
66
66
  },
67
+ {
68
+ name: 'Agent',
69
+ value: 'agent',
70
+ },
67
71
  ],
68
72
  default: 'lead',
69
73
  description: 'Recurso del CRM a operar',
@@ -1297,7 +1301,153 @@ class AivenceRealty {
1297
1301
  },
1298
1302
  },
1299
1303
  default: false,
1300
- description: 'Si está activado, usará el JSON completo del nodo anterior con campos: name, email, phone, specialties, rating, availability',
1304
+ description: 'Si está activado, usará el JSON completo del nodo anterior. Si desactivado, mostrará campos individuales.',
1305
+ },
1306
+ // Contractor Create Fields (when useJsonInput is false)
1307
+ {
1308
+ displayName: 'Nombre',
1309
+ name: 'contractorNombre',
1310
+ type: 'string',
1311
+ required: true,
1312
+ displayOptions: {
1313
+ show: {
1314
+ resource: ['contractor'],
1315
+ operation: ['create'],
1316
+ useJsonInput: [false],
1317
+ },
1318
+ },
1319
+ default: '',
1320
+ description: 'Nombre del contratista',
1321
+ },
1322
+ {
1323
+ displayName: 'Email',
1324
+ name: 'contractorEmail',
1325
+ type: 'string',
1326
+ required: true,
1327
+ displayOptions: {
1328
+ show: {
1329
+ resource: ['contractor'],
1330
+ operation: ['create'],
1331
+ useJsonInput: [false],
1332
+ },
1333
+ },
1334
+ default: '',
1335
+ placeholder: 'nombre@email.com',
1336
+ description: 'Email del contratista',
1337
+ },
1338
+ {
1339
+ displayName: 'Teléfono',
1340
+ name: 'contractorTelefono',
1341
+ type: 'string',
1342
+ required: true,
1343
+ displayOptions: {
1344
+ show: {
1345
+ resource: ['contractor'],
1346
+ operation: ['create'],
1347
+ useJsonInput: [false],
1348
+ },
1349
+ },
1350
+ default: '',
1351
+ placeholder: '+54 11 1234-5678',
1352
+ description: 'Teléfono del contratista',
1353
+ },
1354
+ {
1355
+ displayName: 'Especialización',
1356
+ name: 'contractorEspecializacion',
1357
+ type: 'string',
1358
+ required: true,
1359
+ displayOptions: {
1360
+ show: {
1361
+ resource: ['contractor'],
1362
+ operation: ['create'],
1363
+ useJsonInput: [false],
1364
+ },
1365
+ },
1366
+ default: '',
1367
+ placeholder: 'Plomería, Electricidad, Pintura...',
1368
+ description: 'Especialización o área de trabajo del contratista',
1369
+ },
1370
+ {
1371
+ displayName: 'Descripción',
1372
+ name: 'contractorDescripcion',
1373
+ type: 'string',
1374
+ typeOptions: {
1375
+ rows: 3,
1376
+ },
1377
+ displayOptions: {
1378
+ show: {
1379
+ resource: ['contractor'],
1380
+ operation: ['create'],
1381
+ useJsonInput: [false],
1382
+ },
1383
+ },
1384
+ default: '',
1385
+ description: 'Descripción adicional del contratista',
1386
+ },
1387
+ {
1388
+ displayName: 'Ciudad',
1389
+ name: 'contractorCiudad',
1390
+ type: 'string',
1391
+ displayOptions: {
1392
+ show: {
1393
+ resource: ['contractor'],
1394
+ operation: ['create'],
1395
+ useJsonInput: [false],
1396
+ },
1397
+ },
1398
+ default: '',
1399
+ placeholder: 'Buenos Aires',
1400
+ description: 'Ciudad donde trabaja el contratista',
1401
+ },
1402
+ {
1403
+ displayName: 'Disponible',
1404
+ name: 'contractorDisponible',
1405
+ type: 'boolean',
1406
+ displayOptions: {
1407
+ show: {
1408
+ resource: ['contractor'],
1409
+ operation: ['create'],
1410
+ useJsonInput: [false],
1411
+ },
1412
+ },
1413
+ default: true,
1414
+ description: 'Si el contratista está disponible para trabajos',
1415
+ },
1416
+ {
1417
+ displayName: 'Tarifa por Hora',
1418
+ name: 'contractorTarifaHora',
1419
+ type: 'number',
1420
+ displayOptions: {
1421
+ show: {
1422
+ resource: ['contractor'],
1423
+ operation: ['create'],
1424
+ useJsonInput: [false],
1425
+ },
1426
+ },
1427
+ default: 0,
1428
+ description: 'Tarifa por hora del contratista',
1429
+ },
1430
+ {
1431
+ displayName: 'Moneda',
1432
+ name: 'contractorMoneda',
1433
+ type: 'options',
1434
+ displayOptions: {
1435
+ show: {
1436
+ resource: ['contractor'],
1437
+ operation: ['create'],
1438
+ useJsonInput: [false],
1439
+ },
1440
+ },
1441
+ options: [
1442
+ { name: 'Peso Argentino (ARS)', value: 'ARS' },
1443
+ { name: 'Dólar (USD)', value: 'USD' },
1444
+ { name: 'Peso Mexicano (MXN)', value: 'MXN' },
1445
+ { name: 'Peso Colombiano (COP)', value: 'COP' },
1446
+ { name: 'Sol Peruano (PEN)', value: 'PEN' },
1447
+ { name: 'Peso Chileno (CLP)', value: 'CLP' },
1448
+ ],
1449
+ default: 'ARS',
1450
+ description: 'Moneda para la tarifa',
1301
1451
  },
1302
1452
  // ============================================
1303
1453
  // TENANT OPERATIONS
@@ -1361,7 +1511,96 @@ class AivenceRealty {
1361
1511
  },
1362
1512
  },
1363
1513
  default: false,
1364
- description: 'Si está activado, usará el JSON completo del nodo anterior con campos: name, email, phone, property_id, lease_start, lease_end, monthly_rent',
1514
+ description: 'Si está activado, usará el JSON completo del nodo anterior. Si desactivado, mostrará campos individuales.',
1515
+ },
1516
+ // Tenant Create Fields (when useJsonInput is false)
1517
+ {
1518
+ displayName: 'Nombre',
1519
+ name: 'tenantName',
1520
+ type: 'string',
1521
+ required: true,
1522
+ displayOptions: {
1523
+ show: {
1524
+ resource: ['tenant'],
1525
+ operation: ['create'],
1526
+ useJsonInput: [false],
1527
+ },
1528
+ },
1529
+ default: '',
1530
+ description: 'Nombre completo del inquilino',
1531
+ },
1532
+ {
1533
+ displayName: 'Email',
1534
+ name: 'tenantEmail',
1535
+ type: 'string',
1536
+ required: true,
1537
+ displayOptions: {
1538
+ show: {
1539
+ resource: ['tenant'],
1540
+ operation: ['create'],
1541
+ useJsonInput: [false],
1542
+ },
1543
+ },
1544
+ default: '',
1545
+ placeholder: 'inquilino@email.com',
1546
+ description: 'Email del inquilino',
1547
+ },
1548
+ {
1549
+ displayName: 'Teléfono',
1550
+ name: 'tenantPhone',
1551
+ type: 'string',
1552
+ displayOptions: {
1553
+ show: {
1554
+ resource: ['tenant'],
1555
+ operation: ['create'],
1556
+ useJsonInput: [false],
1557
+ },
1558
+ },
1559
+ default: '',
1560
+ placeholder: '+54 11 1234-5678',
1561
+ description: 'Teléfono del inquilino (opcional)',
1562
+ },
1563
+ {
1564
+ displayName: 'Dirección',
1565
+ name: 'tenantAddress',
1566
+ type: 'string',
1567
+ displayOptions: {
1568
+ show: {
1569
+ resource: ['tenant'],
1570
+ operation: ['create'],
1571
+ useJsonInput: [false],
1572
+ },
1573
+ },
1574
+ default: '',
1575
+ description: 'Dirección actual del inquilino (opcional)',
1576
+ },
1577
+ {
1578
+ displayName: 'Contacto de Emergencia - Nombre',
1579
+ name: 'emergencyContactName',
1580
+ type: 'string',
1581
+ displayOptions: {
1582
+ show: {
1583
+ resource: ['tenant'],
1584
+ operation: ['create'],
1585
+ useJsonInput: [false],
1586
+ },
1587
+ },
1588
+ default: '',
1589
+ description: 'Nombre del contacto de emergencia (opcional)',
1590
+ },
1591
+ {
1592
+ displayName: 'Contacto de Emergencia - Teléfono',
1593
+ name: 'emergencyContactPhone',
1594
+ type: 'string',
1595
+ displayOptions: {
1596
+ show: {
1597
+ resource: ['tenant'],
1598
+ operation: ['create'],
1599
+ useJsonInput: [false],
1600
+ },
1601
+ },
1602
+ default: '',
1603
+ description: 'Teléfono del contacto de emergencia (opcional)',
1365
1604
  },
1366
1605
  // ============================================
1367
1606
  // APPOINTMENT OPERATIONS
@@ -1401,6 +1640,12 @@ class AivenceRealty {
1401
1640
  description: 'Actualizar estado de cita',
1402
1641
  action: 'Actualizar estado',
1403
1642
  },
1643
+ {
1644
+ name: 'Reschedule',
1645
+ value: 'reschedule',
1646
+ description: 'Reprogramar cita (cambiar fecha y hora)',
1647
+ action: 'Reprogramar cita',
1648
+ },
1404
1649
  {
1405
1650
  name: 'Delete',
1406
1651
  value: 'delete',
@@ -1601,7 +1846,7 @@ class AivenceRealty {
1601
1846
  default: '',
1602
1847
  description: 'Origen de la cita (máximo 50 caracteres)',
1603
1848
  },
1604
- // Appointment ID para get, updateStatus y delete
1849
+ // Appointment ID para get, updateStatus, reschedule y delete
1605
1850
  {
1606
1851
  displayName: 'Appointment ID',
1607
1852
  name: 'appointmentId',
@@ -1610,7 +1855,7 @@ class AivenceRealty {
1610
1855
  displayOptions: {
1611
1856
  show: {
1612
1857
  resource: ['appointment'],
1613
- operation: ['get', 'updateStatus', 'delete'],
1858
+ operation: ['get', 'updateStatus', 'reschedule', 'delete'],
1614
1859
  },
1615
1860
  },
1616
1861
  default: '',
@@ -1649,6 +1894,142 @@ class AivenceRealty {
1649
1894
  default: 'pending',
1650
1895
  description: 'Nuevo estado de la cita',
1651
1896
  },
1897
+ // Parámetros para Reschedule (Reprogramar)
1898
+ {
1899
+ displayName: 'Nueva Fecha',
1900
+ name: 'reschedule_fecha',
1901
+ type: 'string',
1902
+ required: true,
1903
+ displayOptions: {
1904
+ show: {
1905
+ resource: ['appointment'],
1906
+ operation: ['reschedule'],
1907
+ },
1908
+ },
1909
+ default: '',
1910
+ placeholder: '2026-01-20',
1911
+ description: 'Nueva fecha para la cita (formato: YYYY-MM-DD)',
1912
+ },
1913
+ {
1914
+ displayName: 'Nueva Hora',
1915
+ name: 'reschedule_hora',
1916
+ type: 'string',
1917
+ required: true,
1918
+ displayOptions: {
1919
+ show: {
1920
+ resource: ['appointment'],
1921
+ operation: ['reschedule'],
1922
+ },
1923
+ },
1924
+ default: '',
1925
+ placeholder: '14:30',
1926
+ description: 'Nueva hora para la cita (formato: HH:mm, ejemplo: 14:30)',
1927
+ },
1928
+ {
1929
+ displayName: 'Notas',
1930
+ name: 'reschedule_notas',
1931
+ type: 'string',
1932
+ required: false,
1933
+ displayOptions: {
1934
+ show: {
1935
+ resource: ['appointment'],
1936
+ operation: ['reschedule'],
1937
+ },
1938
+ },
1939
+ default: '',
1940
+ description: 'Motivo o notas de la reprogramación (opcional)',
1941
+ },
1942
+ // Appointment List Filters
1943
+ {
1944
+ displayName: 'Filtro por Propiedad',
1945
+ name: 'appointmentPropertyIdFilter',
1946
+ type: 'number',
1947
+ displayOptions: {
1948
+ show: {
1949
+ resource: ['appointment'],
1950
+ operation: ['list'],
1951
+ },
1952
+ },
1953
+ default: 0,
1954
+ description: 'Filtrar citas por ID de propiedad (opcional, 0 = sin filtro)',
1955
+ },
1956
+ {
1957
+ displayName: 'Filtro por Agente',
1958
+ name: 'appointmentStaffIdFilter',
1959
+ type: 'number',
1960
+ displayOptions: {
1961
+ show: {
1962
+ resource: ['appointment'],
1963
+ operation: ['list'],
1964
+ },
1965
+ },
1966
+ default: 0,
1967
+ description: 'Filtrar citas por ID de agente asignado (opcional, 0 = sin filtro)',
1968
+ },
1969
+ {
1970
+ displayName: 'Filtro por Estado',
1971
+ name: 'appointmentStatusFilter',
1972
+ type: 'options',
1973
+ displayOptions: {
1974
+ show: {
1975
+ resource: ['appointment'],
1976
+ operation: ['list'],
1977
+ },
1978
+ },
1979
+ options: [
1980
+ { name: 'Todos', value: '' },
1981
+ { name: 'Pendiente', value: 'pending' },
1982
+ { name: 'Confirmada', value: 'confirmed' },
1983
+ { name: 'Completada', value: 'completed' },
1984
+ { name: 'Cancelada', value: 'cancelled' },
1985
+ { name: 'Reprogramada', value: 'rescheduled' },
1986
+ ],
1987
+ default: '',
1988
+ description: 'Filtrar citas por estado',
1989
+ },
1990
+ {
1991
+ displayName: 'Fecha Desde',
1992
+ name: 'appointmentDateFrom',
1993
+ type: 'dateTime',
1994
+ displayOptions: {
1995
+ show: {
1996
+ resource: ['appointment'],
1997
+ operation: ['list'],
1998
+ },
1999
+ },
2000
+ default: '',
2001
+ description: 'Filtrar citas desde esta fecha (formato: YYYY-MM-DD)',
2002
+ },
2003
+ {
2004
+ displayName: 'Fecha Hasta',
2005
+ name: 'appointmentDateTo',
2006
+ type: 'dateTime',
2007
+ displayOptions: {
2008
+ show: {
2009
+ resource: ['appointment'],
2010
+ operation: ['list'],
2011
+ },
2012
+ },
2013
+ default: '',
2014
+ description: 'Filtrar citas hasta esta fecha (formato: YYYY-MM-DD)',
2015
+ },
2016
+ {
2017
+ displayName: 'Límite',
2018
+ name: 'appointmentLimit',
2019
+ type: 'number',
2020
+ typeOptions: {
2021
+ minValue: 1,
2022
+ maxValue: 100,
2023
+ },
2024
+ displayOptions: {
2025
+ show: {
2026
+ resource: ['appointment'],
2027
+ operation: ['list'],
2028
+ },
2029
+ },
2030
+ default: 50,
2031
+ description: 'Número máximo de citas a devolver (1-100)',
2032
+ },
1652
2033
  // ============================================
1653
2034
  // CALCULATOR OPERATIONS
1654
2035
  // ============================================
@@ -1781,7 +2162,7 @@ class AivenceRealty {
1781
2162
  // Tipo de Propiedad (costos escrituración)
1782
2163
  {
1783
2164
  displayName: 'Tipo de Propiedad',
1784
- name: 'property_type',
2165
+ name: 'property_type_escrituracion',
1785
2166
  type: 'options',
1786
2167
  displayOptions: {
1787
2168
  show: {
@@ -1877,6 +2258,209 @@ class AivenceRealty {
1877
2258
  default: 40,
1878
2259
  description: 'Incremento esperado del alquiler por año',
1879
2260
  },
2261
+ // ============================================
2262
+ // AGENT OPERATIONS
2263
+ // ============================================
2264
+ {
2265
+ displayName: 'Operación',
2266
+ name: 'operation',
2267
+ type: 'options',
2268
+ noDataExpression: true,
2269
+ displayOptions: {
2270
+ show: {
2271
+ resource: ['agent'],
2272
+ },
2273
+ },
2274
+ options: [
2275
+ {
2276
+ name: 'List',
2277
+ value: 'list',
2278
+ description: 'Listar agentes disponibles',
2279
+ action: 'Listar agentes',
2280
+ },
2281
+ {
2282
+ name: 'Get',
2283
+ value: 'get',
2284
+ description: 'Obtener agente por ID',
2285
+ action: 'Obtener agente',
2286
+ },
2287
+ {
2288
+ name: 'Assign by Zone',
2289
+ value: 'assignByZone',
2290
+ description: 'Asignar agente automáticamente según zona',
2291
+ action: 'Asignar agente por zona',
2292
+ },
2293
+ {
2294
+ name: 'Notify',
2295
+ value: 'notify',
2296
+ description: 'Notificar agente sobre nueva cita',
2297
+ action: 'Notificar agente',
2298
+ },
2299
+ ],
2300
+ default: 'list',
2301
+ },
2302
+ // Agent ID (for get operation)
2303
+ {
2304
+ displayName: 'Agent ID',
2305
+ name: 'agentId',
2306
+ type: 'number',
2307
+ required: true,
2308
+ displayOptions: {
2309
+ show: {
2310
+ resource: ['agent'],
2311
+ operation: ['get', 'notify'],
2312
+ },
2313
+ },
2314
+ default: 0,
2315
+ description: 'ID del agente',
2316
+ },
2317
+ // Zone (for assignByZone operation)
2318
+ {
2319
+ displayName: 'Zona',
2320
+ name: 'zona',
2321
+ type: 'string',
2322
+ required: true,
2323
+ displayOptions: {
2324
+ show: {
2325
+ resource: ['agent'],
2326
+ operation: ['assignByZone'],
2327
+ },
2328
+ },
2329
+ default: '',
2330
+ placeholder: 'Palermo, Recoleta, etc.',
2331
+ description: 'Zona/barrio para asignar agente automáticamente',
2332
+ },
2333
+ // Booking ID (for assignByZone and notify)
2334
+ {
2335
+ displayName: 'Booking ID',
2336
+ name: 'bookingId',
2337
+ type: 'number',
2338
+ displayOptions: {
2339
+ show: {
2340
+ resource: ['agent'],
2341
+ operation: ['assignByZone', 'notify'],
2342
+ },
2343
+ },
2344
+ default: 0,
2345
+ description: 'ID de la cita (opcional para assignByZone, requerido para notify)',
2346
+ },
2347
+ // Property ID (for assignByZone)
2348
+ {
2349
+ displayName: 'Property ID',
2350
+ name: 'propertyIdAgent',
2351
+ type: 'number',
2352
+ displayOptions: {
2353
+ show: {
2354
+ resource: ['agent'],
2355
+ operation: ['assignByZone'],
2356
+ },
2357
+ },
2358
+ default: 0,
2359
+ description: 'ID de la propiedad (opcional, para contexto)',
2360
+ },
2361
+ // Fecha de la cita (for assignByZone) - Para verificar conflictos de horario
2362
+ {
2363
+ displayName: 'Fecha de Cita',
2364
+ name: 'fechaCita',
2365
+ type: 'string',
2366
+ displayOptions: {
2367
+ show: {
2368
+ resource: ['agent'],
2369
+ operation: ['assignByZone'],
2370
+ },
2371
+ },
2372
+ default: '',
2373
+ placeholder: '2025-12-31',
2374
+ description: 'Fecha de la cita en formato YYYY-MM-DD (opcional, para verificar conflictos)',
2375
+ },
2376
+ // Hora de la cita (for assignByZone) - Para verificar conflictos de horario
2377
+ {
2378
+ displayName: 'Hora de Cita',
2379
+ name: 'horaCita',
2380
+ type: 'string',
2381
+ displayOptions: {
2382
+ show: {
2383
+ resource: ['agent'],
2384
+ operation: ['assignByZone'],
2385
+ },
2386
+ },
2387
+ default: '',
2388
+ placeholder: '10:00',
2389
+ description: 'Hora de la cita en formato HH:MM (opcional, para verificar conflictos)',
2390
+ },
2391
+ // Property Title (for notify)
2392
+ {
2393
+ displayName: 'Property Title',
2394
+ name: 'propertyTitle',
2395
+ type: 'string',
2396
+ displayOptions: {
2397
+ show: {
2398
+ resource: ['agent'],
2399
+ operation: ['notify'],
2400
+ },
2401
+ },
2402
+ default: '',
2403
+ description: 'Título de la propiedad (para notificación)',
2404
+ },
2405
+ // Client Name (for notify)
2406
+ {
2407
+ displayName: 'Client Name',
2408
+ name: 'clientNameNotify',
2409
+ type: 'string',
2410
+ displayOptions: {
2411
+ show: {
2412
+ resource: ['agent'],
2413
+ operation: ['notify'],
2414
+ },
2415
+ },
2416
+ default: '',
2417
+ description: 'Nombre del cliente (para notificación)',
2418
+ },
2419
+ // Appointment Date (for notify)
2420
+ {
2421
+ displayName: 'Appointment Date',
2422
+ name: 'appointmentDate',
2423
+ type: 'string',
2424
+ displayOptions: {
2425
+ show: {
2426
+ resource: ['agent'],
2427
+ operation: ['notify'],
2428
+ },
2429
+ },
2430
+ default: '',
2431
+ placeholder: '2025-01-15',
2432
+ description: 'Fecha de la cita (para notificación)',
2433
+ },
2434
+ // Appointment Time (for notify)
2435
+ {
2436
+ displayName: 'Appointment Time',
2437
+ name: 'appointmentTime',
2438
+ type: 'string',
2439
+ displayOptions: {
2440
+ show: {
2441
+ resource: ['agent'],
2442
+ operation: ['notify'],
2443
+ },
2444
+ },
2445
+ default: '',
2446
+ placeholder: '14:30',
2447
+ description: 'Hora de la cita (para notificación)',
2448
+ },
2449
+ // Zone filter (for list)
2450
+ {
2451
+ displayName: 'Filtrar por Zona',
2452
+ name: 'zonaFilter',
2453
+ type: 'string',
2454
+ displayOptions: {
2455
+ show: {
2456
+ resource: ['agent'],
2457
+ operation: ['list'],
2458
+ },
2459
+ },
2460
+ default: '',
2461
+ placeholder: 'Palermo',
2462
+ description: 'Filtrar agentes por zona (opcional)',
2463
+ },
1880
2464
  ],
1881
2465
  };
1882
2466
  }
@@ -1885,7 +2469,6 @@ class AivenceRealty {
1885
2469
  const returnData = [];
1886
2470
  const credentials = await this.getCredentials('aivenceRealtyApi');
1887
2471
  const baseUrl = credentials.baseUrl;
1888
- const apiKey = credentials.apiKey;
1889
2472
  for (let i = 0; i < items.length; i++) {
1890
2473
  try {
1891
2474
  const resource = this.getNodeParameter('resource', i);
@@ -2287,9 +2870,6 @@ class AivenceRealty {
2287
2870
  responseData = await this.helpers.httpRequest({
2288
2871
  method: 'POST',
2289
2872
  url: `${baseUrl}/api/v1/emails/ingest`,
2290
- headers: {
2291
- 'Authorization': `Bearer ${apiKey}`,
2292
- },
2293
2873
  body,
2294
2874
  json: true,
2295
2875
  });
@@ -2456,8 +3036,32 @@ class AivenceRealty {
2456
3036
  });
2457
3037
  }
2458
3038
  else if (operation === 'create') {
2459
- const useJsonInput = this.getNodeParameter('useJsonInput', i, true);
2460
- const body = useJsonInput ? items[i].json : {};
3039
+ const useJsonInput = this.getNodeParameter('useJsonInput', i, false);
3040
+ let body;
3041
+ if (useJsonInput) {
3042
+ body = items[i].json;
3043
+ }
3044
+ else {
3045
+ body = {
3046
+ nombre: this.getNodeParameter('contractorNombre', i),
3047
+ email: this.getNodeParameter('contractorEmail', i),
3048
+ telefono: this.getNodeParameter('contractorTelefono', i),
3049
+ especializacion: this.getNodeParameter('contractorEspecializacion', i),
3050
+ };
3051
+ const descripcion = this.getNodeParameter('contractorDescripcion', i, '');
3052
+ if (descripcion)
3053
+ body.descripcion = descripcion;
3054
+ const ciudad = this.getNodeParameter('contractorCiudad', i, '');
3055
+ if (ciudad)
3056
+ body.ciudad = ciudad;
3057
+ body.disponible = this.getNodeParameter('contractorDisponible', i, true);
3058
+ const tarifaHora = this.getNodeParameter('contractorTarifaHora', i, 0);
3059
+ if (tarifaHora > 0)
3060
+ body.tarifa_hora = tarifaHora;
3061
+ const moneda = this.getNodeParameter('contractorMoneda', i, 'ARS');
3062
+ if (tarifaHora > 0)
3063
+ body.moneda = moneda;
3064
+ }
2461
3065
  responseData = await this.helpers.httpRequest({
2462
3066
  method: 'POST',
2463
3067
  url: `${baseUrl}/api/v1/contratistas`,
@@ -2504,8 +3108,29 @@ class AivenceRealty {
2504
3108
  });
2505
3109
  }
2506
3110
  else if (operation === 'create') {
2507
- const useJsonInput = this.getNodeParameter('useJsonInput', i, true);
2508
- const body = useJsonInput ? items[i].json : {};
3111
+ const useJsonInput = this.getNodeParameter('useJsonInput', i, false);
3112
+ let body;
3113
+ if (useJsonInput) {
3114
+ body = items[i].json;
3115
+ }
3116
+ else {
3117
+ body = {
3118
+ name: this.getNodeParameter('tenantName', i),
3119
+ email: this.getNodeParameter('tenantEmail', i),
3120
+ };
3121
+ const phone = this.getNodeParameter('tenantPhone', i, '');
3122
+ if (phone)
3123
+ body.phone = phone;
3124
+ const address = this.getNodeParameter('tenantAddress', i, '');
3125
+ if (address)
3126
+ body.address = address;
3127
+ const emergencyName = this.getNodeParameter('emergencyContactName', i, '');
3128
+ if (emergencyName)
3129
+ body.emergency_contact_name = emergencyName;
3130
+ const emergencyPhone = this.getNodeParameter('emergencyContactPhone', i, '');
3131
+ if (emergencyPhone)
3132
+ body.emergency_contact_phone = emergencyPhone;
3133
+ }
2509
3134
  responseData = await this.helpers.httpRequest({
2510
3135
  method: 'POST',
2511
3136
  url: `${baseUrl}/api/v1/inquilinos`,
@@ -2519,9 +3144,29 @@ class AivenceRealty {
2519
3144
  // ============================================
2520
3145
  else if (resource === 'appointment') {
2521
3146
  if (operation === 'list') {
3147
+ const propertyIdFilter = this.getNodeParameter('appointmentPropertyIdFilter', i, 0);
3148
+ const staffIdFilter = this.getNodeParameter('appointmentStaffIdFilter', i, 0);
3149
+ const statusFilter = this.getNodeParameter('appointmentStatusFilter', i, '');
3150
+ const dateFrom = this.getNodeParameter('appointmentDateFrom', i, '');
3151
+ const dateTo = this.getNodeParameter('appointmentDateTo', i, '');
3152
+ const limit = this.getNodeParameter('appointmentLimit', i, 50);
3153
+ const queryParams = [];
3154
+ if (propertyIdFilter > 0)
3155
+ queryParams.push(`property_id=${propertyIdFilter}`);
3156
+ if (staffIdFilter > 0)
3157
+ queryParams.push(`staff_id=${staffIdFilter}`);
3158
+ if (statusFilter)
3159
+ queryParams.push(`status=${encodeURIComponent(statusFilter)}`);
3160
+ if (dateFrom)
3161
+ queryParams.push(`date_from=${encodeURIComponent(dateFrom.split('T')[0])}`);
3162
+ if (dateTo)
3163
+ queryParams.push(`date_to=${encodeURIComponent(dateTo.split('T')[0])}`);
3164
+ if (limit)
3165
+ queryParams.push(`limit=${limit}`);
3166
+ const queryString = queryParams.length > 0 ? `?${queryParams.join('&')}` : '';
2522
3167
  responseData = await this.helpers.httpRequest({
2523
3168
  method: 'GET',
2524
- url: `${baseUrl}/api/v1/reservas`,
3169
+ url: `${baseUrl}/api/v1/reservas${queryString}`,
2525
3170
  json: true,
2526
3171
  });
2527
3172
  }
@@ -2586,6 +3231,25 @@ class AivenceRealty {
2586
3231
  json: true,
2587
3232
  });
2588
3233
  }
3234
+ else if (operation === 'reschedule') {
3235
+ const appointmentId = this.getNodeParameter('appointmentId', i);
3236
+ const fecha = this.getNodeParameter('reschedule_fecha', i);
3237
+ const hora = this.getNodeParameter('reschedule_hora', i);
3238
+ const notas = this.getNodeParameter('reschedule_notas', i, '');
3239
+ const body = {
3240
+ fecha,
3241
+ hora,
3242
+ };
3243
+ if (notas) {
3244
+ body.notas = notas;
3245
+ }
3246
+ responseData = await this.helpers.httpRequest({
3247
+ method: 'PUT',
3248
+ url: `${baseUrl}/api/v1/reservas/${appointmentId}/reprogramar`,
3249
+ body,
3250
+ json: true,
3251
+ });
3252
+ }
2589
3253
  else if (operation === 'delete') {
2590
3254
  const appointmentId = this.getNodeParameter('appointmentId', i);
2591
3255
  responseData = await this.helpers.httpRequest({
@@ -2626,7 +3290,7 @@ class AivenceRealty {
2626
3290
  endpoint = '/api/v1/calculadoras/costos-escrituracion';
2627
3291
  body = {
2628
3292
  property_price: this.getNodeParameter('property_price', i),
2629
- property_type: this.getNodeParameter('property_type', i),
3293
+ property_type: this.getNodeParameter('property_type_escrituracion', i),
2630
3294
  is_new: this.getNodeParameter('is_new', i),
2631
3295
  };
2632
3296
  }
@@ -2649,6 +3313,92 @@ class AivenceRealty {
2649
3313
  json: true,
2650
3314
  });
2651
3315
  }
3316
+ // ============================================
3317
+ // AGENT RESOURCE
3318
+ // ============================================
3319
+ else if (resource === 'agent') {
3320
+ if (operation === 'list') {
3321
+ const zonaFilter = this.getNodeParameter('zonaFilter', i);
3322
+ let url = `${baseUrl}/api/v1/agentes/listar-por-zona`;
3323
+ if (zonaFilter) {
3324
+ url += `?zona=${encodeURIComponent(zonaFilter)}`;
3325
+ }
3326
+ responseData = await this.helpers.httpRequest({
3327
+ method: 'GET',
3328
+ url,
3329
+ headers: {
3330
+ 'Authorization': `Bearer ${credentials.apiKey}`,
3331
+ 'Accept': 'application/json',
3332
+ },
3333
+ json: true,
3334
+ });
3335
+ }
3336
+ else if (operation === 'get') {
3337
+ const agentId = this.getNodeParameter('agentId', i);
3338
+ responseData = await this.helpers.httpRequest({
3339
+ method: 'GET',
3340
+ url: `${baseUrl}/api/v1/agentes/${agentId}`,
3341
+ headers: {
3342
+ 'Authorization': `Bearer ${credentials.apiKey}`,
3343
+ 'Accept': 'application/json',
3344
+ },
3345
+ json: true,
3346
+ });
3347
+ }
3348
+ else if (operation === 'assignByZone') {
3349
+ const zona = this.getNodeParameter('zona', i);
3350
+ const bookingId = this.getNodeParameter('bookingId', i);
3351
+ const propertyId = this.getNodeParameter('propertyIdAgent', i);
3352
+ const fechaCita = this.getNodeParameter('fechaCita', i);
3353
+ const horaCita = this.getNodeParameter('horaCita', i);
3354
+ const body = { zona };
3355
+ if (bookingId)
3356
+ body.booking_id = bookingId;
3357
+ if (propertyId)
3358
+ body.property_id = propertyId;
3359
+ if (fechaCita)
3360
+ body.fecha = fechaCita;
3361
+ if (horaCita)
3362
+ body.hora = horaCita;
3363
+ responseData = await this.helpers.httpRequest({
3364
+ method: 'POST',
3365
+ url: `${baseUrl}/api/v1/agentes/asignar-automatico`,
3366
+ headers: {
3367
+ 'Authorization': `Bearer ${credentials.apiKey}`,
3368
+ 'Accept': 'application/json',
3369
+ 'Content-Type': 'application/json',
3370
+ },
3371
+ body,
3372
+ json: true,
3373
+ });
3374
+ }
3375
+ else if (operation === 'notify') {
3376
+ const agentId = this.getNodeParameter('agentId', i);
3377
+ const bookingId = this.getNodeParameter('bookingId', i);
3378
+ const propertyTitle = this.getNodeParameter('propertyTitle', i);
3379
+ const clientName = this.getNodeParameter('clientNameNotify', i);
3380
+ const appointmentDate = this.getNodeParameter('appointmentDate', i);
3381
+ const appointmentTime = this.getNodeParameter('appointmentTime', i);
3382
+ responseData = await this.helpers.httpRequest({
3383
+ method: 'POST',
3384
+ url: `${baseUrl}/api/v1/agentes/notificar-cita`,
3385
+ headers: {
3386
+ 'Authorization': `Bearer ${credentials.apiKey}`,
3387
+ 'Accept': 'application/json',
3388
+ 'Content-Type': 'application/json',
3389
+ },
3390
+ body: {
3391
+ agent_id: agentId,
3392
+ booking_id: bookingId,
3393
+ property_title: propertyTitle,
3394
+ client_name: clientName,
3395
+ appointment_date: appointmentDate,
3396
+ appointment_time: appointmentTime,
3397
+ },
3398
+ json: true,
3399
+ });
3400
+ }
3401
+ }
2652
3402
  // Formatear respuesta
2653
3403
  const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
2654
3404
  returnData.push(...executionData);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-aivencerealtycrm",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "description": "Nodo n8n para integrar el CRM inmobiliario AivenceRealty",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",
@@ -31,7 +31,8 @@
31
31
  "dev": "tsc --watch",
32
32
  "format": "prettier nodes credentials --write",
33
33
  "lint": "eslint nodes credentials package.json",
34
- "lintfix": "eslint nodes credentials package.json --fix"
34
+ "lintfix": "eslint nodes credentials package.json --fix",
35
+ "prepublishOnly": "npm run build"
35
36
  },
36
37
  "files": [
37
38
  "dist"