@machinemetrics/mm-erp-sdk 0.1.1-beta.1

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 (240) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +147 -0
  3. package/dist/config-2l5vnNkA.js +418 -0
  4. package/dist/config-2l5vnNkA.js.map +1 -0
  5. package/dist/connector-factory-CQ8e7Tae.js +21 -0
  6. package/dist/connector-factory-CQ8e7Tae.js.map +1 -0
  7. package/dist/hashed-cache-manager-Ci9X3GAB.js +292 -0
  8. package/dist/hashed-cache-manager-Ci9X3GAB.js.map +1 -0
  9. package/dist/index-Cn9ccxOO.js +179 -0
  10. package/dist/index-Cn9ccxOO.js.map +1 -0
  11. package/dist/index.d.ts +35 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/knexfile-1qKKIORB.js +20 -0
  14. package/dist/knexfile-1qKKIORB.js.map +1 -0
  15. package/dist/knexfile.d.ts +6 -0
  16. package/dist/knexfile.d.ts.map +1 -0
  17. package/dist/logger-QG73MndU.js +17523 -0
  18. package/dist/logger-QG73MndU.js.map +1 -0
  19. package/dist/migrations/20241015162631_create_cache_table.js +17 -0
  20. package/dist/migrations/20241015162631_create_cache_table.js.map +1 -0
  21. package/dist/migrations/20241015162632_create_sdk_cache_table.js +17 -0
  22. package/dist/migrations/20241015162632_create_sdk_cache_table.js.map +1 -0
  23. package/dist/migrations/20250103162631_create_record_tracking_table.js +17 -0
  24. package/dist/migrations/20250103162631_create_record_tracking_table.js.map +1 -0
  25. package/dist/mm-erp-sdk.js +3503 -0
  26. package/dist/mm-erp-sdk.js.map +1 -0
  27. package/dist/services/caching-service/batch-cache-manager.d.ts +52 -0
  28. package/dist/services/caching-service/batch-cache-manager.d.ts.map +1 -0
  29. package/dist/services/caching-service/hashed-cache-manager.d.ts +83 -0
  30. package/dist/services/caching-service/hashed-cache-manager.d.ts.map +1 -0
  31. package/dist/services/caching-service/index.d.ts +92 -0
  32. package/dist/services/caching-service/index.d.ts.map +1 -0
  33. package/dist/services/caching-service/record-tracking-manager.d.ts +15 -0
  34. package/dist/services/caching-service/record-tracking-manager.d.ts.map +1 -0
  35. package/dist/services/data-sync-service/configuration-manager.d.ts +50 -0
  36. package/dist/services/data-sync-service/configuration-manager.d.ts.map +1 -0
  37. package/dist/services/data-sync-service/data-sync-service.d.ts +2 -0
  38. package/dist/services/data-sync-service/data-sync-service.d.ts.map +1 -0
  39. package/dist/services/data-sync-service/index.d.ts +10 -0
  40. package/dist/services/data-sync-service/index.d.ts.map +1 -0
  41. package/dist/services/data-sync-service/jobs/clean-up-expired-cache.d.ts +2 -0
  42. package/dist/services/data-sync-service/jobs/clean-up-expired-cache.d.ts.map +1 -0
  43. package/dist/services/data-sync-service/jobs/clean-up-expired-cache.js +41 -0
  44. package/dist/services/data-sync-service/jobs/clean-up-expired-cache.js.map +1 -0
  45. package/dist/services/data-sync-service/jobs/from-erp.d.ts +4 -0
  46. package/dist/services/data-sync-service/jobs/from-erp.d.ts.map +1 -0
  47. package/dist/services/data-sync-service/jobs/from-erp.js +42 -0
  48. package/dist/services/data-sync-service/jobs/from-erp.js.map +1 -0
  49. package/dist/services/data-sync-service/jobs/retry-failed-labor-tickets.d.ts +2 -0
  50. package/dist/services/data-sync-service/jobs/retry-failed-labor-tickets.d.ts.map +1 -0
  51. package/dist/services/data-sync-service/jobs/retry-failed-labor-tickets.js +41 -0
  52. package/dist/services/data-sync-service/jobs/retry-failed-labor-tickets.js.map +1 -0
  53. package/dist/services/data-sync-service/jobs/run-migrations.d.ts +2 -0
  54. package/dist/services/data-sync-service/jobs/run-migrations.d.ts.map +1 -0
  55. package/dist/services/data-sync-service/jobs/run-migrations.js +21 -0
  56. package/dist/services/data-sync-service/jobs/run-migrations.js.map +1 -0
  57. package/dist/services/data-sync-service/jobs/to-erp.d.ts +4 -0
  58. package/dist/services/data-sync-service/jobs/to-erp.d.ts.map +1 -0
  59. package/dist/services/data-sync-service/jobs/to-erp.js +39 -0
  60. package/dist/services/data-sync-service/jobs/to-erp.js.map +1 -0
  61. package/dist/services/erp-api-services/errors.d.ts +22 -0
  62. package/dist/services/erp-api-services/errors.d.ts.map +1 -0
  63. package/dist/services/erp-api-services/graphql/graphql-service.d.ts +40 -0
  64. package/dist/services/erp-api-services/graphql/graphql-service.d.ts.map +1 -0
  65. package/dist/services/erp-api-services/graphql/types.d.ts +32 -0
  66. package/dist/services/erp-api-services/graphql/types.d.ts.map +1 -0
  67. package/dist/services/erp-api-services/index.d.ts +9 -0
  68. package/dist/services/erp-api-services/index.d.ts.map +1 -0
  69. package/dist/services/erp-api-services/oauth-client.d.ts +45 -0
  70. package/dist/services/erp-api-services/oauth-client.d.ts.map +1 -0
  71. package/dist/services/erp-api-services/rest/get-query-params.d.ts +50 -0
  72. package/dist/services/erp-api-services/rest/get-query-params.d.ts.map +1 -0
  73. package/dist/services/erp-api-services/rest/rest-api-service.d.ts +35 -0
  74. package/dist/services/erp-api-services/rest/rest-api-service.d.ts.map +1 -0
  75. package/dist/services/erp-api-services/types.d.ts +27 -0
  76. package/dist/services/erp-api-services/types.d.ts.map +1 -0
  77. package/dist/services/mm-api-service/index.d.ts +31 -0
  78. package/dist/services/mm-api-service/index.d.ts.map +1 -0
  79. package/dist/services/mm-api-service/mm-api-service.d.ts +214 -0
  80. package/dist/services/mm-api-service/mm-api-service.d.ts.map +1 -0
  81. package/dist/services/mm-api-service/token-mgr.d.ts +33 -0
  82. package/dist/services/mm-api-service/token-mgr.d.ts.map +1 -0
  83. package/dist/services/mm-api-service/types/checkpoint.d.ts +13 -0
  84. package/dist/services/mm-api-service/types/checkpoint.d.ts.map +1 -0
  85. package/dist/services/mm-api-service/types/entity-transformer.d.ts +58 -0
  86. package/dist/services/mm-api-service/types/entity-transformer.d.ts.map +1 -0
  87. package/dist/services/mm-api-service/types/mm-response-interfaces.d.ts +263 -0
  88. package/dist/services/mm-api-service/types/mm-response-interfaces.d.ts.map +1 -0
  89. package/dist/services/mm-api-service/types/receive-types.d.ts +57 -0
  90. package/dist/services/mm-api-service/types/receive-types.d.ts.map +1 -0
  91. package/dist/services/mm-api-service/types/send-types.d.ts +147 -0
  92. package/dist/services/mm-api-service/types/send-types.d.ts.map +1 -0
  93. package/dist/services/reporting-service/index.d.ts +5 -0
  94. package/dist/services/reporting-service/index.d.ts.map +1 -0
  95. package/dist/services/reporting-service/logger.d.ts +4 -0
  96. package/dist/services/reporting-service/logger.d.ts.map +1 -0
  97. package/dist/services/sql-server-erp-service/configuration.d.ts +15 -0
  98. package/dist/services/sql-server-erp-service/configuration.d.ts.map +1 -0
  99. package/dist/services/sql-server-erp-service/index.d.ts +16 -0
  100. package/dist/services/sql-server-erp-service/index.d.ts.map +1 -0
  101. package/dist/services/sql-server-erp-service/internal/sql-labor-ticket-operations.d.ts +31 -0
  102. package/dist/services/sql-server-erp-service/internal/sql-labor-ticket-operations.d.ts.map +1 -0
  103. package/dist/services/sql-server-erp-service/internal/sql-server-config.d.ts +65 -0
  104. package/dist/services/sql-server-erp-service/internal/sql-server-config.d.ts.map +1 -0
  105. package/dist/services/sql-server-erp-service/internal/sql-transaction-manager.d.ts +20 -0
  106. package/dist/services/sql-server-erp-service/internal/sql-transaction-manager.d.ts.map +1 -0
  107. package/dist/services/sql-server-erp-service/internal/types/sql-server-types.d.ts +3 -0
  108. package/dist/services/sql-server-erp-service/internal/types/sql-server-types.d.ts.map +1 -0
  109. package/dist/services/sql-server-erp-service/sql-server-helpers.d.ts +35 -0
  110. package/dist/services/sql-server-erp-service/sql-server-helpers.d.ts.map +1 -0
  111. package/dist/services/sql-server-erp-service/sql-server-service.d.ts +37 -0
  112. package/dist/services/sql-server-erp-service/sql-server-service.d.ts.map +1 -0
  113. package/dist/services/sql-server-erp-service/types/sql-input-param.d.ts +10 -0
  114. package/dist/services/sql-server-erp-service/types/sql-input-param.d.ts.map +1 -0
  115. package/dist/services/sqlite-service/index.d.ts +2 -0
  116. package/dist/services/sqlite-service/index.d.ts.map +1 -0
  117. package/dist/services/sqlite-service/sqlite-coordinator.d.ts +28 -0
  118. package/dist/services/sqlite-service/sqlite-coordinator.d.ts.map +1 -0
  119. package/dist/types/erp-connector.d.ts +40 -0
  120. package/dist/types/erp-connector.d.ts.map +1 -0
  121. package/dist/types/erp-types.d.ts +32 -0
  122. package/dist/types/erp-types.d.ts.map +1 -0
  123. package/dist/types/index.d.ts +7 -0
  124. package/dist/types/index.d.ts.map +1 -0
  125. package/dist/utils/application-initializer.d.ts +15 -0
  126. package/dist/utils/application-initializer.d.ts.map +1 -0
  127. package/dist/utils/cleanup-numbers.d.ts +2 -0
  128. package/dist/utils/cleanup-numbers.d.ts.map +1 -0
  129. package/dist/utils/connector-factory.d.ts +8 -0
  130. package/dist/utils/connector-factory.d.ts.map +1 -0
  131. package/dist/utils/data-transformation.d.ts +20 -0
  132. package/dist/utils/data-transformation.d.ts.map +1 -0
  133. package/dist/utils/erp-type-from-entity.d.ts +5 -0
  134. package/dist/utils/erp-type-from-entity.d.ts.map +1 -0
  135. package/dist/utils/http-client.d.ts +35 -0
  136. package/dist/utils/http-client.d.ts.map +1 -0
  137. package/dist/utils/index.d.ts +57 -0
  138. package/dist/utils/index.d.ts.map +1 -0
  139. package/dist/utils/local-data-store/database-lock.d.ts +29 -0
  140. package/dist/utils/local-data-store/database-lock.d.ts.map +1 -0
  141. package/dist/utils/local-data-store/jobs-shared-data.d.ts +34 -0
  142. package/dist/utils/local-data-store/jobs-shared-data.d.ts.map +1 -0
  143. package/dist/utils/mm-labor-ticket-helpers.d.ts +9 -0
  144. package/dist/utils/mm-labor-ticket-helpers.d.ts.map +1 -0
  145. package/dist/utils/removeExtraneousFields.d.ts +6 -0
  146. package/dist/utils/removeExtraneousFields.d.ts.map +1 -0
  147. package/dist/utils/removeIdFieldFromPayload.d.ts +6 -0
  148. package/dist/utils/removeIdFieldFromPayload.d.ts.map +1 -0
  149. package/dist/utils/resource-group.d.ts +11 -0
  150. package/dist/utils/resource-group.d.ts.map +1 -0
  151. package/dist/utils/standard-process-drivers/error-processor.d.ts +68 -0
  152. package/dist/utils/standard-process-drivers/error-processor.d.ts.map +1 -0
  153. package/dist/utils/standard-process-drivers/index.d.ts +3 -0
  154. package/dist/utils/standard-process-drivers/index.d.ts.map +1 -0
  155. package/dist/utils/standard-process-drivers/labor-ticket-erp-synchronizer.d.ts +18 -0
  156. package/dist/utils/standard-process-drivers/labor-ticket-erp-synchronizer.d.ts.map +1 -0
  157. package/dist/utils/standard-process-drivers/mm-entity-processor.d.ts +40 -0
  158. package/dist/utils/standard-process-drivers/mm-entity-processor.d.ts.map +1 -0
  159. package/dist/utils/standard-process-drivers/standard-process-drivers.d.ts +178 -0
  160. package/dist/utils/standard-process-drivers/standard-process-drivers.d.ts.map +1 -0
  161. package/dist/utils/time-utils.d.ts +31 -0
  162. package/dist/utils/time-utils.d.ts.map +1 -0
  163. package/dist/utils/timezone.d.ts +21 -0
  164. package/dist/utils/timezone.d.ts.map +1 -0
  165. package/dist/utils/trimObjectValues.d.ts +5 -0
  166. package/dist/utils/trimObjectValues.d.ts.map +1 -0
  167. package/dist/utils/uniqueRows.d.ts +9 -0
  168. package/dist/utils/uniqueRows.d.ts.map +1 -0
  169. package/package.json +50 -0
  170. package/src/index.ts +98 -0
  171. package/src/knexfile.ts +21 -0
  172. package/src/migrations/20241015162631_create_cache_table.ts +15 -0
  173. package/src/migrations/20241015162632_create_sdk_cache_table.ts +15 -0
  174. package/src/migrations/20250103162631_create_record_tracking_table.ts +18 -0
  175. package/src/services/caching-service/batch-cache-manager.ts +111 -0
  176. package/src/services/caching-service/hashed-cache-manager.ts +253 -0
  177. package/src/services/caching-service/index.ts +114 -0
  178. package/src/services/caching-service/record-tracking-manager.ts +41 -0
  179. package/src/services/data-sync-service/configuration-manager.ts +153 -0
  180. package/src/services/data-sync-service/data-sync-service.ts +100 -0
  181. package/src/services/data-sync-service/index.ts +14 -0
  182. package/src/services/data-sync-service/jobs/clean-up-expired-cache.ts +38 -0
  183. package/src/services/data-sync-service/jobs/from-erp.ts +55 -0
  184. package/src/services/data-sync-service/jobs/retry-failed-labor-tickets.ts +44 -0
  185. package/src/services/data-sync-service/jobs/run-migrations.ts +21 -0
  186. package/src/services/data-sync-service/jobs/to-erp.ts +53 -0
  187. package/src/services/erp-api-services/errors.ts +115 -0
  188. package/src/services/erp-api-services/graphql/graphql-service.ts +116 -0
  189. package/src/services/erp-api-services/graphql/types.ts +30 -0
  190. package/src/services/erp-api-services/index.ts +14 -0
  191. package/src/services/erp-api-services/oauth-client.ts +72 -0
  192. package/src/services/erp-api-services/rest/get-query-params.ts +63 -0
  193. package/src/services/erp-api-services/rest/rest-api-service.ts +212 -0
  194. package/src/services/erp-api-services/types.ts +28 -0
  195. package/src/services/mm-api-service/index.ts +83 -0
  196. package/src/services/mm-api-service/mm-api-service.ts +685 -0
  197. package/src/services/mm-api-service/token-mgr.ts +123 -0
  198. package/src/services/mm-api-service/types/checkpoint.ts +13 -0
  199. package/src/services/mm-api-service/types/entity-transformer.ts +298 -0
  200. package/src/services/mm-api-service/types/mm-response-interfaces.ts +293 -0
  201. package/src/services/mm-api-service/types/receive-types.ts +89 -0
  202. package/src/services/mm-api-service/types/send-types.ts +383 -0
  203. package/src/services/reporting-service/index.ts +4 -0
  204. package/src/services/reporting-service/logger.ts +117 -0
  205. package/src/services/sql-server-erp-service/configuration.ts +14 -0
  206. package/src/services/sql-server-erp-service/index.ts +18 -0
  207. package/src/services/sql-server-erp-service/internal/sql-labor-ticket-operations.ts +66 -0
  208. package/src/services/sql-server-erp-service/internal/sql-server-config.ts +38 -0
  209. package/src/services/sql-server-erp-service/internal/sql-transaction-manager.ts +45 -0
  210. package/src/services/sql-server-erp-service/internal/types/sql-server-types.ts +23 -0
  211. package/src/services/sql-server-erp-service/sql-server-helpers.ts +99 -0
  212. package/src/services/sql-server-erp-service/sql-server-service.ts +191 -0
  213. package/src/services/sql-server-erp-service/types/sql-input-param.ts +14 -0
  214. package/src/services/sqlite-service/index.ts +1 -0
  215. package/src/services/sqlite-service/sqlite-coordinator.ts +80 -0
  216. package/src/types/erp-connector.ts +46 -0
  217. package/src/types/erp-types.ts +37 -0
  218. package/src/types/index.ts +13 -0
  219. package/src/utils/application-initializer.ts +62 -0
  220. package/src/utils/cleanup-numbers.ts +5 -0
  221. package/src/utils/connector-factory.ts +34 -0
  222. package/src/utils/data-transformation.ts +58 -0
  223. package/src/utils/erp-type-from-entity.ts +12 -0
  224. package/src/utils/http-client.ts +137 -0
  225. package/src/utils/index.ts +71 -0
  226. package/src/utils/local-data-store/database-lock.ts +86 -0
  227. package/src/utils/local-data-store/jobs-shared-data.ts +111 -0
  228. package/src/utils/mm-labor-ticket-helpers.ts +28 -0
  229. package/src/utils/removeExtraneousFields.ts +22 -0
  230. package/src/utils/removeIdFieldFromPayload.ts +22 -0
  231. package/src/utils/resource-group.ts +92 -0
  232. package/src/utils/standard-process-drivers/error-processor.ts +417 -0
  233. package/src/utils/standard-process-drivers/index.ts +6 -0
  234. package/src/utils/standard-process-drivers/labor-ticket-erp-synchronizer.ts +261 -0
  235. package/src/utils/standard-process-drivers/mm-entity-processor.ts +265 -0
  236. package/src/utils/standard-process-drivers/standard-process-drivers.ts +459 -0
  237. package/src/utils/time-utils.ts +131 -0
  238. package/src/utils/timezone.ts +96 -0
  239. package/src/utils/trimObjectValues.ts +12 -0
  240. package/src/utils/uniqueRows.ts +40 -0
