@machinemetrics/mm-erp-sdk 0.1.8-beta.1 → 0.1.8-beta.10

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 (46) hide show
  1. package/dist/{config-CV-KosWV.js → config-cB7h4yvc.js} +2 -2
  2. package/dist/{config-CV-KosWV.js.map → config-cB7h4yvc.js.map} +1 -1
  3. package/dist/{connector-factory-D8v6aQIt.js → connector-factory-CKm74_WZ.js} +2 -2
  4. package/dist/{connector-factory-D8v6aQIt.js.map → connector-factory-CKm74_WZ.js.map} +1 -1
  5. package/dist/{hashed-cache-manager-B6hTDLxU.js → hashed-cache-manager-B1hPBNnF.js} +4 -4
  6. package/dist/{hashed-cache-manager-B6hTDLxU.js.map → hashed-cache-manager-B1hPBNnF.js.map} +1 -1
  7. package/dist/{index-Bg76oouR.js → index-DCgheVjV.js} +2 -2
  8. package/dist/{index-Bg76oouR.js.map → index-DCgheVjV.js.map} +1 -1
  9. package/dist/index.d.ts +1 -1
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/{logger-SqdNut1H.js → logger-CBDNtsMq.js} +969 -1024
  12. package/dist/logger-CBDNtsMq.js.map +1 -0
  13. package/dist/mm-erp-sdk.js +60 -53
  14. package/dist/mm-erp-sdk.js.map +1 -1
  15. package/dist/services/data-sync-service/jobs/clean-up-expired-cache.js +4 -4
  16. package/dist/services/data-sync-service/jobs/from-erp.js +4 -4
  17. package/dist/services/data-sync-service/jobs/retry-failed-labor-tickets.js +3 -3
  18. package/dist/services/data-sync-service/jobs/run-migrations.js +1 -1
  19. package/dist/services/data-sync-service/jobs/to-erp.js +3 -3
  20. package/dist/services/psql-erp-service/index.d.ts +0 -5
  21. package/dist/services/psql-erp-service/index.d.ts.map +1 -1
  22. package/dist/services/psql-erp-service/internal/types/psql-types.d.ts +0 -3
  23. package/dist/services/psql-erp-service/internal/types/psql-types.d.ts.map +1 -1
  24. package/dist/services/psql-erp-service/psql-service.d.ts +7 -0
  25. package/dist/services/psql-erp-service/psql-service.d.ts.map +1 -1
  26. package/dist/services/reporting-service/logger.d.ts.map +1 -1
  27. package/dist/utils/index.d.ts +1 -1
  28. package/dist/utils/index.d.ts.map +1 -1
  29. package/dist/utils/timezone.d.ts +7 -0
  30. package/dist/utils/timezone.d.ts.map +1 -1
  31. package/package.json +4 -3
  32. package/src/index.ts +0 -1
  33. package/src/services/psql-erp-service/index.ts +0 -6
  34. package/src/services/psql-erp-service/internal/types/psql-types.ts +0 -4
  35. package/src/services/psql-erp-service/psql-service.ts +65 -3
  36. package/src/services/reporting-service/logger.ts +57 -70
  37. package/src/utils/index.ts +1 -1
  38. package/src/utils/mm-labor-ticket-helpers.ts +2 -2
  39. package/src/utils/timezone.ts +28 -0
  40. package/dist/logger-SqdNut1H.js.map +0 -1
  41. package/dist/services/psql-erp-service/internal/psql-config.d.ts +0 -28
  42. package/dist/services/psql-erp-service/internal/psql-config.d.ts.map +0 -1
  43. package/dist/services/psql-erp-service/internal/psql-labor-ticket-operations.d.ts +0 -40
  44. package/dist/services/psql-erp-service/internal/psql-labor-ticket-operations.d.ts.map +0 -1
  45. package/src/services/psql-erp-service/internal/psql-config.ts +0 -13
  46. package/src/services/psql-erp-service/internal/psql-labor-ticket-operations.ts +0 -58
@@ -1,20 +1,19 @@
1
- import { C as CoreConfiguration, H as HashedCacheManager } from "./hashed-cache-manager-B6hTDLxU.js";
2
- import { E, g, a } from "./hashed-cache-manager-B6hTDLxU.js";
3
- import { l as logger } from "./logger-SqdNut1H.js";
4
- import { g as getCachedMMToken, s as setCachedMMToken, a as setTimezoneOffsetInCache, b as getCachedTimezoneOffset, S as SQLiteCoordinator } from "./index-Bg76oouR.js";
5
- import { c, d } from "./index-Bg76oouR.js";
1
+ import { C as CoreConfiguration, H as HashedCacheManager } from "./hashed-cache-manager-B1hPBNnF.js";
2
+ import { E, g, a } from "./hashed-cache-manager-B1hPBNnF.js";
3
+ import { l as logger } from "./logger-CBDNtsMq.js";
4
+ import { g as getCachedMMToken, s as setCachedMMToken, a as setTimezoneOffsetInCache, b as getCachedTimezoneOffset, S as SQLiteCoordinator } from "./index-DCgheVjV.js";
5
+ import { c, d } from "./index-DCgheVjV.js";
6
6
  import axios, { AxiosError } from "axios";
