@shipengine/elements 2.26.2 → 2.26.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/cc-provider-logo/cc-provider-logo.cjs +2 -1
- package/dist/cjs/components/forms/wallet-form/wallet-schema.cjs +1 -1
- package/dist/cjs/components/shipment-not-found-error/shipment-not-found-error.cjs +17 -2
- package/dist/cjs/components/suspend-purchase/suspend-purchase.cjs +3 -3
- package/dist/cjs/elements/purchase-label/hooks/use-address.cjs +1 -1
- package/dist/cjs/elements/purchase-label/purchase-label.cjs +7 -1
- package/dist/cjs/hooks/use-configure-shipment.cjs +127 -17
- package/dist/cjs/hooks/use-import-sales-order.cjs +45 -20
- package/dist/cjs/locales/en/common.json.cjs +1 -1
- package/dist/cjs/locales/en/purchase-label.json.cjs +7 -0
- package/dist/cjs/package.json.cjs +1 -1
- package/dist/cjs/workflows/connect-external-carrier/components/custom-external-carrier-form/custom-form-fedex.cjs +11 -11
- package/dist/cjs/workflows/connect-external-carrier/connect-external-carrier.cjs +3 -63
- package/dist/cjs/workflows/label-workflow/label-workflow.cjs +26 -2
- package/dist/esm/components/cc-provider-logo/cc-provider-logo.js +2 -1
- package/dist/esm/components/forms/wallet-form/wallet-schema.js +1 -1
- package/dist/esm/components/shipment-not-found-error/shipment-not-found-error.js +17 -2
- package/dist/esm/components/suspend-purchase/suspend-purchase.js +3 -3
- package/dist/esm/elements/purchase-label/hooks/use-address.js +1 -1
- package/dist/esm/elements/purchase-label/purchase-label.js +7 -1
- package/dist/esm/hooks/use-configure-shipment.js +127 -17
- package/dist/esm/hooks/use-import-sales-order.js +47 -22
- package/dist/esm/locales/en/common.json.js +1 -1
- package/dist/esm/locales/en/purchase-label.json.js +7 -0
- package/dist/esm/package.json.js +1 -1
- package/dist/esm/workflows/connect-external-carrier/components/custom-external-carrier-form/custom-form-fedex.js +11 -11
- package/dist/esm/workflows/connect-external-carrier/connect-external-carrier.js +3 -44
- package/dist/esm/workflows/label-workflow/label-workflow.js +26 -2
- package/dist/types/components/cc-provider-logo/cc-provider-logo.d.ts.map +1 -1
- package/dist/types/components/forms/wallet-form/wallet-schema.d.ts.map +1 -1
- package/dist/types/components/shipment-not-found-error/shipment-not-found-error.d.ts +3 -2
- package/dist/types/components/shipment-not-found-error/shipment-not-found-error.d.ts.map +1 -1
- package/dist/types/components/suspend-purchase/suspend-purchase.d.ts +3 -2
- package/dist/types/components/suspend-purchase/suspend-purchase.d.ts.map +1 -1
- package/dist/types/elements/labels-grid/labels-grid.d.ts +7 -0
- package/dist/types/elements/labels-grid/labels-grid.d.ts.map +1 -1
- package/dist/types/elements/manage-carriers/manage-carriers.d.ts +7 -0
- package/dist/types/elements/manage-carriers/manage-carriers.d.ts.map +1 -1
- package/dist/types/elements/manage-external-carriers/manage-external-carriers.d.ts +7 -0
- package/dist/types/elements/manage-external-carriers/manage-external-carriers.d.ts.map +1 -1
- package/dist/types/elements/manage-funding/manage-funding-element.d.ts +7 -0
- package/dist/types/elements/manage-funding/manage-funding-element.d.ts.map +1 -1
- package/dist/types/elements/manage-warehouses/manage-warehouses.d.ts +7 -0
- package/dist/types/elements/manage-warehouses/manage-warehouses.d.ts.map +1 -1
- package/dist/types/elements/payment-method-settings/payment-method-settings-element.d.ts +7 -0
- package/dist/types/elements/payment-method-settings/payment-method-settings-element.d.ts.map +1 -1
- package/dist/types/elements/purchase-label/hooks/use-address.d.ts.map +1 -1
- package/dist/types/elements/purchase-label/purchase-label.d.ts +7 -0
- package/dist/types/elements/purchase-label/purchase-label.d.ts.map +1 -1
- package/dist/types/elements/select-label-layout/select-label-layout-element.d.ts +7 -0
- package/dist/types/elements/select-label-layout/select-label-layout-element.d.ts.map +1 -1
- package/dist/types/elements/shipment-summary/shipment-summary.d.ts +7 -0
- package/dist/types/elements/shipment-summary/shipment-summary.d.ts.map +1 -1
- package/dist/types/elements/shipments-grid/shipments-grid.d.ts +7 -0
- package/dist/types/elements/shipments-grid/shipments-grid.d.ts.map +1 -1
- package/dist/types/elements/theme-creator/theme-creator.d.ts +7 -0
- package/dist/types/elements/theme-creator/theme-creator.d.ts.map +1 -1
- package/dist/types/elements/transaction-history/transaction-history-element.d.ts +7 -0
- package/dist/types/elements/transaction-history/transaction-history-element.d.ts.map +1 -1
- package/dist/types/elements/unit-settings/unit-settings-element.d.ts +7 -0
- package/dist/types/elements/unit-settings/unit-settings-element.d.ts.map +1 -1
- package/dist/types/elements/vat-settings/vat-settings-element.d.ts +7 -0
- package/dist/types/elements/vat-settings/vat-settings-element.d.ts.map +1 -1
- package/dist/types/elements/void-label/void-label.d.ts +7 -0
- package/dist/types/elements/void-label/void-label.d.ts.map +1 -1
- package/dist/types/hooks/use-configure-shipment.d.ts.map +1 -1
- package/dist/types/hooks/use-import-sales-order.d.ts +20 -1
- package/dist/types/hooks/use-import-sales-order.d.ts.map +1 -1
- package/dist/types/locales/en/index.d.ts +7 -0
- package/dist/types/locales/en/index.d.ts.map +1 -1
- package/dist/types/workflows/account-settings/account-settings.d.ts +7 -0
- package/dist/types/workflows/account-settings/account-settings.d.ts.map +1 -1
- package/dist/types/workflows/carrier-services/carrier-services.d.ts +7 -0
- package/dist/types/workflows/carrier-services/carrier-services.d.ts.map +1 -1
- package/dist/types/workflows/connect-external-carrier/connect-external-carrier.d.ts +7 -0
- package/dist/types/workflows/connect-external-carrier/connect-external-carrier.d.ts.map +1 -1
- package/dist/types/workflows/label-workflow/label-workflow.d.ts +7 -0
- package/dist/types/workflows/label-workflow/label-workflow.d.ts.map +1 -1
- package/dist/types/workflows/onboarding/onboarding.d.ts +7 -0
- package/dist/types/workflows/onboarding/onboarding.d.ts.map +1 -1
- package/package.json +137 -10
|
@@ -14,7 +14,7 @@ const CcProviderLogo = ({
|
|
|
14
14
|
height = 36
|
|
15
15
|
}) => {
|
|
16
16
|
const providerLogos = {
|
|
17
|
-
|
|
17
|
+
american_express: amex,
|
|
18
18
|
discover,
|
|
19
19
|
mastercard,
|
|
20
20
|
visa
|
|
@@ -25,6 +25,7 @@ const CcProviderLogo = ({
|
|
|
25
25
|
size: giger.IconSize.SIZE_LARGE
|
|
26
26
|
});
|
|
27
27
|
}
|
|
28
|
+
// TODO: LMNT-1810 - Add missing provider logos
|
|
28
29
|
const Logo = providerLogos[provider];
|
|
29
30
|
return jsxRuntime.jsx(Logo, {
|
|
30
31
|
height: height,
|
|
@@ -77,7 +77,7 @@ const creditCardSchema = zod.z.object({
|
|
|
77
77
|
expirationMonth: expirationMonth,
|
|
78
78
|
expirationYear: expirationYear,
|
|
79
79
|
name: creditCard.name,
|
|
80
|
-
provider: creditCardVendor === "american-express" ? "
|
|
80
|
+
provider: creditCardVendor === "american-express" ? "american_express" : creditCardVendor
|
|
81
81
|
};
|
|
82
82
|
});
|
|
83
83
|
const getWalletSchema = (emailRequirement, blackboxRequirement) => {
|
|
@@ -7,12 +7,26 @@ var reactI18next = require('react-i18next');
|
|
|
7
7
|
var shipmentNotFoundError_styles = require('./shipment-not-found-error.styles.cjs');
|
|
8
8
|
|
|
9
9
|
const ShipmentNotFoundError = ({
|
|
10
|
-
|
|
10
|
+
identifier,
|
|
11
11
|
onCreateNewShipment
|
|
12
12
|
}) => {
|
|
13
13
|
const {
|
|
14
14
|
t
|
|
15
15
|
} = reactI18next.useTranslation(["common", "purchase-label"]);
|
|
16
|
+
const getIdentifierInfo = identifier => {
|
|
17
|
+
// Order should match the actual search priority in useConfigureShipment:
|
|
18
|
+
const identifierKeys = ["shipmentId", "externalShipmentId", "salesOrderId", "externalOrderId", "externalOrderNumber"];
|
|
19
|
+
const foundKey = identifierKeys.find(key => identifier === null || identifier === void 0 ? void 0 : identifier[key]);
|
|
20
|
+
const identifierKey = foundKey || "shipmentId";
|
|
21
|
+
return {
|
|
22
|
+
type: t(`purchase-label:identifierTypes.${identifierKey}`),
|
|
23
|
+
value: identifier === null || identifier === void 0 ? void 0 : identifier[identifierKey]
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
const {
|
|
27
|
+
type: identifierType,
|
|
28
|
+
value: identifierNumber
|
|
29
|
+
} = getIdentifierInfo(identifier);
|
|
16
30
|
return jsxRuntime.jsxs("div", {
|
|
17
31
|
css: shipmentNotFoundError_styles.styles.container,
|
|
18
32
|
children: [jsxRuntime.jsx("div", {
|
|
@@ -24,7 +38,8 @@ const ShipmentNotFoundError = ({
|
|
|
24
38
|
}), jsxRuntime.jsx("div", {
|
|
25
39
|
css: shipmentNotFoundError_styles.styles.message,
|
|
26
40
|
children: t("common:errorMessages.shipmentNotFound", {
|
|
27
|
-
|
|
41
|
+
identifierType,
|
|
42
|
+
identifierNumber
|
|
28
43
|
})
|
|
29
44
|
}), jsxRuntime.jsx(giger.Button, {
|
|
30
45
|
"data-testid": "create-new-shipment",
|
|
@@ -11,7 +11,7 @@ const SuspendPurchase = ({
|
|
|
11
11
|
isLoading,
|
|
12
12
|
data,
|
|
13
13
|
onCreateNewShipment,
|
|
14
|
-
|
|
14
|
+
identifier
|
|
15
15
|
}) => {
|
|
16
16
|
const {
|
|
17
17
|
t
|
|
@@ -38,8 +38,8 @@ const SuspendPurchase = ({
|
|
|
38
38
|
throw new Error(t("common:errorMessages.labelHasBeenPurchased"));
|
|
39
39
|
case "shipment_not_found":
|
|
40
40
|
return jsxRuntime.jsx(shipmentNotFoundError.ShipmentNotFoundError, {
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
identifier: identifier,
|
|
42
|
+
onCreateNewShipment: onCreateNewShipment
|
|
43
43
|
});
|
|
44
44
|
}
|
|
45
45
|
}
|
|
@@ -162,7 +162,7 @@ const useAddress = ({
|
|
|
162
162
|
if (warning && warning.error) return warning;
|
|
163
163
|
const value = addressMinusGeolocation[key];
|
|
164
164
|
if (!value) return warning;
|
|
165
|
-
if (/^[0-
|
|
165
|
+
if (/^[0-9A-Za-z\u00C0-\u017F\u0100-\u024F\u1E00-\u1EFF\u0020-\u002F\u003A-\u0040\u005B-\u0060\u007B-\u007E\u00A0-\u00BF\u2000-\u206F\u2E00-\u2E7F\s]+$/u.test(value)) return warning;
|
|
166
166
|
if (key === "name" || key === "companyName") {
|
|
167
167
|
return {
|
|
168
168
|
error: false,
|
|
@@ -92,9 +92,15 @@ const Component = _a => {
|
|
|
92
92
|
return jsxRuntime.jsx(suspendPurchase.SuspendPurchase, {
|
|
93
93
|
data: shipment || salesOrder,
|
|
94
94
|
errors: errors,
|
|
95
|
+
identifier: {
|
|
96
|
+
externalOrderId,
|
|
97
|
+
externalOrderNumber,
|
|
98
|
+
externalShipmentId,
|
|
99
|
+
salesOrderId,
|
|
100
|
+
shipmentId
|
|
101
|
+
},
|
|
95
102
|
isLoading: isLoading || insuranceIsLoading,
|
|
96
103
|
onCreateNewShipment: createNewShipmentForNotFound,
|
|
97
|
-
shipmentId: shipmentId,
|
|
98
104
|
children: jsxRuntime.jsx(configureShipment.ConfigureShipment, Object.assign({
|
|
99
105
|
currency: currency,
|
|
100
106
|
features: features,
|
|
@@ -22,8 +22,8 @@ const useConfigureShipment = ({
|
|
|
22
22
|
warehouseId,
|
|
23
23
|
useWarehouses = true
|
|
24
24
|
}) => {
|
|
25
|
-
// Track when
|
|
26
|
-
const [
|
|
25
|
+
// Track when user manually created a shipment for a "not found" case
|
|
26
|
+
const [manuallyCreatedShipmentId, setManuallyCreatedShipmentId] = React.useState();
|
|
27
27
|
// Queue of incomplete requirement keys (i.e., Ship From addresses, Warehouses, Carriers)
|
|
28
28
|
const incompleteRequirementsKeys = React.useMemo(() => [], []);
|
|
29
29
|
const {
|
|
@@ -47,6 +47,7 @@ const useConfigureShipment = ({
|
|
|
47
47
|
// Dont run Sales Order Import unless the Sales order info is present
|
|
48
48
|
enabled: !!externalOrderNumber || !!orderSourceCode || !!salesOrderId || !!externalOrderId,
|
|
49
49
|
externalOrderId,
|
|
50
|
+
externalOrderNumber,
|
|
50
51
|
orderSourceCode,
|
|
51
52
|
salesOrderId
|
|
52
53
|
});
|
|
@@ -63,24 +64,49 @@ const useConfigureShipment = ({
|
|
|
63
64
|
isInitialLoading: isExternalShipmentInitialLoading,
|
|
64
65
|
isFetching: isExternalShipmentFetching
|
|
65
66
|
} = reactApi.useGetShipmentByExternalId({
|
|
66
|
-
enabled: !!externalShipmentId && !shipmentId,
|
|
67
|
+
enabled: !!externalShipmentId && !shipmentId && !manuallyCreatedShipmentId,
|
|
67
68
|
queryFnParams: {
|
|
68
69
|
externalId: externalShipmentId !== null && externalShipmentId !== void 0 ? externalShipmentId : ""
|
|
69
70
|
}
|
|
71
|
+
// TODO: weird refetch on focus behavior
|
|
70
72
|
});
|
|
73
|
+
// #region List Sales Order Shipments
|
|
74
|
+
const externalOrderIds = React.useMemo(() => {
|
|
75
|
+
return externalOrderId ? [externalOrderId] : undefined;
|
|
76
|
+
}, [externalOrderId]);
|
|
77
|
+
const salesOrderIds = React.useMemo(() => {
|
|
78
|
+
return salesOrderId ? [salesOrderId] : salesOrder$1 ? [salesOrder$1.salesOrderId] :
|
|
79
|
+
// TODO: current workaround - revert to being undefined rather than empty list
|
|
80
|
+
[];
|
|
81
|
+
}, [salesOrderId, salesOrder$1]);
|
|
82
|
+
const shipmentIds = React.useMemo(() => {
|
|
83
|
+
return manuallyCreatedShipmentId ? [manuallyCreatedShipmentId] : shipmentId ? [shipmentId] : externalShipment ? [externalShipment.shipmentId] : newV1Shipment ? [newV1Shipment.shipments[0].shipmentId] : undefined;
|
|
84
|
+
}, [manuallyCreatedShipmentId, shipmentId, externalShipment, newV1Shipment]);
|
|
85
|
+
const listSalesOrderShipmentsParams = React.useMemo(() => {
|
|
86
|
+
// TODO: useListSalesOrderShipments needs to be able to use the enabled prop, this is a workaround
|
|
87
|
+
// Prevent query with stale params during shipment creation or when V1 shipment exists but manuallyCreatedShipmentId not set
|
|
88
|
+
if (creatingV1Shipment && !manuallyCreatedShipmentId || newV1Shipment && !manuallyCreatedShipmentId) {
|
|
89
|
+
return {};
|
|
90
|
+
}
|
|
91
|
+
if (manuallyCreatedShipmentId) {
|
|
92
|
+
return {
|
|
93
|
+
shipmentIds
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
externalOrderIds,
|
|
98
|
+
salesOrderIds,
|
|
99
|
+
shipmentIds
|
|
100
|
+
};
|
|
101
|
+
}, [manuallyCreatedShipmentId, externalOrderIds, salesOrderIds, shipmentIds, creatingV1Shipment, newV1Shipment]);
|
|
71
102
|
const {
|
|
72
103
|
data: salesOrderShipments,
|
|
73
104
|
error: listSalesOrderShipmentsErrors,
|
|
74
105
|
refetch: refetchSalesOrderShipments,
|
|
75
106
|
isInitialLoading: listSalesOrderShipmentsInitiallyLoading,
|
|
76
107
|
isFetching: listSalesOrderShipmentsIsFetching
|
|
77
|
-
} = reactApi.useListSalesOrderShipments(
|
|
78
|
-
|
|
79
|
-
salesOrderIds: salesOrderId ? [salesOrderId] : salesOrder$1 ? [salesOrder$1.salesOrderId] :
|
|
80
|
-
// TODO: current workaround - revert to being undefined rather than empty list
|
|
81
|
-
[],
|
|
82
|
-
shipmentIds: replacementShipmentId ? [replacementShipmentId] : shipmentId ? [shipmentId] : externalShipment ? [externalShipment.shipmentId] : newV1Shipment ? [newV1Shipment.shipments[0].shipmentId] : undefined
|
|
83
|
-
});
|
|
108
|
+
} = reactApi.useListSalesOrderShipments(listSalesOrderShipmentsParams);
|
|
109
|
+
// #endregion
|
|
84
110
|
const {
|
|
85
111
|
error: createSalesOrderShipmentErrors,
|
|
86
112
|
mutateAsync: createSalesOrderShipment,
|
|
@@ -105,6 +131,7 @@ const useConfigureShipment = ({
|
|
|
105
131
|
}
|
|
106
132
|
return null;
|
|
107
133
|
}), [createV1Shipment, defaultShipFromAddress, defaultWarehouse, warehouseId, refetchSalesOrderShipments]);
|
|
134
|
+
// #region Create Sales Order Shipment
|
|
108
135
|
// Handles the creation of new shipments for the sales order flow and one-off flow
|
|
109
136
|
const handleShipmentCreation = React.useCallback(() => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
110
137
|
var _a, _b, _c;
|
|
@@ -154,17 +181,23 @@ const useConfigureShipment = ({
|
|
|
154
181
|
}
|
|
155
182
|
// Create a Shipment for one-off flow
|
|
156
183
|
if (!salesOrderId && !externalOrderId && !externalOrderNumber && !orderSourceCode && !shipmentId && !externalShipmentId) {
|
|
157
|
-
yield createV1ShipmentWithDefaults();
|
|
184
|
+
const v1Shipment = yield createV1ShipmentWithDefaults();
|
|
185
|
+
// Set manuallyCreatedShipmentId to ensure proper query parameter handling
|
|
186
|
+
if (v1Shipment) {
|
|
187
|
+
setManuallyCreatedShipmentId(v1Shipment.shipments[0].shipmentId);
|
|
188
|
+
}
|
|
158
189
|
}
|
|
159
190
|
}), [createSalesOrderShipment, createV1ShipmentWithDefaults, creatingSalesOrderShipment, creatingV1Shipment, defaultShipFromAddress, defaultWarehouse, externalOrderId, externalOrderNumber, externalShipmentId, incompleteRequirementsKeys, isExternalShipmentFetching, isExternalShipmentInitialLoading, isFetchingWarehouses, isInitialLoadingWarehouses, labelPurchasedSalesOrderShipment, listSalesOrderShipmentsInitiallyLoading, listSalesOrderShipmentsIsFetching, orderSourceCode, pendingSalesOrderShipment, salesOrder$1, salesOrderId, salesOrderShipmentCreated, shipFromAddresses === null || shipFromAddresses === void 0 ? void 0 : shipFromAddresses.length, shipmentId, useWarehouses, v1shipmentCreated, warehouseId, warehouses$1]);
|
|
191
|
+
// #endregion
|
|
160
192
|
const createNewShipmentForNotFound = React.useCallback(() => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
161
193
|
// Force create a new shipment even if shipmentId exists (for shipment_not_found case)
|
|
162
194
|
const v1Shipment = yield createV1ShipmentWithDefaults();
|
|
163
195
|
if (v1Shipment) {
|
|
164
|
-
|
|
165
|
-
|
|
196
|
+
setManuallyCreatedShipmentId(v1Shipment.shipments[0].shipmentId);
|
|
197
|
+
// Refetch to ensure we have the latest shipment data
|
|
198
|
+
yield refetchSalesOrderShipments();
|
|
166
199
|
}
|
|
167
|
-
}), [createV1ShipmentWithDefaults]);
|
|
200
|
+
}), [createV1ShipmentWithDefaults, refetchSalesOrderShipments]);
|
|
168
201
|
const refetchPendingSalesOrderShipments = React.useCallback(() => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
169
202
|
const {
|
|
170
203
|
data: shipments
|
|
@@ -188,7 +221,83 @@ const useConfigureShipment = ({
|
|
|
188
221
|
if (isInitialLoadingCarriers || isFetchingCarriers) return;
|
|
189
222
|
if ((carriers === null || carriers === void 0 ? void 0 : carriers.length) === 0) incompleteRequirementsKeys.push("no_carriers");
|
|
190
223
|
}, [carriers, incompleteRequirementsKeys, isFetchingCarriers, isInitialLoadingCarriers]);
|
|
191
|
-
const
|
|
224
|
+
const isConfigureShipmentLoading = React.useMemo(() => {
|
|
225
|
+
if (isSalesOrderLoading) return true;
|
|
226
|
+
if (listSalesOrderShipmentsInitiallyLoading) return true;
|
|
227
|
+
if (listSalesOrderShipmentsIsFetching) return true;
|
|
228
|
+
if (creatingSalesOrderShipment) return true;
|
|
229
|
+
if (creatingV1Shipment) return true;
|
|
230
|
+
// Include external shipment loading states to prevent premature error display
|
|
231
|
+
// Only keep loading if we're actually fetching and don't have an error yet
|
|
232
|
+
// Skip this check if we already have an error to avoid infinite loading
|
|
233
|
+
if (externalShipmentId && isExternalShipmentFetching && !getExternalShipmentErrors && !isExternalShipmentInitialLoading) {
|
|
234
|
+
return true;
|
|
235
|
+
}
|
|
236
|
+
// Check if this is a one-off flow (no identifiers provided)
|
|
237
|
+
const isOneOffFlow = !salesOrderId && !externalOrderId && !externalOrderNumber && !orderSourceCode && !shipmentId && !externalShipmentId;
|
|
238
|
+
// For one-off flow, keep loading until we have shipment data or V1 creation is complete
|
|
239
|
+
if (isOneOffFlow && !pendingSalesOrderShipment && !labelPurchasedSalesOrderShipment) {
|
|
240
|
+
return true;
|
|
241
|
+
}
|
|
242
|
+
// Only consider empty salesOrderShipments array as loading if we're not initially loading and have valid identifiers
|
|
243
|
+
const shouldReturnTrueForEmptyShipments = (salesOrderShipments === null || salesOrderShipments === void 0 ? void 0 : salesOrderShipments.length) === 0 && !listSalesOrderShipmentsInitiallyLoading && !listSalesOrderShipmentsIsFetching;
|
|
244
|
+
if (shouldReturnTrueForEmptyShipments) {
|
|
245
|
+
return true;
|
|
246
|
+
}
|
|
247
|
+
return false;
|
|
248
|
+
}, [isSalesOrderLoading, listSalesOrderShipmentsInitiallyLoading, listSalesOrderShipmentsIsFetching, creatingSalesOrderShipment, creatingV1Shipment, isExternalShipmentInitialLoading, isExternalShipmentFetching, getExternalShipmentErrors,
|
|
249
|
+
// This was missing!
|
|
250
|
+
salesOrderId, externalOrderId, externalOrderNumber, orderSourceCode, shipmentId, externalShipmentId, pendingSalesOrderShipment, labelPurchasedSalesOrderShipment, salesOrderShipments === null || salesOrderShipments === void 0 ? void 0 : salesOrderShipments.length]);
|
|
251
|
+
// #region Custom Error Mapping
|
|
252
|
+
const hasGetShipmentErrors = React.useMemo(() => {
|
|
253
|
+
// Check for explicit API errors
|
|
254
|
+
if (listSalesOrderShipmentsErrors) return true;
|
|
255
|
+
if (getExternalShipmentErrors) return true;
|
|
256
|
+
if (importSalesOrderErrors) return true;
|
|
257
|
+
// Only treat empty results as error if we're not loading and have finished initial fetch
|
|
258
|
+
if ((salesOrderShipments === null || salesOrderShipments === void 0 ? void 0 : salesOrderShipments.length) === 0 && shipmentId && !listSalesOrderShipmentsInitiallyLoading && !listSalesOrderShipmentsIsFetching) {
|
|
259
|
+
return true;
|
|
260
|
+
}
|
|
261
|
+
return false;
|
|
262
|
+
}, [listSalesOrderShipmentsErrors, getExternalShipmentErrors, importSalesOrderErrors, salesOrderShipments === null || salesOrderShipments === void 0 ? void 0 : salesOrderShipments.length, shipmentId, listSalesOrderShipmentsInitiallyLoading, listSalesOrderShipmentsIsFetching]);
|
|
263
|
+
const hasValidShipmentData = React.useMemo(() => {
|
|
264
|
+
if (manuallyCreatedShipmentId) return true;
|
|
265
|
+
if (pendingSalesOrderShipment) return true;
|
|
266
|
+
if (labelPurchasedSalesOrderShipment) return true;
|
|
267
|
+
return false;
|
|
268
|
+
}, [labelPurchasedSalesOrderShipment, manuallyCreatedShipmentId, pendingSalesOrderShipment]);
|
|
269
|
+
const showShipmentNotFoundError = React.useMemo(() => {
|
|
270
|
+
// Don't show error if we have a manually created shipment
|
|
271
|
+
if (manuallyCreatedShipmentId) {
|
|
272
|
+
return false;
|
|
273
|
+
}
|
|
274
|
+
// Don't show error if we're creating a V1 shipment
|
|
275
|
+
if (creatingV1Shipment || newV1Shipment) {
|
|
276
|
+
return false;
|
|
277
|
+
}
|
|
278
|
+
// For external shipment ID, show error if we're not in loading state
|
|
279
|
+
// and we don't have valid shipment data
|
|
280
|
+
if (externalShipmentId && !isConfigureShipmentLoading && !hasValidShipmentData) {
|
|
281
|
+
return true;
|
|
282
|
+
}
|
|
283
|
+
// Don't show error if external shipment is still loading, unless we have explicit errors
|
|
284
|
+
if (externalShipmentId && (isExternalShipmentInitialLoading || isExternalShipmentFetching) && !getExternalShipmentErrors) {
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
// Show error immediately if we have shipment errors, even if still loading
|
|
288
|
+
if (hasGetShipmentErrors) {
|
|
289
|
+
return true;
|
|
290
|
+
}
|
|
291
|
+
// Check if this is a one-off flow (no identifiers provided)
|
|
292
|
+
const isOneOffFlow = !salesOrderId && !externalOrderId && !externalOrderNumber && !orderSourceCode && !shipmentId && !externalShipmentId;
|
|
293
|
+
// Don't show error for one-off flow until we've attempted shipment creation
|
|
294
|
+
if (isOneOffFlow && !v1shipmentCreated) {
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
// Otherwise, only show if not loading and no valid shipment data
|
|
298
|
+
return !isConfigureShipmentLoading && !hasValidShipmentData;
|
|
299
|
+
}, [manuallyCreatedShipmentId, creatingV1Shipment, newV1Shipment, hasGetShipmentErrors, isExternalShipmentInitialLoading, isExternalShipmentFetching, getExternalShipmentErrors, listSalesOrderShipmentsErrors, importSalesOrderErrors, salesOrderId, externalOrderId, externalOrderNumber, orderSourceCode, shipmentId, externalShipmentId, v1shipmentCreated, isConfigureShipmentLoading, hasValidShipmentData, pendingSalesOrderShipment, externalShipment]);
|
|
300
|
+
const errors = [...(listWarehouseErrors !== null && listWarehouseErrors !== void 0 ? listWarehouseErrors : []), ...(createSalesOrderShipmentErrors !== null && createSalesOrderShipmentErrors !== void 0 ? createSalesOrderShipmentErrors : []), ...(createV1ShipmentErrors !== null && createV1ShipmentErrors !== void 0 ? createV1ShipmentErrors : []), ...(errorWhenShipmentCancelled && cancelledShipment ? [new reactApi.CodedError("shipment_cancelled", {
|
|
192
301
|
errorCode: "invalid_status",
|
|
193
302
|
errorSource: "elements",
|
|
194
303
|
errorType: "business_rules"
|
|
@@ -200,16 +309,17 @@ const useConfigureShipment = ({
|
|
|
200
309
|
errorCode: "unknown",
|
|
201
310
|
errorSource: "elements",
|
|
202
311
|
errorType: "business_rules"
|
|
203
|
-
})] : []), ...(
|
|
312
|
+
})] : []), ...(showShipmentNotFoundError ? [new reactApi.CodedError("shipment_not_found", {
|
|
204
313
|
errorCode: "invalid_status",
|
|
205
314
|
errorSource: "elements",
|
|
206
315
|
errorType: "business_rules"
|
|
207
316
|
})] : [])];
|
|
317
|
+
// #endregion
|
|
208
318
|
return {
|
|
209
319
|
carriers,
|
|
210
320
|
createNewShipmentForNotFound,
|
|
211
321
|
errors: errors.length > 0 ? errors : undefined,
|
|
212
|
-
isLoading:
|
|
322
|
+
isLoading: isConfigureShipmentLoading && errors.length === 0,
|
|
213
323
|
refetchPendingSalesOrderShipments,
|
|
214
324
|
salesOrder: salesOrder$1,
|
|
215
325
|
shipment: pendingSalesOrderShipment !== null && pendingSalesOrderShipment !== void 0 ? pendingSalesOrderShipment : labelPurchasedSalesOrderShipment,
|
|
@@ -5,26 +5,49 @@ var reactApi = require('@shipengine/react-api');
|
|
|
5
5
|
var reactQuery = require('@tanstack/react-query');
|
|
6
6
|
var React = require('react');
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Imports and retrieves sales orders by either:
|
|
10
|
+
* - Sales order ID lookup
|
|
11
|
+
* - External order ID/number search
|
|
12
|
+
*
|
|
13
|
+
* 1. First attempts to find the sales order using provided identifiers
|
|
14
|
+
* 2. If no order is found and initial fetches have run, automatically refreshes order sources
|
|
15
|
+
* 3. Invalidates relevant queries after successful refresh to refetch updated data
|
|
16
|
+
*
|
|
17
|
+
* @returns Object:
|
|
18
|
+
* - `salesOrder`: The found sales order, or undefined
|
|
19
|
+
* - `isLoading`: Boolean indicating if the hook is currently loading data
|
|
20
|
+
* - `errors`: Array of errors from failed queries, or undefined
|
|
21
|
+
*/
|
|
8
22
|
const useImportSalesOrder = ({
|
|
9
23
|
enabled,
|
|
10
24
|
externalOrderId,
|
|
25
|
+
externalOrderNumber,
|
|
11
26
|
orderSourceCode,
|
|
12
27
|
salesOrderId
|
|
13
28
|
}) => {
|
|
14
29
|
var _a, _b, _c;
|
|
15
30
|
const queryClient = reactQuery.useQueryClient();
|
|
16
31
|
const [refreshAttempted, setRefreshAttempted] = React.useState(false);
|
|
17
|
-
//
|
|
18
|
-
const
|
|
19
|
-
|
|
32
|
+
// Fetch sales order by External Order ID or External Order Number
|
|
33
|
+
const salesOrderByExternalIdQuery = reactApi.useListSalesOrders({
|
|
34
|
+
externalOrderId,
|
|
35
|
+
externalOrderNumber
|
|
20
36
|
});
|
|
21
37
|
// if an order was found through external search disable this query
|
|
22
|
-
const
|
|
38
|
+
const salesOrderByIdQuery = reactApi.useGetSalesOrder(salesOrderId, {
|
|
23
39
|
enabled: enabled && !!salesOrderId
|
|
24
40
|
});
|
|
25
|
-
const salesOrder = React.useMemo(() =>
|
|
41
|
+
const salesOrder = React.useMemo(() => {
|
|
42
|
+
if (salesOrderId) {
|
|
43
|
+
return salesOrderByIdQuery.data;
|
|
44
|
+
} else if (salesOrderByExternalIdQuery.data && salesOrderByExternalIdQuery.data.length > 0) {
|
|
45
|
+
return salesOrderByExternalIdQuery.data[0];
|
|
46
|
+
}
|
|
47
|
+
return undefined;
|
|
48
|
+
}, [salesOrderId, salesOrderByIdQuery.data, salesOrderByExternalIdQuery.data]);
|
|
26
49
|
// Determine if the initial fetch attempts (if applicable) have settled without finding data
|
|
27
|
-
const initialFetchSettled = (salesOrderId ? !
|
|
50
|
+
const initialFetchSettled = (salesOrderId ? !salesOrderByIdQuery.isInitialLoading && !salesOrderByIdQuery.isFetching : true) && ((externalOrderNumber || externalOrderId) && !salesOrderId ? !salesOrderByExternalIdQuery.isLoading && !salesOrderByExternalIdQuery.isFetching : true);
|
|
28
51
|
const shouldAttemptRefresh = enabled && initialFetchSettled && !salesOrder && !refreshAttempted;
|
|
29
52
|
const listOrderSourcesQuery = reactApi.useListOrderSources({
|
|
30
53
|
enabled: shouldAttemptRefresh
|
|
@@ -34,6 +57,17 @@ const useImportSalesOrder = ({
|
|
|
34
57
|
isLoading: isRefreshingOrderSource,
|
|
35
58
|
mutateAsync: refreshOrderSource
|
|
36
59
|
} = reactApi.useRefreshOrderSource();
|
|
60
|
+
const invalidateSalesOrderQueries = React.useCallback(() => {
|
|
61
|
+
if (salesOrderId) {
|
|
62
|
+
void queryClient.invalidateQueries({
|
|
63
|
+
queryKey: ["useGetSalesOrder", salesOrderId]
|
|
64
|
+
});
|
|
65
|
+
} else if (externalOrderId || externalOrderNumber) {
|
|
66
|
+
void queryClient.invalidateQueries({
|
|
67
|
+
queryKey: ["useListSalesOrders", externalOrderId, externalOrderNumber]
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}, [queryClient, salesOrderId, externalOrderId, externalOrderNumber]);
|
|
37
71
|
React.useEffect(() => {
|
|
38
72
|
if (listOrderSourcesQuery.isSuccess && listOrderSourcesQuery.data && shouldAttemptRefresh && !isRefreshingOrderSource) {
|
|
39
73
|
const orderSourcesToRefresh = orderSourceCode ? listOrderSourcesQuery.data.filter(o => o.orderSourceCode.includes(orderSourceCode) && o.active) : listOrderSourcesQuery.data.filter(o => o.active);
|
|
@@ -41,29 +75,20 @@ const useImportSalesOrder = ({
|
|
|
41
75
|
setRefreshAttempted(true);
|
|
42
76
|
void (() => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
43
77
|
yield Promise.all(orderSourcesToRefresh.map(o => refreshOrderSource(o.orderSourceId, {
|
|
44
|
-
// Invalidate relevant queries
|
|
78
|
+
// Invalidate relevant queries
|
|
45
79
|
onSuccess: () => {
|
|
46
|
-
|
|
47
|
-
void queryClient.invalidateQueries({
|
|
48
|
-
queryKey: ["useGetSalesOrder", salesOrderId]
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
if (externalOrderId && !salesOrderId) {
|
|
52
|
-
void queryClient.invalidateQueries({
|
|
53
|
-
queryKey: ["useGetSalesOrderByExternalOrderId", externalOrderId]
|
|
54
|
-
});
|
|
55
|
-
}
|
|
80
|
+
invalidateSalesOrderQueries();
|
|
56
81
|
}
|
|
57
82
|
})));
|
|
58
83
|
}))();
|
|
59
84
|
}
|
|
60
85
|
}
|
|
61
86
|
}, [externalOrderId, isRefreshingOrderSource, listOrderSourcesQuery.data, listOrderSourcesQuery.isSuccess, orderSourceCode, queryClient, refreshOrderSource, salesOrderId, shouldAttemptRefresh]);
|
|
62
|
-
const isLoading =
|
|
63
|
-
const errors = [...((_a =
|
|
87
|
+
const isLoading = salesOrderByIdQuery.isInitialLoading || salesOrderByExternalIdQuery.isInitialLoading || listOrderSourcesQuery.isInitialLoading || isRefreshingOrderSource;
|
|
88
|
+
const errors = [...((_a = salesOrderByIdQuery.error) !== null && _a !== void 0 ? _a : []), ...((_b = salesOrderByExternalIdQuery.error) !== null && _b !== void 0 ? _b : []), ...((_c = listOrderSourcesQuery.error) !== null && _c !== void 0 ? _c : []), ...(refreshOrderSourceErrors !== null && refreshOrderSourceErrors !== void 0 ? refreshOrderSourceErrors : [])];
|
|
64
89
|
return {
|
|
65
90
|
errors: errors.length > 0 ? errors : undefined,
|
|
66
|
-
isLoading,
|
|
91
|
+
isLoading: isLoading && errors.length === 0,
|
|
67
92
|
salesOrder
|
|
68
93
|
};
|
|
69
94
|
};
|
|
@@ -170,7 +170,7 @@ var common = {
|
|
|
170
170
|
invalidNameOrCompany: "Recipient name and company name (if provided) must have two characters in first and last name.",
|
|
171
171
|
parsingFailure: "Parsing failed. Please check address and try again.",
|
|
172
172
|
incompleteLabelPurchaseRequirements: "Please add your {{requirements}} to continue purchasing a label.",
|
|
173
|
-
shipmentNotFound: "Cannot find
|
|
173
|
+
shipmentNotFound: "Cannot find {{identifierType}}: {{identifierNumber}}",
|
|
174
174
|
shipmentCancelled: "This shipment is Cancelled in ShipStation. Log into ShipStation to restore the order to Awaiting Shipment status.",
|
|
175
175
|
unableToLoad: {
|
|
176
176
|
accountSettings: "Unable to load account settings",
|
|
@@ -32,6 +32,13 @@ var purchaseLabel = {
|
|
|
32
32
|
saveRateFailedMessage: "Saving DHL Express Worldwide rates is temporarily unavailable. Please try again later.",
|
|
33
33
|
saveRateFailedTitle: "Unable To Save Rate"
|
|
34
34
|
},
|
|
35
|
+
identifierTypes: {
|
|
36
|
+
externalOrderId: "External Order ID",
|
|
37
|
+
externalOrderNumber: "External Order Number",
|
|
38
|
+
externalShipmentId: "External Shipment ID",
|
|
39
|
+
salesOrderId: "Sales Order ID",
|
|
40
|
+
shipmentId: "Shipment ID"
|
|
41
|
+
},
|
|
35
42
|
errorTypes: {
|
|
36
43
|
results: "No results returned"
|
|
37
44
|
},
|
|
@@ -112,7 +112,7 @@ const supportedCountriesUK = [{
|
|
|
112
112
|
const fedexJsonSchema = isUK => ({
|
|
113
113
|
description: `You'll need an existing FedEx account to complete this form. If you don't have a FedEx account, please <a href="${newAccountHref}" target="_blank" rel="noopener noreferrer">click here to open one now!</a>`,
|
|
114
114
|
properties: {
|
|
115
|
-
|
|
115
|
+
account_number: {
|
|
116
116
|
maxLength: 50,
|
|
117
117
|
title: "FedEx Account No",
|
|
118
118
|
type: "string"
|
|
@@ -129,7 +129,7 @@ const fedexJsonSchema = isUK => ({
|
|
|
129
129
|
title: "Address Line 2",
|
|
130
130
|
type: "string"
|
|
131
131
|
},
|
|
132
|
-
|
|
132
|
+
agree_to_eula: {
|
|
133
133
|
title: "I agree to the End-User License Agreement",
|
|
134
134
|
type: "boolean"
|
|
135
135
|
},
|
|
@@ -143,7 +143,7 @@ const fedexJsonSchema = isUK => ({
|
|
|
143
143
|
title: "Company Name",
|
|
144
144
|
type: "string"
|
|
145
145
|
},
|
|
146
|
-
|
|
146
|
+
country_code: {
|
|
147
147
|
oneOf: isUK ? supportedCountriesUK : supportedCountries,
|
|
148
148
|
title: "Country",
|
|
149
149
|
type: "string"
|
|
@@ -153,13 +153,13 @@ const fedexJsonSchema = isUK => ({
|
|
|
153
153
|
title: "Email",
|
|
154
154
|
type: "string"
|
|
155
155
|
},
|
|
156
|
-
|
|
156
|
+
first_name: {
|
|
157
157
|
// TODO: Can we make firstname/lastname in the same row?
|
|
158
158
|
maxLength: 50,
|
|
159
159
|
title: "Contact First Name",
|
|
160
160
|
type: "string"
|
|
161
161
|
},
|
|
162
|
-
|
|
162
|
+
last_name: {
|
|
163
163
|
// TODO: Can we make firstname/lastname in the same row?
|
|
164
164
|
maxLength: 50,
|
|
165
165
|
title: "Contact Last Name",
|
|
@@ -174,7 +174,7 @@ const fedexJsonSchema = isUK => ({
|
|
|
174
174
|
title: "Phone #",
|
|
175
175
|
type: "string"
|
|
176
176
|
},
|
|
177
|
-
|
|
177
|
+
postal_code: {
|
|
178
178
|
// TODO: Can we make this reactive to country selection? Can we group State/Zip?
|
|
179
179
|
maxLength: 8,
|
|
180
180
|
title: "Zip/Postal Code",
|
|
@@ -187,16 +187,16 @@ const fedexJsonSchema = isUK => ({
|
|
|
187
187
|
type: "string"
|
|
188
188
|
}
|
|
189
189
|
},
|
|
190
|
-
required: ["
|
|
190
|
+
required: ["account_number", "first_name", "last_name", "email", "country_code", "address1", "city", "state", "postal_code", "phone", "nickname"],
|
|
191
191
|
title: "Connect Your FedEx Account",
|
|
192
192
|
type: "object"
|
|
193
193
|
});
|
|
194
194
|
const fedexUiSchema = {
|
|
195
|
-
|
|
195
|
+
account_number: {
|
|
196
196
|
"ui:autofocus": true,
|
|
197
197
|
"ui:emptyValue": ""
|
|
198
198
|
},
|
|
199
|
-
|
|
199
|
+
agree_to_eula: {
|
|
200
200
|
"ui:widget": "hidden"
|
|
201
201
|
},
|
|
202
202
|
email: {
|
|
@@ -209,7 +209,7 @@ const fedexUiSchema = {
|
|
|
209
209
|
inputType: "tel"
|
|
210
210
|
}
|
|
211
211
|
},
|
|
212
|
-
"ui:order": ["
|
|
212
|
+
"ui:order": ["account_number", "first_name", "last_name", "company", "email", "country_code", "address1", "address2", "city", "state", "postal_code", "phone", "agree_to_eula", "nickname"]
|
|
213
213
|
};
|
|
214
214
|
const CustomExternalCarrierFormFedex = ({
|
|
215
215
|
carrierName,
|
|
@@ -232,7 +232,7 @@ const CustomExternalCarrierFormFedex = ({
|
|
|
232
232
|
displayName: displayName,
|
|
233
233
|
iconUrl: iconUrl,
|
|
234
234
|
initialFormData: {
|
|
235
|
-
agreeToEula,
|
|
235
|
+
agree_to_eula: agreeToEula,
|
|
236
236
|
nickname: ""
|
|
237
237
|
},
|
|
238
238
|
isBeta: isBeta,
|