diff --git a/client/package-lock.json b/client/package-lock.json index 2ec3d13e4..ffad1fe55 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -9,48 +9,49 @@ "version": "0.2.1", "hasInstallScript": true, "dependencies": { - "@amplitude/analytics-browser": "^2.23.1", + "@amplitude/analytics-browser": "^2.23.5", "@ant-design/pro-layout": "^7.22.6", "@apollo/client": "^3.13.9", - "@emotion/is-prop-valid": "^1.3.1", + "@emotion/is-prop-valid": "^1.4.0", "@fingerprintjs/fingerprintjs": "^4.6.1", "@firebase/analytics": "^0.10.17", - "@firebase/app": "^0.14.1", + "@firebase/app": "^0.14.2", "@firebase/auth": "^1.10.8", - "@firebase/firestore": "^4.8.0", + "@firebase/firestore": "^4.9.1", "@firebase/messaging": "^0.12.22", "@jsreport/browser-client": "^3.1.0", - "@reduxjs/toolkit": "^2.8.2", - "@sentry/cli": "^2.52.0", + "@reduxjs/toolkit": "^2.9.0", + "@sentry/cli": "^2.53.0", "@sentry/react": "^9.43.0", - "@sentry/vite-plugin": "^4.1.1", + "@sentry/vite-plugin": "^4.3.0", "@splitsoftware/splitio-react": "^2.3.1", "@tanem/react-nprogress": "^5.0.53", - "antd": "^5.27.1", + "antd": "^5.27.3", "apollo-link-logger": "^2.0.1", "apollo-link-sentry": "^4.4.0", "autosize": "^6.0.1", "axios": "^1.11.0", "classnames": "^2.5.1", "css-box-model": "^1.2.1", - "dayjs": "^1.11.13", + "dayjs": "^1.11.18", "dayjs-business-days2": "^1.3.0", "dinero.js": "^1.9.1", - "dotenv": "^17.2.1", + "dotenv": "^17.2.2", "env-cmd": "^10.1.0", "exifr": "^7.1.3", "graphql": "^16.11.0", - "i18next": "^25.4.0", + "i18next": "^25.5.2", "i18next-browser-languagedetector": "^8.2.0", "immutability-helper": "^3.1.1", - "libphonenumber-js": "^1.12.13", + "libphonenumber-js": "^1.12.15", + "lightningcss": "^1.30.1", "logrocket": "^9.0.2", "markerjs2": "^2.32.6", "memoize-one": "^6.0.0", "normalize-url": "^8.0.2", "object-hash": "^3.0.0", "phone": "^3.1.67", - "posthog-js": "^1.260.2", + "posthog-js": "^1.261.7", "prop-types": "^15.8.1", "query-string": "^9.2.2", "raf-schd": "^4.0.3", @@ -62,7 +63,7 @@ "react-drag-listview": "^2.0.0", "react-grid-gallery": "^1.0.1", "react-grid-layout": "1.3.4", - "react-i18next": "^15.7.1", + "react-i18next": "^15.7.3", "react-icons": "^5.5.0", "react-image-lightbox": "^5.1.4", "react-markdown": "^10.1.0", @@ -81,7 +82,7 @@ "redux-saga": "^1.3.0", "redux-state-sync": "^3.1.4", "reselect": "^5.1.1", - "sass": "^1.90.0", + "sass": "^1.92.0", "socket.io-client": "^4.8.1", "styled-components": "^6.1.19", "subscriptions-transport-ws": "^0.11.0", @@ -110,7 +111,6 @@ "eslint-plugin-react": "^7.37.5", "globals": "^15.15.0", "jsdom": "^26.0.0", - "lightningcss": "^1.30.1", "memfs": "^4.36.3", "os-browserify": "^0.3.0", "playwright": "^1.55.0", @@ -141,28 +141,28 @@ "license": "MIT" }, "node_modules/@amplitude/analytics-browser": { - "version": "2.23.1", - "resolved": "https://registry.npmjs.org/@amplitude/analytics-browser/-/analytics-browser-2.23.1.tgz", - "integrity": "sha512-TYsh7ORT9UoEF3JpmWVpyyRyeE4k8SS+6TNgEoCRj4ZtjiiWKP1CE7lEspgVBjWdSCUqS1o85Cte7c2mkj+SiA==", + "version": "2.23.5", + "resolved": "https://registry.npmjs.org/@amplitude/analytics-browser/-/analytics-browser-2.23.5.tgz", + "integrity": "sha512-R1N506rifI3/axSTM3EQkVjCgeJsmhybRONOdnA3MCJwOIC77UVEOIzTVNjnAAzgBSxDNTCy6ejGgBf3PgzBog==", "license": "MIT", "dependencies": { - "@amplitude/analytics-core": "^2.21.1", + "@amplitude/analytics-core": "^2.22.1", "@amplitude/analytics-remote-config": "^0.4.0", - "@amplitude/plugin-autocapture-browser": "^1.10.1", - "@amplitude/plugin-network-capture-browser": "^1.5.1", - "@amplitude/plugin-page-view-tracking-browser": "^2.3.42", - "@amplitude/plugin-web-vitals-browser": "^0.1.0-beta.17", + "@amplitude/plugin-autocapture-browser": "^1.11.1", + "@amplitude/plugin-network-capture-browser": "^1.5.4", + "@amplitude/plugin-page-view-tracking-browser": "^2.3.45", + "@amplitude/plugin-web-vitals-browser": "^0.1.0-beta.20", "tslib": "^2.4.1" } }, "node_modules/@amplitude/analytics-client-common": { - "version": "2.3.36", - "resolved": "https://registry.npmjs.org/@amplitude/analytics-client-common/-/analytics-client-common-2.3.36.tgz", - "integrity": "sha512-4MmuUuX8V9HOCrZ3VMQ3v3lkdksKQxswsO6mpm4YJvznty16+AaaupajubHik5GmmK8MV89ZqG0yLQLKiQm4yg==", + "version": "2.3.39", + "resolved": "https://registry.npmjs.org/@amplitude/analytics-client-common/-/analytics-client-common-2.3.39.tgz", + "integrity": "sha512-Dt31IIalME8whTXLgnKPLh9HbHTr8dC9F51reS1gngXAkOTErzAvbBl6UIc09bjqHWmimsRYgi6nflubnqwvMQ==", "license": "MIT", "dependencies": { "@amplitude/analytics-connector": "^1.4.8", - "@amplitude/analytics-core": "^2.21.1", + "@amplitude/analytics-core": "^2.22.1", "@amplitude/analytics-types": "^2.10.0", "tslib": "^2.4.1" } @@ -174,9 +174,9 @@ "license": "MIT" }, "node_modules/@amplitude/analytics-core": { - "version": "2.21.1", - "resolved": "https://registry.npmjs.org/@amplitude/analytics-core/-/analytics-core-2.21.1.tgz", - "integrity": "sha512-4lfjUDl4VF4H+O9uZJsf6hlmOlVte+CJI45i8gV8vh9jUEn0/Ad3Cyeu2D9p2dUtLUgKVcXglqkoSpxPzhGWFw==", + "version": "2.22.1", + "resolved": "https://registry.npmjs.org/@amplitude/analytics-core/-/analytics-core-2.22.1.tgz", + "integrity": "sha512-nzlulhS7jYQc91wOc392avBLDAiPZmIBuJ1apA640YlleX/egVxKgZVYHH3Ge4ZNkaxoESwUb4mf2R+ZI0fXxA==", "license": "MIT", "dependencies": { "@amplitude/analytics-connector": "^1.6.4", @@ -202,12 +202,12 @@ "license": "MIT" }, "node_modules/@amplitude/plugin-autocapture-browser": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@amplitude/plugin-autocapture-browser/-/plugin-autocapture-browser-1.10.1.tgz", - "integrity": "sha512-fLsad4xnxkiZ62mEFxze5SgNyxbc6qk7FMlzUPCpgkPhdbJkiogajTonEnRi+p5HU2Ze8K242gsfnR66xLEU1Q==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@amplitude/plugin-autocapture-browser/-/plugin-autocapture-browser-1.11.1.tgz", + "integrity": "sha512-6nus1nXlH1ru/yjx07yk1cyjc9scAsE9dO4f0xxH8xpHlYQ4yVCuYApcguIpogISlPiySAxSZ+4WDreLrpQiDw==", "license": "MIT", "dependencies": { - "@amplitude/analytics-core": "^2.21.1", + "@amplitude/analytics-core": "^2.22.1", "@amplitude/analytics-remote-config": "^0.6.3", "rxjs": "^7.8.1", "tslib": "^2.4.1" @@ -241,23 +241,23 @@ "license": "MIT" }, "node_modules/@amplitude/plugin-network-capture-browser": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@amplitude/plugin-network-capture-browser/-/plugin-network-capture-browser-1.5.1.tgz", - "integrity": "sha512-45KD4wo+7dfFIi3Q7w3u6x3R9FQdYifSZPyDG02V7YYdOjmRFC0K4Jzx0fpmbYqsl4BQDwe4q2DC6eDPKYDn3A==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@amplitude/plugin-network-capture-browser/-/plugin-network-capture-browser-1.5.4.tgz", + "integrity": "sha512-GRvi44tNx2TdHQ/dnC9DLqwsaBE1gC/bmHNaudTbp/nwIM8nVCAxZaXaXJEUouK7WBAamr7a3WmFruecqCeOlA==", "license": "MIT", "dependencies": { - "@amplitude/analytics-core": "^2.21.1", + "@amplitude/analytics-core": "^2.22.1", "rxjs": "^7.8.1", "tslib": "^2.4.1" } }, "node_modules/@amplitude/plugin-page-view-tracking-browser": { - "version": "2.3.42", - "resolved": "https://registry.npmjs.org/@amplitude/plugin-page-view-tracking-browser/-/plugin-page-view-tracking-browser-2.3.42.tgz", - "integrity": "sha512-MSO5hOSXdPXAUSW3vFqUz08/MrAfzn4TU1uyYL0q1MZz63bEwxppVaMnwgx1NfkyYf4zlWn0KZ6PREhXeWL0YA==", + "version": "2.3.45", + "resolved": "https://registry.npmjs.org/@amplitude/plugin-page-view-tracking-browser/-/plugin-page-view-tracking-browser-2.3.45.tgz", + "integrity": "sha512-L2JH/TDTdjfexkY5hHVS3dCb4+q5H1jeIKhXUcBQ/Wx91asLY9BsH91J4bo9EK4J4Al8jVRwqJz0tIQ17qW9RQ==", "license": "MIT", "dependencies": { - "@amplitude/analytics-client-common": "^2.3.36", + "@amplitude/analytics-client-common": "^2.3.39", "@amplitude/analytics-types": "^2.10.0", "tslib": "^2.4.1" } @@ -2534,9 +2534,9 @@ "license": "MIT" }, "node_modules/@emotion/is-prop-valid": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.1.tgz", - "integrity": "sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.4.0.tgz", + "integrity": "sha512-QgD4fyscGcbbKwJmqNvUMSE02OsHUa+lAWKdEUIJKgqe5IwRSKd7+KhibEWdaKwgjLj0DRSHA9biAIqGBk05lw==", "license": "MIT", "dependencies": { "@emotion/memoize": "^0.9.0" @@ -3280,9 +3280,9 @@ } }, "node_modules/@firebase/app": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.14.1.tgz", - "integrity": "sha512-jxTrDbxnGoX7cGz7aP9E7v9iKvBbQfZ8Gz4TH3SfrrkcyIojJM3+hJnlbGnGxHrABts844AxRcg00arMZEyA6Q==", + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.14.2.tgz", + "integrity": "sha512-Ecx2ig/JLC9ayIQwZHqm41Tzlf4c1WUuFhFUZB1y+JIJqDRE579x7Uil7tKT8MwDpOPwrK5ZtpxdSsrfy/LF8Q==", "license": "Apache-2.0", "dependencies": { "@firebase/component": "0.7.0", @@ -3333,9 +3333,9 @@ } }, "node_modules/@firebase/firestore": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.9.0.tgz", - "integrity": "sha512-5zl0+/h1GvlCSLt06RMwqFsd7uqRtnNZt4sW99k2rKRd6k/ECObIWlEnvthm2cuOSnUmwZknFqtmd1qyYSLUuQ==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.9.1.tgz", + "integrity": "sha512-PYVUTkhC9y8pydrqC3O1Oc4AMfkGSWdmuH9xgPJjiEbpUIUPQ4J8wJhyuash+o2u+axmyNRFP8ULNUKb+WzBzQ==", "license": "Apache-2.0", "dependencies": { "@firebase/component": "0.7.0", @@ -4090,6 +4090,12 @@ "url": "https://opencollective.com/popperjs" } }, + "node_modules/@posthog/core": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@posthog/core/-/core-1.0.2.tgz", + "integrity": "sha512-hWk3rUtJl2crQK0WNmwg13n82hnTwB99BT99/XI5gZSvIlYZ1TPmMZE8H2dhJJ98J/rm9vYJ/UXNzw3RV5HTpQ==", + "license": "MIT" + }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -4387,9 +4393,9 @@ "license": "MIT" }, "node_modules/@reduxjs/toolkit": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.8.2.tgz", - "integrity": "sha512-MYlOhQ0sLdw4ud48FoC5w0dH9VfWQjtCjreKwYTT3l+r427qYC5Y8PihNutepr8XrNaBUDQo9khWUwQxZaqt5A==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.9.0.tgz", + "integrity": "sha512-fSfQlSRu9Z5yBkvsNhYF2rPS8cGXn/TZVrlwN1948QyZ8xMZ0JvP50S2acZNaf+o63u6aEeMjipFyksjIcWrog==", "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.0.0", @@ -5055,6 +5061,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-4.1.1.tgz", "integrity": "sha512-HUpqrCK7zDVojTV6KL6BO9ZZiYrEYQqvYQrscyMsq04z+WCupXaH6YEliiNRvreR8DBJgdsG3lBRpebhUGmvfA==", + "dev": true, "license": "MIT", "engines": { "node": ">= 14" @@ -5080,6 +5087,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/@sentry/bundler-plugin-core/-/bundler-plugin-core-4.1.1.tgz", "integrity": "sha512-Hx9RgXaD1HEYmL5aYoWwCKkVvPp4iklwfD9mvmdpQtcwLg6b6oLnPVDQaOry1ak6Pxt8smlrWcKy4IiKASlvig==", + "dev": true, "license": "MIT", "dependencies": { "@babel/core": "^7.18.5", @@ -5099,6 +5107,7 @@ "version": "16.6.1", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=12" @@ -5108,9 +5117,9 @@ } }, "node_modules/@sentry/cli": { - "version": "2.52.0", - "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.52.0.tgz", - "integrity": "sha512-PXyo7Yv7+rVMSBGZfI/eFEzzhiKedTs25sDCjz4a3goAZ/F5R5tn3MKq30pnze5wNnoQmLujAa0uUjfNcWP+uQ==", + "version": "2.53.0", + "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.53.0.tgz", + "integrity": "sha512-n2ZNb+5Z6AZKQSI0SusQ7ZzFL637mfw3Xh4C3PEyVSn9LiF683fX0TTq8OeGmNZQS4maYfS95IFD+XpydU0dEA==", "hasInstallScript": true, "license": "BSD-3-Clause", "dependencies": { @@ -5127,20 +5136,20 @@ "node": ">= 10" }, "optionalDependencies": { - "@sentry/cli-darwin": "2.52.0", - "@sentry/cli-linux-arm": "2.52.0", - "@sentry/cli-linux-arm64": "2.52.0", - "@sentry/cli-linux-i686": "2.52.0", - "@sentry/cli-linux-x64": "2.52.0", - "@sentry/cli-win32-arm64": "2.52.0", - "@sentry/cli-win32-i686": "2.52.0", - "@sentry/cli-win32-x64": "2.52.0" + "@sentry/cli-darwin": "2.53.0", + "@sentry/cli-linux-arm": "2.53.0", + "@sentry/cli-linux-arm64": "2.53.0", + "@sentry/cli-linux-i686": "2.53.0", + "@sentry/cli-linux-x64": "2.53.0", + "@sentry/cli-win32-arm64": "2.53.0", + "@sentry/cli-win32-i686": "2.53.0", + "@sentry/cli-win32-x64": "2.53.0" } }, "node_modules/@sentry/cli-darwin": { - "version": "2.52.0", - "resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-2.52.0.tgz", - "integrity": "sha512-ieQs/p4yTHT27nBzy0wtAb8BSISfWlpXdgsACcwXimYa36NJRwyCqgOXUaH/BYiTdwWSHpuANbUHGJW6zljzxw==", + "version": "2.53.0", + "resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-2.53.0.tgz", + "integrity": "sha512-NNPfpILMwKgpHiyJubHHuauMKltkrgLQ5tvMdxNpxY60jBNdo5VJtpESp4XmXlnidzV4j1z61V4ozU6ttDgt5Q==", "license": "BSD-3-Clause", "optional": true, "os": [ @@ -5151,9 +5160,9 @@ } }, "node_modules/@sentry/cli-linux-arm": { - "version": "2.52.0", - "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm/-/cli-linux-arm-2.52.0.tgz", - "integrity": "sha512-tWMLU+hj+iip5Akx+S76biAOE1eMMWTDq8c0MqMv/ahHgb6/HiVngMcUsp59Oz3EczJGbTkcnS3vRTDodEcMDw==", + "version": "2.53.0", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm/-/cli-linux-arm-2.53.0.tgz", + "integrity": "sha512-NdRzQ15Ht83qG0/Lyu11ciy/Hu/oXbbtJUgwzACc7bWvHQA8xEwTsehWexqn1529Kfc5EjuZ0Wmj3MHmp+jOWw==", "cpu": [ "arm" ], @@ -5169,9 +5178,9 @@ } }, "node_modules/@sentry/cli-linux-arm64": { - "version": "2.52.0", - "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.52.0.tgz", - "integrity": "sha512-RxT5uzxjCkcvplmx0bavJIEYerRex2Rg/2RAVBdVvWLKFOcmeerTn/VVxPZVuDIVMVyjlZsteWPYwfUm+Ia3wQ==", + "version": "2.53.0", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.53.0.tgz", + "integrity": "sha512-xY/CZ1dVazsSCvTXzKpAgXaRqfljVfdrFaYZRUaRPf1ZJRGa3dcrivoOhSIeG/p5NdYtMvslMPY9Gm2MT0M83A==", "cpu": [ "arm64" ], @@ -5187,9 +5196,9 @@ } }, "node_modules/@sentry/cli-linux-i686": { - "version": "2.52.0", - "resolved": "https://registry.npmjs.org/@sentry/cli-linux-i686/-/cli-linux-i686-2.52.0.tgz", - "integrity": "sha512-sKcJmIg7QWFtlNU5Bs5OZprwdIzzyYMRpFkWioPZ4TE82yvP1+2SAX31VPUlTx+7NLU6YVEWNwvSxh8LWb7iOw==", + "version": "2.53.0", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-i686/-/cli-linux-i686-2.53.0.tgz", + "integrity": "sha512-0REmBibGAB4jtqt9S6JEsFF4QybzcXHPcHtJjgMi5T0ueh952uG9wLzjSxQErCsxTKF+fL8oG0Oz5yKBuCwCCQ==", "cpu": [ "x86", "ia32" @@ -5206,9 +5215,9 @@ } }, "node_modules/@sentry/cli-linux-x64": { - "version": "2.52.0", - "resolved": "https://registry.npmjs.org/@sentry/cli-linux-x64/-/cli-linux-x64-2.52.0.tgz", - "integrity": "sha512-aPZ7bP02zGkuEqTiOAm4np/ggfgtzrq4ti1Xze96Csi/DV3820SCfLrPlsvcvnqq7x69IL9cI3kXjdEpgrfGxw==", + "version": "2.53.0", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-x64/-/cli-linux-x64-2.53.0.tgz", + "integrity": "sha512-9UGJL+Vy5N/YL1EWPZ/dyXLkShlNaDNrzxx4G7mTS9ywjg+BIuemo6rnN7w43K1NOjObTVO6zY0FwumJ1pCyLg==", "cpu": [ "x64" ], @@ -5224,9 +5233,9 @@ } }, "node_modules/@sentry/cli-win32-arm64": { - "version": "2.52.0", - "resolved": "https://registry.npmjs.org/@sentry/cli-win32-arm64/-/cli-win32-arm64-2.52.0.tgz", - "integrity": "sha512-90hrB5XdwJVhRpCmVrEcYoKW8nl5/V9OfVvOGeKUPvUkApLzvsInK74FYBZEVyAn1i/NdUv+Xk9q2zqUGK1aLQ==", + "version": "2.53.0", + "resolved": "https://registry.npmjs.org/@sentry/cli-win32-arm64/-/cli-win32-arm64-2.53.0.tgz", + "integrity": "sha512-G1kjOjrjMBY20rQcJV2GA8KQE74ufmROCDb2GXYRfjvb1fKAsm4Oh8N5+Tqi7xEHdjQoLPkE4CNW0aH68JSUDQ==", "cpu": [ "arm64" ], @@ -5240,9 +5249,9 @@ } }, "node_modules/@sentry/cli-win32-i686": { - "version": "2.52.0", - "resolved": "https://registry.npmjs.org/@sentry/cli-win32-i686/-/cli-win32-i686-2.52.0.tgz", - "integrity": "sha512-HXlSE4CaLylNrELx4KVmOQjV5bURCNuky6sjCWiTH7HyDqHEak2Rk8iLE0JNLj5RETWMvmaZnZZFfmyGlY1opg==", + "version": "2.53.0", + "resolved": "https://registry.npmjs.org/@sentry/cli-win32-i686/-/cli-win32-i686-2.53.0.tgz", + "integrity": "sha512-qbGTZUzesuUaPtY9rPXdNfwLqOZKXrJRC1zUFn52hdo6B+Dmv0m/AHwRVFHZP53Tg1NCa8bDei2K/uzRN0dUZw==", "cpu": [ "x86", "ia32" @@ -5257,9 +5266,9 @@ } }, "node_modules/@sentry/cli-win32-x64": { - "version": "2.52.0", - "resolved": "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-2.52.0.tgz", - "integrity": "sha512-hJT0C3FwHk1Mt9oFqcci88wbO1D+yAWUL8J29HEGM5ZAqlhdh7sAtPDIC3P2LceUJOjnXihow47Bkj62juatIQ==", + "version": "2.53.0", + "resolved": "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-2.53.0.tgz", + "integrity": "sha512-1TXYxYHtwgUq5KAJt3erRzzUtPqg7BlH9T7MdSPHjJatkrr/kwZqnVe2H6Arr/5NH891vOlIeSPHBdgJUAD69g==", "cpu": [ "x64" ], @@ -5320,18 +5329,58 @@ } }, "node_modules/@sentry/vite-plugin": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@sentry/vite-plugin/-/vite-plugin-4.1.1.tgz", - "integrity": "sha512-kNIZiqRbFHJHzV0QF1RyuwMprwK2Lk354qs98P7DduU1TkzrNG3+2f8liYJaiYCrsjDvJlPHyVFBDF9IRhJGdA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@sentry/vite-plugin/-/vite-plugin-4.3.0.tgz", + "integrity": "sha512-MeTAHMmTOgBPMAjeW7/ONyXwgScZdaFFtNiALKcAODnVqC7eoHdSRIWeH5mkLr2Dvs7nqtBaDpKxRjUBgfm9LQ==", "license": "MIT", "dependencies": { - "@sentry/bundler-plugin-core": "4.1.1", + "@sentry/bundler-plugin-core": "4.3.0", "unplugin": "1.0.1" }, "engines": { "node": ">= 14" } }, + "node_modules/@sentry/vite-plugin/node_modules/@sentry/babel-plugin-component-annotate": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-4.3.0.tgz", + "integrity": "sha512-OuxqBprXRyhe8Pkfyz/4yHQJc5c3lm+TmYWSSx8u48g5yKewSQDOxkiLU5pAk3WnbLPy8XwU/PN+2BG0YFU9Nw==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/@sentry/vite-plugin/node_modules/@sentry/bundler-plugin-core": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@sentry/bundler-plugin-core/-/bundler-plugin-core-4.3.0.tgz", + "integrity": "sha512-dmR4DJhJ4jqVWGWppuTL2blNFqOZZnt4aLkewbD1myFG3KVfUx8CrMQWEmGjkgPOtj5TO6xH9PyTJjXC6o5tnA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.18.5", + "@sentry/babel-plugin-component-annotate": "4.3.0", + "@sentry/cli": "^2.51.0", + "dotenv": "^16.3.1", + "find-up": "^5.0.0", + "glob": "^9.3.2", + "magic-string": "0.30.8", + "unplugin": "1.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@sentry/vite-plugin/node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/@sentry/webpack-plugin": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/@sentry/webpack-plugin/-/webpack-plugin-4.1.1.tgz", @@ -6148,9 +6197,9 @@ } }, "node_modules/antd": { - "version": "5.27.1", - "resolved": "https://registry.npmjs.org/antd/-/antd-5.27.1.tgz", - "integrity": "sha512-jGMSdBN7hAMvPV27B4RhzZfL6n6yu8yDbo7oXrlJasaOqB7bSDPcjdEy1kXy3JPsny/Qazb1ykzRI4EfcByAPQ==", + "version": "5.27.3", + "resolved": "https://registry.npmjs.org/antd/-/antd-5.27.3.tgz", + "integrity": "sha512-Jewp1ek1iyqoAyjWyPgzc2kioZ+7S3jh39a+tld/j4ucnuf/cBk4omfyIdhLz49pVNsaEcRp5LtJOSQPFwPgpA==", "license": "MIT", "dependencies": { "@ant-design/colors": "^7.2.1", @@ -6192,7 +6241,7 @@ "rc-slider": "~11.1.8", "rc-steps": "~6.0.1", "rc-switch": "~4.1.0", - "rc-table": "~7.51.1", + "rc-table": "~7.52.6", "rc-tabs": "~15.7.0", "rc-textarea": "~1.10.2", "rc-tooltip": "~6.4.0", @@ -7897,9 +7946,9 @@ "license": "MIT" }, "node_modules/dayjs": { - "version": "1.11.13", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", - "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", + "version": "1.11.18", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.18.tgz", + "integrity": "sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==", "license": "MIT" }, "node_modules/dayjs-business-days2": { @@ -8074,7 +8123,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", - "dev": true, "license": "Apache-2.0", "engines": { "node": ">=8" @@ -8197,9 +8245,9 @@ } }, "node_modules/dotenv": { - "version": "17.2.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.1.tgz", - "integrity": "sha512-kQhDYKZecqnM0fCnzI5eIv5L4cAe/iRI+HqMbO/hbRdTAeXDG+M9FjipUxNfbARuEg4iHIbhnhs78BCHNbSxEQ==", + "version": "17.2.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.2.tgz", + "integrity": "sha512-Sf2LSQP+bOlhKWWyhFsn0UsfdK/kCWRv1iuA2gXAwt3dyNabr6QSj00I2V10pidqz69soatm9ZwZvpQMTIOd5Q==", "license": "BSD-2-Clause", "engines": { "node": ">=12" @@ -9846,9 +9894,9 @@ } }, "node_modules/i18next": { - "version": "25.4.0", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.4.0.tgz", - "integrity": "sha512-UH5aiamXsO3cfrZFurCHiB6YSs3C+s+XY9UaJllMMSbmaoXILxFgqDEZu4NbfzJFjmUo3BNMa++Rjkr3ofjfLw==", + "version": "25.5.2", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.5.2.tgz", + "integrity": "sha512-lW8Zeh37i/o0zVr+NoCHfNnfvVw+M6FQbRp36ZZ/NyHDJ3NJVpp2HhAUyU9WafL5AssymNoOjMRB48mmx2P6Hw==", "funding": [ { "type": "individual", @@ -10992,16 +11040,15 @@ } }, "node_modules/libphonenumber-js": { - "version": "1.12.13", - "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.12.13.tgz", - "integrity": "sha512-QZXnR/OGiDcBjF4hGk0wwVrPcZvbSSyzlvkjXv5LFfktj7O2VZDrt4Xs8SgR/vOFco+qk1i8J43ikMXZoTrtPw==", + "version": "1.12.15", + "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.12.15.tgz", + "integrity": "sha512-TMDCtIhWUDHh91wRC+wFuGlIzKdPzaTUHHVrIZ3vPUEoNaXFLrsIQ1ZpAeZeXApIF6rvDksMTvjrIQlLKaYxqQ==", "license": "MIT" }, "node_modules/lightningcss": { "version": "1.30.1", "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", - "dev": true, "license": "MPL-2.0", "dependencies": { "detect-libc": "^2.0.3" @@ -11033,7 +11080,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -11054,7 +11100,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -11075,7 +11120,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -11096,7 +11140,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -11117,7 +11160,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -11138,7 +11180,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -11159,7 +11200,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -11180,7 +11220,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -11201,7 +11240,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -11222,7 +11260,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -13152,11 +13189,12 @@ "license": "MIT" }, "node_modules/posthog-js": { - "version": "1.260.2", - "resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.260.2.tgz", - "integrity": "sha512-2Q+QUz9j9+uG16wp0WcOEbezVsLZCobZyTX8NvWPMGKyPaf2lOsjbPjznsq5JiIt324B6NAqzpWYZTzvhn9k9Q==", + "version": "1.261.7", + "resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.261.7.tgz", + "integrity": "sha512-Fjpbz6VfIMsEbKIN/UyTWhU1DGgVIngqoRjPGRolemIMOVzTfI77OZq8WwiBhMug+rU+wNhGCQhC41qRlR5CxA==", "license": "SEE LICENSE IN LICENSE", "dependencies": { + "@posthog/core": "1.0.2", "core-js": "^3.38.1", "fflate": "^0.4.8", "preact": "^10.19.3", @@ -13892,9 +13930,9 @@ } }, "node_modules/rc-table": { - "version": "7.51.1", - "resolved": "https://registry.npmjs.org/rc-table/-/rc-table-7.51.1.tgz", - "integrity": "sha512-5iq15mTHhvC42TlBLRCoCBLoCmGlbRZAlyF21FonFnS/DIC8DeRqnmdyVREwt2CFbPceM0zSNdEeVfiGaqYsKw==", + "version": "7.52.7", + "resolved": "https://registry.npmjs.org/rc-table/-/rc-table-7.52.7.tgz", + "integrity": "sha512-yuZfnTpuHwRa4JH+F28wQfGeDzqtgIDvLBBJk5sFncXQjTExhtBNc6dPfVo5pL5SjabJEoejefs6wsrAKfhDoQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.10.1", @@ -14204,16 +14242,16 @@ } }, "node_modules/react-i18next": { - "version": "15.7.1", - "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.7.1.tgz", - "integrity": "sha512-o4VsKh30fy7p0z5ACHuyWqB6xu9WpQIQy2/ZcbCqopNnrnTVOPn/nAv9uYP4xYAWg99QMpvZ9Bu/si3eGurzGw==", + "version": "15.7.3", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.7.3.tgz", + "integrity": "sha512-AANws4tOE+QSq/IeMF/ncoHlMNZaVLxpa5uUGW1wjike68elVYr0018L9xYoqBr1OFO7G7boDPrbn0HpMCJxTw==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.27.6", "html-parse-stringify": "^3.0.1" }, "peerDependencies": { - "i18next": ">= 23.4.0", + "i18next": ">= 25.4.1", "react": ">= 16.8.0", "typescript": "^5" }, @@ -15134,9 +15172,9 @@ "license": "MIT" }, "node_modules/sass": { - "version": "1.90.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.90.0.tgz", - "integrity": "sha512-9GUyuksjw70uNpb1MTYWsH9MQHOHY6kwfnkafC24+7aOMZn9+rVMBxRbLvw756mrBFbIsFg6Xw9IkR2Fnn3k+Q==", + "version": "1.92.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.92.0.tgz", + "integrity": "sha512-KDNI0BxgIRDAfJgzNm5wuy+4yOCIZyrUbjSpiU/JItfih+KGXAVefKL53MTml054MmBA3DDKIBMSI/7XLxZJ3A==", "license": "MIT", "dependencies": { "chokidar": "^4.0.0", diff --git a/client/package.json b/client/package.json index 73f192767..c9cacf3b4 100644 --- a/client/package.json +++ b/client/package.json @@ -8,48 +8,48 @@ "private": true, "proxy": "http://localhost:4000", "dependencies": { - "@amplitude/analytics-browser": "^2.23.1", + "@amplitude/analytics-browser": "^2.23.5", "@ant-design/pro-layout": "^7.22.6", "@apollo/client": "^3.13.9", - "@emotion/is-prop-valid": "^1.3.1", + "@emotion/is-prop-valid": "^1.4.0", "@fingerprintjs/fingerprintjs": "^4.6.1", "@firebase/analytics": "^0.10.17", - "@firebase/app": "^0.14.1", + "@firebase/app": "^0.14.2", "@firebase/auth": "^1.10.8", - "@firebase/firestore": "^4.8.0", + "@firebase/firestore": "^4.9.1", "@firebase/messaging": "^0.12.22", "@jsreport/browser-client": "^3.1.0", - "@reduxjs/toolkit": "^2.8.2", - "@sentry/cli": "^2.52.0", + "@reduxjs/toolkit": "^2.9.0", + "@sentry/cli": "^2.53.0", "@sentry/react": "^9.43.0", - "@sentry/vite-plugin": "^4.1.1", + "@sentry/vite-plugin": "^4.3.0", "@splitsoftware/splitio-react": "^2.3.1", "@tanem/react-nprogress": "^5.0.53", - "antd": "^5.27.1", + "antd": "^5.27.3", "apollo-link-logger": "^2.0.1", "apollo-link-sentry": "^4.4.0", "autosize": "^6.0.1", "axios": "^1.11.0", "classnames": "^2.5.1", "css-box-model": "^1.2.1", - "dayjs": "^1.11.13", + "dayjs": "^1.11.18", "dayjs-business-days2": "^1.3.0", "dinero.js": "^1.9.1", - "dotenv": "^17.2.1", + "dotenv": "^17.2.2", "env-cmd": "^10.1.0", "exifr": "^7.1.3", "graphql": "^16.11.0", - "i18next": "^25.4.0", + "i18next": "^25.5.2", "i18next-browser-languagedetector": "^8.2.0", "immutability-helper": "^3.1.1", - "libphonenumber-js": "^1.12.13", + "libphonenumber-js": "^1.12.15", "logrocket": "^9.0.2", "markerjs2": "^2.32.6", "memoize-one": "^6.0.0", "normalize-url": "^8.0.2", "object-hash": "^3.0.0", "phone": "^3.1.67", - "posthog-js": "^1.260.2", + "posthog-js": "^1.261.7", "prop-types": "^15.8.1", "query-string": "^9.2.2", "raf-schd": "^4.0.3", @@ -57,11 +57,12 @@ "react-big-calendar": "^1.19.4", "react-color": "^2.19.3", "react-cookie": "^8.0.1", + "lightningcss": "^1.30.1", "react-dom": "^18.3.1", "react-drag-listview": "^2.0.0", "react-grid-gallery": "^1.0.1", "react-grid-layout": "1.3.4", - "react-i18next": "^15.7.1", + "react-i18next": "^15.7.3", "react-icons": "^5.5.0", "react-image-lightbox": "^5.1.4", "react-markdown": "^10.1.0", @@ -80,7 +81,7 @@ "redux-saga": "^1.3.0", "redux-state-sync": "^3.1.4", "reselect": "^5.1.1", - "sass": "^1.90.0", + "sass": "^1.92.0", "socket.io-client": "^4.8.1", "styled-components": "^6.1.19", "subscriptions-transport-ws": "^0.11.0", @@ -152,7 +153,6 @@ "eslint-plugin-react": "^7.37.5", "globals": "^15.15.0", "jsdom": "^26.0.0", - "lightningcss": "^1.30.1", "memfs": "^4.36.3", "os-browserify": "^0.3.0", "playwright": "^1.55.0", diff --git a/client/src/components/jobs-detail-header/jobs-detail-header.component.jsx b/client/src/components/jobs-detail-header/jobs-detail-header.component.jsx index 4c430fba0..f631bf8ab 100644 --- a/client/src/components/jobs-detail-header/jobs-detail-header.component.jsx +++ b/client/src/components/jobs-detail-header/jobs-detail-header.component.jsx @@ -177,7 +177,7 @@ export function JobsDetailHeader({ job, bodyshop, disabled, insertAuditTrail, is handleCheckboxChange("estimate_sent_approval", e.target.checked)} - disabled={disabled} + disabled={disabled || isPartsEntry} > {job.estimate_sent_approval && ( @@ -192,7 +192,7 @@ export function JobsDetailHeader({ job, bodyshop, disabled, insertAuditTrail, is handleCheckboxChange("estimate_approved", e.target.checked)} - disabled={disabled} + disabled={disabled || isPartsEntry} > {job.estimate_approved && ( @@ -237,7 +237,7 @@ export function JobsDetailHeader({ job, bodyshop, disabled, insertAuditTrail, is {ownerTitle.length > 0 ? ownerTitle : t("owner.labels.noownerinfo")} ) : ( @@ -248,14 +248,14 @@ export function JobsDetailHeader({ job, bodyshop, disabled, insertAuditTrail, is >
- {disabled ? ( + {disabled || isPartsEntry ? ( {job.ownr_ph1} ) : ( )} - {disabled ? ( + {disabled || isPartsEntry ? ( {job.ownr_ph2} ) : ( @@ -267,7 +267,7 @@ export function JobsDetailHeader({ job, bodyshop, disabled, insertAuditTrail, is } ${job.ownr_st || ""} ${job.ownr_zip || ""}`} - {disabled ? ( + {disabled || isPartsEntry ? ( <>{job.ownr_ea || ""} ) : job.ownr_ea ? ( {job.ownr_ea} @@ -317,7 +317,7 @@ export function JobsDetailHeader({ job, bodyshop, disabled, insertAuditTrail, is - {job.vehicle && job.vehicle.notes && ( + {job.vehicle?.notes && ( )} - {job.vehicle && job.vehicle.v_paint_codes && ( + {job.vehicle?.v_paint_codes && ( {Object.keys(job.vehicle.v_paint_codes) diff --git a/client/src/components/jobs-related-ros/jobs-related-ros.component.jsx b/client/src/components/jobs-related-ros/jobs-related-ros.component.jsx index 5fccd626b..e71fbcc55 100644 --- a/client/src/components/jobs-related-ros/jobs-related-ros.component.jsx +++ b/client/src/components/jobs-related-ros/jobs-related-ros.component.jsx @@ -1,8 +1,18 @@ import { Space, Tag } from "antd"; import { Link } from "react-router-dom"; +import { createStructuredSelector } from "reselect"; +import { selectIsPartsEntry } from "../../redux/application/application.selectors.js"; +import { connect } from "react-redux"; +import getPartsBasePath from "../../utils/getPartsBasePath.js"; -export default function JobsRelatedRos({ job, disabled }) { +const mapStateToProps = createStructuredSelector({ + isPartsEntry: selectIsPartsEntry +}); + +function JobsRelatedRos({ job, disabled, isPartsEntry }) { if (!(job?.vehicle && job.vehicle.jobs)) return null; + const basePath = getPartsBasePath(isPartsEntry); + return ( {job.vehicle.jobs @@ -12,7 +22,7 @@ export default function JobsRelatedRos({ job, disabled }) { {disabled ? ( <>{`${j.ro_number || "N/A"}${j.clm_no ? ` | ${j.clm_no}` : ""}${j.status ? ` | ${j.status}` : ""}`} ) : ( - {`${j.ro_number || "N/A"}${ + {`${j.ro_number || "N/A"}${ j.clm_no ? ` | ${j.clm_no}` : "" }${j.status ? ` | ${j.status}` : ""}`} )} @@ -21,3 +31,4 @@ export default function JobsRelatedRos({ job, disabled }) { ); } +export default connect(mapStateToProps)(JobsRelatedRos); diff --git a/client/src/components/parts-order-list-table/parts-order-list-table.component.jsx b/client/src/components/parts-order-list-table/parts-order-list-table.component.jsx index af0814429..c26b1e3dc 100644 --- a/client/src/components/parts-order-list-table/parts-order-list-table.component.jsx +++ b/client/src/components/parts-order-list-table/parts-order-list-table.component.jsx @@ -227,15 +227,21 @@ export function PartsOrderListTableComponent({ sorter: (a, b) => a.order_date - b.order_date, sortOrder: state.sortedInfo.columnKey === "order_date" && state.sortedInfo.order, render: (text, record) => {record.order_date} - }, - { + } + ]; + + if (!isPartsEntry) { + columns.push({ title: t("parts_orders.fields.return"), dataIndex: "return", key: "return", sorter: (a, b) => a.return - b.return, sortOrder: state.sortedInfo.columnKey === "return" && state.sortedInfo.order, render: (text, record) => - }, + }); + } + + columns.push( { title: t("parts_orders.fields.deliver_by"), dataIndex: "deliver_by", @@ -256,7 +262,7 @@ export function PartsOrderListTableComponent({ render: (text, record) => recordActions(record, true), id: "parts-order-list-table-actions" } - ]; + ); const handleTableChange = (pagination, filters, sorter) => { setState({ ...state, filteredInfo: filters, sortedInfo: sorter }); diff --git a/client/src/components/parts-order-modal/parts-order-modal.component.jsx b/client/src/components/parts-order-modal/parts-order-modal.component.jsx index f55809209..858dd4563 100644 --- a/client/src/components/parts-order-modal/parts-order-modal.component.jsx +++ b/client/src/components/parts-order-modal/parts-order-modal.component.jsx @@ -11,16 +11,27 @@ import LayoutFormRow from "../layout-form-row/layout-form-row.component"; import VendorSearchSelect from "../vendor-search-select/vendor-search-select.component"; import PartsOrderModalPriceChange from "./parts-order-modal-price-change.component"; import DateTimePicker from "../form-date-time-picker/form-date-time-picker.component.jsx"; +import { selectIsPartsEntry } from "../../redux/application/application.selectors.js"; const mapStateToProps = createStructuredSelector({ - bodyshop: selectBodyshop + bodyshop: selectBodyshop, + isPartsEntry: selectIsPartsEntry }); const mapDispatchToProps = () => ({ //setUserLanguage: language => dispatch(setUserLanguage(language)) }); export default connect(mapStateToProps, mapDispatchToProps)(PartsOrderModalComponent); -export function PartsOrderModalComponent({ bodyshop, vendorList, sendTypeState, isReturn, preferredMake, job, form }) { +export function PartsOrderModalComponent({ + bodyshop, + vendorList, + sendTypeState, + isReturn, + preferredMake, + job, + form, + isPartsEntry +}) { const [sendType, setSendType] = sendTypeState; const { @@ -83,7 +94,7 @@ export function PartsOrderModalComponent({ bodyshop, vendorList, sendTypeState, )} - {!isReturn && ( + {!isReturn && !isPartsEntry && ( )} - {OEConnection.treatment === "on" && !isReturn && ( + {OEConnection.treatment === "on" && !isReturn && !isPartsEntry && ( @@ -249,7 +260,7 @@ export function PartsOrderModalComponent({ bodyshop, vendorList, sendTypeState, {t("parts_orders.labels.print")} - {OEConnection.treatment === "on" && !isReturn && ( + {OEConnection.treatment === "on" && !isReturn && !isPartsEntry && ( {t("parts_orders.labels.oec")} )} diff --git a/client/src/pages/simplified-parts-jobs-detail/simplified-parts-jobs-detail.component.jsx b/client/src/pages/simplified-parts-jobs-detail/simplified-parts-jobs-detail.component.jsx index 997865209..e9578eaad 100644 --- a/client/src/pages/simplified-parts-jobs-detail/simplified-parts-jobs-detail.component.jsx +++ b/client/src/pages/simplified-parts-jobs-detail/simplified-parts-jobs-detail.component.jsx @@ -11,7 +11,6 @@ import { createStructuredSelector } from "reselect"; import FormFieldsChanged from "../../components/form-fields-changed-alert/form-fields-changed-alert.component.jsx"; import JobsLinesContainer from "../../components/job-detail-lines/job-lines.container.jsx"; import JobLineUpsertModalContainer from "../../components/job-lines-upsert-modal/job-lines-upsert-modal.container.jsx"; -import JobProfileDataWarning from "../../components/job-profile-data-warning/job-profile-data-warning.component.jsx"; import JobsChangeStatus from "../../components/jobs-change-status/jobs-change-status.component.jsx"; import JobsDetailHeaderActions from "../../components/jobs-detail-header-actions/jobs-detail-header-actions.component.jsx"; import JobsDetailHeader from "../../components/jobs-detail-header/jobs-detail-header.component.jsx"; @@ -133,9 +132,8 @@ export function SimplifiedPartsJobDetailComponent({ setPrintCenterContext, jobRO {job.ro_number || t("general.labels.na")}} extra={menuExtra} /> - + - =18.0.0" }, "peerDependencies": { - "@aws-sdk/client-s3": "^3.876.0" + "@aws-sdk/client-s3": "^3.882.0" } }, "node_modules/@aws-sdk/middleware-bucket-endpoint": { @@ -898,15 +898,15 @@ } }, "node_modules/@aws-sdk/middleware-flexible-checksums": { - "version": "3.876.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.876.0.tgz", - "integrity": "sha512-Xfb9/XP0WcQq/yJxUubfzMUF0AYSX10UUIRbCJog0/lnDNocEiGEIaarwuQzoxb9QW9TQ1l5dDc/5bOMa1YVGw==", + "version": "3.882.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.882.0.tgz", + "integrity": "sha512-VZSeGckiRNEUYNYni8JFGB+uFqPq6L+IWPXTOMh6RtpDpamDSqZLgDEfXqopc+Awxpz1sQbdxSHMm2HZlqVW2g==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/crc32": "5.2.0", "@aws-crypto/crc32c": "5.2.0", "@aws-crypto/util": "5.2.0", - "@aws-sdk/core": "3.876.0", + "@aws-sdk/core": "3.882.0", "@aws-sdk/types": "3.862.0", "@smithy/is-array-buffer": "^4.0.0", "@smithy/node-config-provider": "^4.1.4", @@ -980,19 +980,19 @@ } }, "node_modules/@aws-sdk/middleware-sdk-s3": { - "version": "3.876.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.876.0.tgz", - "integrity": "sha512-h+TDs9EKAfXnrkogQpQz3o11zvs6Vh9+ehxyd35OcM7evnDeoV4GFjjnAKq+MxbBk/5Ewnvng+d6/WQDvMbj7Q==", + "version": "3.882.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.882.0.tgz", + "integrity": "sha512-j5Ya7RKSQSKkpcLsO+Rh272zKD63JYkLKY/N8m5MVNWQafMdUbkZi7nwwjq7s5t7r3Pmz7a4gLf4n6ZEL5eaow==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.876.0", + "@aws-sdk/core": "3.882.0", "@aws-sdk/types": "3.862.0", "@aws-sdk/util-arn-parser": "3.873.0", - "@smithy/core": "^3.8.0", + "@smithy/core": "^3.9.2", "@smithy/node-config-provider": "^4.1.4", "@smithy/protocol-http": "^5.1.3", "@smithy/signature-v4": "^5.1.3", - "@smithy/smithy-client": "^4.4.10", + "@smithy/smithy-client": "^4.5.2", "@smithy/types": "^4.3.2", "@smithy/util-config-provider": "^4.0.0", "@smithy/util-middleware": "^4.0.5", @@ -1019,15 +1019,15 @@ } }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.876.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.876.0.tgz", - "integrity": "sha512-FR+8INfnbNv32QDQ5szxkWX6mB/QgezfNyx8LnAh1ErISZMmEFBxXXir+ZOfuV8vsmal1a6cy9qmnMNDaNnaNQ==", + "version": "3.882.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.882.0.tgz", + "integrity": "sha512-IdLVpV2b0qryxFb/gNPwZoayLUdgmb41fWpLiIf99pyNwR7TGs/9Ri2amS3PnaQHuES947xYSYZ9Ej0kBgjHKg==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.876.0", + "@aws-sdk/core": "3.882.0", "@aws-sdk/types": "3.862.0", - "@aws-sdk/util-endpoints": "3.873.0", - "@smithy/core": "^3.8.0", + "@aws-sdk/util-endpoints": "3.879.0", + "@smithy/core": "^3.9.2", "@smithy/protocol-http": "^5.1.3", "@smithy/types": "^4.3.2", "tslib": "^2.6.2" @@ -1037,44 +1037,44 @@ } }, "node_modules/@aws-sdk/nested-clients": { - "version": "3.876.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.876.0.tgz", - "integrity": "sha512-R4TZrkM2gUElTsotk8mt3y7iLG8TNi1LL1wgVdEEWSLOYTaFyglGdoNBMtEeP7lmXilaTy00AbYF6BakJvSTHg==", + "version": "3.882.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.882.0.tgz", + "integrity": "sha512-IQkOtl/DhLV5+tJI7ZwjBDJO1lIoYOcmNQzcg8ly9RTdMoTcEtklevxmAwWB4DEFiIctUk2OSjHqhfWjeYredA==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.876.0", + "@aws-sdk/core": "3.882.0", "@aws-sdk/middleware-host-header": "3.873.0", "@aws-sdk/middleware-logger": "3.876.0", "@aws-sdk/middleware-recursion-detection": "3.873.0", - "@aws-sdk/middleware-user-agent": "3.876.0", + "@aws-sdk/middleware-user-agent": "3.882.0", "@aws-sdk/region-config-resolver": "3.873.0", "@aws-sdk/types": "3.862.0", - "@aws-sdk/util-endpoints": "3.873.0", + "@aws-sdk/util-endpoints": "3.879.0", "@aws-sdk/util-user-agent-browser": "3.873.0", - "@aws-sdk/util-user-agent-node": "3.876.0", + "@aws-sdk/util-user-agent-node": "3.882.0", "@smithy/config-resolver": "^4.1.5", - "@smithy/core": "^3.8.0", + "@smithy/core": "^3.9.2", "@smithy/fetch-http-handler": "^5.1.1", "@smithy/hash-node": "^4.0.5", "@smithy/invalid-dependency": "^4.0.5", "@smithy/middleware-content-length": "^4.0.5", - "@smithy/middleware-endpoint": "^4.1.18", - "@smithy/middleware-retry": "^4.1.19", + "@smithy/middleware-endpoint": "^4.1.21", + "@smithy/middleware-retry": "^4.1.22", "@smithy/middleware-serde": "^4.0.9", "@smithy/middleware-stack": "^4.0.5", "@smithy/node-config-provider": "^4.1.4", "@smithy/node-http-handler": "^4.1.1", "@smithy/protocol-http": "^5.1.3", - "@smithy/smithy-client": "^4.4.10", + "@smithy/smithy-client": "^4.5.2", "@smithy/types": "^4.3.2", "@smithy/url-parser": "^4.0.5", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.26", - "@smithy/util-defaults-mode-node": "^4.0.26", + "@smithy/util-defaults-mode-browser": "^4.0.29", + "@smithy/util-defaults-mode-node": "^4.0.29", "@smithy/util-endpoints": "^3.0.7", "@smithy/util-middleware": "^4.0.5", "@smithy/util-retry": "^4.0.7", @@ -1103,17 +1103,17 @@ } }, "node_modules/@aws-sdk/s3-request-presigner": { - "version": "3.876.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.876.0.tgz", - "integrity": "sha512-Mmj9xZ+NWDxatIsVsQ4986fTpNcPhLbWMX0PcgGLsSd8CnciWFsy06i7LbCzXS6sr6QzLP5Yesfdj+WWxgnFNQ==", + "version": "3.882.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.882.0.tgz", + "integrity": "sha512-Yahd3yQTUjuocDVKxYmoeoL3fXLI3rCw0oz3y4yGJl2ZIAIoIBN9iyIz/rVwiejeJJNGwO2iEhKJK0JJGAR3/A==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/signature-v4-multi-region": "3.876.0", + "@aws-sdk/signature-v4-multi-region": "3.882.0", "@aws-sdk/types": "3.862.0", "@aws-sdk/util-format-url": "3.873.0", - "@smithy/middleware-endpoint": "^4.1.18", + "@smithy/middleware-endpoint": "^4.1.21", "@smithy/protocol-http": "^5.1.3", - "@smithy/smithy-client": "^4.4.10", + "@smithy/smithy-client": "^4.5.2", "@smithy/types": "^4.3.2", "tslib": "^2.6.2" }, @@ -1122,12 +1122,12 @@ } }, "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.876.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.876.0.tgz", - "integrity": "sha512-OMDcuaVlC2rbze92w4QcNfuEA0IeT2GsT1ByZCwe+Y9tZwxzj7fCiOOU0UmJfa+juuQ/YBzVYxnkrkz3Rg6DEw==", + "version": "3.882.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.882.0.tgz", + "integrity": "sha512-hAmA9BgL3nIRTGoOGjMXMqVtPhtPFKBFaqhgQkgmkzpbZ6aaGecNIqBfGxi9oezR4dnvI+PvKoRo2F8csF7fMA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-sdk-s3": "3.876.0", + "@aws-sdk/middleware-sdk-s3": "3.882.0", "@aws-sdk/types": "3.862.0", "@smithy/protocol-http": "^5.1.3", "@smithy/signature-v4": "^5.1.3", @@ -1139,13 +1139,13 @@ } }, "node_modules/@aws-sdk/token-providers": { - "version": "3.876.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.876.0.tgz", - "integrity": "sha512-iU08kaQbhXnY0CC2TBcr7y/2PqPwZP2CTWX/Rbq0NvhOyteikfh7ASC+bRfLUp0XMSHKvSb+w2dh8a0lvx4oHg==", + "version": "3.882.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.882.0.tgz", + "integrity": "sha512-/Z6F8Cc+QjBMEPh3ZXy7JM1vMZCS41+Nh9VgdUwvvdJTA7LRXSDBRDL3cQPa7bii9unZ8SqsIC+7Nlw1LKwwJA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.876.0", - "@aws-sdk/nested-clients": "3.876.0", + "@aws-sdk/core": "3.882.0", + "@aws-sdk/nested-clients": "3.882.0", "@aws-sdk/types": "3.862.0", "@smithy/property-provider": "^4.0.5", "@smithy/shared-ini-file-loader": "^4.0.5", @@ -1182,9 +1182,9 @@ } }, "node_modules/@aws-sdk/util-endpoints": { - "version": "3.873.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.873.0.tgz", - "integrity": "sha512-YByHrhjxYdjKRf/RQygRK1uh0As1FIi9+jXTcIEX/rBgN8mUByczr2u4QXBzw7ZdbdcOBMOkPnLRjNOWW1MkFg==", + "version": "3.879.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.879.0.tgz", + "integrity": "sha512-aVAJwGecYoEmbEFju3127TyJDF9qJsKDUUTRMDuS8tGn+QiWQFnfInmbt+el9GU1gEJupNTXV+E3e74y51fb7A==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.862.0", @@ -1237,12 +1237,12 @@ } }, "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.876.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.876.0.tgz", - "integrity": "sha512-/ZIaeUt60JBdI0mNc7sZ8v3Tuzp8Pbe4gIAYnppGyF4KV8QA+Yu8tp2bGHfkKn150t1uvQ6P/4CwFfoGF34dzg==", + "version": "3.882.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.882.0.tgz", + "integrity": "sha512-7zPtGXeAs6UzKjrrSbMNiFMSLZ/2DWvJ26KBOasS3zQbL534yoNos4HUA3OOXSpKFBAIEcYWu6rzR4ptlvx50w==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-user-agent": "3.876.0", + "@aws-sdk/middleware-user-agent": "3.882.0", "@aws-sdk/types": "3.862.0", "@smithy/node-config-provider": "^4.1.4", "@smithy/types": "^4.3.2", @@ -1403,9 +1403,9 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.6.1.tgz", - "integrity": "sha512-KTsJMmobmbrFLe3LDh0PC2FXpcSYJt/MLjlkh/9LEnmKYLSYmT/0EW9JWANjeoemiuZrmogti0tW5Ch+qNUYDw==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.8.0.tgz", + "integrity": "sha512-MJQFqrZgcW0UNYLGOuQpey/oTN59vyWwplvCGZztn1cKz9agZPPYpJB7h2OMmuu7VLqkvEjN8feFZJmxNF9D+Q==", "dev": true, "license": "MIT", "dependencies": { @@ -1520,9 +1520,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.34.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.34.0.tgz", - "integrity": "sha512-EoyvqQnBNsV1CWaEJ559rxXL4c8V92gxirbawSmVUOWXlsRxxQXl6LmCpdUblgxgSkDIqKnhzba2SjRTI/A5Rw==", + "version": "9.35.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.35.0.tgz", + "integrity": "sha512-30iXE9whjlILfWobBkNerJo+TXYsgVM5ERQwMcMKCHckHflCmf7wXDAHlARoWnh0s1U72WqlbeyE7iAcCzuCPw==", "dev": true, "license": "MIT", "engines": { @@ -2161,12 +2161,12 @@ ] }, "node_modules/@smithy/abort-controller": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.0.5.tgz", - "integrity": "sha512-jcrqdTQurIrBbUm4W2YdLVMQDoL0sA9DTxYd2s+R/y+2U9NLOP7Xf/YqfSg1FZhlZIYEnvk2mwbyvIfdLEPo8g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.1.0.tgz", + "integrity": "sha512-wEhSYznxOmx7EdwK1tYEWJF5+/wmSFsff9BfTOn8oO/+KPl3gsmThrb6MJlWbOC391+Ya31s5JuHiC2RlT80Zg==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.3.2", + "@smithy/types": "^4.4.0", "tslib": "^2.6.2" }, "engines": { @@ -2199,15 +2199,15 @@ } }, "node_modules/@smithy/config-resolver": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.1.5.tgz", - "integrity": "sha512-viuHMxBAqydkB0AfWwHIdwf/PRH2z5KHGUzqyRtS/Wv+n3IHI993Sk76VCA7dD/+GzgGOmlJDITfPcJC1nIVIw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.2.0.tgz", + "integrity": "sha512-FA10YhPFLy23uxeWu7pOM2ctlw+gzbPMTZQwrZ8FRIfyJ/p8YIVz7AVTB5jjLD+QIerydyKcVMZur8qzzDILAQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.1.4", - "@smithy/types": "^4.3.2", - "@smithy/util-config-provider": "^4.0.0", - "@smithy/util-middleware": "^4.0.5", + "@smithy/node-config-provider": "^4.2.0", + "@smithy/types": "^4.4.0", + "@smithy/util-config-provider": "^4.1.0", + "@smithy/util-middleware": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -2215,19 +2215,19 @@ } }, "node_modules/@smithy/core": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.8.0.tgz", - "integrity": "sha512-EYqsIYJmkR1VhVE9pccnk353xhs+lB6btdutJEtsp7R055haMJp2yE16eSxw8fv+G0WUY6vqxyYOP8kOqawxYQ==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.10.0.tgz", + "integrity": "sha512-bXyD3Ij6b1qDymEYlEcF+QIjwb9gObwZNaRjETJsUEvSIzxFdynSQ3E4ysY7lUFSBzeWBNaFvX+5A0smbC2q6A==", "license": "Apache-2.0", "dependencies": { - "@smithy/middleware-serde": "^4.0.9", - "@smithy/protocol-http": "^5.1.3", - "@smithy/types": "^4.3.2", - "@smithy/util-base64": "^4.0.0", - "@smithy/util-body-length-browser": "^4.0.0", - "@smithy/util-middleware": "^4.0.5", - "@smithy/util-stream": "^4.2.4", - "@smithy/util-utf8": "^4.0.0", + "@smithy/middleware-serde": "^4.1.0", + "@smithy/protocol-http": "^5.2.0", + "@smithy/types": "^4.4.0", + "@smithy/util-base64": "^4.1.0", + "@smithy/util-body-length-browser": "^4.1.0", + "@smithy/util-middleware": "^4.1.0", + "@smithy/util-stream": "^4.3.0", + "@smithy/util-utf8": "^4.1.0", "@types/uuid": "^9.0.1", "tslib": "^2.6.2", "uuid": "^9.0.1" @@ -2250,15 +2250,15 @@ } }, "node_modules/@smithy/credential-provider-imds": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.0.7.tgz", - "integrity": "sha512-dDzrMXA8d8riFNiPvytxn0mNwR4B3h8lgrQ5UjAGu6T9z/kRg/Xncf4tEQHE/+t25sY8IH3CowcmWi+1U5B1Gw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.1.0.tgz", + "integrity": "sha512-iVwNhxTsCQTPdp++4C/d9xvaDmuEWhXi55qJobMp9QMaEHRGH3kErU4F8gohtdsawRqnUy/ANylCjKuhcR2mPw==", "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.1.4", - "@smithy/property-provider": "^4.0.5", - "@smithy/types": "^4.3.2", - "@smithy/url-parser": "^4.0.5", + "@smithy/node-config-provider": "^4.2.0", + "@smithy/property-provider": "^4.1.0", + "@smithy/types": "^4.4.0", + "@smithy/url-parser": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -2336,15 +2336,15 @@ } }, "node_modules/@smithy/fetch-http-handler": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.1.1.tgz", - "integrity": "sha512-61WjM0PWmZJR+SnmzaKI7t7G0UkkNFboDpzIdzSoy7TByUzlxo18Qlh9s71qug4AY4hlH/CwXdubMtkcNEb/sQ==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.2.0.tgz", + "integrity": "sha512-VZenjDdVaUGiy3hwQtxm75nhXZrhFG+3xyL93qCQAlYDyhT/jeDWM8/3r5uCFMlTmmyrIjiDyiOynVFchb0BSg==", "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^5.1.3", - "@smithy/querystring-builder": "^4.0.5", - "@smithy/types": "^4.3.2", - "@smithy/util-base64": "^4.0.0", + "@smithy/protocol-http": "^5.2.0", + "@smithy/querystring-builder": "^4.1.0", + "@smithy/types": "^4.4.0", + "@smithy/util-base64": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -2409,9 +2409,9 @@ } }, "node_modules/@smithy/is-array-buffer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.0.0.tgz", - "integrity": "sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.1.0.tgz", + "integrity": "sha512-ePTYUOV54wMogio+he4pBybe8fwg4sDvEVDBU8ZlHOZXbXK3/C0XfJgUCu6qAZcawv05ZhZzODGUerFBPsPUDQ==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -2449,18 +2449,18 @@ } }, "node_modules/@smithy/middleware-endpoint": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.1.18.tgz", - "integrity": "sha512-ZhvqcVRPZxnZlokcPaTwb+r+h4yOIOCJmx0v2d1bpVlmP465g3qpVSf7wxcq5zZdu4jb0H4yIMxuPwDJSQc3MQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.2.0.tgz", + "integrity": "sha512-J1eCF7pPDwgv7fGwRd2+Y+H9hlIolF3OZ2PjptonzzyOXXGh/1KGJAHpEcY1EX+WLlclKu2yC5k+9jWXdUG4YQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.8.0", - "@smithy/middleware-serde": "^4.0.9", - "@smithy/node-config-provider": "^4.1.4", - "@smithy/shared-ini-file-loader": "^4.0.5", - "@smithy/types": "^4.3.2", - "@smithy/url-parser": "^4.0.5", - "@smithy/util-middleware": "^4.0.5", + "@smithy/core": "^3.10.0", + "@smithy/middleware-serde": "^4.1.0", + "@smithy/node-config-provider": "^4.2.0", + "@smithy/shared-ini-file-loader": "^4.1.0", + "@smithy/types": "^4.4.0", + "@smithy/url-parser": "^4.1.0", + "@smithy/util-middleware": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -2468,18 +2468,18 @@ } }, "node_modules/@smithy/middleware-retry": { - "version": "4.1.19", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.1.19.tgz", - "integrity": "sha512-X58zx/NVECjeuUB6A8HBu4bhx72EoUz+T5jTMIyeNKx2lf+Gs9TmWPNNkH+5QF0COjpInP/xSpJGJ7xEnAklQQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.2.0.tgz", + "integrity": "sha512-raL5oWYf5ALl3jCJrajE8enKJEnV/2wZkKS6mb3ZRY2tg3nj66ssdWy5Ps8E6Yu8Wqh3Tt+Sb9LozjvwZupq+A==", "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.1.4", - "@smithy/protocol-http": "^5.1.3", - "@smithy/service-error-classification": "^4.0.7", - "@smithy/smithy-client": "^4.4.10", - "@smithy/types": "^4.3.2", - "@smithy/util-middleware": "^4.0.5", - "@smithy/util-retry": "^4.0.7", + "@smithy/node-config-provider": "^4.2.0", + "@smithy/protocol-http": "^5.2.0", + "@smithy/service-error-classification": "^4.1.0", + "@smithy/smithy-client": "^4.6.0", + "@smithy/types": "^4.4.0", + "@smithy/util-middleware": "^4.1.0", + "@smithy/util-retry": "^4.1.0", "@types/uuid": "^9.0.1", "tslib": "^2.6.2", "uuid": "^9.0.1" @@ -2502,13 +2502,13 @@ } }, "node_modules/@smithy/middleware-serde": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.0.9.tgz", - "integrity": "sha512-uAFFR4dpeoJPGz8x9mhxp+RPjo5wW0QEEIPPPbLXiRRWeCATf/Km3gKIVR5vaP8bN1kgsPhcEeh+IZvUlBv6Xg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.1.0.tgz", + "integrity": "sha512-CtLFYlHt7c2VcztyVRc+25JLV4aGpmaSv9F1sPB0AGFL6S+RPythkqpGDa2XBQLJQooKkjLA1g7Xe4450knShg==", "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^5.1.3", - "@smithy/types": "^4.3.2", + "@smithy/protocol-http": "^5.2.0", + "@smithy/types": "^4.4.0", "tslib": "^2.6.2" }, "engines": { @@ -2516,12 +2516,12 @@ } }, "node_modules/@smithy/middleware-stack": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.0.5.tgz", - "integrity": "sha512-/yoHDXZPh3ocRVyeWQFvC44u8seu3eYzZRveCMfgMOBcNKnAmOvjbL9+Cp5XKSIi9iYA9PECUuW2teDAk8T+OQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.1.0.tgz", + "integrity": "sha512-91Fuw4IKp0eK8PNhMXrHRcYA1jvbZ9BJGT91wwPy3bTQT8mHTcQNius/EhSQTlT9QUI3Ki1wjHeNXbWK0tO8YQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.3.2", + "@smithy/types": "^4.4.0", "tslib": "^2.6.2" }, "engines": { @@ -2529,14 +2529,14 @@ } }, "node_modules/@smithy/node-config-provider": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.1.4.tgz", - "integrity": "sha512-+UDQV/k42jLEPPHSn39l0Bmc4sB1xtdI9Gd47fzo/0PbXzJ7ylgaOByVjF5EeQIumkepnrJyfx86dPa9p47Y+w==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.2.0.tgz", + "integrity": "sha512-8/fpilqKurQ+f8nFvoFkJ0lrymoMJ+5/CQV5IcTv/MyKhk2Q/EFYCAgTSWHD4nMi9ux9NyBBynkyE9SLg2uSLA==", "license": "Apache-2.0", "dependencies": { - "@smithy/property-provider": "^4.0.5", - "@smithy/shared-ini-file-loader": "^4.0.5", - "@smithy/types": "^4.3.2", + "@smithy/property-provider": "^4.1.0", + "@smithy/shared-ini-file-loader": "^4.1.0", + "@smithy/types": "^4.4.0", "tslib": "^2.6.2" }, "engines": { @@ -2544,15 +2544,15 @@ } }, "node_modules/@smithy/node-http-handler": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.1.1.tgz", - "integrity": "sha512-RHnlHqFpoVdjSPPiYy/t40Zovf3BBHc2oemgD7VsVTFFZrU5erFFe0n52OANZZ/5sbshgD93sOh5r6I35Xmpaw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.2.0.tgz", + "integrity": "sha512-G4NV70B4hF9vBrUkkvNfWO6+QR4jYjeO4tc+4XrKCb4nPYj49V9Hu8Ftio7Mb0/0IlFyEOORudHrm+isY29nCA==", "license": "Apache-2.0", "dependencies": { - "@smithy/abort-controller": "^4.0.5", - "@smithy/protocol-http": "^5.1.3", - "@smithy/querystring-builder": "^4.0.5", - "@smithy/types": "^4.3.2", + "@smithy/abort-controller": "^4.1.0", + "@smithy/protocol-http": "^5.2.0", + "@smithy/querystring-builder": "^4.1.0", + "@smithy/types": "^4.4.0", "tslib": "^2.6.2" }, "engines": { @@ -2560,12 +2560,12 @@ } }, "node_modules/@smithy/property-provider": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.0.5.tgz", - "integrity": "sha512-R/bswf59T/n9ZgfgUICAZoWYKBHcsVDurAGX88zsiUtOTA/xUAPyiT+qkNCPwFn43pZqN84M4MiUsbSGQmgFIQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.1.0.tgz", + "integrity": "sha512-eksMjMHUlG5PwOUWO3k+rfLNOPVPJ70mUzyYNKb5lvyIuAwS4zpWGsxGiuT74DFWonW0xRNy+jgzGauUzX7SyA==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.3.2", + "@smithy/types": "^4.4.0", "tslib": "^2.6.2" }, "engines": { @@ -2573,12 +2573,12 @@ } }, "node_modules/@smithy/protocol-http": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.1.3.tgz", - "integrity": "sha512-fCJd2ZR7D22XhDY0l+92pUag/7je2BztPRQ01gU5bMChcyI0rlly7QFibnYHzcxDvccMjlpM/Q1ev8ceRIb48w==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.2.0.tgz", + "integrity": "sha512-bwjlh5JwdOQnA01be+5UvHK4HQz4iaRKlVG46hHSJuqi0Ribt3K06Z1oQ29i35Np4G9MCDgkOGcHVyLMreMcbg==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.3.2", + "@smithy/types": "^4.4.0", "tslib": "^2.6.2" }, "engines": { @@ -2586,13 +2586,13 @@ } }, "node_modules/@smithy/querystring-builder": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.0.5.tgz", - "integrity": "sha512-NJeSCU57piZ56c+/wY+AbAw6rxCCAOZLCIniRE7wqvndqxcKKDOXzwWjrY7wGKEISfhL9gBbAaWWgHsUGedk+A==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.1.0.tgz", + "integrity": "sha512-JqTWmVIq4AF8R8OK/2cCCiQo5ZJ0SRPsDkDgLO5/3z8xxuUp1oMIBBjfuueEe+11hGTZ6rRebzYikpKc6yQV9Q==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.3.2", - "@smithy/util-uri-escape": "^4.0.0", + "@smithy/types": "^4.4.0", + "@smithy/util-uri-escape": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -2600,12 +2600,12 @@ } }, "node_modules/@smithy/querystring-parser": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.0.5.tgz", - "integrity": "sha512-6SV7md2CzNG/WUeTjVe6Dj8noH32r4MnUeFKZrnVYsQxpGSIcphAanQMayi8jJLZAWm6pdM9ZXvKCpWOsIGg0w==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.1.0.tgz", + "integrity": "sha512-VgdHhr8YTRsjOl4hnKFm7xEMOCRTnKw3FJ1nU+dlWNhdt/7eEtxtkdrJdx7PlRTabdANTmvyjE4umUl9cK4awg==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.3.2", + "@smithy/types": "^4.4.0", "tslib": "^2.6.2" }, "engines": { @@ -2613,24 +2613,24 @@ } }, "node_modules/@smithy/service-error-classification": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.0.7.tgz", - "integrity": "sha512-XvRHOipqpwNhEjDf2L5gJowZEm5nsxC16pAZOeEcsygdjv9A2jdOh3YoDQvOXBGTsaJk6mNWtzWalOB9976Wlg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.1.0.tgz", + "integrity": "sha512-UBpNFzBNmS20jJomuYn++Y+soF8rOK9AvIGjS9yGP6uRXF5rP18h4FDUsoNpWTlSsmiJ87e2DpZo9ywzSMH7PQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.3.2" + "@smithy/types": "^4.4.0" }, "engines": { "node": ">=18.0.0" } }, "node_modules/@smithy/shared-ini-file-loader": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.0.5.tgz", - "integrity": "sha512-YVVwehRDuehgoXdEL4r1tAAzdaDgaC9EQvhK0lEbfnbrd0bd5+CTQumbdPryX3J2shT7ZqQE+jPW4lmNBAB8JQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.1.0.tgz", + "integrity": "sha512-W0VMlz9yGdQ/0ZAgWICFjFHTVU0YSfGoCVpKaExRM/FDkTeP/yz8OKvjtGjs6oFokCRm0srgj/g4Cg0xuHu8Rw==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.3.2", + "@smithy/types": "^4.4.0", "tslib": "^2.6.2" }, "engines": { @@ -2638,18 +2638,18 @@ } }, "node_modules/@smithy/signature-v4": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.1.3.tgz", - "integrity": "sha512-mARDSXSEgllNzMw6N+mC+r1AQlEBO3meEAkR/UlfAgnMzJUB3goRBWgip1EAMG99wh36MDqzo86SfIX5Y+VEaw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.2.0.tgz", + "integrity": "sha512-ObX1ZqG2DdZQlXx9mLD7yAR8AGb7yXurGm+iWx9x4l1fBZ8CZN2BRT09aSbcXVPZXWGdn5VtMuupjxhOTI2EjA==", "license": "Apache-2.0", "dependencies": { - "@smithy/is-array-buffer": "^4.0.0", - "@smithy/protocol-http": "^5.1.3", - "@smithy/types": "^4.3.2", - "@smithy/util-hex-encoding": "^4.0.0", - "@smithy/util-middleware": "^4.0.5", - "@smithy/util-uri-escape": "^4.0.0", - "@smithy/util-utf8": "^4.0.0", + "@smithy/is-array-buffer": "^4.1.0", + "@smithy/protocol-http": "^5.2.0", + "@smithy/types": "^4.4.0", + "@smithy/util-hex-encoding": "^4.1.0", + "@smithy/util-middleware": "^4.1.0", + "@smithy/util-uri-escape": "^4.1.0", + "@smithy/util-utf8": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -2657,17 +2657,17 @@ } }, "node_modules/@smithy/smithy-client": { - "version": "4.4.10", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.4.10.tgz", - "integrity": "sha512-iW6HjXqN0oPtRS0NK/zzZ4zZeGESIFcxj2FkWed3mcK8jdSdHzvnCKXSjvewESKAgGKAbJRA+OsaqKhkdYRbQQ==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.6.0.tgz", + "integrity": "sha512-TvlIshqx5PIi0I0AiR+PluCpJ8olVG++xbYkAIGCUkByaMUlfOXLgjQTmYbr46k4wuDe8eHiTIlUflnjK2drPQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.8.0", - "@smithy/middleware-endpoint": "^4.1.18", - "@smithy/middleware-stack": "^4.0.5", - "@smithy/protocol-http": "^5.1.3", - "@smithy/types": "^4.3.2", - "@smithy/util-stream": "^4.2.4", + "@smithy/core": "^3.10.0", + "@smithy/middleware-endpoint": "^4.2.0", + "@smithy/middleware-stack": "^4.1.0", + "@smithy/protocol-http": "^5.2.0", + "@smithy/types": "^4.4.0", + "@smithy/util-stream": "^4.3.0", "tslib": "^2.6.2" }, "engines": { @@ -2675,9 +2675,9 @@ } }, "node_modules/@smithy/types": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.3.2.tgz", - "integrity": "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.4.0.tgz", + "integrity": "sha512-4jY91NgZz+ZnSFcVzWwngOW6VuK3gR/ihTwSU1R/0NENe9Jd8SfWgbhDCAGUWL3bI7DiDSW7XF6Ui6bBBjrqXw==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -2687,13 +2687,13 @@ } }, "node_modules/@smithy/url-parser": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.0.5.tgz", - "integrity": "sha512-j+733Um7f1/DXjYhCbvNXABV53NyCRRA54C7bNEIxNPs0YjfRxeMKjjgm2jvTYrciZyCjsicHwQ6Q0ylo+NAUw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.1.0.tgz", + "integrity": "sha512-/LYEIOuO5B2u++tKr1NxNxhZTrr3A63jW8N73YTwVeUyAlbB/YM+hkftsvtKAcMt3ADYo0FsF1GY3anehffSVQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/querystring-parser": "^4.0.5", - "@smithy/types": "^4.3.2", + "@smithy/querystring-parser": "^4.1.0", + "@smithy/types": "^4.4.0", "tslib": "^2.6.2" }, "engines": { @@ -2701,13 +2701,13 @@ } }, "node_modules/@smithy/util-base64": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.0.0.tgz", - "integrity": "sha512-CvHfCmO2mchox9kjrtzoHkWHxjHZzaFojLc8quxXY7WAAMAg43nuxwv95tATVgQFNDwd4M9S1qFzj40Ul41Kmg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.1.0.tgz", + "integrity": "sha512-RUGd4wNb8GeW7xk+AY5ghGnIwM96V0l2uzvs/uVHf+tIuVX2WSvynk5CxNoBCsM2rQRSZElAo9rt3G5mJ/gktQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/util-buffer-from": "^4.0.0", - "@smithy/util-utf8": "^4.0.0", + "@smithy/util-buffer-from": "^4.1.0", + "@smithy/util-utf8": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -2715,9 +2715,9 @@ } }, "node_modules/@smithy/util-body-length-browser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.0.0.tgz", - "integrity": "sha512-sNi3DL0/k64/LO3A256M+m3CDdG6V7WKWHdAiBBMUN8S3hK3aMPhwnPik2A/a2ONN+9doY9UxaLfgqsIRg69QA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.1.0.tgz", + "integrity": "sha512-V2E2Iez+bo6bUMOTENPr6eEmepdY8Hbs+Uc1vkDKgKNA/brTJqOW/ai3JO1BGj9GbCeLqw90pbbH7HFQyFotGQ==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -2739,12 +2739,12 @@ } }, "node_modules/@smithy/util-buffer-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.0.0.tgz", - "integrity": "sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.1.0.tgz", + "integrity": "sha512-N6yXcjfe/E+xKEccWEKzK6M+crMrlwaCepKja0pNnlSkm6SjAeLKKA++er5Ba0I17gvKfN/ThV+ZOx/CntKTVw==", "license": "Apache-2.0", "dependencies": { - "@smithy/is-array-buffer": "^4.0.0", + "@smithy/is-array-buffer": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -2752,9 +2752,9 @@ } }, "node_modules/@smithy/util-config-provider": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.0.0.tgz", - "integrity": "sha512-L1RBVzLyfE8OXH+1hsJ8p+acNUSirQnWQ6/EgpchV88G6zGBTDPdXiiExei6Z1wR2RxYvxY/XLw6AMNCCt8H3w==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.1.0.tgz", + "integrity": "sha512-swXz2vMjrP1ZusZWVTB/ai5gK+J8U0BWvP10v9fpcFvg+Xi/87LHvHfst2IgCs1i0v4qFZfGwCmeD/KNCdJZbQ==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -2764,14 +2764,14 @@ } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "4.0.26", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.26.tgz", - "integrity": "sha512-xgl75aHIS/3rrGp7iTxQAOELYeyiwBu+eEgAk4xfKwJJ0L8VUjhO2shsDpeil54BOFsqmk5xfdesiewbUY5tKQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.1.0.tgz", + "integrity": "sha512-D27cLtJtC4EEeERJXS+JPoogz2tE5zeE3zhWSSu6ER5/wJ5gihUxIzoarDX6K1U27IFTHit5YfHqU4Y9RSGE0w==", "license": "Apache-2.0", "dependencies": { - "@smithy/property-provider": "^4.0.5", - "@smithy/smithy-client": "^4.4.10", - "@smithy/types": "^4.3.2", + "@smithy/property-provider": "^4.1.0", + "@smithy/smithy-client": "^4.6.0", + "@smithy/types": "^4.4.0", "bowser": "^2.11.0", "tslib": "^2.6.2" }, @@ -2780,17 +2780,17 @@ } }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "4.0.26", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.26.tgz", - "integrity": "sha512-z81yyIkGiLLYVDetKTUeCZQ8x20EEzvQjrqJtb/mXnevLq2+w3XCEWTJ2pMp401b6BkEkHVfXb/cROBpVauLMQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.1.0.tgz", + "integrity": "sha512-gnZo3u5dP1o87plKupg39alsbeIY1oFFnCyV2nI/++pL19vTtBLgOyftLEjPjuXmoKn2B2rskX8b7wtC/+3Okg==", "license": "Apache-2.0", "dependencies": { - "@smithy/config-resolver": "^4.1.5", - "@smithy/credential-provider-imds": "^4.0.7", - "@smithy/node-config-provider": "^4.1.4", - "@smithy/property-provider": "^4.0.5", - "@smithy/smithy-client": "^4.4.10", - "@smithy/types": "^4.3.2", + "@smithy/config-resolver": "^4.2.0", + "@smithy/credential-provider-imds": "^4.1.0", + "@smithy/node-config-provider": "^4.2.0", + "@smithy/property-provider": "^4.1.0", + "@smithy/smithy-client": "^4.6.0", + "@smithy/types": "^4.4.0", "tslib": "^2.6.2" }, "engines": { @@ -2812,9 +2812,9 @@ } }, "node_modules/@smithy/util-hex-encoding": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.0.0.tgz", - "integrity": "sha512-Yk5mLhHtfIgW2W2WQZWSg5kuMZCVbvhFmC7rV4IO2QqnZdbEFPmQnCcGMAX2z/8Qj3B9hYYNjZOhWym+RwhePw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.1.0.tgz", + "integrity": "sha512-1LcueNN5GYC4tr8mo14yVYbh/Ur8jHhWOxniZXii+1+ePiIbsLZ5fEI0QQGtbRRP5mOhmooos+rLmVASGGoq5w==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -2824,12 +2824,12 @@ } }, "node_modules/@smithy/util-middleware": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.0.5.tgz", - "integrity": "sha512-N40PfqsZHRSsByGB81HhSo+uvMxEHT+9e255S53pfBw/wI6WKDI7Jw9oyu5tJTLwZzV5DsMha3ji8jk9dsHmQQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.1.0.tgz", + "integrity": "sha512-612onNcKyxhP7/YOTKFTb2F6sPYtMRddlT5mZvYf1zduzaGzkYhpYIPxIeeEwBZFjnvEqe53Ijl2cYEfJ9d6/Q==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.3.2", + "@smithy/types": "^4.4.0", "tslib": "^2.6.2" }, "engines": { @@ -2837,13 +2837,13 @@ } }, "node_modules/@smithy/util-retry": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.0.7.tgz", - "integrity": "sha512-TTO6rt0ppK70alZpkjwy+3nQlTiqNfoXja+qwuAchIEAIoSZW8Qyd76dvBv3I5bCpE38APafG23Y/u270NspiQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.1.0.tgz", + "integrity": "sha512-5AGoBHb207xAKSVwaUnaER+L55WFY8o2RhlafELZR3mB0J91fpL+Qn+zgRkPzns3kccGaF2vy0HmNVBMWmN6dA==", "license": "Apache-2.0", "dependencies": { - "@smithy/service-error-classification": "^4.0.7", - "@smithy/types": "^4.3.2", + "@smithy/service-error-classification": "^4.1.0", + "@smithy/types": "^4.4.0", "tslib": "^2.6.2" }, "engines": { @@ -2851,18 +2851,18 @@ } }, "node_modules/@smithy/util-stream": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.2.4.tgz", - "integrity": "sha512-vSKnvNZX2BXzl0U2RgCLOwWaAP9x/ddd/XobPK02pCbzRm5s55M53uwb1rl/Ts7RXZvdJZerPkA+en2FDghLuQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.3.0.tgz", + "integrity": "sha512-ZOYS94jksDwvsCJtppHprUhsIscRnCKGr6FXCo3SxgQ31ECbza3wqDBqSy6IsAak+h/oAXb1+UYEBmDdseAjUQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/fetch-http-handler": "^5.1.1", - "@smithy/node-http-handler": "^4.1.1", - "@smithy/types": "^4.3.2", - "@smithy/util-base64": "^4.0.0", - "@smithy/util-buffer-from": "^4.0.0", - "@smithy/util-hex-encoding": "^4.0.0", - "@smithy/util-utf8": "^4.0.0", + "@smithy/fetch-http-handler": "^5.2.0", + "@smithy/node-http-handler": "^4.2.0", + "@smithy/types": "^4.4.0", + "@smithy/util-base64": "^4.1.0", + "@smithy/util-buffer-from": "^4.1.0", + "@smithy/util-hex-encoding": "^4.1.0", + "@smithy/util-utf8": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -2870,9 +2870,9 @@ } }, "node_modules/@smithy/util-uri-escape": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.0.0.tgz", - "integrity": "sha512-77yfbCbQMtgtTylO9itEAdpPXSog3ZxMe09AEhm0dU0NLTalV70ghDZFR+Nfi1C60jnJoh/Re4090/DuZh2Omg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.1.0.tgz", + "integrity": "sha512-b0EFQkq35K5NHUYxU72JuoheM6+pytEVUGlTwiFxWFpmddA+Bpz3LgsPRIpBk8lnPE47yT7AF2Egc3jVnKLuPg==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -2882,12 +2882,12 @@ } }, "node_modules/@smithy/util-utf8": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.0.0.tgz", - "integrity": "sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.1.0.tgz", + "integrity": "sha512-mEu1/UIXAdNYuBcyEPbjScKi/+MQVXNIuY/7Cm5XLIWe319kDrT5SizBE95jqtmEXoDbGoZxKLCMttdZdqTZKQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/util-buffer-from": "^4.0.0", + "@smithy/util-buffer-from": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -3951,9 +3951,9 @@ } }, "node_modules/bullmq": { - "version": "5.58.2", - "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.58.2.tgz", - "integrity": "sha512-HSGtNFM8Ttzml4OHO5cy6ju0ObnDmSedXJwpSUCFSDXR6l9MQe5CQCs/FzAb6Ac9EXYIvvF20UMV+C1OVDW39w==", + "version": "5.58.5", + "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.58.5.tgz", + "integrity": "sha512-0A6Qjxdn8j7aOcxfRZY798vO/aMuwvoZwfE6a9EOXHb1pzpBVAogsc/OfRWeUf+5wMBoYB5nthstnJo/zrQOeQ==", "license": "MIT", "dependencies": { "cron-parser": "^4.9.0", @@ -4758,9 +4758,9 @@ } }, "node_modules/dd-trace": { - "version": "5.64.0", - "resolved": "https://registry.npmjs.org/dd-trace/-/dd-trace-5.64.0.tgz", - "integrity": "sha512-24vovvBujJ6zMv5CSro0X29YN8DkoSLd4IVEGUtIWA6ypltU38q+PtPngwRhjb/v11/jvJ+U0P0zyNjfP9FZWg==", + "version": "5.65.0", + "resolved": "https://registry.npmjs.org/dd-trace/-/dd-trace-5.65.0.tgz", + "integrity": "sha512-U4zt7n8hKxjA3y3GTbJI7+ix5iwO5agn+8p6MNIAPgq2JG49jB6hUf78HvrPjGWX5R0fBpyiceOl+aLCsZIHNg==", "hasInstallScript": true, "license": "(Apache-2.0 OR BSD-3-Clause)", "dependencies": { @@ -5086,9 +5086,9 @@ } }, "node_modules/dotenv": { - "version": "17.2.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.1.tgz", - "integrity": "sha512-kQhDYKZecqnM0fCnzI5eIv5L4cAe/iRI+HqMbO/hbRdTAeXDG+M9FjipUxNfbARuEg4iHIbhnhs78BCHNbSxEQ==", + "version": "17.2.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.2.tgz", + "integrity": "sha512-Sf2LSQP+bOlhKWWyhFsn0UsfdK/kCWRv1iuA2gXAwt3dyNabr6QSj00I2V10pidqz69soatm9ZwZvpQMTIOd5Q==", "license": "BSD-2-Clause", "engines": { "node": ">=12" @@ -5529,19 +5529,19 @@ } }, "node_modules/eslint": { - "version": "9.34.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.34.0.tgz", - "integrity": "sha512-RNCHRX5EwdrESy3Jc9o8ie8Bog+PeYvvSR8sDGoZxNFTvZ4dlxUB3WzQ3bQMztFrSRODGrLLj8g6OFuGY/aiQg==", + "version": "9.35.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.35.0.tgz", + "integrity": "sha512-QePbBFMJFjgmlE+cXAlbHZbHpdFVS2E/6vzCy7aKlebddvl1vadiC4JFV5u/wqTkNUwEV8WrQi257jf5f06hrg==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.0", "@eslint/config-helpers": "^0.3.1", "@eslint/core": "^0.15.2", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.34.0", + "@eslint/js": "9.35.0", "@eslint/plugin-kit": "^0.3.5", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -5926,7 +5926,6 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "devOptional": true, "license": "MIT" }, "node_modules/fast-fifo": { @@ -6084,9 +6083,9 @@ } }, "node_modules/firebase-admin": { - "version": "13.4.0", - "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-13.4.0.tgz", - "integrity": "sha512-Y8DcyKK+4pl4B93ooiy1G8qvdyRMkcNFfBSh+8rbVcw4cW8dgG0VXCCTp5NUwub8sn9vSPsOwpb9tE2OuFmcfQ==", + "version": "13.5.0", + "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-13.5.0.tgz", + "integrity": "sha512-QZOpv1DJRJpH8NcWiL1xXE10tw3L/bdPFlgjcWrqU3ufyOJDYfxB1MMtxiVTwxK16NlybQbEM6ciSich2uWEIQ==", "license": "Apache-2.0", "dependencies": { "@fastify/busboy": "^3.0.0", @@ -6094,6 +6093,7 @@ "@firebase/database-types": "^1.0.6", "@types/node": "^22.8.7", "farmhash-modern": "^1.1.0", + "fast-deep-equal": "^3.1.1", "google-auth-library": "^9.14.2", "jsonwebtoken": "^9.0.0", "jwks-rsa": "^3.1.0", @@ -9832,9 +9832,9 @@ } }, "node_modules/skia-canvas": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/skia-canvas/-/skia-canvas-3.0.4.tgz", - "integrity": "sha512-48VxhqX1162eI4V/q2xigK2AfdCPkK7OYiVppOPuRe1mvr0xBzTxPbPmoSOC8L1QZjiyOHfcgMufvp4cJkIMUw==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/skia-canvas/-/skia-canvas-3.0.6.tgz", + "integrity": "sha512-OehNQUz6Oucji41Rh82I5V9IqbTfaEqiD5ua+dnrZXymuQDEGOfUXH9JdgvsVEAD+VEdc3iJLQ4lKsSpV8AC5g==", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -10726,9 +10726,9 @@ "license": "Unlicense" }, "node_modules/twilio": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/twilio/-/twilio-5.8.0.tgz", - "integrity": "sha512-aJLBvI7ODLmFHI7ZYLBiMZKIdHuF9PrPeRM/GBMDg/AAzGXs4V8gEnNPHyTVThK0/8J48YHSqXMlQ+WJR5nxoQ==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/twilio/-/twilio-5.9.0.tgz", + "integrity": "sha512-Ij+xT9MZZSjP64lsy+x6vYsCCb5m2Db9KffkMXBrN3zWbG3rbkXxl+MZVVzrvpwEdSbQD0vMuin+TTlQ6kR6Xg==", "license": "MIT", "dependencies": { "axios": "^1.11.0", diff --git a/package.json b/package.json index dcb2c70ff..332914d40 100644 --- a/package.json +++ b/package.json @@ -18,14 +18,14 @@ "job-totals-fixtures:local": "docker exec node-app /usr/bin/node /app/download-job-totals-fixtures.js" }, "dependencies": { - "@aws-sdk/client-cloudwatch-logs": "^3.876.0", - "@aws-sdk/client-elasticache": "^3.876.0", - "@aws-sdk/client-s3": "^3.876.0", - "@aws-sdk/client-secrets-manager": "^3.876.0", - "@aws-sdk/client-ses": "^3.876.0", - "@aws-sdk/credential-provider-node": "^3.876.0", - "@aws-sdk/lib-storage": "^3.876.0", - "@aws-sdk/s3-request-presigner": "^3.876.0", + "@aws-sdk/client-cloudwatch-logs": "^3.882.0", + "@aws-sdk/client-elasticache": "^3.882.0", + "@aws-sdk/client-s3": "^3.882.0", + "@aws-sdk/client-secrets-manager": "^3.882.0", + "@aws-sdk/client-ses": "^3.882.0", + "@aws-sdk/credential-provider-node": "^3.882.0", + "@aws-sdk/lib-storage": "^3.882.0", + "@aws-sdk/s3-request-presigner": "^3.882.0", "@opensearch-project/opensearch": "^2.13.0", "@socket.io/admin-ui": "^0.5.1", "@socket.io/redis-adapter": "^8.3.0", @@ -33,18 +33,18 @@ "aws4": "^1.13.2", "axios": "^1.11.0", "better-queue": "^3.8.12", - "bullmq": "^5.58.2", + "bullmq": "^5.58.5", "chart.js": "^4.5.0", "cloudinary": "^2.7.0", "compression": "^1.8.1", "cookie-parser": "^1.4.7", "cors": "^2.8.5", "crisp-status-reporter": "^1.2.2", - "dd-trace": "^5.64.0", + "dd-trace": "^5.65.0", "dinero.js": "^1.9.1", - "dotenv": "^17.2.1", + "dotenv": "^17.2.2", "express": "^4.21.1", - "firebase-admin": "^13.4.0", + "firebase-admin": "^13.5.0", "graphql": "^16.11.0", "graphql-request": "^6.1.0", "intuit-oauth": "^4.2.0", @@ -62,12 +62,12 @@ "query-string": "7.1.3", "recursive-diff": "^1.0.9", "rimraf": "^6.0.1", - "skia-canvas": "^3.0.4", + "skia-canvas": "^3.0.6", "soap": "^1.3.0", "socket.io": "^4.8.1", "socket.io-adapter": "^2.5.5", "ssh2-sftp-client": "^11.0.0", - "twilio": "^5.8.0", + "twilio": "^5.9.0", "uuid": "^11.1.0", "winston": "^3.17.0", "winston-cloudwatch": "^6.3.0", @@ -76,8 +76,8 @@ "yazl": "^3.3.1" }, "devDependencies": { - "@eslint/js": "^9.34.0", - "eslint": "^9.34.0", + "@eslint/js": "^9.35.0", + "eslint": "^9.35.0", "eslint-plugin-react": "^7.37.5", "globals": "^15.15.0", "mock-require": "^3.0.3", diff --git a/server/integrations/partsManagement/endpoints/partsManagementDeprovisioning.js b/server/integrations/partsManagement/endpoints/partsManagementDeprovisioning.js index d780daaa5..e9875fe10 100644 --- a/server/integrations/partsManagement/endpoints/partsManagementDeprovisioning.js +++ b/server/integrations/partsManagement/endpoints/partsManagementDeprovisioning.js @@ -144,7 +144,7 @@ const partsManagementDeprovisioning = async (req, res) => { } catch (userError) { logger.log("admin-delete-user-error", "warn", null, null, { email: user.email, - error: userError.message + error: userError.message || userError }); } } diff --git a/server/integrations/partsManagement/endpoints/vehicleDamageEstimateAddRq.js b/server/integrations/partsManagement/endpoints/vehicleDamageEstimateAddRq.js index cc88cf78f..78c344387 100644 --- a/server/integrations/partsManagement/endpoints/vehicleDamageEstimateAddRq.js +++ b/server/integrations/partsManagement/endpoints/vehicleDamageEstimateAddRq.js @@ -1,9 +1,10 @@ -// no-dd-sa:javascript-code-style/assignment-name -// CamelCase is used for GraphQL and database fields. - const client = require("../../../graphql-client/graphql-client").client; const { extractPartsTaxRates } = require("./lib/extractPartsTaxRates"); const { parseXml, normalizeXmlObject } = require("../partsManagementUtils"); +const opCodes = require("./lib/opCodes.json"); +// New imports for S3 XML archival +const { uploadFileToS3 } = require("../../../utils/s3"); +const InstanceMgr = require("../../../utils/instanceMgr").default; // GraphQL Queries and Mutations const { @@ -12,10 +13,28 @@ const { INSERT_OWNER, INSERT_JOB_WITH_LINES } = require("../partsManagement.queries"); +const { v4: uuidv4 } = require("uuid"); // Defaults const FALLBACK_DEFAULT_JOB_STATUS = "Open"; +const ESTIMATE_XML_BUCKET = + process.env?.NODE_ENV === "development" + ? "parts-estimates" // local/dev shared bucket name + : InstanceMgr({ + imex: `imex-webest-xml`, + rome: `rome-webest-xml` + }); + +const buildEstimateXmlKey = (rq) => { + const refClaimNum = rq.RefClaimNum; + const shopId = rq.ShopID; + + const ts = new Date().toISOString().replace(/:/g, "-"); + const safeClaim = (refClaimNum || "no-claim").toString().replace(/[^A-Za-z0-9_-]/g, "_"); + return `addRequest/${shopId}/${safeClaim}/${ts}-${uuidv4()}.xml`; +}; + /** * Fetches the default order status for a bodyshop. * @param {string} shopId - The bodyshop UUID. @@ -65,6 +84,7 @@ const extractJobData = (rq) => { const ci = rq.ClaimInfo || {}; return { + driveable: !!rq.VehicleInfo?.Condition?.DrivableInd, shopId: rq.ShopID || rq.shopId, // status: ci.ClaimStatus || null, Proper, setting it default for now refClaimNum: rq.RefClaimNum, @@ -107,8 +127,7 @@ const extractOwnerData = (rq, shopId) => { : [ownerOrClaimant.ContactInfo?.Communications || {}]; for (const c of comms) { - // TODO: Should document this logic. 1 and 2 don't - // typically indicate type in EMS. This makes sense, but good to document. + // -- Document if (c.CommQualifier === "CP") ownr_ph1 = c.CommPhone; if (c.CommQualifier === "WP") ownr_ph2 = c.CommPhone; if (c.CommQualifier === "EM") ownr_ea = c.CommEmail; @@ -167,7 +186,7 @@ const extractEstimatorData = (rq) => { // : [adjParty.ContactInfo?.Communications || {}]; // // return { -// //TODO: I dont think we display agt_ct_* fields in app. Have they typically been sending data here? +// //TODO (FUTURE): I dont think we display agt_ct_* fields in app. Have they typically been sending data here? // agt_ct_fn: adjParty.PersonInfo?.PersonName?.FirstName || null, // agt_ct_ln: adjParty.PersonInfo?.PersonName?.LastName || null, // agt_ct_ph: adjComms.find((c) => c.CommQualifier === "CP")?.CommPhone || null, @@ -188,8 +207,8 @@ const extractEstimatorData = (rq) => { // // return { // servicing_dealer: rfParty.OrgInfo?.CompanyName || null, -// // TODO: The servicing dealer fields are a relic from synergy for a few folks -// // TODO: I suspect RF data could be ignored since they are the RF. +// // TODO (Future): The servicing dealer fields are a relic from synergy for a few folks +// // TODO (Future): I suspect RF data could be ignored since they are the RF. // servicing_dealer_contact: // rfComms.find((c) => c.CommQualifier === "WP" || c.CommQualifier === "FX")?.CommPhone || null // }; @@ -294,10 +313,9 @@ const extractVehicleData = (rq, shopId) => { v_color: exterior.Color?.ColorName || null, v_bstyle: desc.BodyStyle || null, v_engine: desc.EngineDesc || null, - // TODO Need to confirm with exact data, but this is typically a list of options. Not used AFAIK. - v_options: desc.SubModelDesc || null, + // TODO (for future) Need to confirm with exact data, but this is typically a list of options. Not used AFAIK. + // v_options: desc.SubModelDesc || null, v_type: desc.FuelType || null, - // TODO there is a separate driveable flag on the job. v_cond: rq.VehicleInfo?.Condition?.DrivableInd, v_trimcode: desc.TrimCode || null, v_tone: exterior.Tone || null, @@ -345,30 +363,34 @@ const extractJobLines = (rq) => { const lineOut = { ...base }; // Manual line flag coercion - if (line.ManualLineInd !== undefined) { - lineOut.manual_line = - line.ManualLineInd === true || - line.ManualLineInd === 1 || - line.ManualLineInd === "1" || - // TODO: manual line tracks manual in IO or not, this woudl presumably always be false - (typeof line.ManualLineInd === "string" && line.ManualLineInd.toUpperCase() === "Y"); - } else { - lineOut.manual_line = null; - } + // if (line.ManualLineInd !== undefined) { + // lineOut.manual_line = + // line.ManualLineInd === true || + // line.ManualLineInd === 1 || + // line.ManualLineInd === "1" || + // // TODO (FUTURE): manual line tracks manual in IO or not, this woudl presumably always be false + // (typeof line.ManualLineInd === "string" && line.ManualLineInd.toUpperCase() === "Y"); + // } else { + // lineOut.manual_line = null; + // } + + // Is set to false because anything coming from the DMS is considered not a manual line, it becomes + // a manual line once it is edited in OUR system. + lineOut.manual_line = false; // Parts (preferred) or Sublet (fallback when no PartInfo) const hasPart = Object.keys(partInfo).length > 0; const hasSublet = Object.keys(subletInfo).length > 0; if (hasPart) { - const price = parseFloat(partInfo.PartPrice || partInfo.ListPrice || 0); lineOut.part_type = partInfo.PartType || null ? String(partInfo.PartType).toUpperCase() : null; lineOut.part_qty = parseFloat(partInfo.Quantity || 0) || 1; - //TODO: if aftermarket part, we have alt_part_no to capture. - lineOut.oem_partno = partInfo.OEMPartNum || partInfo.PartNum || null; - //TODO: the Db and act price often are different. These should map back to their EMS equivalents. - lineOut.db_price = isNaN(price) ? 0 : price; - lineOut.act_price = isNaN(price) ? 0 : price; + lineOut.oem_partno = partInfo.OEMPartNum; + lineOut.alt_partno = partInfo?.NonOEM?.NonOEMPartNum; + + // THIS NEEDS TO BE CHANGED IN CHANGE REQUEST + lineOut.act_price = parseFloat(partInfo?.PartPrice || 0); + lineOut.db_price = parseFloat(partInfo?.OEMPartPrice || 0); // Tax flag from PartInfo.TaxableInd when provided if ( @@ -384,8 +406,10 @@ const extractJobLines = (rq) => { (typeof partInfo.TaxableInd === "string" && partInfo.TaxableInd.toUpperCase() === "Y"); } } - //TODO: Some nuance here. Usually a part and sublet amount shouldnt be on the same line, but they theoretically - // could.May require additional discussion. + + //TODO (FUTURE): Some nuance here. Usually a part and sublet amount shouldnt be on the same line, but they theoretically + // could. May require additional discussion. + // EMS - > Misc Amount, calibration for example, painting, etc else if (hasSublet) { const amt = parseFloat(subletInfo.SubletAmount || 0); lineOut.part_type = "PAS"; // Sublet as parts-as-service @@ -400,18 +424,22 @@ const extractJobLines = (rq) => { (!!laborInfo.LaborType && String(laborInfo.LaborType).length > 0) || (!isNaN(hrs) && hrs !== 0) || (!isNaN(amt) && amt !== 0); + if (hasLabor) { lineOut.mod_lbr_ty = laborInfo.LaborType || null; lineOut.mod_lb_hrs = isNaN(hrs) ? 0 : hrs; - //TODO: can add lbr_op_desc according to mapping available in new partner. - lineOut.lbr_op = laborInfo.LaborOperation || null; + const opCodeKey = + typeof laborInfo.LaborOperation === "string" ? laborInfo.LaborOperation.trim().toUpperCase() : null; + lineOut.op_code_desc = opCodes?.[opCodeKey]?.desc || null; + lineOut.lbr_amt = isNaN(amt) ? 0 : amt; } - //TODO: what's the BMS logic for this? Body and refinish operations can often happen to the same part, + //TODO (FUTURE): what's the BMS logic for this? Body and refinish operations can often happen to the same part, // but most systems output a second line for the refinish labor. - //TODO: 2nd line may include a duplicate of the part price, but that can be removed. This is the case for CCC. + //TODO (FUTURE): 2nd line may include a duplicate of the part price, but that can be removed. This is the case for CCC. // Refinish labor (if present) recorded on the same line using secondary labor fields + const rHrs = parseFloat(refinishInfo.LaborHours || 0); const rAmt = parseFloat(refinishInfo.LaborAmt || 0); const hasRefinish = @@ -421,9 +449,9 @@ const extractJobLines = (rq) => { !isNaN(rAmt) || !!refinishInfo.LaborOperation); if (hasRefinish) { - lineOut.lbr_typ_j = refinishInfo.LaborType || "LAR"; //TODO: _j fields indicate judgement, and are bool type. - lineOut.lbr_hrs_j = isNaN(rHrs) ? 0 : rHrs; //TODO: _j fields indicate judgement, and are bool type. - lineOut.lbr_op_j = refinishInfo.LaborOperation || null; //TODO: _j fields indicate judgement, and are bool type. + lineOut.lbr_typ_j = !!refinishInfo?.LaborAmtJudgmentInd; + lineOut.lbr_hrs_j = !!refinishInfo?.LaborHoursJudgmentInd; + lineOut.lbr_op_j = !!refinishInfo.LaborOperationJudgmentInd; // Aggregate refinish labor amount into the total labor amount for the line if (!isNaN(rAmt)) { lineOut.lbr_amt = (Number.isFinite(lineOut.lbr_amt) ? lineOut.lbr_amt : 0) + rAmt; @@ -494,9 +522,10 @@ const insertOwner = async (ownerInput, logger) => { // } // const total = parts + labor; // -// //TODO: clm_total is the 100% full amount of the repair including deductible, betterment and taxes. Typically provided by the source system. +// //TODO (FUTURE): clm_total is the 100% full amount of the repair including deductible, betterment and taxes. Typically provided by the source system. // return Number.isFinite(total) && total > 0 ? total : 0; -// }; +// //TODO (FUTURE): clm_total is the 100% full amount of the repair including deductible, +// // betterment and taxes. Typically provided by the source system. /** * Handles the VehicleDamageEstimateAddRq XML request from parts management. @@ -506,17 +535,10 @@ const insertOwner = async (ownerInput, logger) => { */ const vehicleDamageEstimateAddRq = async (req, res) => { const { logger } = req; - + const rawXml = typeof req.body === "string" ? req.body : Buffer.isBuffer(req.body) ? req.body.toString("utf8") : ""; try { - // Parse XML const payload = await parseXml(req.body, logger); const rq = normalizeXmlObject(payload.VehicleDamageEstimateAddRq); - if (!rq) { - logger.log("parts-missing-root", "error"); - return res.status(400).send("Missing "); - } - - // Extract job data const { shopId, refClaimNum, @@ -534,39 +556,22 @@ const vehicleDamageEstimateAddRq = async (req, res) => { scheduled_completion, clm_no, policy_no, - ded_amt - // status, + ded_amt, + driveable } = extractJobData(rq); - - if (!shopId) { - throw { status: 400, message: "Missing in XML" }; - } - - // Get default status const defaultStatus = await getDefaultJobStatus(shopId, logger); - - // Extract additional data const parts_tax_rates = extractPartsTaxRates(rq.ProfileInfo); const ownerData = extractOwnerData(rq, shopId); const estimatorData = extractEstimatorData(rq); - // const adjusterData = extractAdjusterData(rq); - // const repairFacilityData = extractRepairFacilityData(rq); const vehicleData = extractVehicleData(rq, shopId); const lossInfo = extractLossInfo(rq); const joblinesData = extractJobLines(rq); const insuranceData = extractInsuranceData(rq); - - // Derive clm_total: prefer RepairTotalsInfo SummaryTotals GRAND TOTAL; else sum from lines - // const grandTotal = extractGrandTotal(rq); - // const computedTotal = grandTotal ?? computeLinesTotal(joblinesData); - - // Find or create relationships const ownerid = await insertOwner(ownerData, logger); const vehicleid = await findExistingVehicle(shopId, vehicleData.v_vin, logger); - - // Build job input const jobInput = { shopid: shopId, + driveable, converted: true, ownerid, ro_number: refClaimNum, @@ -578,7 +583,7 @@ const vehicleDamageEstimateAddRq = async (req, res) => { parts_tax_rates, clm_no, status: defaultStatus, - clm_total: 0, // computedTotal || null, + clm_total: 0, policy_no, ded_amt, comment, @@ -588,14 +593,10 @@ const vehicleDamageEstimateAddRq = async (req, res) => { asgn_date, scheduled_in, scheduled_completion, - // Inline insurance/loss/contacts ...insuranceData, ...lossInfo, ...ownerData, ...estimatorData, - // ...adjusterData, - // ...repairFacilityData, - // Inline vehicle data v_vin: vehicleData.v_vin, v_model_yr: vehicleData.v_model_yr, v_model_desc: vehicleData.v_model_desc, @@ -606,10 +607,23 @@ const vehicleDamageEstimateAddRq = async (req, res) => { ...(vehicleid ? { vehicleid } : { vehicle: { data: vehicleData } }), joblines: { data: joblinesData } }; - - // Insert job const { insert_jobs_one: newJob } = await client.request(INSERT_JOB_WITH_LINES, { job: jobInput }); + // Upload AFTER job creation to include job id in filename + (async () => { + try { + const key = buildEstimateXmlKey(rq); + await uploadFileToS3({ + bucketName: ESTIMATE_XML_BUCKET, + key, + content: rawXml || "", + contentType: "application/xml" + }); + logger.log("parts-estimate-xml-uploaded", "info", shopId, newJob.id, { key, bytes: rawXml?.length || 0 }); + } catch (e) { + logger.log("parts-estimate-xml-upload-failed", "warn", shopId, null, { error: e?.message }); + } + })(); return res.status(200).json({ success: true, jobId: newJob.id }); } catch (err) { logger.log("parts-route-error", "error", null, null, { error: err }); diff --git a/server/integrations/partsManagement/endpoints/vehicleDamageEstimateChgRq.js b/server/integrations/partsManagement/endpoints/vehicleDamageEstimateChgRq.js index b69b2466c..87ddee580 100644 --- a/server/integrations/partsManagement/endpoints/vehicleDamageEstimateChgRq.js +++ b/server/integrations/partsManagement/endpoints/vehicleDamageEstimateChgRq.js @@ -4,17 +4,22 @@ const client = require("../../../graphql-client/graphql-client").client; const { parseXml, normalizeXmlObject } = require("../partsManagementUtils"); const { extractPartsTaxRates } = require("./lib/extractPartsTaxRates"); +const opCodes = require("./lib/opCodes.json"); +const { uploadFileToS3 } = require("../../../utils/s3"); +const InstanceMgr = require("../../../utils/instanceMgr").default; const { GET_JOB_BY_ID, UPDATE_JOB_BY_ID, SOFT_DELETE_JOBLINES_BY_IDS, - INSERT_JOBLINES, - GET_JOBLINES_NOTES_BY_JOBID_UNQSEQ + GET_JOBLINES_NOTES_BY_JOBID_UNQSEQ, + GET_JOBLINE_IDS_BY_JOBID_UNQSEQ, + UPDATE_JOBLINE_BY_PK, + INSERT_JOBLINES } = require("../partsManagement.queries"); /** - * Finds a job by shop ID and claim number. + * Finds a job by shop ID and job ID. * @param shopId * @param jobId * @param logger @@ -32,38 +37,37 @@ const findJob = async (shopId, jobId, logger) => { /** * Extracts updated job data from the request payload. + * Mirrors AddRq for parts_tax_rates + driveable when present. * @param rq - * @returns {{comment: (number|((comment: Comment, helper: postcss.Helpers) => (Promise | void))|string|null), clm_no: null, status: (*|null), policy_no: (*|null)}} */ const extractUpdatedJobData = (rq) => { const doc = rq.DocumentInfo || {}; const claim = rq.ClaimInfo || {}; - //TODO: In the full BMS world, much more can change, this will need to be expanded - // before it can be considered an generic BMS importer, currently it is bespoke to webest const policyNo = claim.PolicyInfo?.PolicyInfo?.PolicyNum || claim.PolicyInfo?.PolicyNum || null; const out = { comment: doc.Comment || null, clm_no: claim.ClaimNum || null, - // TODO: Commented out so they do not blow over with 'Auth Cust' - // status: claim.ClaimStatus || null, + // TODO (future): status omitted intentionally to avoid overwriting with 'Auth Cust' policy_no: policyNo }; - // If ProfileInfo provided in ChangeRq, update parts_tax_rates to stay in sync with AddRq behavior if (rq.ProfileInfo) { out.parts_tax_rates = extractPartsTaxRates(rq.ProfileInfo); } + if (rq.VehicleInfo?.Condition?.DrivableInd !== undefined) { + out.driveable = !!rq.VehicleInfo.Condition.DrivableInd; + } + return out; }; /** - * Extracts updated job lines from the request payload without splitting parts and labor: - * - Keep part and labor on the same jobline - * - Aggregate RefinishLabor into secondary labor fields and add its amount to lbr_amt - * - SUBLET-only lines become PAS part_type with act_price = SubletAmount - * Accepts currentJobLineNotes map for notes merging. + * Build jobline payloads for updates/inserts (no split between parts & labor). + * - Refinish labor aggregated into lbr_* secondary fields and lbr_amt. + * - SUBLET-only -> PAS line with act_price = SubletAmount. + * - Notes merged with current DB value by unq_seq. */ const extractUpdatedJobLines = (addsChgs = {}, jobId, currentJobLineNotes = {}) => { const linesIn = Array.isArray(addsChgs.DamageLineInfo) ? addsChgs.DamageLineInfo : [addsChgs.DamageLineInfo || {}]; @@ -87,56 +91,38 @@ const extractUpdatedJobLines = (addsChgs = {}, jobId, currentJobLineNotes = {}) unq_seq: parseInt(line.UniqueSequenceNum || 0, 10), status: line.LineStatusCode || null, line_desc: line.LineDesc || null, - // notes will be set below manual_line: line.ManualLineInd !== undefined ? coerceManual(line.ManualLineInd) : null }; const lineOut = { ...base }; - // --- Notes merge logic --- + // --- Notes merge --- const unqSeq = lineOut.unq_seq; const currentNotes = currentJobLineNotes?.[unqSeq] || null; const newNotes = line.LineMemo || null; if (newNotes && currentNotes) { - if (currentNotes === newNotes) { - lineOut.notes = currentNotes; - } else if (currentNotes.includes(newNotes)) { - lineOut.notes = currentNotes; - } else { - lineOut.notes = `${currentNotes} | ${newNotes}`; - } - } else if (newNotes) { - lineOut.notes = newNotes; - } else if (currentNotes) { - lineOut.notes = currentNotes; - } else { - lineOut.notes = null; - } - // --- End notes merge logic --- + if (currentNotes === newNotes || currentNotes.includes(newNotes)) lineOut.notes = currentNotes; + else lineOut.notes = `${currentNotes} | ${newNotes}`; + } else if (newNotes) lineOut.notes = newNotes; + else if (currentNotes) lineOut.notes = currentNotes; + else lineOut.notes = null; + // --- end notes merge --- const hasPart = Object.keys(partInfo).length > 0; const hasSublet = Object.keys(subletInfo).length > 0; if (hasPart) { - const price = parseFloat(partInfo.PartPrice || partInfo.ListPrice || 0); - lineOut.part_type = partInfo.PartType ? String(partInfo.PartType).toUpperCase() : null; lineOut.part_qty = parseFloat(partInfo.Quantity || 0) || 1; - lineOut.oem_partno = partInfo.OEMPartNum || partInfo.PartNum || null; - lineOut.db_price = isNaN(price) ? 0 : price; - lineOut.act_price = isNaN(price) ? 0 : price; + lineOut.oem_partno = partInfo.OEMPartNum; + lineOut.alt_partno = partInfo?.NonOEM?.NonOEMPartNum; + lineOut.part_type = partInfo.PartType || null ? String(partInfo.PartType).toUpperCase() : null; - // Optional: taxability flag for parts - if ( - partInfo.TaxableInd !== undefined && - (typeof partInfo.TaxableInd === "string" || - typeof partInfo.TaxableInd === "number" || - typeof partInfo.TaxableInd === "boolean") - ) { - lineOut.tax_part = - partInfo.TaxableInd === true || - partInfo.TaxableInd === 1 || - partInfo.TaxableInd === "1" || - (typeof partInfo.TaxableInd === "string" && partInfo.TaxableInd.toUpperCase() === "Y"); + lineOut.act_price = parseFloat(partInfo?.PartPrice || 0); + lineOut.db_price = parseFloat(partInfo?.OEMPartPrice || 0); + + if (partInfo.TaxableInd !== undefined) { + const t = partInfo.TaxableInd; + lineOut.tax_part = t === true || t === 1 || t === "1" || (typeof t === "string" && t.toUpperCase() === "Y"); } } else if (hasSublet) { const amt = parseFloat(subletInfo.SubletAmount || 0); @@ -145,7 +131,7 @@ const extractUpdatedJobLines = (addsChgs = {}, jobId, currentJobLineNotes = {}) lineOut.act_price = isNaN(amt) ? 0 : amt; } - // Primary labor on same line + // Primary labor const hrs = parseFloat(laborInfo.LaborHours || 0); const amt = parseFloat(laborInfo.LaborAmt || 0); const hasLabor = @@ -155,11 +141,15 @@ const extractUpdatedJobLines = (addsChgs = {}, jobId, currentJobLineNotes = {}) if (hasLabor) { lineOut.mod_lbr_ty = laborInfo.LaborType || null; lineOut.mod_lb_hrs = isNaN(hrs) ? 0 : hrs; - lineOut.lbr_op = laborInfo.LaborOperation || null; + + const opCodeKey = + typeof laborInfo.LaborOperation === "string" ? laborInfo.LaborOperation.trim().toUpperCase() : null; + lineOut.op_code_desc = opCodeKey && opCodes?.[opCodeKey]?.desc ? opCodes[opCodeKey].desc : null; + lineOut.lbr_amt = isNaN(amt) ? 0 : amt; } - // Refinish labor on same line using secondary fields; aggregate amount into lbr_amt + // Refinish (secondary fields, add amount) const rHrs = parseFloat(refinishInfo.LaborHours || 0); const rAmt = parseFloat(refinishInfo.LaborAmt || 0); const hasRefinish = @@ -172,9 +162,7 @@ const extractUpdatedJobLines = (addsChgs = {}, jobId, currentJobLineNotes = {}) lineOut.lbr_typ_j = refinishInfo.LaborType || "LAR"; lineOut.lbr_hrs_j = isNaN(rHrs) ? 0 : rHrs; lineOut.lbr_op_j = refinishInfo.LaborOperation || null; - if (!isNaN(rAmt)) { - lineOut.lbr_amt = (Number.isFinite(lineOut.lbr_amt) ? lineOut.lbr_amt : 0) + rAmt; - } + if (!isNaN(rAmt)) lineOut.lbr_amt = (Number.isFinite(lineOut.lbr_amt) ? lineOut.lbr_amt : 0) + rAmt; if (refinishInfo.PaintStagesNum !== undefined) lineOut.paint_stg = refinishInfo.PaintStagesNum; if (refinishInfo.PaintTonesNum !== undefined) lineOut.paint_tone = refinishInfo.PaintTonesNum; } @@ -186,85 +174,186 @@ const extractUpdatedJobLines = (addsChgs = {}, jobId, currentJobLineNotes = {}) }; /** - * Extracts deletion IDs from the deletions object, also removing any derived labor/refinish lines - * by including offsets (base + 400000, base + 500000). + * Expand deletion IDs to include derived labor/refinish offsets. */ const extractDeletions = (deletions = {}) => { const items = Array.isArray(deletions.DamageLineInfo) ? deletions.DamageLineInfo : [deletions.DamageLineInfo || {}]; const baseSeqs = items.map((line) => parseInt(line.UniqueSequenceNum, 10)).filter((id) => Number.isInteger(id)); const allSeqs = []; - for (const u of baseSeqs) { - allSeqs.push(u, u + 400000, u + 500000); - } - // De-dup + for (const u of baseSeqs) allSeqs.push(u, u + 400000, u + 500000); return Array.from(new Set(allSeqs)); }; +// S3 bucket + key builder (mirrors AddRq but with changeRequest prefix) +const ESTIMATE_XML_BUCKET = + process.env?.NODE_ENV === "development" + ? "parts-estimates" + : InstanceMgr({ + imex: `imex-webest-xml`, + rome: `rome-webest-xml` + }); + +const buildEstimateXmlKey = (rq) => { + const shopId = rq.ShopID; + const jobId = rq.JobID; + const ts = new Date().toISOString().replace(/:/g, "-"); + return `changeRequest/${shopId}/${jobId}/${ts}.xml`; +}; + /** - * Handles VehicleDamageEstimateChgRq requests. - * @param req - * @param res - * @returns {Promise<*>} + * Convert a full jobline object into a jobs_set_input for update_by_pk (omit immutable fields). + */ +const toJoblineSetInput = (jl) => { + const { + // immutable identity fields: + // jobid, + // unq_seq, + // everything else: + line_no, + status, + line_desc, + manual_line, + notes, + part_qty, + oem_partno, + alt_partno, + part_type, + act_price, + db_price, + tax_part, + mod_lbr_ty, + mod_lb_hrs, + op_code_desc, + lbr_amt, + lbr_typ_j, + lbr_hrs_j, + lbr_op_j, + paint_stg, + paint_tone + } = jl; + + return { + line_no, + status, + line_desc, + manual_line, + notes, + part_qty, + oem_partno, + alt_partno, + part_type, + act_price, + db_price, + tax_part, + mod_lbr_ty, + mod_lb_hrs, + op_code_desc, + lbr_amt, + lbr_typ_j, + lbr_hrs_j, + lbr_op_j, + paint_stg, + paint_tone + }; +}; + +/** + * Handles VehicleDamageEstimateChgRq requests: + * - Update core job fields + * - For lines: update by PK if existing; otherwise bulk insert + * - Soft-delete only explicit deletions (exclude any updated seqs) */ const partsManagementVehicleDamageEstimateChgRq = async (req, res) => { const { logger } = req; - + const rawXml = typeof req.body === "string" ? req.body : Buffer.isBuffer(req.body) ? req.body.toString("utf8") : ""; try { const payload = await parseXml(req.body, logger); const rq = normalizeXmlObject(payload.VehicleDamageEstimateChgRq); - if (!rq) return res.status(400).send("Missing "); - const shopId = rq.ShopID; const jobId = rq.JobID; + const shopId = rq.ShopID; - if (!shopId || !jobId) return res.status(400).send("Missing ShopID or JobID"); + // Fire-and-forget archival on valid request + (async () => { + try { + const key = buildEstimateXmlKey(rq); + await uploadFileToS3({ + bucketName: ESTIMATE_XML_BUCKET, + key, + content: rawXml || "", + contentType: "application/xml" + }); + logger.log("parts-estimate-xml-uploaded", "info", jobId, null, { key, bytes: rawXml?.length || 0 }); + } catch (e) { + logger.log("parts-estimate-xml-upload-failed", "warn", jobId, null, { error: e?.message }); + } + })(); const job = await findJob(shopId, jobId, logger); - if (!job) return res.status(404).send("Job not found"); - // --- Get updated lines and their unq_seq --- + // --- Updated seqs from incoming changes --- const linesIn = Array.isArray(rq.AddsChgs?.DamageLineInfo) ? rq.AddsChgs.DamageLineInfo : [rq.AddsChgs?.DamageLineInfo || {}]; + const updatedSeqs = Array.from( new Set((linesIn || []).map((l) => parseInt(l?.UniqueSequenceNum || 0, 10)).filter((v) => Number.isInteger(v))) ); + + // --- Fetch current notes for merge --- let currentJobLineNotes = {}; if (updatedSeqs.length > 0) { const resp = await client.request(GET_JOBLINES_NOTES_BY_JOBID_UNQSEQ, { jobid: job.id, unqSeqs: updatedSeqs }); if (resp?.joblines) { - for (const jl of resp.joblines) { - currentJobLineNotes[jl.unq_seq] = jl.notes; - } + for (const jl of resp.joblines) currentJobLineNotes[jl.unq_seq] = jl.notes; } } - // --- End fetch current notes --- const updatedJobData = extractUpdatedJobData(rq); const updatedLines = extractUpdatedJobLines(rq.AddsChgs, job.id, currentJobLineNotes); - const deletedLineIds = extractDeletions(rq.Deletions); - await client.request(UPDATE_JOB_BY_ID, { id: job.id, job: updatedJobData }); - - //TODO: for changed lines, are they deleted and then reinserted? - //TODO: Updated lines should get an upsert to update things like desc, price, etc. - if (deletedLineIds?.length || updatedSeqs?.length) { - const allToDelete = Array.from(new Set([...(deletedLineIds || []), ...(updatedSeqs || [])])); - if (allToDelete.length) { - await client.request(SOFT_DELETE_JOBLINES_BY_IDS, { jobid: job.id, unqSeqs: allToDelete }); - //TODO: appears to soft delete updated lines as well. + // --- Look up existing rows (by natural key) to decide update vs insert --- + let existingIdByUnqSeq = {}; + if (updatedSeqs.length > 0) { + const existing = await client.request(GET_JOBLINE_IDS_BY_JOBID_UNQSEQ, { jobid: job.id, unqSeqs: updatedSeqs }); + if (existing?.joblines) { + for (const row of existing.joblines) existingIdByUnqSeq[row.unq_seq] = row.id; } } - if (updatedLines.length > 0) { - // Insert fresh versions after deletion so we don’t depend on a unique constraint - await client.request(INSERT_JOBLINES, { - joblines: updatedLines - }); + const toUpdate = []; + const toInsert = []; + for (const jl of updatedLines) { + const id = existingIdByUnqSeq[jl.unq_seq]; + if (id) toUpdate.push({ id, _set: toJoblineSetInput(jl) }); + else toInsert.push(jl); } + // Build deletions list and exclude any seqs we are updating (avoid accidental removal) + const deletedLineIdsAll = extractDeletions(rq.Deletions); + const deletionSeqs = deletedLineIdsAll.filter((u) => !updatedSeqs.includes(u)); + + // Mutations: + const updateJobPromise = client.request(UPDATE_JOB_BY_ID, { id: job.id, job: updatedJobData }); + + const softDeletePromise = deletionSeqs.length + ? client.request(SOFT_DELETE_JOBLINES_BY_IDS, { jobid: job.id, unqSeqs: deletionSeqs }) + : Promise.resolve({}); + + // Update each existing row by primary key (parallelized) + const perRowUpdatesPromise = + toUpdate.length > 0 + ? Promise.all(toUpdate.map(({ id, _set }) => client.request(UPDATE_JOBLINE_BY_PK, { id, jl: _set }))) + : Promise.resolve([]); + + // Insert brand-new rows in bulk + const insertPromise = + toInsert.length > 0 ? client.request(INSERT_JOBLINES, { joblines: toInsert }) : Promise.resolve({}); + + await Promise.all([updateJobPromise, softDeletePromise, perRowUpdatesPromise, insertPromise]); + logger.log("parts-job-changed", "info", job.id, null); return res.status(200).json({ success: true, jobId: job.id }); } catch (err) { diff --git a/server/integrations/partsManagement/partsManagement.queries.js b/server/integrations/partsManagement/partsManagement.queries.js index 129ca4419..6b73fcf41 100644 --- a/server/integrations/partsManagement/partsManagement.queries.js +++ b/server/integrations/partsManagement/partsManagement.queries.js @@ -246,6 +246,58 @@ const DELETE_PARTS_ORDERS_BY_JOB_IDS = ` } `; +const UPSERT_JOBLINES = ` + mutation UpsertJoblines($joblines: [joblines_insert_input!]!) { + insert_joblines( + objects: $joblines, + on_conflict: { + constraint: joblines_jobid_unq_seq_key, + update_columns: [ + status, + line_desc, + notes, + manual_line, + part_qty, + oem_partno, + alt_partno, + part_type, + act_price, + db_price, + tax_part, + mod_lbr_ty, + mod_lb_hrs, + op_code_desc, + lbr_amt, + lbr_typ_j, + lbr_hrs_j, + lbr_op_j, + paint_stg, + paint_tone + ] + } + ) { + affected_rows + } + } +`; + +// Get jobline IDs for the incoming unq_seq values (only non-removed) +const GET_JOBLINE_IDS_BY_JOBID_UNQSEQ = ` + query GetJoblineIdsByJobIdUnqSeq($jobid: uuid!, $unqSeqs: [Int!]!) { + joblines(where: { jobid: { _eq: $jobid }, unq_seq: { _in: $unqSeqs }, removed: { _neq: true } }) { + id + unq_seq + } + } +`; + +// Update a single jobline by primary key +const UPDATE_JOBLINE_BY_PK = ` + mutation UpdateJoblineByPk($id: uuid!, $jl: joblines_set_input!) { + update_joblines_by_pk(pk_columns: { id: $id }, _set: $jl) { id } + } +`; + module.exports = { GET_BODYSHOP_STATUS, GET_VEHICLE_BY_SHOP_VIN, @@ -272,8 +324,10 @@ module.exports = { DELETE_AUDIT_TRAIL_BY_SHOP, GET_JOBLINES_NOTES_BY_JOBID_UNQSEQ, GET_JOB_BY_ID, - // newly added exports CLEAR_TASKS_PARTSORDER_LINKS_BY_JOBIDS, DELETE_PARTS_ORDER_LINES_BY_JOB_IDS, - DELETE_PARTS_ORDERS_BY_JOB_IDS + DELETE_PARTS_ORDERS_BY_JOB_IDS, + UPSERT_JOBLINES, + GET_JOBLINE_IDS_BY_JOBID_UNQSEQ, + UPDATE_JOBLINE_BY_PK };