@machinemetrics/mm-erp-sdk 0.2.0-beta.2 → 0.3.0-beta.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.
- package/README.md +5 -0
- package/dist/index.d.ts +42 -43
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +48 -0
- package/dist/index.js.map +1 -0
- package/dist/knexfile.d.ts.map +1 -1
- package/dist/knexfile.js +19 -0
- package/dist/knexfile.js.map +1 -0
- package/dist/migrations/20241015162631_create_cache_table.d.ts +4 -0
- package/dist/migrations/20241015162631_create_cache_table.d.ts.map +1 -0
- package/dist/migrations/20241015162631_create_cache_table.js +11 -15
- package/dist/migrations/20241015162631_create_cache_table.js.map +1 -1
- package/dist/migrations/20241015162632_create_sdk_cache_table.d.ts +4 -0
- package/dist/migrations/20241015162632_create_sdk_cache_table.d.ts.map +1 -0
- package/dist/migrations/20241015162632_create_sdk_cache_table.js +11 -15
- package/dist/migrations/20241015162632_create_sdk_cache_table.js.map +1 -1
- package/dist/migrations/20250103162631_create_record_tracking_table.d.ts +4 -0
- package/dist/migrations/20250103162631_create_record_tracking_table.d.ts.map +1 -0
- package/dist/migrations/20250103162631_create_record_tracking_table.js +14 -15
- package/dist/migrations/20250103162631_create_record_tracking_table.js.map +1 -1
- package/dist/services/caching-service/batch-cache-manager.d.ts +1 -1
- package/dist/services/caching-service/batch-cache-manager.d.ts.map +1 -1
- package/dist/services/caching-service/batch-cache-manager.js +84 -0
- package/dist/services/caching-service/batch-cache-manager.js.map +1 -0
- package/dist/services/caching-service/hashed-cache-manager.d.ts +2 -2
- package/dist/services/caching-service/hashed-cache-manager.d.ts.map +1 -1
- package/dist/services/caching-service/hashed-cache-manager.js +223 -0
- package/dist/services/caching-service/hashed-cache-manager.js.map +1 -0
- package/dist/services/caching-service/index.d.ts +1 -1
- package/dist/services/caching-service/index.d.ts.map +1 -1
- package/dist/services/caching-service/index.js +2 -0
- package/dist/services/caching-service/index.js.map +1 -0
- package/dist/services/caching-service/record-tracking-manager.d.ts +1 -1
- package/dist/services/caching-service/record-tracking-manager.d.ts.map +1 -1
- package/dist/services/caching-service/record-tracking-manager.js +28 -0
- package/dist/services/caching-service/record-tracking-manager.js.map +1 -0
- package/dist/services/data-sync-service/configuration-manager.d.ts +1 -1
- package/dist/services/data-sync-service/configuration-manager.d.ts.map +1 -1
- package/dist/services/data-sync-service/configuration-manager.js +163 -0
- package/dist/services/data-sync-service/configuration-manager.js.map +1 -0
- package/dist/services/data-sync-service/data-sync-service.d.ts.map +1 -1
- package/dist/services/data-sync-service/data-sync-service.js +95 -0
- package/dist/services/data-sync-service/data-sync-service.js.map +1 -0
- package/dist/services/data-sync-service/index.d.ts +3 -3
- package/dist/services/data-sync-service/index.d.ts.map +1 -1
- package/dist/services/data-sync-service/index.js +10 -0
- package/dist/services/data-sync-service/index.js.map +1 -0
- package/dist/services/data-sync-service/jobs/clean-up-expired-cache.d.ts.map +1 -1
- package/dist/services/data-sync-service/jobs/clean-up-expired-cache.js +42 -40
- package/dist/services/data-sync-service/jobs/clean-up-expired-cache.js.map +1 -1
- package/dist/services/data-sync-service/jobs/from-erp.d.ts.map +1 -1
- package/dist/services/data-sync-service/jobs/from-erp.js +50 -37
- package/dist/services/data-sync-service/jobs/from-erp.js.map +1 -1
- package/dist/services/data-sync-service/jobs/retry-failed-labor-tickets.d.ts.map +1 -1
- package/dist/services/data-sync-service/jobs/retry-failed-labor-tickets.js +38 -36
- package/dist/services/data-sync-service/jobs/retry-failed-labor-tickets.js.map +1 -1
- package/dist/services/data-sync-service/jobs/run-migrations.d.ts.map +1 -1
- package/dist/services/data-sync-service/jobs/run-migrations.js +24 -22
- package/dist/services/data-sync-service/jobs/run-migrations.js.map +1 -1
- package/dist/services/data-sync-service/jobs/to-erp.d.ts.map +1 -1
- package/dist/services/data-sync-service/jobs/to-erp.js +49 -49
- package/dist/services/data-sync-service/jobs/to-erp.js.map +1 -1
- package/dist/services/erp-api-services/errors.d.ts +1 -1
- package/dist/services/erp-api-services/errors.d.ts.map +1 -1
- package/dist/services/erp-api-services/errors.js +83 -0
- package/dist/services/erp-api-services/errors.js.map +1 -0
- package/dist/services/erp-api-services/graphql/graphql-service.d.ts +2 -2
- package/dist/services/erp-api-services/graphql/graphql-service.d.ts.map +1 -1
- package/dist/services/erp-api-services/graphql/graphql-service.js +102 -0
- package/dist/services/erp-api-services/graphql/graphql-service.js.map +1 -0
- package/dist/services/erp-api-services/graphql/types.js +6 -0
- package/dist/services/erp-api-services/graphql/types.js.map +1 -0
- package/dist/services/erp-api-services/index.d.ts +8 -8
- package/dist/services/erp-api-services/index.d.ts.map +1 -1
- package/dist/services/erp-api-services/index.js +13 -0
- package/dist/services/erp-api-services/index.js.map +1 -0
- package/dist/services/erp-api-services/oauth-client.js +41 -0
- package/dist/services/erp-api-services/oauth-client.js.map +1 -0
- package/dist/services/erp-api-services/rest/get-query-params.js +23 -0
- package/dist/services/erp-api-services/rest/get-query-params.js.map +1 -0
- package/dist/services/erp-api-services/rest/rest-api-service.d.ts +2 -2
- package/dist/services/erp-api-services/rest/rest-api-service.d.ts.map +1 -1
- package/dist/services/erp-api-services/rest/rest-api-service.js +163 -0
- package/dist/services/erp-api-services/rest/rest-api-service.js.map +1 -0
- package/dist/services/erp-api-services/types.d.ts +2 -2
- package/dist/services/erp-api-services/types.d.ts.map +1 -1
- package/dist/services/erp-api-services/types.js +2 -0
- package/dist/services/erp-api-services/types.js.map +1 -0
- package/dist/services/mm-api-service/index.d.ts +6 -13
- package/dist/services/mm-api-service/index.d.ts.map +1 -1
- package/dist/services/mm-api-service/index.js +15 -0
- package/dist/services/mm-api-service/index.js.map +1 -0
- package/dist/services/mm-api-service/mm-api-service.d.ts +7 -13
- package/dist/services/mm-api-service/mm-api-service.d.ts.map +1 -1
- package/dist/services/mm-api-service/mm-api-service.js +519 -0
- package/dist/services/mm-api-service/mm-api-service.js.map +1 -0
- package/dist/services/mm-api-service/token-mgr.js +113 -0
- package/dist/services/mm-api-service/token-mgr.js.map +1 -0
- package/dist/services/mm-api-service/types/checkpoint.js +2 -0
- package/dist/services/mm-api-service/types/checkpoint.js.map +1 -0
- package/dist/services/mm-api-service/types/entity-transformer.d.ts +2 -2
- package/dist/services/mm-api-service/types/entity-transformer.d.ts.map +1 -1
- package/dist/services/mm-api-service/types/entity-transformer.js +186 -0
- package/dist/services/mm-api-service/types/entity-transformer.js.map +1 -0
- package/dist/services/mm-api-service/types/mm-response-interfaces.js +34 -0
- package/dist/services/mm-api-service/types/mm-response-interfaces.js.map +1 -0
- package/dist/services/mm-api-service/types/receive-types.d.ts +0 -3
- package/dist/services/mm-api-service/types/receive-types.d.ts.map +1 -1
- package/dist/services/mm-api-service/types/receive-types.js +55 -0
- package/dist/services/mm-api-service/types/receive-types.js.map +1 -0
- package/dist/services/mm-api-service/types/send-types.js +337 -0
- package/dist/services/mm-api-service/types/send-types.js.map +1 -0
- package/dist/services/psql-erp-service/configuration.js +2 -0
- package/dist/services/psql-erp-service/configuration.js.map +1 -0
- package/dist/services/psql-erp-service/index.d.ts +3 -3
- package/dist/services/psql-erp-service/index.d.ts.map +1 -1
- package/dist/services/psql-erp-service/index.js +10 -0
- package/dist/services/psql-erp-service/index.js.map +1 -0
- package/dist/services/psql-erp-service/internal/types/psql-types.js +5 -0
- package/dist/services/psql-erp-service/internal/types/psql-types.js.map +1 -0
- package/dist/services/psql-erp-service/psql-helpers.js +99 -0
- package/dist/services/psql-erp-service/psql-helpers.js.map +1 -0
- package/dist/services/psql-erp-service/psql-service.d.ts +2 -2
- package/dist/services/psql-erp-service/psql-service.d.ts.map +1 -1
- package/dist/services/psql-erp-service/psql-service.js +187 -0
- package/dist/services/psql-erp-service/psql-service.js.map +1 -0
- package/dist/services/reporting-service/index.d.ts +1 -1
- package/dist/services/reporting-service/index.d.ts.map +1 -1
- package/dist/services/reporting-service/index.js +5 -0
- package/dist/services/reporting-service/index.js.map +1 -0
- package/dist/services/reporting-service/logger.d.ts.map +1 -1
- package/dist/services/reporting-service/logger.js +221 -0
- package/dist/services/reporting-service/logger.js.map +1 -0
- package/dist/services/sql-server-erp-service/configuration.js +2 -0
- package/dist/services/sql-server-erp-service/configuration.js.map +1 -0
- package/dist/services/sql-server-erp-service/index.d.ts +3 -3
- package/dist/services/sql-server-erp-service/index.d.ts.map +1 -1
- package/dist/services/sql-server-erp-service/index.js +11 -0
- package/dist/services/sql-server-erp-service/index.js.map +1 -0
- package/dist/services/sql-server-erp-service/internal/sql-labor-ticket-operations.d.ts +2 -2
- package/dist/services/sql-server-erp-service/internal/sql-labor-ticket-operations.d.ts.map +1 -1
- package/dist/services/sql-server-erp-service/internal/sql-labor-ticket-operations.js +50 -0
- package/dist/services/sql-server-erp-service/internal/sql-labor-ticket-operations.js.map +1 -0
- package/dist/services/sql-server-erp-service/internal/sql-server-config.js +40 -0
- package/dist/services/sql-server-erp-service/internal/sql-server-config.js.map +1 -0
- package/dist/services/sql-server-erp-service/internal/sql-transaction-manager.js +36 -0
- package/dist/services/sql-server-erp-service/internal/sql-transaction-manager.js.map +1 -0
- package/dist/services/sql-server-erp-service/internal/types/sql-server-types.js +2 -0
- package/dist/services/sql-server-erp-service/internal/types/sql-server-types.js.map +1 -0
- package/dist/services/sql-server-erp-service/sql-server-helpers.d.ts +3 -3
- package/dist/services/sql-server-erp-service/sql-server-helpers.d.ts.map +1 -1
- package/dist/services/sql-server-erp-service/sql-server-helpers.js +66 -0
- package/dist/services/sql-server-erp-service/sql-server-helpers.js.map +1 -0
- package/dist/services/sql-server-erp-service/sql-server-service.d.ts +2 -2
- package/dist/services/sql-server-erp-service/sql-server-service.d.ts.map +1 -1
- package/dist/services/sql-server-erp-service/sql-server-service.js +154 -0
- package/dist/services/sql-server-erp-service/sql-server-service.js.map +1 -0
- package/dist/services/sql-server-erp-service/types/sql-input-param.js +2 -0
- package/dist/services/sql-server-erp-service/types/sql-input-param.js.map +1 -0
- package/dist/services/sqlite-service/index.d.ts +1 -1
- package/dist/services/sqlite-service/index.d.ts.map +1 -1
- package/dist/services/sqlite-service/index.js +2 -0
- package/dist/services/sqlite-service/index.js.map +1 -0
- package/dist/services/sqlite-service/sqlite-coordinator.js +60 -0
- package/dist/services/sqlite-service/sqlite-coordinator.js.map +1 -0
- package/dist/types/erp-connector.d.ts +9 -2
- package/dist/types/erp-connector.d.ts.map +1 -1
- package/dist/types/erp-connector.js +2 -0
- package/dist/types/erp-connector.js.map +1 -0
- package/dist/types/erp-types.js +13 -0
- package/dist/types/erp-types.js.map +1 -0
- package/dist/types/flattened-work-order.d.ts +99 -0
- package/dist/types/flattened-work-order.d.ts.map +1 -0
- package/dist/types/flattened-work-order.js +2 -0
- package/dist/types/flattened-work-order.js.map +1 -0
- package/dist/types/index.d.ts +3 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/application-initializer.js +55 -0
- package/dist/utils/application-initializer.js.map +1 -0
- package/dist/utils/cleanup-numbers.js +6 -0
- package/dist/utils/cleanup-numbers.js.map +1 -0
- package/dist/utils/connector-factory.d.ts +1 -1
- package/dist/utils/connector-factory.d.ts.map +1 -1
- package/dist/utils/connector-factory.js +34 -0
- package/dist/utils/connector-factory.js.map +1 -0
- package/dist/utils/connector-log/log-deduper.d.ts +1 -1
- package/dist/utils/connector-log/log-deduper.d.ts.map +1 -1
- package/dist/utils/connector-log/log-deduper.js +240 -0
- package/dist/utils/connector-log/log-deduper.js.map +1 -0
- package/dist/utils/connector-log/mm-connector-logger-example.d.ts +1 -0
- package/dist/utils/connector-log/mm-connector-logger-example.js +88 -0
- package/dist/utils/connector-log/mm-connector-logger-example.js.map +1 -0
- package/dist/utils/connector-log/mm-connector-logger.d.ts +1 -1
- package/dist/utils/connector-log/mm-connector-logger.d.ts.map +1 -1
- package/dist/utils/connector-log/mm-connector-logger.js +151 -0
- package/dist/utils/connector-log/mm-connector-logger.js.map +1 -0
- package/dist/utils/data-transformation.js +38 -0
- package/dist/utils/data-transformation.js.map +1 -0
- package/dist/utils/env.d.ts +8 -0
- package/dist/utils/env.d.ts.map +1 -0
- package/dist/utils/env.js +58 -0
- package/dist/utils/env.js.map +1 -0
- package/dist/utils/erp-timezone-utils.d.ts +20 -0
- package/dist/utils/erp-timezone-utils.d.ts.map +1 -0
- package/dist/utils/erp-timezone-utils.js +75 -0
- package/dist/utils/erp-timezone-utils.js.map +1 -0
- package/dist/utils/erp-type-from-entity.d.ts +1 -1
- package/dist/utils/erp-type-from-entity.d.ts.map +1 -1
- package/dist/utils/erp-type-from-entity.js +6 -0
- package/dist/utils/erp-type-from-entity.js.map +1 -0
- package/dist/utils/error-utils.js +21 -0
- package/dist/utils/error-utils.js.map +1 -0
- package/dist/utils/http-client.js +189 -0
- package/dist/utils/http-client.js.map +1 -0
- package/dist/utils/index.d.ts +34 -38
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +66 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/local-data-store/database-lock.js +68 -0
- package/dist/utils/local-data-store/database-lock.js.map +1 -0
- package/dist/utils/local-data-store/jobs-shared-data.d.ts +2 -0
- package/dist/utils/local-data-store/jobs-shared-data.d.ts.map +1 -1
- package/dist/utils/local-data-store/jobs-shared-data.js +118 -0
- package/dist/utils/local-data-store/jobs-shared-data.js.map +1 -0
- package/dist/utils/mm-labor-ticket-helpers.d.ts +4 -5
- package/dist/utils/mm-labor-ticket-helpers.d.ts.map +1 -1
- package/dist/utils/mm-labor-ticket-helpers.js +28 -0
- package/dist/utils/mm-labor-ticket-helpers.js.map +1 -0
- package/dist/utils/removeExtraneousFields.d.ts +1 -1
- package/dist/utils/removeExtraneousFields.d.ts.map +1 -1
- package/dist/utils/removeExtraneousFields.js +16 -0
- package/dist/utils/removeExtraneousFields.js.map +1 -0
- package/dist/utils/removeIdFieldFromPayload.d.ts +1 -1
- package/dist/utils/removeIdFieldFromPayload.d.ts.map +1 -1
- package/dist/utils/removeIdFieldFromPayload.js +16 -0
- package/dist/utils/removeIdFieldFromPayload.js.map +1 -0
- package/dist/utils/resource-group.d.ts +1 -1
- package/dist/utils/resource-group.d.ts.map +1 -1
- package/dist/utils/resource-group.js +59 -0
- package/dist/utils/resource-group.js.map +1 -0
- package/dist/utils/standard-process-drivers/error-processor.d.ts +3 -3
- package/dist/utils/standard-process-drivers/error-processor.d.ts.map +1 -1
- package/dist/utils/standard-process-drivers/error-processor.js +262 -0
- package/dist/utils/standard-process-drivers/error-processor.js.map +1 -0
- package/dist/utils/standard-process-drivers/index.d.ts +3 -3
- package/dist/utils/standard-process-drivers/index.d.ts.map +1 -1
- package/dist/utils/standard-process-drivers/index.js +4 -0
- package/dist/utils/standard-process-drivers/index.js.map +1 -0
- package/dist/utils/standard-process-drivers/labor-ticket-erp-synchronizer.d.ts +16 -1
- package/dist/utils/standard-process-drivers/labor-ticket-erp-synchronizer.d.ts.map +1 -1
- package/dist/utils/standard-process-drivers/labor-ticket-erp-synchronizer.js +299 -0
- package/dist/utils/standard-process-drivers/labor-ticket-erp-synchronizer.js.map +1 -0
- package/dist/utils/standard-process-drivers/mm-entity-processor.d.ts +11 -5
- package/dist/utils/standard-process-drivers/mm-entity-processor.d.ts.map +1 -1
- package/dist/utils/standard-process-drivers/mm-entity-processor.js +174 -0
- package/dist/utils/standard-process-drivers/mm-entity-processor.js.map +1 -0
- package/dist/utils/standard-process-drivers/standard-process-drivers.d.ts +12 -6
- package/dist/utils/standard-process-drivers/standard-process-drivers.d.ts.map +1 -1
- package/dist/utils/standard-process-drivers/standard-process-drivers.js +333 -0
- package/dist/utils/standard-process-drivers/standard-process-drivers.js.map +1 -0
- package/dist/utils/time-utils.d.ts.map +1 -1
- package/dist/utils/time-utils.js +103 -0
- package/dist/utils/time-utils.js.map +1 -0
- package/dist/utils/timezone.js +105 -0
- package/dist/utils/timezone.js.map +1 -0
- package/dist/utils/trimObjectValues.js +11 -0
- package/dist/utils/trimObjectValues.js.map +1 -0
- package/dist/utils/uniqueRows.js +35 -0
- package/dist/utils/uniqueRows.js.map +1 -0
- package/package.json +8 -10
- package/src/index.ts +42 -45
- package/src/knexfile.ts +1 -0
- package/src/services/caching-service/batch-cache-manager.ts +2 -2
- package/src/services/caching-service/hashed-cache-manager.ts +5 -5
- package/src/services/caching-service/index.ts +1 -1
- package/src/services/caching-service/record-tracking-manager.ts +2 -2
- package/src/services/data-sync-service/configuration-manager.ts +52 -39
- package/src/services/data-sync-service/data-sync-service.ts +10 -19
- package/src/services/data-sync-service/index.ts +3 -3
- package/src/services/data-sync-service/jobs/clean-up-expired-cache.ts +5 -4
- package/src/services/data-sync-service/jobs/from-erp.ts +12 -6
- package/src/services/data-sync-service/jobs/retry-failed-labor-tickets.ts +4 -3
- package/src/services/data-sync-service/jobs/run-migrations.ts +4 -3
- package/src/services/data-sync-service/jobs/to-erp.ts +5 -14
- package/src/services/erp-api-services/errors.ts +3 -3
- package/src/services/erp-api-services/graphql/graphql-service.ts +5 -5
- package/src/services/erp-api-services/index.ts +8 -8
- package/src/services/erp-api-services/rest/rest-api-service.ts +4 -4
- package/src/services/erp-api-services/types.ts +2 -2
- package/src/services/mm-api-service/index.ts +6 -14
- package/src/services/mm-api-service/mm-api-service.ts +13 -30
- package/src/services/mm-api-service/token-mgr.ts +4 -4
- package/src/services/mm-api-service/types/entity-transformer.ts +3 -3
- package/src/services/mm-api-service/types/receive-types.ts +0 -1
- package/src/services/psql-erp-service/index.ts +3 -3
- package/src/services/psql-erp-service/psql-service.ts +4 -4
- package/src/services/reporting-service/index.ts +1 -1
- package/src/services/reporting-service/logger.ts +116 -81
- package/src/services/sql-server-erp-service/index.ts +3 -3
- package/src/services/sql-server-erp-service/internal/sql-labor-ticket-operations.ts +2 -2
- package/src/services/sql-server-erp-service/internal/sql-transaction-manager.ts +1 -1
- package/src/services/sql-server-erp-service/sql-server-helpers.ts +6 -6
- package/src/services/sql-server-erp-service/sql-server-service.ts +4 -4
- package/src/services/sqlite-service/index.ts +1 -1
- package/src/services/sqlite-service/sqlite-coordinator.ts +2 -2
- package/src/types/erp-connector.ts +9 -2
- package/src/types/flattened-work-order.ts +108 -0
- package/src/types/index.ts +10 -2
- package/src/utils/application-initializer.ts +5 -5
- package/src/utils/connector-factory.ts +2 -2
- package/src/utils/connector-log/log-deduper.ts +2 -2
- package/src/utils/connector-log/mm-connector-logger.ts +3 -3
- package/src/utils/env.ts +75 -0
- package/src/utils/erp-timezone-utils.ts +99 -0
- package/src/utils/erp-type-from-entity.ts +1 -1
- package/src/utils/http-client.ts +5 -4
- package/src/utils/index.ts +38 -39
- package/src/utils/local-data-store/database-lock.ts +1 -1
- package/src/utils/local-data-store/jobs-shared-data.ts +2 -0
- package/src/utils/mm-labor-ticket-helpers.ts +12 -9
- package/src/utils/removeExtraneousFields.ts +1 -1
- package/src/utils/removeIdFieldFromPayload.ts +1 -1
- package/src/utils/resource-group.ts +2 -2
- package/src/utils/standard-process-drivers/error-processor.ts +5 -5
- package/src/utils/standard-process-drivers/index.ts +3 -3
- package/src/utils/standard-process-drivers/labor-ticket-erp-synchronizer.ts +225 -69
- package/src/utils/standard-process-drivers/mm-entity-processor.ts +14 -8
- package/src/utils/standard-process-drivers/standard-process-drivers.ts +39 -25
- package/src/utils/time-utils.ts +14 -3
- package/src/utils/timezone.ts +2 -2
- package/dist/config-CvA-mFWF.js +0 -418
- package/dist/config-CvA-mFWF.js.map +0 -1
- package/dist/connector-factory-BPm2GVVF.js +0 -30
- package/dist/connector-factory-BPm2GVVF.js.map +0 -1
- package/dist/hashed-cache-manager-B15NN8hK.js +0 -322
- package/dist/hashed-cache-manager-B15NN8hK.js.map +0 -1
- package/dist/index-D8qO1NyK.js +0 -192
- package/dist/index-D8qO1NyK.js.map +0 -1
- package/dist/knexfile-Bng2Ru9c.js +0 -20
- package/dist/knexfile-Bng2Ru9c.js.map +0 -1
- package/dist/logger-BWw0_z9q.js +0 -17557
- package/dist/logger-BWw0_z9q.js.map +0 -1
- package/dist/mm-erp-sdk.js +0 -4978
- package/dist/mm-erp-sdk.js.map +0 -1
- package/dist/services/data-sync-service/nats-labor-ticket-listener.d.ts +0 -30
- package/dist/services/data-sync-service/nats-labor-ticket-listener.d.ts.map +0 -1
- package/dist/services/mm-api-service/company-info.d.ts +0 -13
- package/dist/services/mm-api-service/company-info.d.ts.map +0 -1
- package/dist/services/nats-service/nats-service.d.ts +0 -114
- package/dist/services/nats-service/nats-service.d.ts.map +0 -1
- package/dist/services/nats-service/test-nats-subscriber.d.ts +0 -6
- package/dist/services/nats-service/test-nats-subscriber.d.ts.map +0 -1
- package/dist/utils/error-formatter.d.ts +0 -19
- package/dist/utils/error-formatter.d.ts.map +0 -1
- package/src/services/data-sync-service/nats-labor-ticket-listener.ts +0 -341
- package/src/services/mm-api-service/company-info.ts +0 -87
- package/src/services/nats-service/nats-service.ts +0 -351
- package/src/services/nats-service/test-nats-subscriber.ts +0 -96
- package/src/utils/error-formatter.ts +0 -205
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
import { IERPLaborTicketHandler } from "../../types/erp-connector";
|
|
2
|
-
import { MMApiClient } from "../../services/mm-api-service/mm-api-service";
|
|
3
|
-
import { MMReceiveLaborTicket } from "../../services/mm-api-service/types/receive-types";
|
|
4
|
-
import { convertLaborTicketToLocalTimezone } from "../mm-labor-ticket-helpers";
|
|
5
|
-
import
|
|
6
|
-
import logger from "../../services/reporting-service/logger";
|
|
1
|
+
import { IERPLaborTicketHandler } from "../../types/erp-connector.js";
|
|
2
|
+
import { MMApiClient } from "../../services/mm-api-service/mm-api-service.js";
|
|
3
|
+
import { MMReceiveLaborTicket } from "../../services/mm-api-service/types/receive-types.js";
|
|
4
|
+
import { convertLaborTicketToLocalTimezone } from "../mm-labor-ticket-helpers.js";
|
|
5
|
+
import logger from "../../services/reporting-service/logger.js";
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
8
|
* Handles synchronization of labor tickets between MachineMetrics and ERP systems
|
|
10
9
|
*/
|
|
11
10
|
export class LaborTicketERPSynchronizer {
|
|
11
|
+
// Small allowance to mitigate tiny clock offsets / timestamp granularity differences
|
|
12
|
+
// between the connector host and MM's timestamps.
|
|
13
|
+
private static readonly CHECKPOINT_SKEW_MS = 2_000;
|
|
14
|
+
|
|
12
15
|
/**
|
|
13
16
|
* Synchronizes updated labor tickets from MachineMetrics to an ERP system
|
|
14
17
|
*/
|
|
@@ -18,9 +21,9 @@ export class LaborTicketERPSynchronizer {
|
|
|
18
21
|
): Promise<void> {
|
|
19
22
|
try {
|
|
20
23
|
const mmApiClient = new MMApiClient();
|
|
21
|
-
const failedLaborTicketRefs
|
|
24
|
+
const failedLaborTicketRefs = new Set<string>();
|
|
25
|
+
const attemptedSignatures = new Set<string>();
|
|
22
26
|
|
|
23
|
-
// Initialize and fetch checkpoint (quick operations, don't need prolonged lock)
|
|
24
27
|
await mmApiClient.initializeCheckpoint({
|
|
25
28
|
system: connectorType,
|
|
26
29
|
table: "labor_tickets",
|
|
@@ -30,95 +33,168 @@ export class LaborTicketERPSynchronizer {
|
|
|
30
33
|
},
|
|
31
34
|
});
|
|
32
35
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
/**
|
|
37
|
+
* We cannot safely checkpoint to "now" without draining, because updates can arrive mid-run.
|
|
38
|
+
* And we cannot checkpoint to "most recent updatedAt from the initial fetch" because we
|
|
39
|
+
* update MM (setting laborTicketId on creates), which bumps updatedAt and causes the same
|
|
40
|
+
* ticket to be re-pulled next cycle.
|
|
41
|
+
*
|
|
42
|
+
* We also cannot dedupe only by laborTicketRef, because the same ticket can legitimately
|
|
43
|
+
* change multiple times within a single run (parts counts, times, reasons, state, etc.).
|
|
44
|
+
* And we cannot dedupe by (laborTicketRef, updatedAt) because updatedAt is exactly what our
|
|
45
|
+
* own MM write-back (setting laborTicketId) mutates, creating a false "new version".
|
|
46
|
+
*
|
|
47
|
+
* Remedy: drain the window up to a moving barrier time (local "now"), re-fetching until MM
|
|
48
|
+
* reports no additional unattempted tickets in that window, and dedupe within the run by a
|
|
49
|
+
* stable business signature (operational fields only; excludes metadata like updatedAt and
|
|
50
|
+
* excludes SDK-mutated fields like laborTicketId). Then checkpoint to a value that is not
|
|
51
|
+
* meaningfully ahead of MM's own timestamps (small skew clamp).
|
|
52
|
+
*/
|
|
53
|
+
const maxPasses = 10;
|
|
54
|
+
let pass = 0;
|
|
55
|
+
let barrierTime = new Date().toISOString();
|
|
56
|
+
let maxMmTimestampWithinBarrier: string | null = null;
|
|
38
57
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
58
|
+
while (pass < maxPasses) {
|
|
59
|
+
pass += 1;
|
|
60
|
+
barrierTime = new Date().toISOString();
|
|
43
61
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
62
|
+
const laborTicketsUpdates = await mmApiClient.fetchLaborTicketUpdates({
|
|
63
|
+
system: connectorType,
|
|
64
|
+
checkpointType: "export",
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
if (laborTicketsUpdates.length === 0) {
|
|
68
|
+
if (pass === 1) {
|
|
69
|
+
logger.info("syncLaborTicketsToERP:No updated labor tickets found");
|
|
70
|
+
}
|
|
71
|
+
break;
|
|
53
72
|
}
|
|
54
|
-
);
|
|
55
73
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if (
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
74
|
+
// Track the latest MM timestamp we see that is <= the current barrier.
|
|
75
|
+
for (const ticket of laborTicketsUpdates) {
|
|
76
|
+
const ts = this.getComparableTicketTimestamp(ticket);
|
|
77
|
+
if (!ts) continue;
|
|
78
|
+
if (new Date(ts) > new Date(barrierTime)) continue;
|
|
79
|
+
if (
|
|
80
|
+
!maxMmTimestampWithinBarrier ||
|
|
81
|
+
new Date(ts) > new Date(maxMmTimestampWithinBarrier)
|
|
82
|
+
) {
|
|
83
|
+
maxMmTimestampWithinBarrier = ts;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
67
86
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
87
|
+
if (pass === 1) {
|
|
88
|
+
logger.info(
|
|
89
|
+
`ToERP: Found ${laborTicketsUpdates.length} Labor Ticket Ids and Refs to process`,
|
|
90
|
+
{
|
|
91
|
+
laborTickets: laborTicketsUpdates.map(
|
|
92
|
+
(ticket: MMReceiveLaborTicket) => ({
|
|
93
|
+
ref: ticket.laborTicketRef,
|
|
94
|
+
id: ticket.laborTicketId,
|
|
95
|
+
})
|
|
96
|
+
),
|
|
97
|
+
}
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Build a unique pending list by a stable "business signature", and only consider tickets
|
|
102
|
+
// whose timestamps are <= the barrierTime (prevents checkpoint gaps if clocks differ).
|
|
103
|
+
const pending: Array<{ sig: string; ticket: MMReceiveLaborTicket }> = [];
|
|
104
|
+
const dedupeWithinFetch = new Set<string>();
|
|
105
|
+
|
|
106
|
+
for (const ticket of laborTicketsUpdates) {
|
|
107
|
+
if (!ticket.laborTicketRef) {
|
|
71
108
|
logger.error(
|
|
72
109
|
"syncLaborTicketsToERP: laborTicketRef is not set for laborTicket pulled from MM:",
|
|
73
|
-
{ laborTicket }
|
|
110
|
+
{ laborTicket: ticket }
|
|
74
111
|
);
|
|
75
|
-
|
|
112
|
+
continue;
|
|
76
113
|
}
|
|
77
114
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
laborTicket
|
|
83
|
-
);
|
|
84
|
-
} catch (error) {
|
|
85
|
-
failedLaborTicketRefs.push(laborTicket.laborTicketRef);
|
|
86
|
-
logger.error(
|
|
87
|
-
`syncLaborTicketsToERP: Error processing laborTicketRef ${laborTicket.laborTicketRef}:`,
|
|
88
|
-
{ error }
|
|
89
|
-
);
|
|
90
|
-
return undefined;
|
|
115
|
+
const ts = this.getComparableTicketTimestamp(ticket);
|
|
116
|
+
if (ts && new Date(ts) > new Date(barrierTime)) {
|
|
117
|
+
// Defer "future" tickets (relative to local wall clock) to a later run/pass.
|
|
118
|
+
continue;
|
|
91
119
|
}
|
|
92
|
-
|
|
93
|
-
|
|
120
|
+
|
|
121
|
+
const sig = this.laborTicketBusinessSignature(ticket);
|
|
122
|
+
if (attemptedSignatures.has(sig) || dedupeWithinFetch.has(sig)) continue;
|
|
123
|
+
dedupeWithinFetch.add(sig);
|
|
124
|
+
pending.push({ sig, ticket });
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (pending.length === 0) {
|
|
128
|
+
// Nothing new to do in this barrier window; safe to checkpoint and exit.
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
logger.info(
|
|
133
|
+
`syncLaborTicketsToERP: pass=${pass}/${maxPasses}, barrier=${barrierTime}, pending=${pending.length}`
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
await Promise.all(
|
|
137
|
+
pending.map(async ({ sig, ticket }) => {
|
|
138
|
+
// Mark attempted up-front so we don't re-attempt within this run even if MM reorders.
|
|
139
|
+
attemptedSignatures.add(sig);
|
|
140
|
+
|
|
141
|
+
try {
|
|
142
|
+
return await this.processLaborTicket(connector, mmApiClient, ticket);
|
|
143
|
+
} catch (error) {
|
|
144
|
+
failedLaborTicketRefs.add(ticket.laborTicketRef);
|
|
145
|
+
logger.error(
|
|
146
|
+
`syncLaborTicketsToERP: Error processing laborTicketRef ${ticket.laborTicketRef}:`,
|
|
147
|
+
{ error }
|
|
148
|
+
);
|
|
149
|
+
return undefined;
|
|
150
|
+
}
|
|
151
|
+
})
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (pass >= maxPasses) {
|
|
156
|
+
logger.warn(
|
|
157
|
+
`syncLaborTicketsToERP: Reached max passes (${maxPasses}). Checkpointing anyway to avoid infinite loops.`
|
|
158
|
+
);
|
|
159
|
+
}
|
|
94
160
|
|
|
95
161
|
logger.info(
|
|
96
|
-
`syncLaborTicketsToERP: ${failedLaborTicketRefs.
|
|
162
|
+
`syncLaborTicketsToERP: ${failedLaborTicketRefs.size} failed labor ticket ids`
|
|
97
163
|
);
|
|
98
|
-
if (failedLaborTicketRefs.
|
|
164
|
+
if (failedLaborTicketRefs.size > 0) {
|
|
165
|
+
const failedTicketRefs = Array.from(failedLaborTicketRefs);
|
|
99
166
|
logger.info(
|
|
100
|
-
`syncLaborTicketsToERP: Reporting ${
|
|
167
|
+
`syncLaborTicketsToERP: Reporting ${failedTicketRefs.length} labor ticket failures:`,
|
|
101
168
|
{
|
|
102
|
-
failedLaborTicketRefs,
|
|
169
|
+
failedLaborTicketRefs: failedTicketRefs,
|
|
103
170
|
}
|
|
104
171
|
);
|
|
105
172
|
const addFailedResult = await mmApiClient.addFailedLaborTicketRefs(
|
|
106
173
|
connectorType,
|
|
107
|
-
|
|
174
|
+
failedTicketRefs
|
|
108
175
|
);
|
|
109
176
|
logger.info("syncLaborTicketsToERP: addFailedResult:", {
|
|
110
177
|
addFailedResult,
|
|
111
178
|
});
|
|
112
179
|
}
|
|
113
180
|
|
|
114
|
-
|
|
181
|
+
const checkpointTimestamp = this.computeCheckpointTimestamp({
|
|
182
|
+
barrierTime,
|
|
183
|
+
maxMmTimestampWithinBarrier,
|
|
184
|
+
skewMs: this.CHECKPOINT_SKEW_MS,
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
await mmApiClient.saveCheckpoint({
|
|
115
188
|
system: connectorType,
|
|
116
189
|
table: "labor_tickets",
|
|
117
190
|
checkpointType: "export",
|
|
118
191
|
checkpointValue: {
|
|
119
|
-
timestamp:
|
|
192
|
+
timestamp: checkpointTimestamp,
|
|
120
193
|
},
|
|
121
194
|
});
|
|
195
|
+
logger.info("syncLaborTicketsToERP: Checkpoint saved:", {
|
|
196
|
+
checkpointTimestamp,
|
|
197
|
+
});
|
|
122
198
|
} catch (error) {
|
|
123
199
|
logger.error("syncLaborTicketsToERP: Error:", error);
|
|
124
200
|
}
|
|
@@ -215,10 +291,10 @@ export class LaborTicketERPSynchronizer {
|
|
|
215
291
|
): Promise<MMReceiveLaborTicket> {
|
|
216
292
|
let laborTicketResult: MMReceiveLaborTicket;
|
|
217
293
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
);
|
|
294
|
+
// Convert MM's UTC timestamps into the ERP's local timezone before invoking connector code.
|
|
295
|
+
// Connector implementations should treat the incoming values as localized wall time and avoid
|
|
296
|
+
// applying any further timezone shifts.
|
|
297
|
+
laborTicketResult = convertLaborTicketToLocalTimezone(laborTicket);
|
|
222
298
|
|
|
223
299
|
logger.info(
|
|
224
300
|
`processing laborTicket, id=${laborTicket.laborTicketId}, ref=${laborTicket.laborTicketRef}`
|
|
@@ -258,4 +334,84 @@ export class LaborTicketERPSynchronizer {
|
|
|
258
334
|
|
|
259
335
|
return laborTicketResult;
|
|
260
336
|
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* A stable identity for "did the business-relevant contents of this labor ticket change?"
|
|
340
|
+
*
|
|
341
|
+
* IMPORTANT: Excludes fields that the SDK itself mutates (e.g. laborTicketId, updatedAt),
|
|
342
|
+
* otherwise we'd reprocess the write-back bump on the next cycle.
|
|
343
|
+
*/
|
|
344
|
+
private static laborTicketBusinessSignature(ticket: MMReceiveLaborTicket): string {
|
|
345
|
+
const reasons = (ticket.reasons ?? [])
|
|
346
|
+
.map((r) => {
|
|
347
|
+
const reason: any = (r as any)?.reason ?? {};
|
|
348
|
+
return (
|
|
349
|
+
reason.reasonId ??
|
|
350
|
+
reason.code ??
|
|
351
|
+
reason.reasonRef ??
|
|
352
|
+
reason.rejectReasonRef ??
|
|
353
|
+
""
|
|
354
|
+
);
|
|
355
|
+
})
|
|
356
|
+
.filter((v) => v !== "" && v !== null && v !== undefined)
|
|
357
|
+
.map(String)
|
|
358
|
+
.sort();
|
|
359
|
+
|
|
360
|
+
const signatureObject = {
|
|
361
|
+
laborTicketRef: ticket.laborTicketRef ?? null,
|
|
362
|
+
clockIn: ticket.clockIn ?? null,
|
|
363
|
+
clockOut: ticket.clockOut ?? null,
|
|
364
|
+
goodParts: ticket.goodParts ?? null,
|
|
365
|
+
badParts: ticket.badParts ?? null,
|
|
366
|
+
state: ticket.state ?? null,
|
|
367
|
+
type: ticket.type ?? null,
|
|
368
|
+
transactionDate: ticket.transactionDate ?? null,
|
|
369
|
+
workOrderId: ticket.workOrderId ?? null,
|
|
370
|
+
sequenceNumber: ticket.sequenceNumber ?? null,
|
|
371
|
+
personId: ticket.personId ?? null,
|
|
372
|
+
resourceId: ticket.resourceId ?? null,
|
|
373
|
+
lot: ticket.lot ?? null,
|
|
374
|
+
split: ticket.split ?? null,
|
|
375
|
+
sub: ticket.sub ?? null,
|
|
376
|
+
comment: ticket.comment ?? null,
|
|
377
|
+
workOrderOperationClosedDate: ticket.workOrderOperationClosedDate ?? null,
|
|
378
|
+
reasons,
|
|
379
|
+
};
|
|
380
|
+
|
|
381
|
+
return JSON.stringify(signatureObject);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Selects a comparable timestamp for windowing decisions.
|
|
386
|
+
* Prefer updatedAt; fall back to other stable timestamps if needed.
|
|
387
|
+
*/
|
|
388
|
+
private static getComparableTicketTimestamp(
|
|
389
|
+
ticket: MMReceiveLaborTicket
|
|
390
|
+
): string | null {
|
|
391
|
+
return (
|
|
392
|
+
ticket.updatedAt ??
|
|
393
|
+
ticket.createdAt ??
|
|
394
|
+
ticket.transactionDate ??
|
|
395
|
+
ticket.clockOut ??
|
|
396
|
+
ticket.clockIn ??
|
|
397
|
+
null
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
private static addMsToIso(iso: string, ms: number): string {
|
|
402
|
+
return new Date(new Date(iso).getTime() + ms).toISOString();
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
private static computeCheckpointTimestamp(options: {
|
|
406
|
+
barrierTime: string;
|
|
407
|
+
maxMmTimestampWithinBarrier: string | null;
|
|
408
|
+
skewMs: number;
|
|
409
|
+
}): string {
|
|
410
|
+
const { barrierTime, maxMmTimestampWithinBarrier, skewMs } = options;
|
|
411
|
+
|
|
412
|
+
if (!maxMmTimestampWithinBarrier) return barrierTime;
|
|
413
|
+
|
|
414
|
+
const mmPlusSkew = this.addMsToIso(maxMmTimestampWithinBarrier, skewMs);
|
|
415
|
+
return new Date(mmPlusSkew) < new Date(barrierTime) ? mmPlusSkew : barrierTime;
|
|
416
|
+
}
|
|
261
417
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ERPObjType } from "../../types/erp-types";
|
|
2
|
-
import { BatchCacheManager } from "../../services/caching-service/batch-cache-manager";
|
|
1
|
+
import { ERPObjType } from "../../types/erp-types.js";
|
|
2
|
+
import { BatchCacheManager } from "../../services/caching-service/batch-cache-manager.js";
|
|
3
3
|
import {
|
|
4
4
|
IToRESTApiObject,
|
|
5
5
|
MMSendPerson,
|
|
@@ -15,21 +15,27 @@ import {
|
|
|
15
15
|
MM200LaborTicketResponse,
|
|
16
16
|
MM207NonLaborTicketResponse,
|
|
17
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";
|
|
18
|
+
} from "../../services/mm-api-service/index.js";
|
|
19
|
+
import { MMApiClient } from "../../services/mm-api-service/mm-api-service.js";
|
|
20
|
+
import { HTTPError } from "../http-client.js";
|
|
21
21
|
import {
|
|
22
22
|
WriteEntitiesToMMResult,
|
|
23
23
|
MMBatchValidationError,
|
|
24
|
-
} from "./standard-process-drivers";
|
|
25
|
-
import { ErrorProcessor } from "./error-processor";
|
|
24
|
+
} from "./standard-process-drivers.js";
|
|
25
|
+
import { ErrorProcessor } from "./error-processor.js";
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* Handles processing of entities to the MachineMetrics API
|
|
29
29
|
*/
|
|
30
30
|
export class MMEntityProcessor {
|
|
31
31
|
/**
|
|
32
|
-
* Writes entities to MM API with deduplication and caching
|
|
32
|
+
* Writes entities to MM API with deduplication and caching.
|
|
33
|
+
*
|
|
34
|
+
* IMPORTANT: All datetime fields on `mmRecords` MUST already be expressed as
|
|
35
|
+
* ISO-8601 UTC strings (either trailing `Z` or an explicit offset). The SDK
|
|
36
|
+
* does not apply timezone conversion on this path. It forwards values directly
|
|
37
|
+
* to MachineMetrics and only reserializes them for validation. Connector code
|
|
38
|
+
* is responsible for converting local ERP times to UTC before invoking this API.
|
|
33
39
|
*/
|
|
34
40
|
static async writeEntities(
|
|
35
41
|
entityType: ERPObjType,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { ERPObjType } from "../../types/erp-types";
|
|
2
|
-
import { IERPLaborTicketHandler } from "../../types/erp-connector";
|
|
3
|
-
import {
|
|
1
|
+
import { ERPObjType } from "../../types/erp-types.js";
|
|
2
|
+
import { IERPLaborTicketHandler } from "../../types/erp-connector.js";
|
|
3
|
+
import type { FlattenedWorkOrderRow } from "../../types/flattened-work-order.js";
|
|
4
|
+
import { BatchCacheManager } from "../../services/caching-service/batch-cache-manager.js";
|
|
4
5
|
import {
|
|
5
6
|
IToRESTApiObject,
|
|
6
7
|
MMSendWorkOrderBatch,
|
|
@@ -8,9 +9,9 @@ import {
|
|
|
8
9
|
MMSendPartOperation,
|
|
9
10
|
MMSendWorkOrder,
|
|
10
11
|
MMSendWorkOrderOperation,
|
|
11
|
-
} from "../../services/mm-api-service";
|
|
12
|
-
import { LaborTicketERPSynchronizer } from "./labor-ticket-erp-synchronizer";
|
|
13
|
-
import { MMEntityProcessor } from "./mm-entity-processor";
|
|
12
|
+
} from "../../services/mm-api-service/index.js";
|
|
13
|
+
import { LaborTicketERPSynchronizer } from "./labor-ticket-erp-synchronizer.js";
|
|
14
|
+
import { MMEntityProcessor } from "./mm-entity-processor.js";
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* The result of writing entities to the MachineMetrics API on complete success.
|
|
@@ -248,7 +249,12 @@ export class StandardProcessDrivers {
|
|
|
248
249
|
* parts, part operations, work orders, and work order operations, then process them in the correct order
|
|
249
250
|
* to maintain referential integrity.
|
|
250
251
|
*
|
|
251
|
-
*
|
|
252
|
+
* Timezone expectation: all datetime fields provided in `flattenedData` MUST already be expressed
|
|
253
|
+
* as ISO-8601 UTC strings (trailing `Z` or explicit offset). The SDK does not attempt to infer or
|
|
254
|
+
* convert local ERP timestamps on this path; it simply validates and forwards the values to MM.
|
|
255
|
+
* Connector implementations should convert ERP-local times to UTC before invoking this method.
|
|
256
|
+
*
|
|
257
|
+
* @param flattenedData Array of flattened rows containing both work order and operation data (see `FlattenedWorkOrderRow`)
|
|
252
258
|
* @param batchCacheManager The batch cache manager instance; pass in null if caching is not desired
|
|
253
259
|
*
|
|
254
260
|
* @returns Combined results from all entity processing with detailed logging information
|
|
@@ -256,7 +262,7 @@ export class StandardProcessDrivers {
|
|
|
256
262
|
* @throws Error on other underlying issues (network, authentication, etc.)
|
|
257
263
|
*/
|
|
258
264
|
static async syncWorkOrderBatchFromFlattened(
|
|
259
|
-
flattenedData:
|
|
265
|
+
flattenedData: ReadonlyArray<FlattenedWorkOrderRow>,
|
|
260
266
|
batchCacheManager: BatchCacheManager | null
|
|
261
267
|
): Promise<{
|
|
262
268
|
parts: WriteEntitiesToMMResult;
|
|
@@ -268,6 +274,11 @@ export class StandardProcessDrivers {
|
|
|
268
274
|
throw new Error("No flattened work order data provided");
|
|
269
275
|
}
|
|
270
276
|
|
|
277
|
+
const toStringOrFallback = (
|
|
278
|
+
value: string | number | null | undefined,
|
|
279
|
+
fallback = ""
|
|
280
|
+
): string => (value === undefined || value === null ? fallback : String(value));
|
|
281
|
+
|
|
271
282
|
// Process the flattened data - each row contains both work order and operation info
|
|
272
283
|
const uniqueParts = new Map();
|
|
273
284
|
const uniquePartOperations = new Map();
|
|
@@ -297,8 +308,8 @@ export class StandardProcessDrivers {
|
|
|
297
308
|
resourceId: row.resourceId, // → resourceId
|
|
298
309
|
cycleTimeMs: row.cycleTimeMs, // → cycleTimeMs
|
|
299
310
|
setupTimeMs: row.setupTimeMs, // → setupTimeMs
|
|
300
|
-
|
|
301
|
-
quantityPerPart: row.quantityPerPart
|
|
311
|
+
operationDescription: row.operationDescription, // → description
|
|
312
|
+
quantityPerPart: row.quantityPerPart ?? 1, // → quantityPerPart
|
|
302
313
|
});
|
|
303
314
|
}
|
|
304
315
|
|
|
@@ -351,8 +362,8 @@ export class StandardProcessDrivers {
|
|
|
351
362
|
const parts = Array.from(uniqueParts.values()).map(
|
|
352
363
|
(item) =>
|
|
353
364
|
new MMSendPart(
|
|
354
|
-
item.partNumber
|
|
355
|
-
item.partRevision
|
|
365
|
+
toStringOrFallback(item.partNumber), // partNumber
|
|
366
|
+
toStringOrFallback(item.partRevision), // partRevision
|
|
356
367
|
item.method || "Standard" // method
|
|
357
368
|
)
|
|
358
369
|
);
|
|
@@ -360,14 +371,14 @@ export class StandardProcessDrivers {
|
|
|
360
371
|
const partOperations = Array.from(uniquePartOperations.values()).map(
|
|
361
372
|
(item) =>
|
|
362
373
|
new MMSendPartOperation(
|
|
363
|
-
item.partNumber
|
|
364
|
-
item.partRevision
|
|
374
|
+
toStringOrFallback(item.partNumber), // partNumber
|
|
375
|
+
toStringOrFallback(item.partRevision), // partRevision
|
|
365
376
|
item.method || "Standard", // method
|
|
366
377
|
item.sequenceNumber?.toString() || "", // sequenceNumber
|
|
367
378
|
item.resourceId?.toString() || "", // resourceId
|
|
368
379
|
item.cycleTimeMs || 0, // cycleTimeMs
|
|
369
380
|
item.setupTimeMs || 0, // setupTimeMs
|
|
370
|
-
item.
|
|
381
|
+
item.operationDescription || "", // description
|
|
371
382
|
item.quantityPerPart || 1 // quantityPerPart
|
|
372
383
|
)
|
|
373
384
|
);
|
|
@@ -376,10 +387,12 @@ export class StandardProcessDrivers {
|
|
|
376
387
|
(item) =>
|
|
377
388
|
new MMSendWorkOrder(
|
|
378
389
|
item.workOrderId?.toString() || "", // workOrderId
|
|
379
|
-
item.lot
|
|
380
|
-
item.split
|
|
381
|
-
item.sub
|
|
390
|
+
toStringOrFallback(item.lot), // lot
|
|
391
|
+
toStringOrFallback(item.split), // split
|
|
392
|
+
toStringOrFallback(item.sub), // sub
|
|
382
393
|
item.status || "Open", // status
|
|
394
|
+
// Datetimes are assumed to already be UTC (or include an explicit offset).
|
|
395
|
+
// We reserialize via Date solely to validate the ISO format before sending to MM.
|
|
383
396
|
item.dueDate ? new Date(item.dueDate).toISOString() : null, // dueDate
|
|
384
397
|
item.description || "", // description
|
|
385
398
|
item.scheduledStartDate
|
|
@@ -390,8 +403,8 @@ export class StandardProcessDrivers {
|
|
|
390
403
|
: null, // scheduledEndDate
|
|
391
404
|
item.closedDate ? new Date(item.closedDate).toISOString() : null, // closedDate
|
|
392
405
|
item.quantityRequired || 0, // quantityRequired
|
|
393
|
-
item.partNumber
|
|
394
|
-
item.partRevision
|
|
406
|
+
toStringOrFallback(item.partNumber), // partNumber
|
|
407
|
+
toStringOrFallback(item.partRevision), // partRevision
|
|
395
408
|
item.method || "Standard" // method
|
|
396
409
|
)
|
|
397
410
|
);
|
|
@@ -400,14 +413,15 @@ export class StandardProcessDrivers {
|
|
|
400
413
|
(item) =>
|
|
401
414
|
new MMSendWorkOrderOperation(
|
|
402
415
|
item.workOrderId?.toString() || "", // workOrderId
|
|
403
|
-
item.lot
|
|
404
|
-
item.split
|
|
405
|
-
item.sub
|
|
416
|
+
toStringOrFallback(item.lot), // lot
|
|
417
|
+
toStringOrFallback(item.split), // split
|
|
418
|
+
toStringOrFallback(item.sub), // sub
|
|
406
419
|
item.sequenceNumber?.toString() || "", // sequenceNumber
|
|
407
420
|
item.resourceId?.toString() || "", // resourceId
|
|
408
421
|
item.startQuantity || 0, // startQuantity
|
|
409
422
|
item.finishQuantity || 0, // finishQuantity
|
|
410
423
|
item.expectedRejectRate || 0, // expectedRejectRate
|
|
424
|
+
// Same UTC expectation as above; reserialize to ensure valid ISO.
|
|
411
425
|
item.scheduledStartDate
|
|
412
426
|
? new Date(item.scheduledStartDate).toISOString()
|
|
413
427
|
: null, // scheduledStartDate
|
|
@@ -417,8 +431,8 @@ export class StandardProcessDrivers {
|
|
|
417
431
|
item.closedDate ? new Date(item.closedDate).toISOString() : null, // closedDate
|
|
418
432
|
item.cycleTimeMs || 0, // cycleTimeMs
|
|
419
433
|
item.setupTimeMs || 0, // setupTimeMs
|
|
420
|
-
parseFloat(item.productionburdenRateHourly
|
|
421
|
-
parseFloat(item.setupburdenRatehourly
|
|
434
|
+
parseFloat(toStringOrFallback(item.productionburdenRateHourly, "0")), // productionburdenRateHourly
|
|
435
|
+
parseFloat(toStringOrFallback(item.setupburdenRatehourly, "0")), // setupburdenRatehourly
|
|
422
436
|
item.operationType || "Production", // operationType
|
|
423
437
|
item.quantityPerPart || 1, // quantityPerPart
|
|
424
438
|
item.status || "Open" // status
|
package/src/utils/time-utils.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { DateTime } from 'luxon';
|
|
2
|
+
import logger from "../services/reporting-service/logger.js";
|
|
2
3
|
import {
|
|
3
4
|
setTimezoneOffsetInCache,
|
|
4
5
|
setTimezoneNameInCache,
|
|
5
|
-
} from "./local-data-store/jobs-shared-data";
|
|
6
|
+
} from "./local-data-store/jobs-shared-data.js";
|
|
6
7
|
import {
|
|
7
8
|
convertToLocalTime,
|
|
8
9
|
formatDateWithTZOffset,
|
|
9
10
|
getTimezoneOffset,
|
|
10
|
-
} from "./timezone";
|
|
11
|
+
} from "./timezone.js";
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Calculates the difference in hours between two timestamps
|
|
@@ -117,6 +118,16 @@ export const getTimezoneOffsetAndPersist = async (
|
|
|
117
118
|
const { offset, timezone } = await getTimezoneOffset();
|
|
118
119
|
logger.info(`Timezone offset: ${offset} hours, timezone: ${timezone}`);
|
|
119
120
|
setTimezoneOffsetInCache(offset);
|
|
121
|
+
|
|
122
|
+
const now = DateTime.now().setZone(timezone);
|
|
123
|
+
if (!now.isValid) {
|
|
124
|
+
throw new Error(
|
|
125
|
+
`Invalid timezone name from Company properties: "${timezone}". ` +
|
|
126
|
+
`Must be a valid IANA timezone name (e.g., "America/Chicago"). ` +
|
|
127
|
+
`See: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones`
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
120
131
|
setTimezoneNameInCache(timezone);
|
|
121
132
|
success = true;
|
|
122
133
|
} catch (error) {
|
package/src/utils/timezone.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CoreConfiguration } from "../services/data-sync-service/configuration-manager";
|
|
2
|
-
import { HTTPClientFactory } from "./http-client";
|
|
1
|
+
import { CoreConfiguration } from "../services/data-sync-service/configuration-manager.js";
|
|
2
|
+
import { HTTPClientFactory } from "./http-client.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Gets the timezone offset in hours and timezone name for the company's timezone
|