n8n-nodes-servicem8-jobcreation 1.0.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.
Files changed (153) hide show
  1. package/README.md +517 -0
  2. package/dist/credentials/ServiceM8Api.credentials.d.ts +9 -0
  3. package/dist/credentials/ServiceM8Api.credentials.js +38 -0
  4. package/dist/credentials/ServiceM8Api.credentials.js.map +1 -0
  5. package/dist/index.d.ts +3 -0
  6. package/dist/index.js +8 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/nodes/ServiceM8JobCreation/ServiceM8JobCreation.node.d.ts +18 -0
  9. package/dist/nodes/ServiceM8JobCreation/ServiceM8JobCreation.node.js +39 -0
  10. package/dist/nodes/ServiceM8JobCreation/ServiceM8JobCreation.node.js.map +1 -0
  11. package/dist/nodes/ServiceM8JobCreation/execute.d.ts +6 -0
  12. package/dist/nodes/ServiceM8JobCreation/execute.js +47 -0
  13. package/dist/nodes/ServiceM8JobCreation/execute.js.map +1 -0
  14. package/dist/nodes/ServiceM8JobCreation/helpers/addressUtils.d.ts +56 -0
  15. package/dist/nodes/ServiceM8JobCreation/helpers/addressUtils.js +124 -0
  16. package/dist/nodes/ServiceM8JobCreation/helpers/addressUtils.js.map +1 -0
  17. package/dist/nodes/ServiceM8JobCreation/helpers/api.d.ts +180 -0
  18. package/dist/nodes/ServiceM8JobCreation/helpers/api.js +418 -0
  19. package/dist/nodes/ServiceM8JobCreation/helpers/api.js.map +1 -0
  20. package/dist/nodes/ServiceM8JobCreation/helpers/clientMatcher.d.ts +67 -0
  21. package/dist/nodes/ServiceM8JobCreation/helpers/clientMatcher.js +216 -0
  22. package/dist/nodes/ServiceM8JobCreation/helpers/clientMatcher.js.map +1 -0
  23. package/dist/nodes/ServiceM8JobCreation/helpers/phoneUtils.d.ts +35 -0
  24. package/dist/nodes/ServiceM8JobCreation/helpers/phoneUtils.js +122 -0
  25. package/dist/nodes/ServiceM8JobCreation/helpers/phoneUtils.js.map +1 -0
  26. package/dist/nodes/ServiceM8JobCreation/methods/index.d.ts +13 -0
  27. package/dist/nodes/ServiceM8JobCreation/methods/index.js +17 -0
  28. package/dist/nodes/ServiceM8JobCreation/methods/index.js.map +1 -0
  29. package/dist/nodes/ServiceM8JobCreation/methods/loadOptions.d.ts +9 -0
  30. package/dist/nodes/ServiceM8JobCreation/methods/loadOptions.js +61 -0
  31. package/dist/nodes/ServiceM8JobCreation/methods/loadOptions.js.map +1 -0
  32. package/dist/nodes/ServiceM8JobCreation/operations/create/categoryAssign.d.ts +22 -0
  33. package/dist/nodes/ServiceM8JobCreation/operations/create/categoryAssign.js +61 -0
  34. package/dist/nodes/ServiceM8JobCreation/operations/create/categoryAssign.js.map +1 -0
  35. package/dist/nodes/ServiceM8JobCreation/operations/create/clientCreate.d.ts +36 -0
  36. package/dist/nodes/ServiceM8JobCreation/operations/create/clientCreate.js +66 -0
  37. package/dist/nodes/ServiceM8JobCreation/operations/create/clientCreate.js.map +1 -0
  38. package/dist/nodes/ServiceM8JobCreation/operations/create/clientLookup.d.ts +28 -0
  39. package/dist/nodes/ServiceM8JobCreation/operations/create/clientLookup.js +46 -0
  40. package/dist/nodes/ServiceM8JobCreation/operations/create/clientLookup.js.map +1 -0
  41. package/dist/nodes/ServiceM8JobCreation/operations/create/contactLookup.d.ts +18 -0
  42. package/dist/nodes/ServiceM8JobCreation/operations/create/contactLookup.js +48 -0
  43. package/dist/nodes/ServiceM8JobCreation/operations/create/contactLookup.js.map +1 -0
  44. package/dist/nodes/ServiceM8JobCreation/operations/create/index.d.ts +12 -0
  45. package/dist/nodes/ServiceM8JobCreation/operations/create/index.js +40 -0
  46. package/dist/nodes/ServiceM8JobCreation/operations/create/index.js.map +1 -0
  47. package/dist/nodes/ServiceM8JobCreation/operations/create/inputProcessor.d.ts +63 -0
  48. package/dist/nodes/ServiceM8JobCreation/operations/create/inputProcessor.js +176 -0
  49. package/dist/nodes/ServiceM8JobCreation/operations/create/inputProcessor.js.map +1 -0
  50. package/dist/nodes/ServiceM8JobCreation/operations/create/jobCreate.d.ts +43 -0
  51. package/dist/nodes/ServiceM8JobCreation/operations/create/jobCreate.js +82 -0
  52. package/dist/nodes/ServiceM8JobCreation/operations/create/jobCreate.js.map +1 -0
  53. package/dist/nodes/ServiceM8JobCreation/operations/create/notifications.d.ts +38 -0
  54. package/dist/nodes/ServiceM8JobCreation/operations/create/notifications.js +123 -0
  55. package/dist/nodes/ServiceM8JobCreation/operations/create/notifications.js.map +1 -0
  56. package/dist/nodes/ServiceM8JobCreation/operations/create/orchestrator.d.ts +12 -0
  57. package/dist/nodes/ServiceM8JobCreation/operations/create/orchestrator.js +192 -0
  58. package/dist/nodes/ServiceM8JobCreation/operations/create/orchestrator.js.map +1 -0
  59. package/dist/nodes/ServiceM8JobCreation/operations/create/queueAssign.d.ts +22 -0
  60. package/dist/nodes/ServiceM8JobCreation/operations/create/queueAssign.js +61 -0
  61. package/dist/nodes/ServiceM8JobCreation/operations/create/queueAssign.js.map +1 -0
  62. package/dist/nodes/ServiceM8JobCreation/operations/index.d.ts +8 -0
  63. package/dist/nodes/ServiceM8JobCreation/operations/index.js +35 -0
  64. package/dist/nodes/ServiceM8JobCreation/operations/index.js.map +1 -0
  65. package/dist/nodes/ServiceM8JobCreation/operations/shared/attachmentsUpload.d.ts +41 -0
  66. package/dist/nodes/ServiceM8JobCreation/operations/shared/attachmentsUpload.js +243 -0
  67. package/dist/nodes/ServiceM8JobCreation/operations/shared/attachmentsUpload.js.map +1 -0
  68. package/dist/nodes/ServiceM8JobCreation/operations/shared/badgesAssign.d.ts +21 -0
  69. package/dist/nodes/ServiceM8JobCreation/operations/shared/badgesAssign.js +65 -0
  70. package/dist/nodes/ServiceM8JobCreation/operations/shared/badgesAssign.js.map +1 -0
  71. package/dist/nodes/ServiceM8JobCreation/operations/shared/index.d.ts +7 -0
  72. package/dist/nodes/ServiceM8JobCreation/operations/shared/index.js +15 -0
  73. package/dist/nodes/ServiceM8JobCreation/operations/shared/index.js.map +1 -0
  74. package/dist/nodes/ServiceM8JobCreation/operations/shared/notesCreate.d.ts +42 -0
  75. package/dist/nodes/ServiceM8JobCreation/operations/shared/notesCreate.js +103 -0
  76. package/dist/nodes/ServiceM8JobCreation/operations/shared/notesCreate.js.map +1 -0
  77. package/dist/nodes/ServiceM8JobCreation/operations/update/index.d.ts +5 -0
  78. package/dist/nodes/ServiceM8JobCreation/operations/update/index.js +9 -0
  79. package/dist/nodes/ServiceM8JobCreation/operations/update/index.js.map +1 -0
  80. package/dist/nodes/ServiceM8JobCreation/operations/update/jobUpdate.d.ts +10 -0
  81. package/dist/nodes/ServiceM8JobCreation/operations/update/jobUpdate.js +239 -0
  82. package/dist/nodes/ServiceM8JobCreation/operations/update/jobUpdate.js.map +1 -0
  83. package/dist/nodes/ServiceM8JobCreation/properties/create/address.d.ts +5 -0
  84. package/dist/nodes/ServiceM8JobCreation/properties/create/address.js +145 -0
  85. package/dist/nodes/ServiceM8JobCreation/properties/create/address.js.map +1 -0
  86. package/dist/nodes/ServiceM8JobCreation/properties/create/business.d.ts +5 -0
  87. package/dist/nodes/ServiceM8JobCreation/properties/create/business.js +22 -0
  88. package/dist/nodes/ServiceM8JobCreation/properties/create/business.js.map +1 -0
  89. package/dist/nodes/ServiceM8JobCreation/properties/create/contact.d.ts +5 -0
  90. package/dist/nodes/ServiceM8JobCreation/properties/create/contact.js +85 -0
  91. package/dist/nodes/ServiceM8JobCreation/properties/create/contact.js.map +1 -0
  92. package/dist/nodes/ServiceM8JobCreation/properties/create/index.d.ts +10 -0
  93. package/dist/nodes/ServiceM8JobCreation/properties/create/index.js +30 -0
  94. package/dist/nodes/ServiceM8JobCreation/properties/create/index.js.map +1 -0
  95. package/dist/nodes/ServiceM8JobCreation/properties/create/job.d.ts +5 -0
  96. package/dist/nodes/ServiceM8JobCreation/properties/create/job.js +43 -0
  97. package/dist/nodes/ServiceM8JobCreation/properties/create/job.js.map +1 -0
  98. package/dist/nodes/ServiceM8JobCreation/properties/create/options/additionalOptions.d.ts +5 -0
  99. package/dist/nodes/ServiceM8JobCreation/properties/create/options/additionalOptions.js +49 -0
  100. package/dist/nodes/ServiceM8JobCreation/properties/create/options/additionalOptions.js.map +1 -0
  101. package/dist/nodes/ServiceM8JobCreation/properties/create/options/attachments.d.ts +5 -0
  102. package/dist/nodes/ServiceM8JobCreation/properties/create/options/attachments.js +151 -0
  103. package/dist/nodes/ServiceM8JobCreation/properties/create/options/attachments.js.map +1 -0
  104. package/dist/nodes/ServiceM8JobCreation/properties/create/options/badges.d.ts +5 -0
  105. package/dist/nodes/ServiceM8JobCreation/properties/create/options/badges.js +65 -0
  106. package/dist/nodes/ServiceM8JobCreation/properties/create/options/badges.js.map +1 -0
  107. package/dist/nodes/ServiceM8JobCreation/properties/create/options/category.d.ts +5 -0
  108. package/dist/nodes/ServiceM8JobCreation/properties/create/options/category.js +65 -0
  109. package/dist/nodes/ServiceM8JobCreation/properties/create/options/category.js.map +1 -0
  110. package/dist/nodes/ServiceM8JobCreation/properties/create/options/index.d.ts +12 -0
  111. package/dist/nodes/ServiceM8JobCreation/properties/create/options/index.js +38 -0
  112. package/dist/nodes/ServiceM8JobCreation/properties/create/options/index.js.map +1 -0
  113. package/dist/nodes/ServiceM8JobCreation/properties/create/options/notes.d.ts +5 -0
  114. package/dist/nodes/ServiceM8JobCreation/properties/create/options/notes.js +49 -0
  115. package/dist/nodes/ServiceM8JobCreation/properties/create/options/notes.js.map +1 -0
  116. package/dist/nodes/ServiceM8JobCreation/properties/create/options/notifications.d.ts +5 -0
  117. package/dist/nodes/ServiceM8JobCreation/properties/create/options/notifications.js +197 -0
  118. package/dist/nodes/ServiceM8JobCreation/properties/create/options/notifications.js.map +1 -0
  119. package/dist/nodes/ServiceM8JobCreation/properties/create/options/queue.d.ts +5 -0
  120. package/dist/nodes/ServiceM8JobCreation/properties/create/options/queue.js +65 -0
  121. package/dist/nodes/ServiceM8JobCreation/properties/create/options/queue.js.map +1 -0
  122. package/dist/nodes/ServiceM8JobCreation/properties/index.d.ts +9 -0
  123. package/dist/nodes/ServiceM8JobCreation/properties/index.js +23 -0
  124. package/dist/nodes/ServiceM8JobCreation/properties/index.js.map +1 -0
  125. package/dist/nodes/ServiceM8JobCreation/properties/operation.d.ts +5 -0
  126. package/dist/nodes/ServiceM8JobCreation/properties/operation.js +28 -0
  127. package/dist/nodes/ServiceM8JobCreation/properties/operation.js.map +1 -0
  128. package/dist/nodes/ServiceM8JobCreation/properties/update/fields.d.ts +5 -0
  129. package/dist/nodes/ServiceM8JobCreation/properties/update/fields.js +74 -0
  130. package/dist/nodes/ServiceM8JobCreation/properties/update/fields.js.map +1 -0
  131. package/dist/nodes/ServiceM8JobCreation/properties/update/index.d.ts +8 -0
  132. package/dist/nodes/ServiceM8JobCreation/properties/update/index.js +22 -0
  133. package/dist/nodes/ServiceM8JobCreation/properties/update/index.js.map +1 -0
  134. package/dist/nodes/ServiceM8JobCreation/properties/update/jobSelection.d.ts +5 -0
  135. package/dist/nodes/ServiceM8JobCreation/properties/update/jobSelection.js +63 -0
  136. package/dist/nodes/ServiceM8JobCreation/properties/update/jobSelection.js.map +1 -0
  137. package/dist/nodes/ServiceM8JobCreation/properties/update/options.d.ts +5 -0
  138. package/dist/nodes/ServiceM8JobCreation/properties/update/options.js +142 -0
  139. package/dist/nodes/ServiceM8JobCreation/properties/update/options.js.map +1 -0
  140. package/dist/nodes/ServiceM8JobCreation/servicem8.svg +75 -0
  141. package/dist/nodes/ServiceM8JobCreation/types/api.d.ts +59 -0
  142. package/dist/nodes/ServiceM8JobCreation/types/api.js +34 -0
  143. package/dist/nodes/ServiceM8JobCreation/types/api.js.map +1 -0
  144. package/dist/nodes/ServiceM8JobCreation/types/index.d.ts +7 -0
  145. package/dist/nodes/ServiceM8JobCreation/types/index.js +21 -0
  146. package/dist/nodes/ServiceM8JobCreation/types/index.js.map +1 -0
  147. package/dist/nodes/ServiceM8JobCreation/types/input.d.ts +119 -0
  148. package/dist/nodes/ServiceM8JobCreation/types/input.js +6 -0
  149. package/dist/nodes/ServiceM8JobCreation/types/input.js.map +1 -0
  150. package/dist/nodes/ServiceM8JobCreation/types/result.d.ts +79 -0
  151. package/dist/nodes/ServiceM8JobCreation/types/result.js +96 -0
  152. package/dist/nodes/ServiceM8JobCreation/types/result.js.map +1 -0
  153. package/package.json +66 -0
