@faststore/api 2.1.9 → 2.1.24
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/api.cjs.development.js +158 -80
- package/dist/api.cjs.development.js.map +1 -1
- package/dist/api.cjs.production.min.js +1 -1
- package/dist/api.cjs.production.min.js.map +1 -1
- package/dist/api.esm.js +158 -80
- package/dist/api.esm.js.map +1 -1
- package/dist/platforms/vtex/clients/commerce/index.d.ts +1 -7
- package/dist/platforms/vtex/clients/commerce/types/OrderForm.d.ts +5 -1
- package/dist/platforms/vtex/clients/index.d.ts +1 -7
- package/dist/platforms/vtex/utils/shouldUpdateShippingData.d.ts +3 -0
- package/package.json +2 -2
- package/src/platforms/vtex/clients/commerce/index.ts +37 -98
- package/src/platforms/vtex/clients/commerce/types/OrderForm.ts +6 -1
- package/src/platforms/vtex/resolvers/validateCart.ts +21 -19
- package/src/platforms/vtex/utils/shouldUpdateShippingData.ts +155 -0
package/dist/api.esm.js
CHANGED
|
@@ -18,7 +18,7 @@ import { trace, context, SpanKind } from '@opentelemetry/api';
|
|
|
18
18
|
import { SeverityNumber } from '@opentelemetry/api-logs';
|
|
19
19
|
|
|
20
20
|
var name = "@faststore/api";
|
|
21
|
-
var version = "2.1.
|
|
21
|
+
var version = "2.1.9";
|
|
22
22
|
var license = "MIT";
|
|
23
23
|
var main = "dist/index.js";
|
|
24
24
|
var typings = "dist/index.d.ts";
|
|
@@ -54,8 +54,8 @@ var dependencies = {
|
|
|
54
54
|
};
|
|
55
55
|
var devDependencies = {
|
|
56
56
|
"@envelop/core": "^2.6.0",
|
|
57
|
-
"@faststore/eslint-config": "^2.1.
|
|
58
|
-
"@faststore/shared": "^2.1.
|
|
57
|
+
"@faststore/eslint-config": "^2.1.9",
|
|
58
|
+
"@faststore/shared": "^2.1.9",
|
|
59
59
|
"@graphql-codegen/cli": "2.2.0",
|
|
60
60
|
"@graphql-codegen/typescript": "2.2.2",
|
|
61
61
|
"@types/express": "^4.17.16",
|
|
@@ -175,60 +175,37 @@ const VtexCommerce = ({
|
|
|
175
175
|
}
|
|
176
176
|
}) : Promise.resolve(undefined);
|
|
177
177
|
},
|
|
178
|
-
getDeliveryWindows: ({
|
|
179
|
-
id,
|
|
180
|
-
index,
|
|
181
|
-
deliveryMode,
|
|
182
|
-
body
|
|
183
|
-
}, incrementedAddress) => {
|
|
184
|
-
var _body$selectedAddress;
|
|
185
|
-
const mappedBody = {
|
|
186
|
-
logisticsInfo: Array.from({
|
|
187
|
-
length: index
|
|
188
|
-
}, (_, itemIndex) => ({
|
|
189
|
-
itemIndex,
|
|
190
|
-
selectedDeliveryChannel: (deliveryMode == null ? void 0 : deliveryMode.deliveryChannel) || null,
|
|
191
|
-
selectedSla: (deliveryMode == null ? void 0 : deliveryMode.deliveryMethod) || null
|
|
192
|
-
})),
|
|
193
|
-
selectedAddresses: body == null ? void 0 : (_body$selectedAddress = body.selectedAddresses) == null ? void 0 : _body$selectedAddress.map(address => {
|
|
194
|
-
var _address$geoCoordinat, _address$geoCoordinat2;
|
|
195
|
-
const selectedAddress = {
|
|
196
|
-
addressType: address.addressType || null,
|
|
197
|
-
receiverName: address.receiverName || null,
|
|
198
|
-
postalCode: address.postalCode || (incrementedAddress == null ? void 0 : incrementedAddress.postalCode) || null,
|
|
199
|
-
city: (incrementedAddress == null ? void 0 : incrementedAddress.city) || null,
|
|
200
|
-
state: (incrementedAddress == null ? void 0 : incrementedAddress.state) || null,
|
|
201
|
-
country: address.country || (incrementedAddress == null ? void 0 : incrementedAddress.country) || null,
|
|
202
|
-
street: (incrementedAddress == null ? void 0 : incrementedAddress.street) || null,
|
|
203
|
-
number: (incrementedAddress == null ? void 0 : incrementedAddress.number) || null,
|
|
204
|
-
neighborhood: (incrementedAddress == null ? void 0 : incrementedAddress.neighborhood) || null,
|
|
205
|
-
complement: (incrementedAddress == null ? void 0 : incrementedAddress.complement) || null,
|
|
206
|
-
reference: (incrementedAddress == null ? void 0 : incrementedAddress.reference) || null,
|
|
207
|
-
geoCoordinates: []
|
|
208
|
-
};
|
|
209
|
-
const longitude = (address == null ? void 0 : address.geoCoordinates) instanceof Array ? null : (address == null ? void 0 : (_address$geoCoordinat = address.geoCoordinates) == null ? void 0 : _address$geoCoordinat.longitude) || null;
|
|
210
|
-
const latitude = (address == null ? void 0 : address.geoCoordinates) instanceof Array ? null : (address == null ? void 0 : (_address$geoCoordinat2 = address.geoCoordinates) == null ? void 0 : _address$geoCoordinat2.latitude) || null;
|
|
211
|
-
selectedAddress.geoCoordinates = longitude && latitude ? {
|
|
212
|
-
longitude,
|
|
213
|
-
latitude
|
|
214
|
-
} : (incrementedAddress == null ? void 0 : incrementedAddress.geoCoordinates) || [];
|
|
215
|
-
return selectedAddress;
|
|
216
|
-
})
|
|
217
|
-
};
|
|
218
|
-
return fetchAPI(`${base}/api/checkout/pub/orderForm/${id}/attachments/shippingData`, {
|
|
219
|
-
...BASE_INIT,
|
|
220
|
-
body: JSON.stringify(mappedBody)
|
|
221
|
-
});
|
|
222
|
-
},
|
|
223
178
|
shippingData: ({
|
|
224
179
|
id,
|
|
225
180
|
index,
|
|
226
181
|
deliveryMode,
|
|
227
182
|
body
|
|
228
|
-
}, incrementedAddress) => {
|
|
229
|
-
var _deliveryMode$deliver, _deliveryMode$deliver2
|
|
230
|
-
const
|
|
231
|
-
|
|
183
|
+
}, incrementedAddress, setDeliveryWindow) => {
|
|
184
|
+
var _body$selectedAddress, _deliveryMode$deliver, _deliveryMode$deliver2;
|
|
185
|
+
const addressSession = body == null ? void 0 : (_body$selectedAddress = body.selectedAddresses) == null ? void 0 : _body$selectedAddress.map(address => {
|
|
186
|
+
const addressSession = {
|
|
187
|
+
addressType: address.addressType || null,
|
|
188
|
+
receiverName: address.receiverName || null,
|
|
189
|
+
postalCode: address.postalCode || (incrementedAddress == null ? void 0 : incrementedAddress.postalCode) || null,
|
|
190
|
+
city: (incrementedAddress == null ? void 0 : incrementedAddress.city) || null,
|
|
191
|
+
state: (incrementedAddress == null ? void 0 : incrementedAddress.state) || null,
|
|
192
|
+
country: address.country || (incrementedAddress == null ? void 0 : incrementedAddress.country) || null,
|
|
193
|
+
street: (incrementedAddress == null ? void 0 : incrementedAddress.street) || null,
|
|
194
|
+
number: (incrementedAddress == null ? void 0 : incrementedAddress.number) || null,
|
|
195
|
+
neighborhood: (incrementedAddress == null ? void 0 : incrementedAddress.neighborhood) || null,
|
|
196
|
+
complement: (incrementedAddress == null ? void 0 : incrementedAddress.complement) || null,
|
|
197
|
+
reference: (incrementedAddress == null ? void 0 : incrementedAddress.reference) || null,
|
|
198
|
+
geoCoordinates: []
|
|
199
|
+
};
|
|
200
|
+
const geoCoordinates = address == null ? void 0 : address.geoCoordinates;
|
|
201
|
+
if (geoCoordinates) {
|
|
202
|
+
const latitude = typeof geoCoordinates === 'object' && 'latitude' in geoCoordinates ? geoCoordinates.latitude : null;
|
|
203
|
+
const longitude = typeof geoCoordinates === 'object' && 'longitude' in geoCoordinates ? geoCoordinates.longitude : null;
|
|
204
|
+
addressSession.geoCoordinates = latitude !== null && longitude !== null ? [longitude, latitude] : (incrementedAddress == null ? void 0 : incrementedAddress.geoCoordinates) || [];
|
|
205
|
+
}
|
|
206
|
+
return addressSession;
|
|
207
|
+
});
|
|
208
|
+
const deliveryWindow = setDeliveryWindow ? {
|
|
232
209
|
startDateUtc: deliveryMode == null ? void 0 : (_deliveryMode$deliver = deliveryMode.deliveryWindow) == null ? void 0 : _deliveryMode$deliver.startDate,
|
|
233
210
|
endDateUtc: deliveryMode == null ? void 0 : (_deliveryMode$deliver2 = deliveryMode.deliveryWindow) == null ? void 0 : _deliveryMode$deliver2.endDate
|
|
234
211
|
} : null;
|
|
@@ -241,27 +218,8 @@ const VtexCommerce = ({
|
|
|
241
218
|
selectedSla: (deliveryMode == null ? void 0 : deliveryMode.deliveryMethod) || null,
|
|
242
219
|
deliveryWindow: deliveryWindow
|
|
243
220
|
})),
|
|
244
|
-
selectedAddresses:
|
|
245
|
-
|
|
246
|
-
const selectedAddress = {
|
|
247
|
-
addressType: address.addressType || null,
|
|
248
|
-
receiverName: address.receiverName || null,
|
|
249
|
-
postalCode: address.postalCode || (incrementedAddress == null ? void 0 : incrementedAddress.postalCode) || null,
|
|
250
|
-
city: (incrementedAddress == null ? void 0 : incrementedAddress.city) || null,
|
|
251
|
-
state: (incrementedAddress == null ? void 0 : incrementedAddress.state) || null,
|
|
252
|
-
country: address.country || (incrementedAddress == null ? void 0 : incrementedAddress.country) || null,
|
|
253
|
-
street: (incrementedAddress == null ? void 0 : incrementedAddress.street) || null,
|
|
254
|
-
number: (incrementedAddress == null ? void 0 : incrementedAddress.number) || null,
|
|
255
|
-
neighborhood: (incrementedAddress == null ? void 0 : incrementedAddress.neighborhood) || null,
|
|
256
|
-
complement: (incrementedAddress == null ? void 0 : incrementedAddress.complement) || null,
|
|
257
|
-
reference: (incrementedAddress == null ? void 0 : incrementedAddress.reference) || null,
|
|
258
|
-
geoCoordinates: []
|
|
259
|
-
};
|
|
260
|
-
const longitude = (address == null ? void 0 : address.geoCoordinates) instanceof Array ? null : (address == null ? void 0 : (_address$geoCoordinat3 = address.geoCoordinates) == null ? void 0 : _address$geoCoordinat3.longitude) || null;
|
|
261
|
-
const latitude = (address == null ? void 0 : address.geoCoordinates) instanceof Array ? null : (address == null ? void 0 : (_address$geoCoordinat4 = address.geoCoordinates) == null ? void 0 : _address$geoCoordinat4.latitude) || null;
|
|
262
|
-
selectedAddress.geoCoordinates = longitude && latitude ? [longitude, latitude] : (incrementedAddress == null ? void 0 : incrementedAddress.geoCoordinates) || [];
|
|
263
|
-
return selectedAddress;
|
|
264
|
-
})
|
|
221
|
+
selectedAddresses: addressSession,
|
|
222
|
+
address: addressSession
|
|
265
223
|
};
|
|
266
224
|
return fetchAPI(`${base}/api/checkout/pub/orderForm/${id}/attachments/shippingData`, {
|
|
267
225
|
...BASE_INIT,
|
|
@@ -1097,6 +1055,119 @@ function getPropertyId(item) {
|
|
|
1097
1055
|
return md5(`${item.name}:${JSON.stringify(item.value)}:${item.valueReference}`);
|
|
1098
1056
|
}
|
|
1099
1057
|
|
|
1058
|
+
const shouldUpdateShippingData = (orderForm, session) => {
|
|
1059
|
+
var _orderForm$shippingDa;
|
|
1060
|
+
if (!hasSessionPostalCodeOrGeoCoordinates(session)) {
|
|
1061
|
+
return false;
|
|
1062
|
+
}
|
|
1063
|
+
const {
|
|
1064
|
+
address
|
|
1065
|
+
} = (_orderForm$shippingDa = orderForm.shippingData) != null ? _orderForm$shippingDa : {
|
|
1066
|
+
address: null
|
|
1067
|
+
};
|
|
1068
|
+
if (checkPostalCode(address, session.postalCode)) {
|
|
1069
|
+
return true;
|
|
1070
|
+
}
|
|
1071
|
+
if (checkGeoCoordinates(address, session.geoCoordinates)) {
|
|
1072
|
+
return true;
|
|
1073
|
+
}
|
|
1074
|
+
if (!hasItems(orderForm)) {
|
|
1075
|
+
return false;
|
|
1076
|
+
}
|
|
1077
|
+
// The logisticsInfo will always exist if there´s at least one item inside the cart
|
|
1078
|
+
const {
|
|
1079
|
+
logisticsInfo
|
|
1080
|
+
} = orderForm.shippingData;
|
|
1081
|
+
if (shouldUpdateDeliveryChannel(logisticsInfo, session)) {
|
|
1082
|
+
return true;
|
|
1083
|
+
}
|
|
1084
|
+
if (shouldUpdateDeliveryMethod(logisticsInfo, session)) {
|
|
1085
|
+
return true;
|
|
1086
|
+
}
|
|
1087
|
+
if (shouldUpdateDeliveryWindow(logisticsInfo, session)) {
|
|
1088
|
+
return true;
|
|
1089
|
+
}
|
|
1090
|
+
return false;
|
|
1091
|
+
};
|
|
1092
|
+
// Validate if theres any postal Code or GeoCoordinates set at the session
|
|
1093
|
+
const hasSessionPostalCodeOrGeoCoordinates = session => {
|
|
1094
|
+
return !!session.postalCode || session.geoCoordinates && session.geoCoordinates.latitude && session.geoCoordinates.longitude;
|
|
1095
|
+
};
|
|
1096
|
+
// Validate if theres a difference between the session postal code and orderForm postal code
|
|
1097
|
+
const checkPostalCode = (address, postalCode) => {
|
|
1098
|
+
return typeof postalCode === 'string' && (address == null ? void 0 : address.postalCode) !== postalCode;
|
|
1099
|
+
};
|
|
1100
|
+
// Validate if theres a difference between the session geoCoords and orderForm geoCoords
|
|
1101
|
+
const checkGeoCoordinates = (address, geoCoordinates) => {
|
|
1102
|
+
return typeof (geoCoordinates == null ? void 0 : geoCoordinates.latitude) === 'number' && typeof (geoCoordinates == null ? void 0 : geoCoordinates.longitude) === 'number' && ((address == null ? void 0 : address.geoCoordinates[0]) !== (geoCoordinates == null ? void 0 : geoCoordinates.longitude) || (address == null ? void 0 : address.geoCoordinates[1]) !== (geoCoordinates == null ? void 0 : geoCoordinates.latitude));
|
|
1103
|
+
};
|
|
1104
|
+
// Validate if theres any item inside the orderForm
|
|
1105
|
+
const hasItems = orderForm => {
|
|
1106
|
+
return orderForm.items.length !== 0;
|
|
1107
|
+
};
|
|
1108
|
+
// Validate if the deliveryChannel from the session is different from the selected delivery channel
|
|
1109
|
+
// and if so needs to validate if the deliveryChannel for the session is available inside the slas for the item
|
|
1110
|
+
const shouldUpdateDeliveryChannel = (logisticsInfo, session) => {
|
|
1111
|
+
var _session$deliveryMode;
|
|
1112
|
+
if (!(session != null && (_session$deliveryMode = session.deliveryMode) != null && _session$deliveryMode.deliveryChannel)) {
|
|
1113
|
+
return false;
|
|
1114
|
+
}
|
|
1115
|
+
const {
|
|
1116
|
+
deliveryChannel
|
|
1117
|
+
} = session.deliveryMode;
|
|
1118
|
+
for (const item of logisticsInfo) {
|
|
1119
|
+
if (item.selectedDeliveryChannel !== deliveryChannel) {
|
|
1120
|
+
const matchingSla = item.slas.find(sla => sla.deliveryChannel === deliveryChannel);
|
|
1121
|
+
if (matchingSla) {
|
|
1122
|
+
return true;
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
return false;
|
|
1127
|
+
};
|
|
1128
|
+
// Validate if the deliveryMethod from the session is different from the selectedSLA
|
|
1129
|
+
// and if so needs to validate if the deliveryMethod for the session is available inside the slas for the item
|
|
1130
|
+
const shouldUpdateDeliveryMethod = (logisticsInfo, session) => {
|
|
1131
|
+
var _session$deliveryMode2;
|
|
1132
|
+
if (!(session != null && (_session$deliveryMode2 = session.deliveryMode) != null && _session$deliveryMode2.deliveryMethod)) {
|
|
1133
|
+
return false;
|
|
1134
|
+
}
|
|
1135
|
+
const {
|
|
1136
|
+
deliveryMethod
|
|
1137
|
+
} = session.deliveryMode;
|
|
1138
|
+
for (const item of logisticsInfo) {
|
|
1139
|
+
if (item.selectedSla !== deliveryMethod) {
|
|
1140
|
+
const matchingSla = item.slas.find(sla => sla.id === deliveryMethod);
|
|
1141
|
+
if (matchingSla) {
|
|
1142
|
+
return true;
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
return false;
|
|
1147
|
+
};
|
|
1148
|
+
// Validate if the deliveryWindow from the session is different from the deliveryWindow of the SLA
|
|
1149
|
+
// and if so needs to validate if the deliveryWindow for the session is available inside the availableDeliveryWindows for the item
|
|
1150
|
+
const shouldUpdateDeliveryWindow = (logisticsInfo, session) => {
|
|
1151
|
+
var _session$deliveryMode3, _session$deliveryMode4, _session$deliveryMode5, _session$deliveryMode6;
|
|
1152
|
+
if (!(session != null && (_session$deliveryMode3 = session.deliveryMode) != null && (_session$deliveryMode4 = _session$deliveryMode3.deliveryWindow) != null && _session$deliveryMode4.startDate) || !(session != null && (_session$deliveryMode5 = session.deliveryMode) != null && (_session$deliveryMode6 = _session$deliveryMode5.deliveryWindow) != null && _session$deliveryMode6.endDate)) {
|
|
1153
|
+
return false;
|
|
1154
|
+
}
|
|
1155
|
+
const {
|
|
1156
|
+
startDate,
|
|
1157
|
+
endDate
|
|
1158
|
+
} = session.deliveryMode.deliveryWindow;
|
|
1159
|
+
for (const item of logisticsInfo) {
|
|
1160
|
+
for (const sla of item.slas) {
|
|
1161
|
+
var _sla$availableDeliver;
|
|
1162
|
+
const matchingWindow = (_sla$availableDeliver = sla.availableDeliveryWindows) == null ? void 0 : _sla$availableDeliver.some(window => window.startDateUtc === startDate && window.endDateUtc === endDate);
|
|
1163
|
+
if (matchingWindow) {
|
|
1164
|
+
return true;
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
return false;
|
|
1169
|
+
};
|
|
1170
|
+
|
|
1100
1171
|
const isAttachment = value => value.valueReference === VALUE_REFERENCES.attachment;
|
|
1101
1172
|
const getId = item => {
|
|
1102
1173
|
var _item$itemOffered$add;
|
|
@@ -1243,7 +1314,6 @@ const getOrderForm = async (id, session, {
|
|
|
1243
1314
|
commerce
|
|
1244
1315
|
}
|
|
1245
1316
|
}) => {
|
|
1246
|
-
var _orderForm$shippingDa, _orderForm$shippingDa2, _session$geoCoordinat, _orderForm$shippingDa3, _orderForm$shippingDa4, _orderForm$shippingDa5, _orderForm$shippingDa6;
|
|
1247
1317
|
const orderForm = await commerce.checkout.orderForm({
|
|
1248
1318
|
id
|
|
1249
1319
|
});
|
|
@@ -1255,8 +1325,8 @@ const getOrderForm = async (id, session, {
|
|
|
1255
1325
|
if (!session) {
|
|
1256
1326
|
return orderForm;
|
|
1257
1327
|
}
|
|
1258
|
-
const
|
|
1259
|
-
if (
|
|
1328
|
+
const updateShipping = shouldUpdateShippingData(orderForm, session);
|
|
1329
|
+
if (updateShipping) {
|
|
1260
1330
|
var _session$deliveryMode;
|
|
1261
1331
|
let incrementedAddress;
|
|
1262
1332
|
if (session.postalCode) {
|
|
@@ -1265,14 +1335,14 @@ const getOrderForm = async (id, session, {
|
|
|
1265
1335
|
const hasDeliveryWindow = (_session$deliveryMode = session.deliveryMode) != null && _session$deliveryMode.deliveryWindow ? true : false;
|
|
1266
1336
|
if (hasDeliveryWindow) {
|
|
1267
1337
|
// if you have a Delivery Window you have to first get the delivery window to set the desired after
|
|
1268
|
-
await commerce.checkout.
|
|
1338
|
+
await commerce.checkout.shippingData({
|
|
1269
1339
|
id: orderForm.orderFormId,
|
|
1270
1340
|
index: orderForm.items.length,
|
|
1271
1341
|
deliveryMode: session.deliveryMode,
|
|
1272
1342
|
body: {
|
|
1273
1343
|
selectedAddresses: [session]
|
|
1274
1344
|
}
|
|
1275
|
-
}, incrementedAddress);
|
|
1345
|
+
}, incrementedAddress, false);
|
|
1276
1346
|
}
|
|
1277
1347
|
return commerce.checkout.shippingData({
|
|
1278
1348
|
id: orderForm.orderFormId,
|
|
@@ -1281,7 +1351,7 @@ const getOrderForm = async (id, session, {
|
|
|
1281
1351
|
body: {
|
|
1282
1352
|
selectedAddresses: [session]
|
|
1283
1353
|
}
|
|
1284
|
-
}, incrementedAddress);
|
|
1354
|
+
}, incrementedAddress, true);
|
|
1285
1355
|
}
|
|
1286
1356
|
return orderForm;
|
|
1287
1357
|
};
|
|
@@ -1331,7 +1401,15 @@ const validateCart = async (_, {
|
|
|
1331
1401
|
const orderNumber = (_ref = orderNumberFromSession != null ? orderNumberFromSession : orderNumberFromCart) != null ? _ref : '';
|
|
1332
1402
|
// Step1: Get OrderForm from VTEX Commerce
|
|
1333
1403
|
const orderForm = await getOrderForm(orderNumber, session, ctx);
|
|
1334
|
-
// Step1.
|
|
1404
|
+
// Step1.1: Checks if the orderForm id has changed. There are three cases for this:
|
|
1405
|
+
// Social Selling: the vtex_session cookie contains a new orderForm id with Social Selling data
|
|
1406
|
+
// My Orders: the customer clicks on reordering through generating a new cart and when returning to the faststore, this information needs to be returned by vtex_session cookie.
|
|
1407
|
+
// New session: a new user enters the website and has no orderForm attributed to it (has no relation to the vtex_session cookie).
|
|
1408
|
+
// In all cases, the origin orderForm should replace the copy that's in the browser
|
|
1409
|
+
if (orderForm.orderFormId != orderNumberFromCart) {
|
|
1410
|
+
return orderFormToCart(orderForm, skuLoader);
|
|
1411
|
+
}
|
|
1412
|
+
// Step1.2: Check if another system changed the orderForm with this orderNumber
|
|
1335
1413
|
// If so, this means the user interacted with this cart elsewhere and expects
|
|
1336
1414
|
// to see this new cart state instead of what's stored on the user's browser.
|
|
1337
1415
|
const isStale = isOrderFormStale(orderForm);
|