@@ -0,0 +1,265 @@
1
+ import { ERPObjType } from "../../types/erp-types";
2
+ import { BatchCacheManager } from "../../services/caching-service/batch-cache-manager";
3
+ import {
4
+ IToRESTApiObject,
5
+ MMSendPerson,
6
+ MMSendResource,
7
+ MMSendPart,
8
+ MMSendPartOperation,
9
+ MMSendWorkOrder,
10
+ MMSendWorkOrderOperation,
11
+ MMSendLaborTicket,
12
+ MMSendReason,
13
+ MMApiBaseResponse,
14
+ MM200NonLaborTicketResponse,
15
+ MM200LaborTicketResponse,
16
+ MM207NonLaborTicketResponse,
17
+ MM207LaborTicketResponse,
18
+ } from "../../services/mm-api-service";
19
+ import { MMApiClient } from "../../services/mm-api-service/mm-api-service";
20
+ import { HTTPError } from "../http-client";
21
+ import {
22
+ WriteEntitiesToMMResult,
23
+ MMBatchValidationError,
24
+ } from "./standard-process-drivers";
25
+ import { ErrorProcessor } from "./error-processor";
26
+
27
+ /**
28
+ * Handles processing of entities to the MachineMetrics API
29
+ */
30
+ export class MMEntityProcessor {
31
+ /**
32
+ * Writes entities to MM API with deduplication and caching
33
+ */
34
+ static async writeEntities(
35
+ entityType: ERPObjType,
36
+ mmRecords: IToRESTApiObject[],
37
+ batchCacheManager: BatchCacheManager | null
38
+ ): Promise<WriteEntitiesToMMResult> {
39
+ const { toProcess, result } = await this._prepareAndDedupe(
40
+ entityType,
41
+ mmRecords,
42
+ batchCacheManager
43
+ );
44
+
45
+ if (toProcess.length === 0) {
46
+ result.message =
47
+ "All records were deduplicated locally - no records sent to MM API";
48
+ return result;
49
+ }
50
+
51
+ let mmApiResponse: MMApiBaseResponse;
52
+ try {
53
+ mmApiResponse = await this._sendToAPI(entityType, toProcess);
54
+ } catch (exception) {
55
+ this._handleException(exception, entityType, result);
56
+ }
57
+
58
+ return await this._handleResponse(
59
+ mmApiResponse,
60
+ entityType,
61
+ toProcess,
62
+ result,
63
+ batchCacheManager
64
+ );
65
+ }
66
+
67
+ // ============================================================================
68
+ // PRIVATE HELPER METHODS
69
+ // ============================================================================
70
+
71
+ /**
72
+ * Deduplicates records against cache
73
+ * Returns the records to process and the result object
74
+ * If the batchCacheManager is provided, the records are deduplicated against the cache
75
+ * If the batchCacheManager is not provided, the records are not deduplicated
76
+ */
77
+ private static async _prepareAndDedupe(
78
+ entityType: ERPObjType,
79
+ mmRecords: IToRESTApiObject[],
80
+ batchCacheManager: BatchCacheManager | null
81
+ ): Promise<{
82
+ toProcess: IToRESTApiObject[];
83
+ result: WriteEntitiesToMMResult;
84
+ }> {
85
+ let toProcess: IToRESTApiObject[] = [];
86
+ const result: WriteEntitiesToMMResult = {
87
+ message: "",
88
+ upsertedEntities: 0,
89
+ localDedupeCount: 0,
90
+ apiDedupeCount: 0,
91
+ };
92
+
93
+ if (batchCacheManager) {
94
+ const { nonDuplicates, duplicates } =
95
+ (await batchCacheManager.dedupeBatch(entityType, mmRecords)) as {
96
+ nonDuplicates: IToRESTApiObject[];
97
+ duplicates: IToRESTApiObject[];
98
+ };
99
+ toProcess = nonDuplicates;
100
+ result.localDedupeCount = duplicates.length;
101
+ } else {
102
+ toProcess = mmRecords;
103
+ }
104
+
105
+ return { toProcess, result };
106
+ }
107
+
108
+ /**
109
+ * Sends records to MM API
110
+ */
111
+ private static async _sendToAPI(
112
+ entityType: ERPObjType,
113
+ toProcess: IToRESTApiObject[]
114
+ ): Promise<MMApiBaseResponse> {
115
+ const mmApiClient = new MMApiClient();
116
+
117
+ switch (entityType) {
118
+ case ERPObjType.PERSONS:
119
+ return await mmApiClient.sendPersonsToMM(toProcess as MMSendPerson[]);
120
+ case ERPObjType.RESOURCES:
121
+ return await mmApiClient.sendResourcesToMM(
122
+ toProcess as MMSendResource[]
123
+ );
124
+ case ERPObjType.PARTS:
125
+ return await mmApiClient.sendPartsToMM(toProcess as MMSendPart[]);
126
+ case ERPObjType.PART_OPERATION:
127
+ return await mmApiClient.sendPartOperationsToMM(
128
+ toProcess as MMSendPartOperation[]
129
+ );
130
+ case ERPObjType.WORK_ORDERS:
131
+ return await mmApiClient.sendWorkOrdersToMM(
132
+ toProcess as MMSendWorkOrder[]
133
+ );
134
+ case ERPObjType.WORK_ORDER_OPERATIONS:
135
+ return await mmApiClient.sendWorkOrderOperationsToMM(
136
+ toProcess as MMSendWorkOrderOperation[]
137
+ );
138
+ case ERPObjType.LABOR_TICKETS:
139
+ return await mmApiClient.sendLaborTicketsToMM(
140
+ toProcess as MMSendLaborTicket[]
141
+ );
142
+ case ERPObjType.REASONS:
143
+ return await mmApiClient.sendReasonsToMM(toProcess as MMSendReason[]);
144
+ default:
145
+ throw new Error(`Unknown entity type: ${entityType}`);
146
+ }
147
+ }
148
+
149
+ /**
150
+ * Handles exceptions from API calls, converting structured 500 errors to MMBatchValidationError
151
+ * @throws MMBatchValidationError for structured 500 errors
152
+ * @throws The original exception for all other errors
153
+ */
154
+ private static _handleException(
155
+ exception: unknown,
156
+ entityType: ERPObjType,
157
+ result: WriteEntitiesToMMResult
158
+ ): never {
159
+ // Handle structured 500 errors that may be appropriate for partial failure
160
+ const structuredCompleteErrorSet =
161
+ ErrorProcessor.extractErrorDetailsFrom500Exception(exception, entityType);
162
+
163
+ if (structuredCompleteErrorSet) {
164
+ const ex = exception as Record<string, unknown>;
165
+ const data = ex?.data as Record<string, unknown>;
166
+ const errorMessage =
167
+ typeof data?.error === "string"
168
+ ? data.error
169
+ : "All entities failed to import";
170
+
171
+ throw new MMBatchValidationError({
172
+ message: errorMessage,
173
+ upsertedEntities: 0,
174
+ localDedupeCount: result.localDedupeCount,
175
+ apiDedupeCount: 0,
176
+ errorCount: structuredCompleteErrorSet.errorCount,
177
+ httpStatus: (exception as HTTPError).status,
178
+ batchErrors: structuredCompleteErrorSet.batchErrors,
179
+ });
180
+ }
181
+
182
+ // For all other exceptions, re-throw as-is
183
+ throw exception;
184
+ }
185
+
186
+ /**
187
+ * Handles the MM API response based on HTTP status code, caching successful records
188
+ * and throwing exceptions for partial failures
189
+ *
190
+ * @returns The final result for success cases
191
+ * @throws MMBatchValidationError for partial success cases
192
+ * @throws Error for unknown status codes
193
+ */
194
+ private static async _handleResponse(
195
+ mmApiResponse: MMApiBaseResponse,
196
+ entityType: ERPObjType,
197
+ toProcess: IToRESTApiObject[],
198
+ result: WriteEntitiesToMMResult,
199
+ batchCacheManager: BatchCacheManager | null
200
+ ): Promise<WriteEntitiesToMMResult> {
201
+ if (mmApiResponse.httpStatus === 200) {
202
+ // Complete success - cache all records
203
+ if (batchCacheManager) {
204
+ await batchCacheManager.storeBatch(entityType, toProcess);
205
+ }
206
+
207
+ if (entityType === ERPObjType.LABOR_TICKETS) {
208
+ const success = mmApiResponse as MM200LaborTicketResponse;
209
+ result.message = success.message || "Entities processed successfully";
210
+ result.upsertedEntities =
211
+ (success.updated || 0) + (success.inserted || 0);
212
+ } else {
213
+ const success = mmApiResponse as MM200NonLaborTicketResponse;
214
+ result.message = success.message || "Entities processed successfully";
215
+ result.upsertedEntities = success.affectedRows || 0;
216
+ }
217
+ result.apiDedupeCount = toProcess.length - result.upsertedEntities;
218
+
219
+ return result;
220
+ } else if (mmApiResponse.httpStatus === 207) {
221
+ // Partial success - cache only successful records before throwing exception
222
+ const partialResponse = mmApiResponse as
223
+ | MM207NonLaborTicketResponse
224
+ | MM207LaborTicketResponse;
225
+ const { errorCount, batchErrors } = ErrorProcessor.extractErrorDetails(
226
+ partialResponse,
227
+ entityType
228
+ );
229
+
230
+ if (batchCacheManager) {
231
+ await ErrorProcessor.cacheSuccessfulRecordsOnPartialFailure(
232
+ entityType,
233
+ toProcess,
234
+ batchErrors,
235
+ batchCacheManager
236
+ );
237
+ }
238
+
239
+ let upsertedEntities = 0;
240
+ if (entityType === ERPObjType.LABOR_TICKETS) {
241
+ const partial = partialResponse as MM207LaborTicketResponse;
242
+ upsertedEntities =
243
+ (partial.data.updated || 0) + (partial.data.inserted || 0);
244
+ } else {
245
+ const partial = partialResponse as MM207NonLaborTicketResponse;
246
+ upsertedEntities = partial.data.affectedRows || 0;
247
+ }
248
+
249
+ throw new MMBatchValidationError({
250
+ message:
251
+ partialResponse.message || "Entities processed with partial failures",
252
+ upsertedEntities: upsertedEntities,
253
+ localDedupeCount: result.localDedupeCount,
254
+ apiDedupeCount: toProcess.length - upsertedEntities - errorCount,
255
+ errorCount: errorCount,
256
+ httpStatus: mmApiResponse.httpStatus,
257
+ batchErrors: batchErrors,
258
+ });
259
+ } else {
260
+ throw new Error(
261
+ `writeEntitiesToMM: Unknown HTTP status code: ${mmApiResponse.httpStatus}. An exception was expected.`
262
+ );
263
+ }
264
+ }
265
+ }