n8n-nodes-didar-crm 0.0.14 → 0.0.16
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.
- package/dist/lib/loadOptions.d.ts +1 -0
- package/dist/lib/loadOptions.js +13 -0
- package/dist/nodes/DidarCrm.node.d.ts +1 -0
- package/dist/nodes/DidarCrm.node.js +41 -6
- package/dist/nodes/activity/index.js +2 -2
- package/dist/nodes/company/index.js +2 -2
- package/dist/nodes/product/create.operation.d.ts +2 -0
- package/dist/nodes/product/create.operation.js +126 -0
- package/dist/nodes/product/create.properties.d.ts +2 -0
- package/dist/nodes/product/create.properties.js +125 -0
- package/dist/nodes/product/getByCodes.operation.d.ts +2 -0
- package/dist/nodes/product/getByCodes.operation.js +23 -0
- package/dist/nodes/product/getByCodes.properties.d.ts +2 -0
- package/dist/nodes/product/getByCodes.properties.js +16 -0
- package/dist/nodes/product/index.d.ts +6 -0
- package/dist/nodes/product/index.js +16 -0
- package/dist/nodes/product/update.operation.d.ts +2 -0
- package/dist/nodes/product/update.operation.js +110 -0
- package/dist/nodes/product/update.properties.d.ts +2 -0
- package/dist/nodes/product/update.properties.js +96 -0
- package/package.json +1 -1
|
@@ -3,3 +3,4 @@ export declare function getPipelines(this: ILoadOptionsFunctions): Promise<INode
|
|
|
3
3
|
export declare function getStagesForPipeline(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
|
|
4
4
|
export declare function getUsers(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
|
|
5
5
|
export declare function getActivityTypes(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
|
|
6
|
+
export declare function getProductCategories(this: ILoadOptionsFunctions): Promise<any>;
|
package/dist/lib/loadOptions.js
CHANGED
|
@@ -4,6 +4,8 @@ exports.getPipelines = getPipelines;
|
|
|
4
4
|
exports.getStagesForPipeline = getStagesForPipeline;
|
|
5
5
|
exports.getUsers = getUsers;
|
|
6
6
|
exports.getActivityTypes = getActivityTypes;
|
|
7
|
+
exports.getProductCategories = getProductCategories;
|
|
8
|
+
const http_1 = require("./http");
|
|
7
9
|
async function getPipelines() {
|
|
8
10
|
var _a;
|
|
9
11
|
const creds = await this.getCredentials('didarApi');
|
|
@@ -99,3 +101,14 @@ async function getActivityTypes() {
|
|
|
99
101
|
.filter((x) => (x === null || x === void 0 ? void 0 : x.Id) && (x === null || x === void 0 ? void 0 : x.Title))
|
|
100
102
|
.map((x) => ({ name: x.Title, value: x.Id }));
|
|
101
103
|
}
|
|
104
|
+
async function getProductCategories() {
|
|
105
|
+
const resp = await http_1.didarRequest(this, 0, { method: 'POST', path: '/api/product/categories' });
|
|
106
|
+
const list = Array.isArray(resp === null || resp === void 0 ? void 0 : resp.Response) ? resp.Response : resp; // در بعضی APIها Response دارند
|
|
107
|
+
return (list || []).map((cat) => {
|
|
108
|
+
var _a, _b;
|
|
109
|
+
return ({
|
|
110
|
+
name: (_b = (_a = cat.Title) !== null && _a !== void 0 ? _a : cat.Name) !== null && _b !== void 0 ? _b : cat.Id,
|
|
111
|
+
value: cat.Id,
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
}
|
|
@@ -6,6 +6,7 @@ export declare class DidarCrm implements INodeType {
|
|
|
6
6
|
getStagesForPipeline: (this: ILoadOptionsFunctions) => Promise<INodePropertyOptions[]>;
|
|
7
7
|
getUsers: (this: ILoadOptionsFunctions) => Promise<INodePropertyOptions[]>;
|
|
8
8
|
getActivityTypes: (this: ILoadOptionsFunctions) => Promise<INodePropertyOptions[]>;
|
|
9
|
+
getProductCategories: (this: ILoadOptionsFunctions) => Promise<INodePropertyOptions[]>;
|
|
9
10
|
};
|
|
10
11
|
};
|
|
11
12
|
description: INodeTypeDescription;
|
|
@@ -47,6 +47,8 @@ const NoteOps = __importStar(require("./note"));
|
|
|
47
47
|
const note_1 = require("./note");
|
|
48
48
|
const CaseOps = __importStar(require("./case"));
|
|
49
49
|
const case_1 = require("./case");
|
|
50
|
+
const ProductOps = __importStar(require("./product"));
|
|
51
|
+
const product_1 = require("./product");
|
|
50
52
|
class DidarCrm {
|
|
51
53
|
constructor() {
|
|
52
54
|
this.methods = {
|
|
@@ -55,6 +57,7 @@ class DidarCrm {
|
|
|
55
57
|
getStagesForPipeline: Load.getStagesForPipeline,
|
|
56
58
|
getUsers: Load.getUsers,
|
|
57
59
|
getActivityTypes: Load.getActivityTypes,
|
|
60
|
+
getProductCategories: Load.getProductCategories,
|
|
58
61
|
},
|
|
59
62
|
};
|
|
60
63
|
this.description = {
|
|
@@ -81,6 +84,7 @@ class DidarCrm {
|
|
|
81
84
|
{ name: 'Activity', value: 'activity' },
|
|
82
85
|
{ name: 'Note', value: 'note' },
|
|
83
86
|
{ name: 'Case', value: 'case' },
|
|
87
|
+
{ name: 'Product', value: 'product' },
|
|
84
88
|
],
|
|
85
89
|
default: 'deal',
|
|
86
90
|
description: 'Choose the entity to act on.',
|
|
@@ -118,8 +122,8 @@ class DidarCrm {
|
|
|
118
122
|
displayOptions: { show: { resource: ['company'] } },
|
|
119
123
|
options: [
|
|
120
124
|
{ name: 'Create', value: 'create', action: 'Create a company' },
|
|
121
|
-
{ name: 'Update', value: 'update', action: 'Update a company by Id' },
|
|
122
|
-
{ name: 'Get', value: 'get', action: 'Get a company by Id' },
|
|
125
|
+
{ name: 'Update', value: 'update', action: 'Update a company by Id' },
|
|
126
|
+
{ name: 'Get', value: 'get', action: 'Get a company by Id' },
|
|
123
127
|
],
|
|
124
128
|
default: 'create',
|
|
125
129
|
description: 'Select the action to perform on the selected resource.',
|
|
@@ -131,7 +135,7 @@ class DidarCrm {
|
|
|
131
135
|
displayOptions: { show: { resource: ['activity'] } },
|
|
132
136
|
options: [
|
|
133
137
|
{ name: 'Create', value: 'create', action: 'Create an activity' },
|
|
134
|
-
{ name: 'Update', value: 'update', action: 'Update an activity by Id' },
|
|
138
|
+
{ name: 'Update', value: 'update', action: 'Update an activity by Id' },
|
|
135
139
|
],
|
|
136
140
|
default: 'create',
|
|
137
141
|
description: 'Select the action to perform on the selected resource.',
|
|
@@ -160,6 +164,19 @@ class DidarCrm {
|
|
|
160
164
|
default: 'create',
|
|
161
165
|
description: 'Select the action to perform on the selected resource.',
|
|
162
166
|
},
|
|
167
|
+
{
|
|
168
|
+
displayName: 'Operation',
|
|
169
|
+
name: 'operation',
|
|
170
|
+
type: 'options',
|
|
171
|
+
displayOptions: { show: { resource: ['product'] } },
|
|
172
|
+
options: [
|
|
173
|
+
{ name: 'Create', value: 'create', action: 'Create a product' },
|
|
174
|
+
{ name: 'Update', value: 'update', action: 'Update a product by ID' },
|
|
175
|
+
{ name: 'Get by Codes', value: 'getByCodes', action: 'Get products by list of codes' },
|
|
176
|
+
],
|
|
177
|
+
default: 'create',
|
|
178
|
+
description: 'Select the action to perform on the selected resource.',
|
|
179
|
+
},
|
|
163
180
|
// Deal properties (imported)
|
|
164
181
|
...deal_1.dealCreateProperties,
|
|
165
182
|
...deal_1.dealUpdateProperties,
|
|
@@ -181,6 +198,10 @@ class DidarCrm {
|
|
|
181
198
|
// Case properties (imported)
|
|
182
199
|
...case_1.caseCreateProperties,
|
|
183
200
|
...case_1.caseUpdateProperties,
|
|
201
|
+
// Product properties (imported)
|
|
202
|
+
...product_1.productCreateProperties,
|
|
203
|
+
...product_1.productUpdateProperties,
|
|
204
|
+
...product_1.productGetByCodesProperties,
|
|
184
205
|
],
|
|
185
206
|
};
|
|
186
207
|
}
|
|
@@ -226,11 +247,11 @@ class DidarCrm {
|
|
|
226
247
|
if (operation === 'update') {
|
|
227
248
|
await CompanyOps.companyUpdate.call(this, i, returnData);
|
|
228
249
|
continue;
|
|
229
|
-
}
|
|
250
|
+
}
|
|
230
251
|
if (operation === 'get') {
|
|
231
252
|
await CompanyOps.companyGet.call(this, i, returnData);
|
|
232
253
|
continue;
|
|
233
|
-
}
|
|
254
|
+
}
|
|
234
255
|
}
|
|
235
256
|
if (resource === 'activity') {
|
|
236
257
|
if (operation === 'create') {
|
|
@@ -240,7 +261,7 @@ class DidarCrm {
|
|
|
240
261
|
if (operation === 'update') {
|
|
241
262
|
await ActivityOps.activityUpdate.call(this, i, returnData);
|
|
242
263
|
continue;
|
|
243
|
-
}
|
|
264
|
+
}
|
|
244
265
|
}
|
|
245
266
|
if (resource === 'note') {
|
|
246
267
|
if (operation === 'create') {
|
|
@@ -262,6 +283,20 @@ class DidarCrm {
|
|
|
262
283
|
continue;
|
|
263
284
|
}
|
|
264
285
|
}
|
|
286
|
+
if (resource === 'product') {
|
|
287
|
+
if (operation === 'create') {
|
|
288
|
+
await ProductOps.productCreate.call(this, i, returnData);
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
291
|
+
if (operation === 'update') {
|
|
292
|
+
await ProductOps.productUpdate.call(this, i, returnData);
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
if (operation === 'getByCodes') {
|
|
296
|
+
await ProductOps.productGetByCodes.call(this, i, returnData);
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
265
300
|
}
|
|
266
301
|
return [returnData];
|
|
267
302
|
}
|
|
@@ -5,7 +5,7 @@ var create_operation_1 = require("./create.operation");
|
|
|
5
5
|
Object.defineProperty(exports, "activityCreate", { enumerable: true, get: function () { return create_operation_1.activityCreate; } });
|
|
6
6
|
var create_properties_1 = require("./create.properties");
|
|
7
7
|
Object.defineProperty(exports, "activityCreateProperties", { enumerable: true, get: function () { return create_properties_1.activityCreateProperties; } });
|
|
8
|
-
var update_operation_1 = require("./update.operation");
|
|
8
|
+
var update_operation_1 = require("./update.operation");
|
|
9
9
|
Object.defineProperty(exports, "activityUpdate", { enumerable: true, get: function () { return update_operation_1.activityUpdate; } });
|
|
10
|
-
var update_properties_1 = require("./update.properties");
|
|
10
|
+
var update_properties_1 = require("./update.properties");
|
|
11
11
|
Object.defineProperty(exports, "activityUpdateProperties", { enumerable: true, get: function () { return update_properties_1.activityUpdateProperties; } });
|
|
@@ -9,7 +9,7 @@ var update_operation_1 = require("./update.operation");
|
|
|
9
9
|
Object.defineProperty(exports, "companyUpdate", { enumerable: true, get: function () { return update_operation_1.companyUpdate; } });
|
|
10
10
|
var update_properties_1 = require("./update.properties");
|
|
11
11
|
Object.defineProperty(exports, "companyUpdateProperties", { enumerable: true, get: function () { return update_properties_1.companyUpdateProperties; } });
|
|
12
|
-
var get_operation_1 = require("./get.operation");
|
|
12
|
+
var get_operation_1 = require("./get.operation");
|
|
13
13
|
Object.defineProperty(exports, "companyGet", { enumerable: true, get: function () { return get_operation_1.companyGet; } });
|
|
14
|
-
var get_properties_1 = require("./get.properties");
|
|
14
|
+
var get_properties_1 = require("./get.properties");
|
|
15
15
|
Object.defineProperty(exports, "companyGetProperties", { enumerable: true, get: function () { return get_properties_1.companyGetProperties; } });
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.productCreate = productCreate;
|
|
4
|
+
const http_1 = require("../../lib/http");
|
|
5
|
+
async function productCreate(i, returnData) {
|
|
6
|
+
var _a;
|
|
7
|
+
// 1) Read main params
|
|
8
|
+
const title = this.getNodeParameter('Title', i, '');
|
|
9
|
+
if (!(title === null || title === void 0 ? void 0 : title.trim()))
|
|
10
|
+
throw new Error('Title is required.');
|
|
11
|
+
const code = this.getNodeParameter('Code', i, '');
|
|
12
|
+
const unit = this.getNodeParameter('Unit', i, '');
|
|
13
|
+
const unitPrice = this.getNodeParameter('UnitPrice', i, 0);
|
|
14
|
+
const productCategoryId = this.getNodeParameter('ProductCategoryId', i, '');
|
|
15
|
+
const isActive = this.getNodeParameter('IsActive', i, true);
|
|
16
|
+
const description = this.getNodeParameter('Description', i, '');
|
|
17
|
+
// 2) Variants (optional)
|
|
18
|
+
// const variantsUi = (this.getNodeParameter('Variants', i, {}) as IDataObject) || {};
|
|
19
|
+
// let variants: IDataObject[] | undefined;
|
|
20
|
+
// if (variantsUi && typeof variantsUi === 'object' && Array.isArray((variantsUi as any).Variant)) {
|
|
21
|
+
// variants = ((variantsUi as any).Variant as IDataObject[])
|
|
22
|
+
// .filter(v => v && typeof v === 'object')
|
|
23
|
+
// .map(v => {
|
|
24
|
+
// const vTitle = (v.Title as string) ?? '';
|
|
25
|
+
// if (!vTitle?.trim()) throw new Error('Each Variant requires a Title.');
|
|
26
|
+
// const vCode = (v.VariantCode as string) ?? '';
|
|
27
|
+
// const vPrice = (typeof v.UnitPrice === 'number') ? (v.UnitPrice as number) : 0;
|
|
28
|
+
// return {
|
|
29
|
+
// Title: vTitle,
|
|
30
|
+
// TitleForInvoice: vTitle, // hidden rule
|
|
31
|
+
// IsDeleted: false, // hidden rule
|
|
32
|
+
// IsDefault: true, // hidden rule
|
|
33
|
+
// UnitPrice: vPrice,
|
|
34
|
+
// VariantCode: vCode,
|
|
35
|
+
// } as IDataObject;
|
|
36
|
+
// });
|
|
37
|
+
// if (!variants.length) variants = undefined;
|
|
38
|
+
// }
|
|
39
|
+
// 2) Variants (dynamic JSON)
|
|
40
|
+
let variants;
|
|
41
|
+
const variantsUi = this.getNodeParameter('Variants', i, '[]');
|
|
42
|
+
// نرمالسازی: هم رشتهٔ JSON قبول کن، هم آبجکت/آرایه (اگر از expression آمده باشد)
|
|
43
|
+
let parsed;
|
|
44
|
+
if (typeof variantsUi === 'string') {
|
|
45
|
+
const trimmed = variantsUi.trim();
|
|
46
|
+
if (trimmed) {
|
|
47
|
+
try {
|
|
48
|
+
parsed = JSON.parse(trimmed);
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
throw new Error('Invalid JSON in "Variants". It must be a JSON array of objects.');
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
parsed = [];
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
parsed = variantsUi;
|
|
60
|
+
}
|
|
61
|
+
// باید آرایهٔ آبجکت باشد
|
|
62
|
+
if (parsed != null) {
|
|
63
|
+
if (!Array.isArray(parsed))
|
|
64
|
+
throw new Error('"Variants" must be an array.');
|
|
65
|
+
// Map و validate
|
|
66
|
+
variants = parsed.map((v, idx) => {
|
|
67
|
+
var _a, _b, _c;
|
|
68
|
+
if (typeof v !== 'object' || v == null) {
|
|
69
|
+
throw new Error(`"Variants[${idx}]" must be an object.`);
|
|
70
|
+
}
|
|
71
|
+
const vTitle = ((_a = v.Title) !== null && _a !== void 0 ? _a : '').toString();
|
|
72
|
+
if (!vTitle.trim())
|
|
73
|
+
throw new Error(`"Variants[${idx}].Title" is required.`);
|
|
74
|
+
const vCode = ((_b = v.VariantCode) !== null && _b !== void 0 ? _b : '').toString();
|
|
75
|
+
const vPrice = typeof v.UnitPrice === 'number' ? v.UnitPrice : Number((_c = v.UnitPrice) !== null && _c !== void 0 ? _c : 0) || 0;
|
|
76
|
+
return {
|
|
77
|
+
Title: vTitle,
|
|
78
|
+
TitleForInvoice: vTitle, // hidden rule
|
|
79
|
+
IsDeleted: false, // hidden rule
|
|
80
|
+
IsDefault: true, // hidden rule
|
|
81
|
+
UnitPrice: vPrice,
|
|
82
|
+
VariantCode: vCode,
|
|
83
|
+
};
|
|
84
|
+
});
|
|
85
|
+
if (!variants.length)
|
|
86
|
+
variants = undefined;
|
|
87
|
+
}
|
|
88
|
+
// 3) Fields (JSON)
|
|
89
|
+
let fields;
|
|
90
|
+
const fieldsUi = this.getNodeParameter('Fields', i, '');
|
|
91
|
+
if (typeof fieldsUi === 'string' && fieldsUi.trim()) {
|
|
92
|
+
try {
|
|
93
|
+
fields = JSON.parse(fieldsUi);
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
throw new Error('Invalid JSON in "Custom Fields (JSON)".');
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else if (typeof fieldsUi === 'object' && fieldsUi) {
|
|
100
|
+
fields = fieldsUi;
|
|
101
|
+
}
|
|
102
|
+
// 4) Build payload
|
|
103
|
+
const product = {
|
|
104
|
+
Title: title,
|
|
105
|
+
Code: code,
|
|
106
|
+
Unit: unit,
|
|
107
|
+
UnitPrice: typeof unitPrice === 'number' ? unitPrice : Number(unitPrice) || 0,
|
|
108
|
+
Description: description,
|
|
109
|
+
IsActive: !!isActive,
|
|
110
|
+
};
|
|
111
|
+
if (productCategoryId)
|
|
112
|
+
product['ProductCategoryId'] = productCategoryId;
|
|
113
|
+
if (variants)
|
|
114
|
+
product['Variants'] = variants;
|
|
115
|
+
if (fields)
|
|
116
|
+
product['Fields'] = fields;
|
|
117
|
+
const body = { Product: product };
|
|
118
|
+
// 5) Request
|
|
119
|
+
const resp = await (0, http_1.didarRequest)(this, i, {
|
|
120
|
+
method: 'POST',
|
|
121
|
+
path: '/api/product/save',
|
|
122
|
+
body,
|
|
123
|
+
});
|
|
124
|
+
returnData.push({ json: ((_a = resp === null || resp === void 0 ? void 0 : resp.Response) !== null && _a !== void 0 ? _a : resp) });
|
|
125
|
+
return returnData;
|
|
126
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.productCreateProperties = void 0;
|
|
4
|
+
const showForProductCreate = { show: { resource: ['product'], operation: ['create'] } };
|
|
5
|
+
exports.productCreateProperties = [
|
|
6
|
+
// ===== Main (ordered) =====
|
|
7
|
+
{
|
|
8
|
+
displayName: 'Title',
|
|
9
|
+
name: 'Title',
|
|
10
|
+
type: 'string',
|
|
11
|
+
default: '',
|
|
12
|
+
required: true,
|
|
13
|
+
displayOptions: showForProductCreate,
|
|
14
|
+
description: 'Product title. Required.',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
displayName: 'Code',
|
|
18
|
+
name: 'Code',
|
|
19
|
+
type: 'string',
|
|
20
|
+
default: '',
|
|
21
|
+
displayOptions: showForProductCreate,
|
|
22
|
+
description: 'Internal product code (optional).',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
displayName: 'Product Category',
|
|
26
|
+
name: 'ProductCategoryId',
|
|
27
|
+
type: 'options',
|
|
28
|
+
typeOptions: { loadOptionsMethod: 'getProductCategories' },
|
|
29
|
+
default: '',
|
|
30
|
+
displayOptions: showForProductCreate,
|
|
31
|
+
description: 'Select a product category (optional).',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
displayName: 'Unit',
|
|
35
|
+
name: 'Unit',
|
|
36
|
+
type: 'string',
|
|
37
|
+
default: '',
|
|
38
|
+
displayOptions: showForProductCreate,
|
|
39
|
+
description: 'Unit name (e.g., USD, item, box).',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
displayName: 'Unit Price',
|
|
43
|
+
name: 'UnitPrice',
|
|
44
|
+
type: 'number',
|
|
45
|
+
typeOptions: { numberPrecision: 10 },
|
|
46
|
+
default: 0,
|
|
47
|
+
displayOptions: showForProductCreate,
|
|
48
|
+
description: 'Base price for the product.',
|
|
49
|
+
},
|
|
50
|
+
// Variants (optional, list)
|
|
51
|
+
// {
|
|
52
|
+
// displayName: 'Variants',
|
|
53
|
+
// name: 'Variants',
|
|
54
|
+
// type: 'fixedCollection',
|
|
55
|
+
// typeOptions: { multipleValues: true },
|
|
56
|
+
// default: {},
|
|
57
|
+
// displayOptions: showForProductCreate,
|
|
58
|
+
// options: [
|
|
59
|
+
// {
|
|
60
|
+
// name: 'Variant',
|
|
61
|
+
// displayName: 'Variant',
|
|
62
|
+
// values: [
|
|
63
|
+
// {
|
|
64
|
+
// displayName: 'Title',
|
|
65
|
+
// name: 'Title',
|
|
66
|
+
// type: 'string',
|
|
67
|
+
// default: '',
|
|
68
|
+
// description: 'Variant title. Required.',
|
|
69
|
+
// },
|
|
70
|
+
// {
|
|
71
|
+
// displayName: 'Variant Code',
|
|
72
|
+
// name: 'VariantCode',
|
|
73
|
+
// type: 'string',
|
|
74
|
+
// default: '',
|
|
75
|
+
// description: 'Variant code (optional).',
|
|
76
|
+
// },
|
|
77
|
+
// {
|
|
78
|
+
// displayName: 'Unit Price',
|
|
79
|
+
// name: 'UnitPrice',
|
|
80
|
+
// type: 'number',
|
|
81
|
+
// typeOptions: { numberPrecision: 10 },
|
|
82
|
+
// default: 0,
|
|
83
|
+
// description: 'Variant price (optional; defaults to 0).',
|
|
84
|
+
// },
|
|
85
|
+
// // نکته: TitleForInvoice, IsDeleted, IsDefault در UI نمایش داده نمیشوند — در operation ست میکنیم.
|
|
86
|
+
// ],
|
|
87
|
+
// },
|
|
88
|
+
// ],
|
|
89
|
+
// description: 'Optional list of variants.',
|
|
90
|
+
// },
|
|
91
|
+
{
|
|
92
|
+
displayName: 'Variants',
|
|
93
|
+
name: 'Variants',
|
|
94
|
+
type: 'json',
|
|
95
|
+
default: '[]',
|
|
96
|
+
displayOptions: showForProductCreate,
|
|
97
|
+
description: 'JSON array of variant objects. Example: ' +
|
|
98
|
+
'[{"Title":"V1","VariantCode":"A1","UnitPrice":1000},{"Title":"V2","VariantCode":"A2", "UnitPrice":0}]',
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
displayName: 'Active',
|
|
102
|
+
name: 'IsActive',
|
|
103
|
+
type: 'boolean',
|
|
104
|
+
default: true,
|
|
105
|
+
displayOptions: showForProductCreate,
|
|
106
|
+
description: 'Whether the product is active.',
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
displayName: 'Description',
|
|
110
|
+
name: 'Description',
|
|
111
|
+
type: 'string',
|
|
112
|
+
default: '',
|
|
113
|
+
displayOptions: showForProductCreate,
|
|
114
|
+
description: 'Optional description.',
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
displayName: 'Custom Fields (JSON)',
|
|
118
|
+
name: 'Fields',
|
|
119
|
+
type: 'json',
|
|
120
|
+
default: '',
|
|
121
|
+
placeholder: '{ "Field_6_0_26": "value" }',
|
|
122
|
+
displayOptions: showForProductCreate,
|
|
123
|
+
description: 'JSON object of custom fields.',
|
|
124
|
+
},
|
|
125
|
+
];
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.productGetByCodes = productGetByCodes;
|
|
4
|
+
const http_1 = require("../../lib/http");
|
|
5
|
+
async function productGetByCodes(i, returnData) {
|
|
6
|
+
var _a;
|
|
7
|
+
// Read & normalize codes
|
|
8
|
+
const raw = this.getNodeParameter('Code', i, []);
|
|
9
|
+
const toArray = (v) => Array.isArray(v) ? v : (typeof v === 'string' && v ? [v] : []);
|
|
10
|
+
const codes = toArray(raw).map(s => (s !== null && s !== void 0 ? s : '').toString().trim()).filter(Boolean);
|
|
11
|
+
if (!codes.length)
|
|
12
|
+
throw new Error('At least one product code is required.');
|
|
13
|
+
const body = { Code: codes };
|
|
14
|
+
const resp = await (0, http_1.didarRequest)(this, i, {
|
|
15
|
+
method: 'POST',
|
|
16
|
+
path: '/api/product/getproductbycodes',
|
|
17
|
+
body,
|
|
18
|
+
});
|
|
19
|
+
// API returns { Response: { Total, Products: [...] } }
|
|
20
|
+
const out = ((_a = resp === null || resp === void 0 ? void 0 : resp.Response) !== null && _a !== void 0 ? _a : resp);
|
|
21
|
+
returnData.push({ json: out });
|
|
22
|
+
return returnData;
|
|
23
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.productGetByCodesProperties = void 0;
|
|
4
|
+
const showForProductGetByCodes = { show: { resource: ['product'], operation: ['getByCodes'] } };
|
|
5
|
+
exports.productGetByCodesProperties = [
|
|
6
|
+
{
|
|
7
|
+
displayName: 'Codes',
|
|
8
|
+
name: 'Code',
|
|
9
|
+
type: 'string',
|
|
10
|
+
typeOptions: { multipleValues: true }, // n8n → string[]
|
|
11
|
+
default: [],
|
|
12
|
+
required: true,
|
|
13
|
+
displayOptions: showForProductGetByCodes,
|
|
14
|
+
description: 'List of product codes (at least one).',
|
|
15
|
+
},
|
|
16
|
+
];
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { productCreate } from './create.operation';
|
|
2
|
+
export { productCreateProperties } from './create.properties';
|
|
3
|
+
export { productUpdate } from './update.operation';
|
|
4
|
+
export { productUpdateProperties } from './update.properties';
|
|
5
|
+
export { productGetByCodes } from './getByCodes.operation';
|
|
6
|
+
export { productGetByCodesProperties } from './getByCodes.properties';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.productGetByCodesProperties = exports.productGetByCodes = exports.productUpdateProperties = exports.productUpdate = exports.productCreateProperties = exports.productCreate = void 0;
|
|
4
|
+
// nodes/product/index.ts
|
|
5
|
+
var create_operation_1 = require("./create.operation");
|
|
6
|
+
Object.defineProperty(exports, "productCreate", { enumerable: true, get: function () { return create_operation_1.productCreate; } });
|
|
7
|
+
var create_properties_1 = require("./create.properties");
|
|
8
|
+
Object.defineProperty(exports, "productCreateProperties", { enumerable: true, get: function () { return create_properties_1.productCreateProperties; } });
|
|
9
|
+
var update_operation_1 = require("./update.operation");
|
|
10
|
+
Object.defineProperty(exports, "productUpdate", { enumerable: true, get: function () { return update_operation_1.productUpdate; } });
|
|
11
|
+
var update_properties_1 = require("./update.properties");
|
|
12
|
+
Object.defineProperty(exports, "productUpdateProperties", { enumerable: true, get: function () { return update_properties_1.productUpdateProperties; } });
|
|
13
|
+
var getByCodes_operation_1 = require("./getByCodes.operation");
|
|
14
|
+
Object.defineProperty(exports, "productGetByCodes", { enumerable: true, get: function () { return getByCodes_operation_1.productGetByCodes; } });
|
|
15
|
+
var getByCodes_properties_1 = require("./getByCodes.properties");
|
|
16
|
+
Object.defineProperty(exports, "productGetByCodesProperties", { enumerable: true, get: function () { return getByCodes_properties_1.productGetByCodesProperties; } });
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.productUpdate = productUpdate;
|
|
4
|
+
const http_1 = require("../../lib/http");
|
|
5
|
+
async function productUpdate(i, returnData) {
|
|
6
|
+
var _a;
|
|
7
|
+
// 1) Main params
|
|
8
|
+
const id = this.getNodeParameter('Id', i, '');
|
|
9
|
+
if (!(id === null || id === void 0 ? void 0 : id.trim()))
|
|
10
|
+
throw new Error('Product ID is required.');
|
|
11
|
+
const title = this.getNodeParameter('Title', i, '');
|
|
12
|
+
if (!(title === null || title === void 0 ? void 0 : title.trim()))
|
|
13
|
+
throw new Error('Title is required.');
|
|
14
|
+
const code = this.getNodeParameter('Code', i, '');
|
|
15
|
+
const unit = this.getNodeParameter('Unit', i, '');
|
|
16
|
+
const unitPrice = this.getNodeParameter('UnitPrice', i, 0);
|
|
17
|
+
const productCategoryId = this.getNodeParameter('ProductCategoryId', i, '');
|
|
18
|
+
const isActive = this.getNodeParameter('IsActive', i, true);
|
|
19
|
+
const description = this.getNodeParameter('Description', i, '');
|
|
20
|
+
// 2) Variants (dynamic JSON, each may include Id)
|
|
21
|
+
let variants;
|
|
22
|
+
const variantsUi = this.getNodeParameter('Variants', i, '[]');
|
|
23
|
+
let parsed;
|
|
24
|
+
if (typeof variantsUi === 'string') {
|
|
25
|
+
const trimmed = variantsUi.trim();
|
|
26
|
+
if (trimmed) {
|
|
27
|
+
try {
|
|
28
|
+
parsed = JSON.parse(trimmed);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
throw new Error('Invalid JSON in "Variants". It must be a JSON array of objects.');
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
parsed = [];
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
parsed = variantsUi;
|
|
40
|
+
}
|
|
41
|
+
if (parsed != null) {
|
|
42
|
+
if (!Array.isArray(parsed))
|
|
43
|
+
throw new Error('"Variants" must be an array.');
|
|
44
|
+
variants = parsed.map((v, idx) => {
|
|
45
|
+
var _a, _b, _c;
|
|
46
|
+
if (typeof v !== 'object' || v == null) {
|
|
47
|
+
throw new Error(`"Variants[${idx}]" must be an object.`);
|
|
48
|
+
}
|
|
49
|
+
const vTitle = ((_a = v.Title) !== null && _a !== void 0 ? _a : '').toString();
|
|
50
|
+
if (!vTitle.trim())
|
|
51
|
+
throw new Error(`"Variants[${idx}].Title" is required.`);
|
|
52
|
+
const vCode = ((_b = v.VariantCode) !== null && _b !== void 0 ? _b : '').toString();
|
|
53
|
+
const vPrice = typeof v.UnitPrice === 'number' ? v.UnitPrice : Number((_c = v.UnitPrice) !== null && _c !== void 0 ? _c : 0) || 0;
|
|
54
|
+
const variant = {
|
|
55
|
+
Title: vTitle,
|
|
56
|
+
TitleForInvoice: vTitle, // hidden rule (same as create)
|
|
57
|
+
IsDeleted: false, // hidden rule
|
|
58
|
+
IsDefault: true, // hidden rule
|
|
59
|
+
UnitPrice: vPrice,
|
|
60
|
+
VariantCode: vCode,
|
|
61
|
+
};
|
|
62
|
+
// If variant Id provided (update existing variant)
|
|
63
|
+
if (typeof v.Id === 'string' && v.Id.trim()) {
|
|
64
|
+
variant['Id'] = v.Id.trim();
|
|
65
|
+
}
|
|
66
|
+
return variant;
|
|
67
|
+
});
|
|
68
|
+
if (!variants.length)
|
|
69
|
+
variants = undefined;
|
|
70
|
+
}
|
|
71
|
+
// 3) Fields (JSON)
|
|
72
|
+
let fields;
|
|
73
|
+
const fieldsUi = this.getNodeParameter('Fields', i, '');
|
|
74
|
+
if (typeof fieldsUi === 'string' && fieldsUi.trim()) {
|
|
75
|
+
try {
|
|
76
|
+
fields = JSON.parse(fieldsUi);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
throw new Error('Invalid JSON in "Custom Fields (JSON)".');
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else if (typeof fieldsUi === 'object' && fieldsUi) {
|
|
83
|
+
fields = fieldsUi;
|
|
84
|
+
}
|
|
85
|
+
// 4) Build payload
|
|
86
|
+
const product = {
|
|
87
|
+
Id: id,
|
|
88
|
+
Title: title,
|
|
89
|
+
Code: code,
|
|
90
|
+
Unit: unit,
|
|
91
|
+
UnitPrice: typeof unitPrice === 'number' ? unitPrice : Number(unitPrice) || 0,
|
|
92
|
+
Description: description,
|
|
93
|
+
IsActive: !!isActive,
|
|
94
|
+
};
|
|
95
|
+
if (productCategoryId)
|
|
96
|
+
product['ProductCategoryId'] = productCategoryId;
|
|
97
|
+
if (variants)
|
|
98
|
+
product['Variants'] = variants;
|
|
99
|
+
if (fields)
|
|
100
|
+
product['Fields'] = fields;
|
|
101
|
+
const body = { Product: product };
|
|
102
|
+
// 5) Request
|
|
103
|
+
const resp = await (0, http_1.didarRequest)(this, i, {
|
|
104
|
+
method: 'POST',
|
|
105
|
+
path: '/api/product/save',
|
|
106
|
+
body,
|
|
107
|
+
});
|
|
108
|
+
returnData.push({ json: ((_a = resp === null || resp === void 0 ? void 0 : resp.Response) !== null && _a !== void 0 ? _a : resp) });
|
|
109
|
+
return returnData;
|
|
110
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.productUpdateProperties = void 0;
|
|
4
|
+
const showForProductUpdate = { show: { resource: ['product'], operation: ['update'] } };
|
|
5
|
+
exports.productUpdateProperties = [
|
|
6
|
+
// ===== Main (ordered) =====
|
|
7
|
+
{
|
|
8
|
+
displayName: 'Product ID',
|
|
9
|
+
name: 'Id',
|
|
10
|
+
type: 'string',
|
|
11
|
+
default: '',
|
|
12
|
+
required: true,
|
|
13
|
+
displayOptions: showForProductUpdate,
|
|
14
|
+
description: 'The ID of the product to update. Required.',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
displayName: 'Title',
|
|
18
|
+
name: 'Title',
|
|
19
|
+
type: 'string',
|
|
20
|
+
default: '',
|
|
21
|
+
required: true,
|
|
22
|
+
displayOptions: showForProductUpdate,
|
|
23
|
+
description: 'Product title. Required.',
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
displayName: 'Code',
|
|
27
|
+
name: 'Code',
|
|
28
|
+
type: 'string',
|
|
29
|
+
default: '',
|
|
30
|
+
displayOptions: showForProductUpdate,
|
|
31
|
+
description: 'Internal product code (optional).',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
displayName: 'Product Category',
|
|
35
|
+
name: 'ProductCategoryId',
|
|
36
|
+
type: 'options',
|
|
37
|
+
typeOptions: { loadOptionsMethod: 'getProductCategories' },
|
|
38
|
+
default: '',
|
|
39
|
+
displayOptions: showForProductUpdate,
|
|
40
|
+
description: 'Select a product category (optional).',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
displayName: 'Unit',
|
|
44
|
+
name: 'Unit',
|
|
45
|
+
type: 'string',
|
|
46
|
+
default: '',
|
|
47
|
+
displayOptions: showForProductUpdate,
|
|
48
|
+
description: 'Unit name (e.g., USD, item, box).',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
displayName: 'Unit Price',
|
|
52
|
+
name: 'UnitPrice',
|
|
53
|
+
type: 'number',
|
|
54
|
+
typeOptions: { numberPrecision: 10 },
|
|
55
|
+
default: 0,
|
|
56
|
+
displayOptions: showForProductUpdate,
|
|
57
|
+
description: 'Base price for the product.',
|
|
58
|
+
},
|
|
59
|
+
// Variants as dynamic JSON (each item may include Id on update)
|
|
60
|
+
{
|
|
61
|
+
displayName: 'Variants',
|
|
62
|
+
name: 'Variants',
|
|
63
|
+
type: 'json',
|
|
64
|
+
default: '[]',
|
|
65
|
+
displayOptions: showForProductUpdate,
|
|
66
|
+
description: 'JSON array of variant objects. For update, each item may include "Id". ' +
|
|
67
|
+
'Example: ' +
|
|
68
|
+
'[{"Id":"<GUID>","Title":"V1","VariantCode":"A1","UnitPrice":1000},' +
|
|
69
|
+
'{"Id":"<GUID>","Title":"V2","VariantCode":"A2","UnitPrice":0}]',
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
displayName: 'Active',
|
|
73
|
+
name: 'IsActive',
|
|
74
|
+
type: 'boolean',
|
|
75
|
+
default: true,
|
|
76
|
+
displayOptions: showForProductUpdate,
|
|
77
|
+
description: 'Whether the product is active.',
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
displayName: 'Description',
|
|
81
|
+
name: 'Description',
|
|
82
|
+
type: 'string',
|
|
83
|
+
default: '',
|
|
84
|
+
displayOptions: showForProductUpdate,
|
|
85
|
+
description: 'Optional description.',
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
displayName: 'Custom Fields (JSON)',
|
|
89
|
+
name: 'Fields',
|
|
90
|
+
type: 'json',
|
|
91
|
+
default: '',
|
|
92
|
+
placeholder: '{ "Field_6_0_26": "value" }',
|
|
93
|
+
displayOptions: showForProductUpdate,
|
|
94
|
+
description: 'JSON object of custom fields.',
|
|
95
|
+
},
|
|
96
|
+
];
|