@@ -0,0 +1,216 @@
1
+ "use strict";
2
+ /**
3
+ * Client Matching Logic
4
+ * Implements fuzzy name + address matching for client deduplication
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.determineAction = exports.findBestMatchingClient = exports.buildBothNameFormats = exports.buildClientName = exports.matchClientName = void 0;
8
+ const addressUtils_1 = require("./addressUtils");
9
+ /**
10
+ * Compare two names and return match quality
11
+ * - 'exact': normalized strings are equal
12
+ * - 'partial': one contains the other, or starts with the other
13
+ * - 'none': no match
14
+ */
15
+ function matchClientName(searchName, clientName) {
16
+ const s = (0, addressUtils_1.normalizeForMatching)(searchName);
17
+ const c = (0, addressUtils_1.normalizeForMatching)(clientName);
18
+ if (!s || !c)
19
+ return 'none';
20
+ // Exact match
21
+ if (s === c)
22
+ return 'exact';
23
+ // Partial match: one contains the other
24
+ if (c.includes(s) || s.includes(c))
25
+ return 'partial';
26
+ // Partial match: one starts with the other
27
+ if (c.startsWith(s) || s.startsWith(c))
28
+ return 'partial';
29
+ return 'none';
30
+ }
31
+ exports.matchClientName = matchClientName;
32
+ /**
33
+ * Build a client name from first/last names or business name
34
+ * For individuals: format depends on nameFormat parameter
35
+ * - 'firstLast': "John Smith"
36
+ * - 'lastFirst': "Smith, John" (ServiceM8 default)
37
+ * For businesses: businessName
38
+ */
39
+ function buildClientName(firstName, lastName, businessName, email, nameFormat = 'firstLast') {
40
+ const trimmedBusiness = (businessName || '').trim();
41
+ const trimmedFirst = (firstName || '').trim();
42
+ const trimmedLast = (lastName || '').trim();
43
+ const trimmedEmail = (email || '').trim().toLowerCase();
44
+ if (trimmedBusiness) {
45
+ return { name: trimmedBusiness, isBusiness: true };
46
+ }
47
+ // Individual: format based on nameFormat setting
48
+ if (trimmedLast && trimmedFirst) {
49
+ const name = nameFormat === 'lastFirst'
50
+ ? `${trimmedLast}, ${trimmedFirst}`
51
+ : `${trimmedFirst} ${trimmedLast}`;
52
+ return { name, isBusiness: false };
53
+ }
54
+ // Only first name provided
55
+ if (trimmedFirst) {
56
+ return { name: trimmedFirst, isBusiness: false };
57
+ }
58
+ // Only last name provided
59
+ if (trimmedLast) {
60
+ return { name: trimmedLast, isBusiness: false };
61
+ }
62
+ // Fallback to email
63
+ const name = trimmedEmail || 'Unknown';
64
+ return { name, isBusiness: false };
65
+ }
66
+ exports.buildClientName = buildClientName;
67
+ /**
68
+ * Build both possible name formats for matching purposes
69
+ * Returns both "First Last" and "Last, First" versions
70
+ */
71
+ function buildBothNameFormats(firstName, lastName) {
72
+ const trimmedFirst = (firstName || '').trim();
73
+ const trimmedLast = (lastName || '').trim();
74
+ if (trimmedFirst && trimmedLast) {
75
+ return {
76
+ firstLast: `${trimmedFirst} ${trimmedLast}`,
77
+ lastFirst: `${trimmedLast}, ${trimmedFirst}`,
78
+ };
79
+ }
80
+ // Only one name available
81
+ const single = trimmedFirst || trimmedLast || '';
82
+ return {
83
+ firstLast: single,
84
+ lastFirst: single,
85
+ };
86
+ }
87
+ exports.buildBothNameFormats = buildBothNameFormats;
88
+ /**
89
+ * Find the best matching client from a list
90
+ * Implements the decision matrix:
91
+ *
92
+ * For BUSINESSES:
93
+ * - Exact name → use existing
94
+ * - Partial name + exact/near address → use existing (same business, name variant)
95
+ * - Partial name + no address match → create new
96
+ *
97
+ * For INDIVIDUALS:
98
+ * - Exact name + exact address → use existing
99
+ * - Exact name + different address → create new (different person, same name)
100
+ * - Partial name + exact/near address → use existing
101
+ */
102
+ function findBestMatchingClient(searchName, searchAddress, clients, isBusiness) {
103
+ let matchedClient = null;
104
+ let matchType = { name: 'none', address: 'none' };
105
+ let matchReason = '';
106
+ for (const client of clients) {
107
+ const nameMatch = matchClientName(searchName, client.name);
108
+ const addressMatch = (0, addressUtils_1.matchAddresses)(searchAddress, client);
109
+ if (nameMatch === 'exact') {
110
+ // EXACT name match
111
+ if (isBusiness) {
112
+ // Business: exact name always matches
113
+ matchedClient = client;
114
+ matchType = { name: 'exact', address: addressMatch };
115
+ matchReason = `Exact name match: "${client.name}"`;
116
+ break; // No need to check further
117
+ }
118
+ else {
119
+ // Individual: exact name + exact address = match
120
+ if (addressMatch === 'exact') {
121
+ matchedClient = client;
122
+ matchType = { name: 'exact', address: 'exact' };
123
+ matchReason = `Exact name match: "${client.name}" with exact address`;
124
+ break;
125
+ }
126
+ else {
127
+ // Same name but different address = different person
128
+ // Don't match, continue looking for a better match
129
+ // But record this as a potential issue
130
+ if (!matchedClient) {
131
+ matchReason = `Exact name match "${client.name}" but different address - different person`;
132
+ }
133
+ }
134
+ }
135
+ }
136
+ else if (nameMatch === 'partial') {
137
+ // PARTIAL name match - need address to confirm
138
+ if (addressMatch === 'exact' || addressMatch === 'near') {
139
+ // Partial name + similar address = same client
140
+ if (!matchedClient || matchType.name !== 'exact') {
141
+ matchedClient = client;
142
+ matchType = { name: 'partial', address: addressMatch };
143
+ matchReason = `Partial name "${client.name}" + ${addressMatch} address match`;
144
+ }
145
+ }
146
+ // Partial name + different address = different client (don't match)
147
+ }
148
+ }
149
+ if (!matchedClient) {
150
+ matchReason = matchReason || 'No matching client found';
151
+ }
152
+ return {
153
+ client: matchedClient,
154
+ matchType,
155
+ reason: matchReason,
156
+ };
157
+ }
158
+ exports.findBestMatchingClient = findBestMatchingClient;
159
+ function determineAction(input) {
160
+ const { contactExists, existingContactClientUuid, matchedClient, matchType, matchReason, isBusiness, kind, } = input;
161
+ let clientUuid = null;
162
+ let needsClient = true;
163
+ let needsContact = true;
164
+ if (matchedClient) {
165
+ // We found a matching client
166
+ clientUuid = matchedClient.uuid;
167
+ if (isBusiness) {
168
+ // BUSINESS rules: use existing if we have a match
169
+ needsClient = false;
170
+ }
171
+ else {
172
+ // INDIVIDUAL rules
173
+ if (matchType.name === 'exact' && matchType.address === 'exact') {
174
+ needsClient = false;
175
+ }
176
+ else if (matchType.name === 'exact') {
177
+ // Same name but different address = different person
178
+ needsClient = true;
179
+ clientUuid = null;
180
+ }
181
+ else {
182
+ // Partial match
183
+ needsClient = false;
184
+ }
185
+ }
186
+ }
187
+ // Determine if we need to create a contact
188
+ if (contactExists && existingContactClientUuid === clientUuid && clientUuid !== null) {
189
+ // Contact already exists on our target client
190
+ needsContact = false;
191
+ }
192
+ // Build the action and reason
193
+ let action;
194
+ let reason;
195
+ if (needsClient) {
196
+ action = 'create_client_and_contact';
197
+ reason = `${kind}: ${matchReason}; creating new client and contact`;
198
+ }
199
+ else if (needsContact) {
200
+ action = 'create_contact_and_job';
201
+ reason = `${kind}: ${matchReason}; creating contact on existing client`;
202
+ }
203
+ else {
204
+ action = 'create_job_only';
205
+ reason = `${kind}: ${matchReason}; contact already exists on this client`;
206
+ }
207
+ return {
208
+ action,
209
+ reason,
210
+ needsClient,
211
+ needsContact,
212
+ clientUuid,
213
+ };
214
+ }
215
+ exports.determineAction = determineAction;
216
+ //# sourceMappingURL=clientMatcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clientMatcher.js","sourceRoot":"","sources":["../../../../nodes/ServiceM8JobCreation/helpers/clientMatcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Australian Phone Number Normalization Utilities
3
+ */
4
+ /**
5
+ * Normalize an Australian mobile phone number to 04xx format
6
+ * Handles formats: 04xx, +614xx, 614xx, 4xx
7
+ * Returns null if not a valid mobile format
8
+ */
9
+ export declare function normalizeAustralianMobile(phone: string | undefined | null): string | null;
10
+ /**
11
+ * Normalize an Australian landline phone number
12
+ * Handles formats: 0x xxxx xxxx, +61x xxxx xxxx, 8 digit local
13
+ * Returns null if not a valid landline format
14
+ */
15
+ export declare function normalizeAustralianLandline(phone: string | undefined | null): string | null;
16
+ /**
17
+ * Smart phone derivation - determines mobile and landline from two input fields
18
+ * Prioritizes the correct field but will detect if values are swapped
19
+ */
20
+ export declare function derivePhones(inputPhone: string | undefined | null, inputMobile: string | undefined | null): {
21
+ mobile: string | null;
22
+ phone: string | null;
23
+ };
24
+ /**
25
+ * Format a phone number for display (with spaces)
26
+ */
27
+ export declare function formatPhoneForDisplay(phone: string | null): string;
28
+ /**
29
+ * Check if a string looks like an Australian mobile number
30
+ */
31
+ export declare function looksLikeMobile(phone: string | undefined | null): boolean;
32
+ /**
33
+ * Check if a string looks like an Australian landline number
34
+ */
35
+ export declare function looksLikeLandline(phone: string | undefined | null): boolean;
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ /**
3
+ * Australian Phone Number Normalization Utilities
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.looksLikeLandline = exports.looksLikeMobile = exports.formatPhoneForDisplay = exports.derivePhones = exports.normalizeAustralianLandline = exports.normalizeAustralianMobile = void 0;
7
+ /**
8
+ * Remove all non-digit characters from a string
9
+ */
10
+ function onlyDigits(str) {
11
+ return (str || '').replace(/\D+/g, '');
12
+ }
13
+ /**
14
+ * Normalize an Australian mobile phone number to 04xx format
15
+ * Handles formats: 04xx, +614xx, 614xx, 4xx
16
+ * Returns null if not a valid mobile format
17
+ */
18
+ function normalizeAustralianMobile(phone) {
19
+ if (!phone)
20
+ return null;
21
+ const digits = onlyDigits(phone);
22
+ // Already in 04xx format (10 digits starting with 04)
23
+ if (/^04\d{8}$/.test(digits)) {
24
+ return digits;
25
+ }
26
+ // International format: +614xx or 614xx (11-12 digits)
27
+ if (/^(?:61)?4\d{8}$/.test(digits)) {
28
+ return '0' + digits.slice(-9);
29
+ }
30
+ // Just the 9 digits without leading 0 (4xx xxx xxx)
31
+ if (/^4\d{8}$/.test(digits)) {
32
+ return '0' + digits;
33
+ }
34
+ return null;
35
+ }
36
+ exports.normalizeAustralianMobile = normalizeAustralianMobile;
37
+ /**
38
+ * Normalize an Australian landline phone number
39
+ * Handles formats: 0x xxxx xxxx, +61x xxxx xxxx, 8 digit local
40
+ * Returns null if not a valid landline format
41
+ */
42
+ function normalizeAustralianLandline(phone) {
43
+ if (!phone)
44
+ return null;
45
+ const digits = onlyDigits(phone);
46
+ // Full Australian landline: 0[2378] followed by 8 digits
47
+ if (/^0[2378]\d{8}$/.test(digits)) {
48
+ return digits;
49
+ }
50
+ // International format: 61[2378] followed by 8 digits
51
+ if (/^61[2378]\d{8}$/.test(digits)) {
52
+ return '0' + digits.slice(2);
53
+ }
54
+ // Local 8-digit number (no area code)
55
+ if (/^\d{8}$/.test(digits)) {
56
+ return digits;
57
+ }
58
+ return null;
59
+ }
60
+ exports.normalizeAustralianLandline = normalizeAustralianLandline;
61
+ /**
62
+ * Smart phone derivation - determines mobile and landline from two input fields
63
+ * Prioritizes the correct field but will detect if values are swapped
64
+ */
65
+ function derivePhones(inputPhone, inputMobile) {
66
+ // First try to normalize each from its expected field
67
+ let mobile = normalizeAustralianMobile(inputMobile);
68
+ let phone = normalizeAustralianLandline(inputPhone);
69
+ // If mobile field is empty but phone field contains a mobile number
70
+ if (!mobile) {
71
+ mobile = normalizeAustralianMobile(inputPhone);
72
+ }
73
+ // If phone field is empty but mobile field contains a landline
74
+ // Only do this if we didn't already get a mobile from it
75
+ if (!phone && !mobile) {
76
+ phone = normalizeAustralianLandline(inputMobile);
77
+ }
78
+ return { mobile, phone };
79
+ }
80
+ exports.derivePhones = derivePhones;
81
+ /**
82
+ * Format a phone number for display (with spaces)
83
+ */
84
+ function formatPhoneForDisplay(phone) {
85
+ if (!phone)
86
+ return '';
87
+ // Mobile: 04xx xxx xxx
88
+ if (/^04\d{8}$/.test(phone)) {
89
+ return `${phone.slice(0, 4)} ${phone.slice(4, 7)} ${phone.slice(7)}`;
90
+ }
91
+ // Landline: 0x xxxx xxxx
92
+ if (/^0[2378]\d{8}$/.test(phone)) {
93
+ return `${phone.slice(0, 2)} ${phone.slice(2, 6)} ${phone.slice(6)}`;
94
+ }
95
+ // 8-digit local: xxxx xxxx
96
+ if (/^\d{8}$/.test(phone)) {
97
+ return `${phone.slice(0, 4)} ${phone.slice(4)}`;
98
+ }
99
+ return phone;
100
+ }
101
+ exports.formatPhoneForDisplay = formatPhoneForDisplay;
102
+ /**
103
+ * Check if a string looks like an Australian mobile number
104
+ */
105
+ function looksLikeMobile(phone) {
106
+ if (!phone)
107
+ return false;
108
+ const digits = onlyDigits(phone);
109
+ return /^(?:0?4|61\s*4|\+61\s*4)/.test(phone) || /^(?:04|614|4)\d{8}$/.test(digits);
110
+ }
111
+ exports.looksLikeMobile = looksLikeMobile;
112
+ /**
113
+ * Check if a string looks like an Australian landline number
114
+ */
115
+ function looksLikeLandline(phone) {
116
+ if (!phone)
117
+ return false;
118
+ const digits = onlyDigits(phone);
119
+ return /^(?:0[2378]|61[2378])\d{8}$/.test(digits) || /^\d{8}$/.test(digits);
120
+ }
121
+ exports.looksLikeLandline = looksLikeLandline;
122
+ //# sourceMappingURL=phoneUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"phoneUtils.js","sourceRoot":"","sources":["../../../../nodes/ServiceM8JobCreation/helpers/phoneUtils.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH;;GAEG;AACH,SAAS,UAAU,CAAC,GAAW;IAC9B,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACxC,CAAC;AAED;;;;GAIG;AACH,SAAgB,yBAAyB,CAAC,KAAgC;IACzE,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IAEjC,sDAAsD;IACtD,IAAI,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;QAC7B,OAAO,MAAM,CAAC;KACd;IAED,uDAAuD;IACvD,IAAI,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;QACnC,OAAO,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;KAC9B;IAED,oDAAoD;IACpD,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;QAC5B,OAAO,GAAG,GAAG,MAAM,CAAC;KACpB;IAED,OAAO,IAAI,CAAC;AACb,CAAC;AArBD,8DAqBC;AAED;;;;GAIG;AACH,SAAgB,2BAA2B,CAAC,KAAgC;IAC3E,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IAEjC,yDAAyD;IACzD,IAAI,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;QAClC,OAAO,MAAM,CAAC;KACd;IAED,sDAAsD;IACtD,IAAI,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;QACnC,OAAO,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KAC7B;IAED,sCAAsC;IACtC,IAAI,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;QAC3B,OAAO,MAAM,CAAC;KACd;IAED,OAAO,IAAI,CAAC;AACb,CAAC;AArBD,kEAqBC;AAED;;;GAGG;AACH,SAAgB,YAAY,CAC3B,UAAqC,EACrC,WAAsC;IAEtC,sDAAsD;IACtD,IAAI,MAAM,GAAG,yBAAyB,CAAC,WAAW,CAAC,CAAC;IACpD,IAAI,KAAK,GAAG,2BAA2B,CAAC,UAAU,CAAC,CAAC;IAEpD,oEAAoE;IACpE,IAAI,CAAC,MAAM,EAAE;QACZ,MAAM,GAAG,yBAAyB,CAAC,UAAU,CAAC,CAAC;KAC/C;IAED,+DAA+D;IAC/D,yDAAyD;IACzD,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,EAAE;QACtB,KAAK,GAAG,2BAA2B,CAAC,WAAW,CAAC,CAAC;KACjD;IAED,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAC1B,CAAC;AApBD,oCAoBC;AAED;;GAEG;AACH,SAAgB,qBAAqB,CAAC,KAAoB;IACzD,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IAEtB,uBAAuB;IACvB,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;QAC5B,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;KACrE;IAED,yBAAyB;IACzB,IAAI,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;QACjC,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;KACrE;IAED,2BAA2B;IAC3B,IAAI,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;QAC1B,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;KAChD;IAED,OAAO,KAAK,CAAC;AACd,CAAC;AAnBD,sDAmBC;AAED;;GAEG;AACH,SAAgB,eAAe,CAAC,KAAgC;IAC/D,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IACjC,OAAO,0BAA0B,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACrF,CAAC;AAJD,0CAIC;AAED;;GAEG;AACH,SAAgB,iBAAiB,CAAC,KAAgC;IACjE,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IACjC,OAAO,6BAA6B,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC7E,CAAC;AAJD,8CAIC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Methods Index
3
+ * Exports all node methods (loadOptions, etc.)
4
+ */
5
+ import { getCategories, getBadges, getQueues, getJobs } from './loadOptions';
6
+ export declare const methods: {
7
+ loadOptions: {
8
+ getCategories: typeof getCategories;
9
+ getBadges: typeof getBadges;
10
+ getQueues: typeof getQueues;
11
+ getJobs: typeof getJobs;
12
+ };
13
+ };
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ /**
3
+ * Methods Index
4
+ * Exports all node methods (loadOptions, etc.)
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.methods = void 0;
8
+ const loadOptions_1 = require("./loadOptions");
9
+ exports.methods = {
10
+ loadOptions: {
11
+ getCategories: loadOptions_1.getCategories,
12
+ getBadges: loadOptions_1.getBadges,
13
+ getQueues: loadOptions_1.getQueues,
14
+ getJobs: loadOptions_1.getJobs,
15
+ },
16
+ };
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../nodes/ServiceM8JobCreation/methods/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+CAA6E;AAEhE,QAAA,OAAO,GAAG;IACtB,WAAW,EAAE;QACZ,aAAa,EAAb,2BAAa;QACb,SAAS,EAAT,uBAAS;QACT,SAAS,EAAT,uBAAS;QACT,OAAO,EAAP,qBAAO;KACP;CACD,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Load Options Methods
3
+ * Dynamic dropdown data fetching for the node
4
+ */
5
+ import type { ILoadOptionsFunctions, INodePropertyOptions } from 'n8n-workflow';
6
+ export declare function getCategories(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
7
+ export declare function getBadges(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
8
+ export declare function getQueues(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
9
+ export declare function getJobs(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ /**
3
+ * Load Options Methods
4
+ * Dynamic dropdown data fetching for the node
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.getJobs = exports.getQueues = exports.getBadges = exports.getCategories = void 0;
8
+ const api_1 = require("../helpers/api");
9
+ async function getCategories() {
10
+ const response = await (0, api_1.serviceM8Request)(this, {
11
+ method: 'GET',
12
+ endpoint: '/api_1.0/category.json',
13
+ query: { $filter: 'active eq 1' },
14
+ });
15
+ const categories = (0, api_1.parseArrayResponse)(response);
16
+ return categories.map((cat) => ({
17
+ name: cat.name,
18
+ value: cat.uuid,
19
+ }));
20
+ }
21
+ exports.getCategories = getCategories;
22
+ async function getBadges() {
23
+ const response = await (0, api_1.serviceM8Request)(this, {
24
+ method: 'GET',
25
+ endpoint: '/api_1.0/badge.json',
26
+ query: { $filter: 'active eq 1' },
27
+ });
28
+ const badges = (0, api_1.parseArrayResponse)(response);
29
+ return badges.map((badge) => ({
30
+ name: badge.name,
31
+ value: badge.uuid,
32
+ }));
33
+ }
34
+ exports.getBadges = getBadges;
35
+ async function getQueues() {
36
+ const response = await (0, api_1.serviceM8Request)(this, {
37
+ method: 'GET',
38
+ endpoint: '/api_1.0/queue.json',
39
+ query: { $filter: 'active eq 1' },
40
+ });
41
+ const queues = (0, api_1.parseArrayResponse)(response);
42
+ return queues.map((queue) => ({
43
+ name: queue.name,
44
+ value: queue.uuid,
45
+ }));
46
+ }
47
+ exports.getQueues = getQueues;
48
+ async function getJobs() {
49
+ const response = await (0, api_1.serviceM8Request)(this, {
50
+ method: 'GET',
51
+ endpoint: '/api_1.0/job.json',
52
+ query: { $filter: 'active eq 1', $orderby: 'edit_date desc' },
53
+ });
54
+ const jobs = (0, api_1.parseArrayResponse)(response);
55
+ return jobs.map((job) => ({
56
+ name: `${job.generated_job_id} - ${job.status}${job.job_description ? ` - ${job.job_description.substring(0, 50)}` : ''}`,
57
+ value: job.uuid,
58
+ }));
59
+ }
60
+ exports.getJobs = getJobs;
61
+ //# sourceMappingURL=loadOptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loadOptions.js","sourceRoot":"","sources":["../../../../nodes/ServiceM8JobCreation/methods/loadOptions.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AASH,wCAAsE;AAE/D,KAAK,UAAU,aAAa;IAGlC,MAAM,QAAQ,GAAG,MAAM,IAAA,sBAAgB,EAAC,IAAI,EAAE;QAC7C,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,wBAAwB;QAClC,KAAK,EAAE,EAAE,OAAO,EAAE,aAAa,EAAE;KACjC,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,IAAA,wBAAkB,EAAoB,QAAQ,CAAC,CAAC;IACnE,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC/B,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,KAAK,EAAE,GAAG,CAAC,IAAI;KACf,CAAC,CAAC,CAAC;AACL,CAAC;AAdD,sCAcC;AAEM,KAAK,UAAU,SAAS;IAG9B,MAAM,QAAQ,GAAG,MAAM,IAAA,sBAAgB,EAAC,IAAI,EAAE;QAC7C,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,qBAAqB;QAC/B,KAAK,EAAE,EAAE,OAAO,EAAE,aAAa,EAAE;KACjC,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,IAAA,wBAAkB,EAAiB,QAAQ,CAAC,CAAC;IAC5D,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC7B,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,KAAK,EAAE,KAAK,CAAC,IAAI;KACjB,CAAC,CAAC,CAAC;AACL,CAAC;AAdD,8BAcC;AAEM,KAAK,UAAU,SAAS;IAG9B,MAAM,QAAQ,GAAG,MAAM,IAAA,sBAAgB,EAAC,IAAI,EAAE;QAC7C,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,qBAAqB;QAC/B,KAAK,EAAE,EAAE,OAAO,EAAE,aAAa,EAAE;KACjC,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,IAAA,wBAAkB,EAAiB,QAAQ,CAAC,CAAC;IAC5D,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC7B,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,KAAK,EAAE,KAAK,CAAC,IAAI;KACjB,CAAC,CAAC,CAAC;AACL,CAAC;AAdD,8BAcC;AAEM,KAAK,UAAU,OAAO;IAG5B,MAAM,QAAQ,GAAG,MAAM,IAAA,sBAAgB,EAAC,IAAI,EAAE;QAC7C,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,mBAAmB;QAC7B,KAAK,EAAE,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,gBAAgB,EAAE;KAC7D,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,IAAA,wBAAkB,EAAe,QAAQ,CAAC,CAAC;IACxD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACzB,IAAI,EAAE,GAAG,GAAG,CAAC,gBAAgB,MAAM,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;QACzH,KAAK,EAAE,GAAG,CAAC,IAAI;KACf,CAAC,CAAC,CAAC;AACL,CAAC;AAdD,0BAcC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Category Assignment Operations
3
+ * Assign category to job (static or dynamic)
4
+ */
5
+ import type { IExecuteFunctions } from 'n8n-workflow';
6
+ export interface CategoryAssignInput {
7
+ jobUuid: string;
8
+ enableCategory: boolean;
9
+ categoryDynamic: boolean;
10
+ categoryUuidInput: string;
11
+ categoryNameInput: string;
12
+ }
13
+ export interface CategoryAssignResult {
14
+ categoryAssigned: boolean;
15
+ categoryName?: string;
16
+ categoryMissing?: string;
17
+ }
18
+ /**
19
+ * Assign a category to a job
20
+ * Handles both static (UUID from dropdown) and dynamic (name lookup) modes
21
+ */
22
+ export declare function assignCategory(context: IExecuteFunctions, input: CategoryAssignInput): Promise<CategoryAssignResult>;
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ /**
3
+ * Category Assignment Operations
4
+ * Assign category to job (static or dynamic)
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.assignCategory = void 0;
8
+ const api_1 = require("../../helpers/api");
9
+ /**
10
+ * Assign a category to a job
11
+ * Handles both static (UUID from dropdown) and dynamic (name lookup) modes
12
+ */
13
+ async function assignCategory(context, input) {
14
+ var _a;
15
+ if (!input.enableCategory) {
16
+ return { categoryAssigned: false };
17
+ }
18
+ let categoryUuid = input.categoryUuidInput;
19
+ let categoryName;
20
+ let categoryMissing;
21
+ // Handle dynamic category name lookup
22
+ if (input.categoryDynamic && input.categoryNameInput) {
23
+ const categoriesResponse = await (0, api_1.serviceM8Request)(context, {
24
+ method: 'GET',
25
+ endpoint: '/api_1.0/category.json',
26
+ query: { $filter: 'active eq 1' },
27
+ });
28
+ const allCategories = (0, api_1.parseArrayResponse)(categoriesResponse);
29
+ const foundCategory = (0, api_1.findCategoryByName)(allCategories, input.categoryNameInput);
30
+ if (foundCategory) {
31
+ categoryUuid = foundCategory.uuid;
32
+ categoryName = foundCategory.name;
33
+ }
34
+ else {
35
+ categoryMissing = input.categoryNameInput;
36
+ }
37
+ }
38
+ if (categoryUuid) {
39
+ await (0, api_1.updateJob)(context, input.jobUuid, { category_uuid: categoryUuid });
40
+ // Get category name for output if not already set
41
+ if (!categoryName) {
42
+ const categoriesResponse = await (0, api_1.serviceM8Request)(context, {
43
+ method: 'GET',
44
+ endpoint: '/api_1.0/category.json',
45
+ query: { $filter: `uuid eq '${categoryUuid}'` },
46
+ });
47
+ const categories = (0, api_1.parseArrayResponse)(categoriesResponse);
48
+ categoryName = (_a = categories[0]) === null || _a === void 0 ? void 0 : _a.name;
49
+ }
50
+ return {
51
+ categoryAssigned: true,
52
+ categoryName,
53
+ };
54
+ }
55
+ return {
56
+ categoryAssigned: false,
57
+ categoryMissing,
58
+ };
59
+ }
60
+ exports.assignCategory = assignCategory;
61
+ //# sourceMappingURL=categoryAssign.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"categoryAssign.js","sourceRoot":"","sources":["../../../../../nodes/ServiceM8JobCreation/operations/create/categoryAssign.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAIH,2CAK2B;AAgB3B;;;GAGG;AACI,KAAK,UAAU,cAAc,CACnC,OAA0B,EAC1B,KAA0B;;IAE1B,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE;QAC1B,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAC;KACnC;IAED,IAAI,YAAY,GAAG,KAAK,CAAC,iBAAiB,CAAC;IAC3C,IAAI,YAAgC,CAAC;IACrC,IAAI,eAAmC,CAAC;IAExC,sCAAsC;IACtC,IAAI,KAAK,CAAC,eAAe,IAAI,KAAK,CAAC,iBAAiB,EAAE;QACrD,MAAM,kBAAkB,GAAG,MAAM,IAAA,sBAAgB,EAAC,OAAO,EAAE;YAC1D,MAAM,EAAE,KAAK;YACb,QAAQ,EAAE,wBAAwB;YAClC,KAAK,EAAE,EAAE,OAAO,EAAE,aAAa,EAAE;SACjC,CAAC,CAAC;QACH,MAAM,aAAa,GAAG,IAAA,wBAAkB,EAAoB,kBAAkB,CAAC,CAAC;QAChF,MAAM,aAAa,GAAG,IAAA,wBAAkB,EAAC,aAAa,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAEjF,IAAI,aAAa,EAAE;YAClB,YAAY,GAAG,aAAa,CAAC,IAAI,CAAC;YAClC,YAAY,GAAG,aAAa,CAAC,IAAI,CAAC;SAClC;aAAM;YACN,eAAe,GAAG,KAAK,CAAC,iBAAiB,CAAC;SAC1C;KACD;IAED,IAAI,YAAY,EAAE;QACjB,MAAM,IAAA,eAAS,EAAC,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,YAAY,EAAE,CAAC,CAAC;QAEzE,kDAAkD;QAClD,IAAI,CAAC,YAAY,EAAE;YAClB,MAAM,kBAAkB,GAAG,MAAM,IAAA,sBAAgB,EAAC,OAAO,EAAE;gBAC1D,MAAM,EAAE,KAAK;gBACb,QAAQ,EAAE,wBAAwB;gBAClC,KAAK,EAAE,EAAE,OAAO,EAAE,YAAY,YAAY,GAAG,EAAE;aAC/C,CAAC,CAAC;YACH,MAAM,UAAU,GAAG,IAAA,wBAAkB,EAAoB,kBAAkB,CAAC,CAAC;YAC7E,YAAY,GAAG,MAAA,UAAU,CAAC,CAAC,CAAC,0CAAE,IAAI,CAAC;SACnC;QAED,OAAO;YACN,gBAAgB,EAAE,IAAI;YACtB,YAAY;SACZ,CAAC;KACF;IAED,OAAO;QACN,gBAAgB,EAAE,KAAK;QACvB,eAAe;KACf,CAAC;AACH,CAAC;AAtDD,wCAsDC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Client Creation Operations
3
+ * Create client and company contact
4
+ */
5
+ import type { IExecuteFunctions } from 'n8n-workflow';
6
+ import type { AddressParts } from '../../types';
7
+ export interface ClientCreateInput {
8
+ clientName: string;
9
+ isIndividual: number;
10
+ clientAddress: string;
11
+ clientAddressParts: AddressParts;
12
+ }
13
+ export interface ContactCreateInput {
14
+ companyUuid: string;
15
+ firstName: string;
16
+ lastName: string;
17
+ email?: string;
18
+ phone?: string | null;
19
+ mobile?: string | null;
20
+ }
21
+ export interface ClientCreateResult {
22
+ clientUuid: string;
23
+ clientCreated: boolean;
24
+ }
25
+ export interface ContactCreateResult {
26
+ contactUuid?: string;
27
+ contactCreated: boolean;
28
+ }
29
+ /**
30
+ * Create a new client if needed
31
+ */
32
+ export declare function createClientIfNeeded(context: IExecuteFunctions, needsClient: boolean, existingClientUuid: string | null, input: ClientCreateInput): Promise<ClientCreateResult>;
33
+ /**
34
+ * Create a company contact if needed
35
+ */
36
+ export declare function createCompanyContactIfNeeded(context: IExecuteFunctions, needsContact: boolean, clientUuid: string, contactLookupField: 'email' | 'mobile' | 'phone' | null, input: ContactCreateInput): Promise<ContactCreateResult>;