@pokash/n8n-nodes-optima-rest-api 1.6.2 → 1.8.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.
@@ -277,7 +277,7 @@ class OptimaRestApi {
277
277
  displayName: 'Operation',
278
278
  name: 'operation',
279
279
  type: 'options',
280
- noDataExpression: true,
280
+ noDataExpression: false,
281
281
  displayOptions: {
282
282
  show: {
283
283
  resource: ['document'],
@@ -302,37 +302,45 @@ class OptimaRestApi {
302
302
  description: 'Create additional purchase/sale record (expense/income)',
303
303
  action: 'Create an additional record',
304
304
  },
305
+ {
306
+ name: 'Update KSeF Data',
307
+ value: 'updateKSeF',
308
+ description: 'Update KSeF header data (numer, data przyjęcia, forma płatności, środowisko, link) by NumerObcy',
309
+ action: 'Update KSeF data of a document',
310
+ },
305
311
  ],
306
312
  default: 'createInvoice',
307
313
  },
308
- // Document Type for Invoice
314
+ // Document Type (Invoice: Sale/Purchase/Margin, Correction: Sale/Purchase/Margin, Additional Record: Purchase/Sale)
309
315
  {
310
316
  displayName: 'Document Type',
311
317
  name: 'documentType',
312
318
  type: 'options',
319
+ noDataExpression: false,
313
320
  displayOptions: {
314
321
  show: {
315
322
  resource: ['document'],
316
- operation: ['createInvoice'],
323
+ operation: ['createInvoice', 'createInvoiceCorrection', 'createAdditionalRecord'],
317
324
  },
318
325
  },
319
326
  options: [
320
327
  {
321
- name: 'Sales Invoice',
328
+ name: 'Sales Invoice / Sale Correction',
322
329
  value: 'Sale',
323
330
  },
324
331
  {
325
- name: 'Purchase Invoice',
332
+ name: 'Purchase Invoice / Purchase Correction',
326
333
  value: 'Purchase',
327
334
  },
328
335
  {
329
- name: 'Margin Invoice (VAT marża)',
336
+ name: 'Margin Invoice / Margin Correction',
330
337
  value: 'Margin',
331
338
  },
332
339
  ],
333
340
  default: 'Sale',
341
+ description: 'Type of document. For invoices: Sale/Purchase/Margin. For corrections: determines which original document type. For additional records: Purchase (expense) or Sale (income).',
334
342
  },
335
- // Procedura marży - only for Margin Invoice
343
+ // Procedura marży - optional, used when Document Type = Margin
336
344
  {
337
345
  displayName: 'Margin Procedure',
338
346
  name: 'proceduraMarzy',
@@ -340,11 +348,14 @@ class OptimaRestApi {
340
348
  displayOptions: {
341
349
  show: {
342
350
  resource: ['document'],
343
- operation: ['createInvoice'],
344
- documentType: ['Margin'],
351
+ operation: ['createInvoice', 'createInvoiceCorrection', 'createAdditionalRecord'],
345
352
  },
346
353
  },
347
354
  options: [
355
+ {
356
+ name: '(not applicable)',
357
+ value: '',
358
+ },
348
359
  {
349
360
  name: 'Towary używane',
350
361
  value: 'towary używane',
@@ -362,87 +373,132 @@ class OptimaRestApi {
362
373
  value: 'przedmioty kolekcjonerskie i antyki',
363
374
  },
364
375
  ],
365
- default: 'towary używane',
376
+ default: '',
377
+ description: 'Only used when Document Type is Margin. Leave empty for non-margin documents.',
366
378
  },
367
- // Correction Type for Invoice Correction
379
+ // Document Data (for Invoice, Correction, and Additional Record)
368
380
  {
369
- displayName: 'Correction Type',
370
- name: 'correctionType',
371
- type: 'options',
381
+ displayName: 'Document Data',
382
+ name: 'documentData',
383
+ type: 'json',
384
+ required: true,
372
385
  displayOptions: {
373
386
  show: {
374
387
  resource: ['document'],
375
- operation: ['createInvoiceCorrection'],
388
+ operation: ['createInvoice', 'createInvoiceCorrection', 'createAdditionalRecord'],
376
389
  },
377
390
  },
378
- options: [
379
- {
380
- name: 'Sales Invoice Correction',
381
- value: 'Sale',
391
+ default: '{\n "platnik": {\n "akronim": "KLIENT01"\n },\n "pozycje": [\n {\n "kod": "PROD01",\n "ilosc": 1,\n "cena": 100\n }\n ]\n}',
392
+ description: 'Document data in JSON format. For corrections: include OryginalDocumentId and PrzyczynaKorekty.',
393
+ },
394
+ // ---- KSeF Update fields (operation: updateKSeF) ----
395
+ {
396
+ displayName: 'Numer Obcy',
397
+ name: 'numerObcy',
398
+ type: 'string',
399
+ required: true,
400
+ default: '',
401
+ displayOptions: {
402
+ show: {
403
+ resource: ['document'],
404
+ operation: ['updateKSeF'],
382
405
  },
383
- {
384
- name: 'Purchase Invoice Correction',
385
- value: 'Purchase',
406
+ },
407
+ description: 'Numer obcy dokumentu (klucz wyszukiwania). Wraz z NIP wskazuje dokładnie 1 dokument.',
408
+ },
409
+ {
410
+ displayName: 'NIP (Sprzedawcy)',
411
+ name: 'nip',
412
+ type: 'string',
413
+ default: '',
414
+ displayOptions: {
415
+ show: {
416
+ resource: ['document'],
417
+ operation: ['updateKSeF'],
386
418
  },
387
- {
388
- name: 'Margin Invoice Correction (VAT marża)',
389
- value: 'Margin',
419
+ },
420
+ description: 'NIP sprzedawcy dopełnia NumerObcy (unikalny tylko w obrębie sprzedawcy). Opcjonalny, ale zalecany.',
421
+ },
422
+ {
423
+ displayName: 'Numer KSeF',
424
+ name: 'nrKsef',
425
+ type: 'string',
426
+ default: '',
427
+ displayOptions: {
428
+ show: {
429
+ resource: ['document'],
430
+ operation: ['updateKSeF'],
390
431
  },
391
- ],
392
- default: 'Sale',
432
+ },
433
+ description: 'Numer KSeF dokumentu. Puste = bez zmian.',
393
434
  },
394
- // Record Type for Additional Record
395
435
  {
396
- displayName: 'Record Type',
397
- name: 'recordType',
398
- type: 'options',
436
+ displayName: 'Data Przyjęcia',
437
+ name: 'dataPrzyjecia',
438
+ type: 'string',
439
+ default: '',
440
+ placeholder: '2026-07-01',
399
441
  displayOptions: {
400
442
  show: {
401
443
  resource: ['document'],
402
- operation: ['createAdditionalRecord'],
444
+ operation: ['updateKSeF'],
403
445
  },
404
446
  },
447
+ description: 'Data przyjęcia w KSeF (format yyyy-MM-dd). Puste = bez zmian.',
448
+ },
449
+ {
450
+ displayName: 'Forma Płatności',
451
+ name: 'formaPlatnosci',
452
+ type: 'options',
453
+ default: '',
405
454
  options: [
406
- {
407
- name: 'Purchase (Expense)',
408
- value: 'Purchase',
409
- },
410
- {
411
- name: 'Sale (Income)',
412
- value: 'Sale',
413
- },
455
+ { name: '(bez zmian)', value: '' },
456
+ { name: 'Przelew', value: 'przelew' },
457
+ { name: 'Gotówka', value: 'gotówka' },
458
+ { name: 'Karta', value: 'karta' },
459
+ { name: 'Bon', value: 'bon' },
460
+ { name: 'Czek', value: 'czek' },
461
+ { name: 'Kredyt', value: 'kredyt' },
462
+ { name: 'Mobilna', value: 'mobilna' },
414
463
  ],
415
- default: 'Purchase',
464
+ displayOptions: {
465
+ show: {
466
+ resource: ['document'],
467
+ operation: ['updateKSeF'],
468
+ },
469
+ },
470
+ description: 'Forma płatności KSeF (mapowana na kod TrN_KSeFFPLId po stronie API)',
416
471
  },
417
- // Document Data for Invoice and Invoice Correction
418
472
  {
419
- displayName: 'Document Data',
420
- name: 'documentData',
421
- type: 'json',
422
- required: true,
473
+ displayName: 'Środowisko',
474
+ name: 'srodowisko',
475
+ type: 'options',
476
+ default: '',
477
+ options: [
478
+ { name: '(bez zmian)', value: '' },
479
+ { name: 'Produkcyjne', value: 'Produkcyjne' },
480
+ { name: 'Demo', value: 'Demo' },
481
+ ],
423
482
  displayOptions: {
424
483
  show: {
425
484
  resource: ['document'],
426
- operation: ['createInvoice', 'createInvoiceCorrection'],
485
+ operation: ['updateKSeF'],
427
486
  },
428
487
  },
429
- default: '{\n "platnik": {\n "akronim": "KLIENT01"\n },\n "pozycje": [\n {\n "kod": "PROD01",\n "ilosc": 1,\n "cena": 100\n }\n ]\n}',
430
- description: 'Document data in JSON format',
488
+ description: 'Środowisko KSeF',
431
489
  },
432
- // Record Data for Additional Record
433
490
  {
434
- displayName: 'Record Data',
435
- name: 'recordData',
436
- type: 'json',
437
- required: true,
491
+ displayName: 'Link Weryfikacyjny',
492
+ name: 'linkWeryfikacyjny',
493
+ type: 'string',
494
+ default: '',
438
495
  displayOptions: {
439
496
  show: {
440
497
  resource: ['document'],
441
- operation: ['createAdditionalRecord'],
498
+ operation: ['updateKSeF'],
442
499
  },
443
500
  },
444
- default: '{\n "platnik": {\n "akronim": "KLIENT01"\n },\n "pozycje": [\n {\n "kod": "PROD01",\n "ilosc": 1,\n "cena": 100\n }\n ]\n}',
445
- description: 'Additional record data in JSON format',
501
+ description: 'Link weryfikacyjny KSeF (QR). Puste = bez zmian.',
446
502
  },
447
503
  // Product Operations
448
504
  {
@@ -880,18 +936,33 @@ class OptimaRestApi {
880
936
  }
881
937
  }
882
938
  else if (resource === 'document') {
883
- if (operation === 'createInvoice') {
884
- const documentType = this.getNodeParameter('documentType', i);
885
- const documentData = JSON.parse(this.getNodeParameter('documentData', i));
886
- // Add ProceduraMarzy for Margin invoices
887
- if (documentType === 'Margin') {
888
- const proceduraMarzy = this.getNodeParameter('proceduraMarzy', i);
889
- documentData.ProceduraMarzy = proceduraMarzy;
890
- }
939
+ if (operation === 'updateKSeF') {
940
+ // Aktualizacja danych KSeF nagłówka po NumerObcy (+ opcjonalnie NIP sprzedawcy).
941
+ // Partial update: dołączamy tylko niepuste pola (pusty string = "bez zmian").
942
+ const numerObcy = this.getNodeParameter('numerObcy', i);
943
+ const nip = this.getNodeParameter('nip', i, '');
944
+ const nrKsef = this.getNodeParameter('nrKsef', i, '');
945
+ const dataPrzyjecia = this.getNodeParameter('dataPrzyjecia', i, '');
946
+ const formaPlatnosci = this.getNodeParameter('formaPlatnosci', i, '');
947
+ const srodowisko = this.getNodeParameter('srodowisko', i, '');
948
+ const linkWeryfikacyjny = this.getNodeParameter('linkWeryfikacyjny', i, '');
949
+ const body = { NumerObcy: numerObcy };
950
+ if (nip)
951
+ body.Nip = nip;
952
+ if (nrKsef)
953
+ body.NrKsef = nrKsef;
954
+ if (dataPrzyjecia)
955
+ body.DataPrzyjecia = dataPrzyjecia;
956
+ if (formaPlatnosci)
957
+ body.FormaPlatnosci = formaPlatnosci;
958
+ if (srodowisko)
959
+ body.Srodowisko = srodowisko;
960
+ if (linkWeryfikacyjny)
961
+ body.LinkWeryfikacyjny = linkWeryfikacyjny;
891
962
  const response = await makeAuthenticatedRequest({
892
- method: 'POST',
893
- url: `${gatewayUrl}/api/Documents/Invoice/${documentType}`,
894
- body: documentData,
963
+ method: 'PUT',
964
+ url: `${gatewayUrl}/api/Documents/KSeF`,
965
+ body,
895
966
  json: true,
896
967
  });
897
968
  const result = {
@@ -902,30 +973,32 @@ class OptimaRestApi {
902
973
  }
903
974
  returnData.push(result);
904
975
  }
905
- else if (operation === 'createInvoiceCorrection') {
906
- const correctionType = this.getNodeParameter('correctionType', i);
976
+ else {
977
+ const documentType = this.getNodeParameter('documentType', i);
907
978
  const documentData = JSON.parse(this.getNodeParameter('documentData', i));
908
- const response = await makeAuthenticatedRequest({
909
- method: 'POST',
910
- url: `${gatewayUrl}/api/Documents/Invoice-Correction/${correctionType}`,
911
- body: documentData,
912
- json: true,
913
- });
914
- const result = {
915
- json: response
916
- };
917
- if (items[i].binary) {
918
- result.binary = items[i].binary;
979
+ // Add ProceduraMarzy for Margin documents (if provided)
980
+ const proceduraMarzy = this.getNodeParameter('proceduraMarzy', i, '');
981
+ if (proceduraMarzy) {
982
+ documentData.ProceduraMarzy = proceduraMarzy;
983
+ }
984
+ // Build endpoint URL based on operation
985
+ let endpoint;
986
+ if (operation === 'createInvoice') {
987
+ endpoint = `Documents/Invoice/${documentType}`;
988
+ }
989
+ else if (operation === 'createInvoiceCorrection') {
990
+ endpoint = `Documents/Invoice-Correction/${documentType}`;
991
+ }
992
+ else if (operation === 'createAdditionalRecord') {
993
+ endpoint = `Documents/AdditionalRecords/${documentType}`;
994
+ }
995
+ else {
996
+ throw new Error(`Unsupported document operation: ${operation}`);
919
997
  }
920
- returnData.push(result);
921
- }
922
- else if (operation === 'createAdditionalRecord') {
923
- const recordType = this.getNodeParameter('recordType', i);
924
- const recordData = JSON.parse(this.getNodeParameter('recordData', i));
925
998
  const response = await makeAuthenticatedRequest({
926
999
  method: 'POST',
927
- url: `${gatewayUrl}/api/Documents/AdditionalRecords/${recordType}`,
928
- body: recordData,
1000
+ url: `${gatewayUrl}/api/${endpoint}`,
1001
+ body: documentData,
929
1002
  json: true,
930
1003
  });
931
1004
  const result = {
package/package.json CHANGED
@@ -1,60 +1,60 @@
1
- {
2
- "name": "@pokash/n8n-nodes-optima-rest-api",
3
- "version": "1.6.2",
4
- "description": "n8n node for Comarch Optima REST API integration",
5
- "keywords": [
6
- "n8n-community-node-package",
7
- "n8n",
8
- "optima",
9
- "comarch",
10
- "erp"
11
- ],
12
- "license": "MIT",
13
- "homepage": "https://github.com/pokash-pl/n8n-nodes-optima-rest-api",
14
- "author": {
15
- "name": "POKASH.PL Sp. z o. o.",
16
- "email": "hello@pokash.cloud"
17
- },
18
- "repository": {
19
- "type": "git",
20
- "url": "git+https://github.com/pokash-pl/n8n-nodes-optima-rest-api.git"
21
- },
22
- "main": "index.js",
23
- "scripts": {
24
- "build": "tsc && gulp build:icons",
25
- "dev": "tsc --watch",
26
- "format": "prettier nodes --write",
27
- "lint": "eslint nodes/**/*.ts package.json",
28
- "lintfix": "eslint nodes/**/*.ts package.json --fix",
29
- "prepublishOnly": "npm run build"
30
- },
31
- "files": [
32
- "dist"
33
- ],
34
- "n8n": {
35
- "n8nNodesApiVersion": 1,
36
- "credentials": [
37
- "dist/credentials/OptimaRestApiCredentials.credentials.js"
38
- ],
39
- "nodes": [
40
- "dist/nodes/OptimaRestApi/OptimaRestApi.node.js"
41
- ]
42
- },
43
- "devDependencies": {
44
- "@types/node": "^20.0.0",
45
- "@typescript-eslint/eslint-plugin": "^6.21.0",
46
- "@typescript-eslint/parser": "^6.21.0",
47
- "eslint": "^8.57.0",
48
- "eslint-plugin-n8n-nodes-base": "^1.16.0",
49
- "gulp": "^5.0.0",
50
- "n8n-workflow": "^2.2.2",
51
- "prettier": "^3.3.0",
52
- "typescript": "~5.6.0"
53
- },
54
- "peerDependencies": {
55
- "n8n-workflow": "^2.0.0"
56
- },
57
- "overrides": {
58
- "form-data": "^4.0.4"
59
- }
60
- }
1
+ {
2
+ "name": "@pokash/n8n-nodes-optima-rest-api",
3
+ "version": "1.8.0",
4
+ "description": "n8n node for Comarch Optima REST API integration",
5
+ "keywords": [
6
+ "n8n-community-node-package",
7
+ "n8n",
8
+ "optima",
9
+ "comarch",
10
+ "erp"
11
+ ],
12
+ "license": "MIT",
13
+ "homepage": "https://github.com/pokash-pl/n8n-nodes-optima-rest-api",
14
+ "author": {
15
+ "name": "POKASH.PL Sp. z o. o.",
16
+ "email": "hello@pokash.cloud"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/pokash-pl/n8n-nodes-optima-rest-api.git"
21
+ },
22
+ "main": "index.js",
23
+ "scripts": {
24
+ "build": "tsc && gulp build:icons",
25
+ "dev": "tsc --watch",
26
+ "format": "prettier nodes --write",
27
+ "lint": "eslint nodes/**/*.ts package.json",
28
+ "lintfix": "eslint nodes/**/*.ts package.json --fix",
29
+ "prepublishOnly": "npm run build"
30
+ },
31
+ "files": [
32
+ "dist"
33
+ ],
34
+ "n8n": {
35
+ "n8nNodesApiVersion": 1,
36
+ "credentials": [
37
+ "dist/credentials/OptimaRestApiCredentials.credentials.js"
38
+ ],
39
+ "nodes": [
40
+ "dist/nodes/OptimaRestApi/OptimaRestApi.node.js"
41
+ ]
42
+ },
43
+ "devDependencies": {
44
+ "@types/node": "^20.0.0",
45
+ "@typescript-eslint/eslint-plugin": "^6.21.0",
46
+ "@typescript-eslint/parser": "^6.21.0",
47
+ "eslint": "^8.57.0",
48
+ "eslint-plugin-n8n-nodes-base": "^1.16.0",
49
+ "gulp": "^5.0.0",
50
+ "n8n-workflow": "^2.2.2",
51
+ "prettier": "^3.3.0",
52
+ "typescript": "~5.6.0"
53
+ },
54
+ "peerDependencies": {
55
+ "n8n-workflow": "^2.0.0"
56
+ },
57
+ "overrides": {
58
+ "form-data": "^4.0.4"
59
+ }
60
+ }