7
7
  import knex from "knex";
8
8
  import { c as config } from "./knexfile-1qKKIORB.js";
9
9
  import fs from "fs";
10
10
  import path from "path";
11
- import "./connector-factory-D8v6aQIt.js";
11
+ import "./connector-factory-CKm74_WZ.js";
12
12
  import Bree from "bree";
13
13
  import Graceful from "@ladjs/graceful";
14
14
  import { fileURLToPath } from "url";
15
15
  import sql from "mssql";
16
16
  import { z } from "zod";
17
- import odbc from "odbc";
18
17
  var ERPType = /* @__PURE__ */ ((ERPType2) => {
19
18
  ERPType2["INVALID"] = "INVALID";
20
19
  ERPType2["D365"] = "D365";
@@ -1463,6 +1462,23 @@ const formatDateWithTZOffset = (date, timezoneOffset) => {
1463
1462
  const minutes = Math.floor(absOffset % 1 * 60).toString().padStart(2, "0");
1464
1463
  return `${isoDate}${sign}${hours}:${minutes}`;
1465
1464
  };
1465
+ const toISOWithOffset = (date, timezoneOffset) => {
1466
+ const sign = timezoneOffset >= 0 ? "+" : "-";
1467
+ const abs = Math.abs(timezoneOffset);
1468
+ const hours = Math.floor(abs);
1469
+ const minutes = Math.round((abs - hours) * 60);
1470
+ const pad2 = (n) => n.toString().padStart(2, "0");
1471
+ const pad3 = (n) => n.toString().padStart(3, "0");
1472
+ const yyyy = date.getUTCFullYear();
1473
+ const MM = pad2(date.getUTCMonth() + 1);
1474
+ const dd = pad2(date.getUTCDate());
1475
+ const HH = pad2(date.getUTCHours());
1476
+ const mm = pad2(date.getUTCMinutes());
1477
+ const ss = pad2(date.getUTCSeconds());
1478
+ const SSS = pad3(date.getUTCMilliseconds());
1479
+ const off = `${sign}${pad2(hours)}:${pad2(minutes)}`;
1480
+ return `${yyyy}-${MM}-${dd}T${HH}:${mm}:${ss}.${SSS}${off}`;
1481
+ };
1466
1482
  function calculateTimeDifferenceInHours(startTime, endTime, timezoneOffset) {
1467
1483
  if (!startTime || !endTime) return 0;
1468
1484
  const localStartTime = convertToLocalTime(startTime, timezoneOffset);
@@ -1645,7 +1661,7 @@ function convertLaborTicketToLocalTimezone(laborTicket, timezoneOffset) {
1645
1661
  ];
1646
1662
  timeFields.forEach((field) => {
1647
1663
  const localTime = convertToLocalTime(laborTicket[field], timezoneOffset);
1648
- laborTicket[field] = localTime?.toISOString() || null;
1664
+ laborTicket[field] = localTime ? toISOWithOffset(localTime, timezoneOffset) : null;
1649
1665
  });
1650
1666
  return laborTicket;
1651
1667
  }
@@ -3969,9 +3985,40 @@ class SqlServerHelper {
3969
3985
  }
3970
3986
  class PsqlService {
3971
3987
  config;
3988
+ static odbcModule = null;
3989
+ static odbcLoadError = null;
3972
3990
  constructor(config2) {
3973
3991
  this.config = config2;
3974
3992
  }
3993
+ /**
3994
+ * Dynamically load the ODBC module with lazy initialization and caching
3995
+ * @throws Error with helpful message if ODBC package is not installed
3996
+ */
3997
+ static async getOdbc() {
3998
+ if (this.odbcLoadError) {
3999
+ throw this.odbcLoadError;
4000
+ }
4001
+ if (this.odbcModule) {
4002
+ return this.odbcModule;
4003
+ }
4004
+ try {
4005
+ const odbcImport = await import("odbc");
4006
+ const odbc = odbcImport.default || odbcImport;
4007
+ this.odbcModule = odbc;
4008
+ return this.odbcModule;
4009
+ } catch (error) {
4010
+ const errorMessage = error instanceof Error ? error.message : String(error);
4011
+ this.odbcLoadError = new Error(
4012
+ `ODBC package is required for PSQL service but is not installed or failed to load.
4013
+ Install it with: npm install odbc
4014
+ Also install OS-level dependencies, e.g. on Alpine Linux:
4015
+ apk add --no-cache unixodbc unixodbc-dev python3 make g++
4016
+ For other Linux distributions, install unixodbc and unixodbc-dev packages.
4017
+ Original error: ${errorMessage}`
4018
+ );
4019
+ throw this.odbcLoadError;
4020
+ }
4021
+ }
3975
4022
  // REMOVED: dispose() method - not needed anymore
3976
4023
  // REMOVED: connection property - not needed anymore
3977
4024
  // REMOVED: openConnection() method - not needed anymore
@@ -4001,6 +4048,7 @@ class PsqlService {
4001
4048
  * @returns The entities fetched from the database, along with paging information
4002
4049
  */
4003
4050
  async executePreparedStatement(query, params = {}, paging) {
4051
+ const odbc = await PsqlService.getOdbc();
4004
4052
  let connection = null;
4005
4053
  try {
4006
4054
  const connStr = this.buildConnectionString();
@@ -4008,7 +4056,7 @@ class PsqlService {
4008
4056
  connection = await odbc.connect(connStr);
4009
4057
  if (Object.keys(params).length > 0) {
4010
4058
  logger.warn(
4011
- "PsqlService: Query parameters provided but parameter binding not yet implemented. Using direct query execution. This is acceptable for Phase 1 read operations."
4059
+ "PsqlService: Query parameters provided but parameter binding not yet implemented. Using direct query execution."
4012
4060
  );
4013
4061
  }
4014
4062
  const records = await connection.query(query);
@@ -4029,6 +4077,9 @@ class PsqlService {
4029
4077
  }
4030
4078
  };
4031
4079
  } catch (error) {
4080
+ if (error instanceof Error && error.message.includes("ODBC package is required")) {
4081
+ throw error;
4082
+ }
4032
4083
  const errorInfo = error;
4033
4084
  logger.error("Error fetching data from PSQL", {
4034
4085
  error: errorInfo.message,
@@ -4095,49 +4146,6 @@ class PsqlService {
4095
4146
  }
4096
4147
  }
4097
4148
  }
4098
- class PsqlLaborTicketOperations {
4099
- constructor(service) {
4100
- this.service = service;
4101
- }
4102
- /**
4103
- * Create labor ticket in START_LABOR table
4104
- *
4105
- * Phase 2 Implementation Notes:
4106
- * - Will use prepared statements with parameter binding
4107
- * - Insert into START_LABOR table
4108
- * - Return GUID as erpUid
4109
- *
4110
- * @param laborTicket Labor ticket from MachineMetrics
4111
- * @returns Labor ticket and ERP unique ID
4112
- */
4113
- async createLaborTicket(laborTicket) {
4114
- logger.warn(
4115
- "PsqlLaborTicketOperations.createLaborTicket not yet implemented (Phase 2)"
4116
- );
4117
- throw new Error(
4118
- "Labor ticket creation not implemented for PSQL. This is a Phase 2 feature."
4119
- );
4120
- }
4121
- /**
4122
- * Update labor ticket (move from START_LABOR to COMPLETED_LABOR)
4123
- *
4124
- * Phase 2 Implementation Notes:
4125
- * - Insert into COMPLETED_LABOR
4126
- * - Delete from START_LABOR
4127
- * - Should be done in a transaction
4128
- *
4129
- * @param laborTicket Labor ticket to update
4130
- * @returns Updated labor ticket
4131
- */
4132
- async updateLaborTicket(laborTicket) {
4133
- logger.warn(
4134
- "PsqlLaborTicketOperations.updateLaborTicket not yet implemented (Phase 2)"
4135
- );
4136
- throw new Error(
4137
- "Labor ticket update not implemented for PSQL. This is a Phase 2 feature."
4138
- );
4139
- }
4140
- }
4141
4149
  function formatPsqlDate(psqlDate) {
4142
4150
  if (!psqlDate || psqlDate === "000000" || psqlDate.trim() === "") {
4143
4151
  return null;
@@ -4212,7 +4220,6 @@ export {
4212
4220
  MMSendWorkOrder,
4213
4221
  MMSendWorkOrderOperation,
4214
4222
  OAuthClient,
4215
- PsqlLaborTicketOperations,
4216
4223
  PsqlService,
4217
4224
  RecordTrackingManager,
4218
4225
  RestAPIService,