@oneblink/apps-react 11.1.0-beta.2 → 11.1.1-beta.1
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/apps/localisation-service.d.ts +9 -0
- package/dist/apps/localisation-service.js +19 -0
- package/dist/apps/localisation-service.js.map +1 -1
- package/dist/apps/payment-service.d.ts +1 -1
- package/dist/apps/payment-service.js +9 -3
- package/dist/apps/payment-service.js.map +1 -1
- package/dist/apps/scheduling-service.js +2 -1
- package/dist/apps/scheduling-service.js.map +1 -1
- package/dist/apps/services/schedulingHandlers.d.ts +1 -1
- package/dist/apps/services/schedulingHandlers.js +9 -2
- package/dist/apps/services/schedulingHandlers.js.map +1 -1
- package/dist/apps/services/submit.js +2 -2
- package/dist/apps/services/submit.js.map +1 -1
- package/dist/form-elements/FormElementCalculation.js +4 -3
- package/dist/form-elements/FormElementCalculation.js.map +1 -1
- package/dist/hooks/useConditionalLogic.js +8 -23
- package/dist/hooks/useConditionalLogic.js.map +1 -1
- package/package.json +2 -2
|
@@ -182,6 +182,15 @@ export declare function generateDate({ daysOffset, value, }: {
|
|
|
182
182
|
daysOffset: number | undefined;
|
|
183
183
|
value: string;
|
|
184
184
|
}): Date | undefined;
|
|
185
|
+
/**
|
|
186
|
+
* Parse a date/datetime string for conditional logic evaluation. Date-only
|
|
187
|
+
* values (`YYYY-MM-DD`) are interpreted in the user's local timezone.
|
|
188
|
+
*/
|
|
189
|
+
export declare function parseDate(value: string): Date;
|
|
190
|
+
/**
|
|
191
|
+
* Add calendar days to a date for conditional logic evaluation.
|
|
192
|
+
*/
|
|
193
|
+
export declare function addDaysToDate(date: Date, days: number): Date;
|
|
185
194
|
export declare const replaceSubmissionFormatters: submissionService.ReplaceInjectablesFormatters;
|
|
186
195
|
/**
|
|
187
196
|
* Replace the `{ELEMENT:<elementName>}` values in text after a successful form
|
|
@@ -270,6 +270,25 @@ function generateDateOffset({ date, daysOffset, }) {
|
|
|
270
270
|
}
|
|
271
271
|
return date;
|
|
272
272
|
}
|
|
273
|
+
/**
|
|
274
|
+
* Parse a date/datetime string for conditional logic evaluation. Date-only
|
|
275
|
+
* values (`YYYY-MM-DD`) are interpreted in the user's local timezone.
|
|
276
|
+
*/
|
|
277
|
+
export function parseDate(value) {
|
|
278
|
+
var _a;
|
|
279
|
+
// Always return a Date so callers can use Number.isNaN(date.getTime()) to
|
|
280
|
+
// detect unparseable values. generateDate returns undefined in that case.
|
|
281
|
+
return ((_a = generateDate({
|
|
282
|
+
value,
|
|
283
|
+
daysOffset: undefined,
|
|
284
|
+
})) !== null && _a !== void 0 ? _a : new Date(NaN));
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Add calendar days to a date for conditional logic evaluation.
|
|
288
|
+
*/
|
|
289
|
+
export function addDaysToDate(date, days) {
|
|
290
|
+
return add(date, { days });
|
|
291
|
+
}
|
|
273
292
|
export const replaceSubmissionFormatters = {
|
|
274
293
|
formatDate: (v) => {
|
|
275
294
|
const date = generateDate({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localisation-service.js","sourceRoot":"","sources":["../../src/apps/localisation-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { submissionService } from '@oneblink/sdk-core'\nimport tenants from './tenants'\nimport parser from 'ua-parser-js'\nimport { add, parse } from 'date-fns'\n\nlet iosVersion: number | undefined\nconst parsedUserAgent: parser.IResult = parser(window.navigator.userAgent)\nif (\n parsedUserAgent.os.name === 'iOS' &&\n typeof parsedUserAgent.os.version === 'string'\n) {\n iosVersion = parseFloat(parsedUserAgent.os.version)\n if (Number.isNaN(iosVersion)) {\n iosVersion = undefined\n }\n}\n\n/**\n * Get the locale (e.g. `en-AU`) for the current tenant.\n *\n * #### Example\n *\n * ```js\n * const locale = localisationService.getLocale()\n * ```\n *\n * @returns\n */\nexport function getLocale() {\n return tenants.locale\n}\n\n/**\n * Get the distance units (e.g. `feet` & 'ft) for the current tenant.\n *\n * #### Example\n *\n * ```js\n * const { distanceUnit, distanceUnitShortName } =\n * localisationService.getDistanceUnits()\n * ```\n *\n * @returns\n */\nexport function getDistanceUnits() {\n return {\n distanceUnit: tenants.current.distanceUnit,\n distanceUnitShortName: tenants.current.distanceUnitShortName,\n }\n}\n\nfunction generateFormats({\n time,\n shortDate,\n shortYearlessDate,\n longDate,\n longYearlessDate,\n}: {\n time: string\n shortDate: string\n shortYearlessDate: string\n longDate: string\n longYearlessDate: string\n}) {\n return {\n time,\n shortDate,\n shortYearlessDate,\n longDate,\n longYearlessDate,\n shortDateTime: `${shortDate} ${time}`,\n longDateTime: `${longDate} ${time}`,\n }\n}\n\nexport function getDateFnsFormats() {\n const time = 'h:mm a'\n switch (tenants.locale) {\n case 'en-US': {\n return generateFormats({\n time,\n shortDate: 'MM/dd/yyyy',\n shortYearlessDate: 'MM/dd',\n longDate: 'MMM do, yyyy',\n longYearlessDate: 'MMM do',\n })\n }\n case 'en-AU':\n default: {\n return generateFormats({\n time,\n shortDate: 'dd/MM/yyyy',\n shortYearlessDate: 'dd/MM',\n longDate: 'do MMM, yyyy',\n longYearlessDate: 'do MMM',\n })\n }\n }\n}\n\n/**\n * Format a `Date` as a `string` that just contains the date portion e.g.\n * _31/01/2020_\n *\n * #### Example\n *\n * ```js\n * const date = new Date()\n * const text = localisationService.formatDate(date)\n * // Display text\n * ```\n *\n * @param value\n * @returns\n */\nexport function formatDate(value: Date): string {\n return tenants.current.intlFormats.date.format(value)\n}\n\n/**\n * Format a `Date` as a `string` that just contains the date portion in a long\n * format e.g. _Thursday, 2 January 2020_\n *\n * #### Example\n *\n * ```js\n * const date = new Date()\n * const text = localisationService.formatDateLong(date)\n * // Display text\n * ```\n *\n * @param value\n * @returns\n */\nexport function formatDateLong(value: Date): string {\n return tenants.current.intlFormats.dateLong.format(value)\n}\n\n/**\n * Format a `Date` as a `string` that just contains the time portion e.g. _5:31\n * pm_\n *\n * #### Example\n *\n * ```js\n * const date = new Date()\n * const text = localisationService.formatTime(date)\n * // Display text\n * ```\n *\n * @param value\n * @returns\n */\nexport function formatTime(value: Date): string {\n /*\n * Time formatting for older iOS devices. Prevents date from repeating.\n * Example: Last sync time: 24/11/2022 24/11/2022\n */\n if (typeof iosVersion === 'number' && iosVersion < 13.0) {\n const time = tenants.current.intlFormats.olderIOSTime.formatToParts(value)\n const newTime = time.map((t) => t.value).join('')\n return `${newTime}`\n }\n return tenants.current.intlFormats.time.format(value)\n}\n\n/**\n * Format a `Date` as a `string` that contains the date and time portions e.g.\n * _31/01/2020 5:31 pm_\n *\n * #### Example\n *\n * ```js\n * const date = new Date()\n * const text = localisationService.formatDatetime(date)\n * // Display text\n * ```\n *\n * @param value\n * @returns\n */\nexport function formatDatetime(value: Date) {\n return `${formatDate(value)} ${formatTime(value)}`\n}\n\n/**\n * Format a `Date` as a `string` that contains the date and time portions in a\n * long format e.g. _Thursday, 2 January 2020 5:31 pm_\n *\n * #### Example\n *\n * ```js\n * const date = new Date()\n * const text = localisationService.formatDatetime(date)\n * // Display text\n * ```\n *\n * @param value\n * @returns\n */\nexport function formatDatetimeLong(value: Date) {\n return `${formatDateLong(value)} ${formatTime(value)}`\n}\n\n/**\n * Format a `number` as a `string` represented as a readable number e.g.\n * _123,321.123_\n *\n * #### Example\n *\n * ```js\n * const amount = 1234.4321\n * const text = localisationService.formatCurrency(amount)\n * // Display text\n * ```\n *\n * @param value\n * @returns\n */\nexport function formatNumber(value: number): string {\n return tenants.current.intlFormats.number.format(value)\n}\n\n/**\n * Format a `number` as a `string` represented as a currency e.g. _$123.31_\n *\n * #### Example\n *\n * ```js\n * const amount = 123.321\n * const text = localisationService.formatCurrency(amount)\n * // Display text\n * ```\n *\n * @param value\n * @returns\n */\nexport function formatCurrency(value: number): string {\n return tenants.current.intlFormats.currency.format(value)\n}\n\n/**\n * Generate a `Date` based a `string` while adding/subtracting a number of days.\n * Use this function to generate a date with the correct time if only the date\n * part is required to be formatted for display purposes. Also supports passing\n * `'NOW'` as the value to get the current date with an offset.\n *\n * #### Example\n *\n * ```js\n * const dateOnly = localisationService.generateDate({\n * value: '2023-05-04',\n * dateOnly: true,\n * daysOffset: undefined,\n * })\n *\n * const date = localisationService.generateDate({\n * value: '2023-05-04T02:49:23.616Z',\n * dateOnly: false,\n * daysOffset: undefined,\n * })\n *\n * const now = localisationService.generateDate({\n * value: 'NOW',\n * dateOnly: false,\n * daysOffset: undefined,\n * })\n * ```\n *\n * @param options\n * @returns\n */\nexport function generateDate({\n daysOffset,\n value,\n}: {\n daysOffset: number | undefined\n value: string\n}): Date | undefined {\n if (value === 'NOW') {\n const date = new Date()\n if (daysOffset !== undefined) {\n date.setDate(date.getDate() + daysOffset)\n }\n return date\n } else {\n let date = parse(value, 'yyyy-MM-dd', new Date())\n if (Number.isNaN(date.getTime())) {\n date = parse(value, \"yyyy-MM-dd'T'HH:mm:ss.SSSX\", new Date())\n if (!Number.isNaN(date.getTime())) {\n return generateDateOffset({ date, daysOffset })\n }\n } else {\n return generateDateOffset({ date, daysOffset })\n }\n }\n}\n\nfunction generateDateOffset({\n date,\n daysOffset,\n}: {\n daysOffset: number | undefined\n date: Date\n}) {\n if (daysOffset !== undefined) {\n return add(date, { days: daysOffset })\n }\n return date\n}\n\nexport const replaceSubmissionFormatters: submissionService.ReplaceInjectablesFormatters =\n {\n formatDate: (v) => {\n const date = generateDate({\n value: v,\n daysOffset: undefined,\n })\n if (date) {\n return formatDate(date)\n }\n return ''\n },\n formatDateTime: (value) => formatDatetime(new Date(value)),\n formatTime: (value) => formatTime(new Date(value)),\n formatCurrency: (value) => formatCurrency(value),\n formatNumber: (value) => value.toString(),\n }\n\n/**\n * Replace the `{ELEMENT:<elementName>}` values in text after a successful form\n * submission as well as other replaceable parameters e.g. `submissionId`. The\n * replacements are suppose to be user friendly and for display purposes, e.g.\n * dates should be displayed in the user's desired format and timezone.\n *\n * @param text\n * @param options\n * @returns\n */\nexport function replaceInjectablesWithSubmissionValues(\n text: string,\n options: Omit<\n Parameters<\n typeof submissionService.replaceInjectablesWithSubmissionValues\n >[1],\n keyof submissionService.ReplaceInjectablesFormatters\n >,\n): ReturnType<typeof submissionService.replaceInjectablesWithSubmissionValues> {\n return submissionService.replaceInjectablesWithSubmissionValues(text, {\n ...options,\n ...replaceSubmissionFormatters,\n })\n}\n\n/**\n * Replace the `{ELEMENT:<elementName>}` values in text while a form is being\n * filled out. The replacements are suppose to be user friendly and for display\n * purposes, e.g. dates should be displayed in the user's desired format and\n * timezone.\n *\n * @param text\n * @param options\n * @returns\n */\nexport function replaceInjectablesWithElementValues(\n text: string,\n options: Omit<\n Parameters<typeof submissionService.replaceInjectablesWithElementValues>[1],\n keyof submissionService.ReplaceInjectablesFormatters\n >,\n): ReturnType<typeof submissionService.replaceInjectablesWithElementValues> {\n return submissionService.replaceInjectablesWithElementValues(text, {\n ...options,\n ...replaceSubmissionFormatters,\n })\n}\n"]}
|
|
1
|
+
{"version":3,"file":"localisation-service.js","sourceRoot":"","sources":["../../src/apps/localisation-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { submissionService } from '@oneblink/sdk-core'\nimport tenants from './tenants'\nimport parser from 'ua-parser-js'\nimport { add, parse } from 'date-fns'\n\nlet iosVersion: number | undefined\nconst parsedUserAgent: parser.IResult = parser(window.navigator.userAgent)\nif (\n parsedUserAgent.os.name === 'iOS' &&\n typeof parsedUserAgent.os.version === 'string'\n) {\n iosVersion = parseFloat(parsedUserAgent.os.version)\n if (Number.isNaN(iosVersion)) {\n iosVersion = undefined\n }\n}\n\n/**\n * Get the locale (e.g. `en-AU`) for the current tenant.\n *\n * #### Example\n *\n * ```js\n * const locale = localisationService.getLocale()\n * ```\n *\n * @returns\n */\nexport function getLocale() {\n return tenants.locale\n}\n\n/**\n * Get the distance units (e.g. `feet` & 'ft) for the current tenant.\n *\n * #### Example\n *\n * ```js\n * const { distanceUnit, distanceUnitShortName } =\n * localisationService.getDistanceUnits()\n * ```\n *\n * @returns\n */\nexport function getDistanceUnits() {\n return {\n distanceUnit: tenants.current.distanceUnit,\n distanceUnitShortName: tenants.current.distanceUnitShortName,\n }\n}\n\nfunction generateFormats({\n time,\n shortDate,\n shortYearlessDate,\n longDate,\n longYearlessDate,\n}: {\n time: string\n shortDate: string\n shortYearlessDate: string\n longDate: string\n longYearlessDate: string\n}) {\n return {\n time,\n shortDate,\n shortYearlessDate,\n longDate,\n longYearlessDate,\n shortDateTime: `${shortDate} ${time}`,\n longDateTime: `${longDate} ${time}`,\n }\n}\n\nexport function getDateFnsFormats() {\n const time = 'h:mm a'\n switch (tenants.locale) {\n case 'en-US': {\n return generateFormats({\n time,\n shortDate: 'MM/dd/yyyy',\n shortYearlessDate: 'MM/dd',\n longDate: 'MMM do, yyyy',\n longYearlessDate: 'MMM do',\n })\n }\n case 'en-AU':\n default: {\n return generateFormats({\n time,\n shortDate: 'dd/MM/yyyy',\n shortYearlessDate: 'dd/MM',\n longDate: 'do MMM, yyyy',\n longYearlessDate: 'do MMM',\n })\n }\n }\n}\n\n/**\n * Format a `Date` as a `string` that just contains the date portion e.g.\n * _31/01/2020_\n *\n * #### Example\n *\n * ```js\n * const date = new Date()\n * const text = localisationService.formatDate(date)\n * // Display text\n * ```\n *\n * @param value\n * @returns\n */\nexport function formatDate(value: Date): string {\n return tenants.current.intlFormats.date.format(value)\n}\n\n/**\n * Format a `Date` as a `string` that just contains the date portion in a long\n * format e.g. _Thursday, 2 January 2020_\n *\n * #### Example\n *\n * ```js\n * const date = new Date()\n * const text = localisationService.formatDateLong(date)\n * // Display text\n * ```\n *\n * @param value\n * @returns\n */\nexport function formatDateLong(value: Date): string {\n return tenants.current.intlFormats.dateLong.format(value)\n}\n\n/**\n * Format a `Date` as a `string` that just contains the time portion e.g. _5:31\n * pm_\n *\n * #### Example\n *\n * ```js\n * const date = new Date()\n * const text = localisationService.formatTime(date)\n * // Display text\n * ```\n *\n * @param value\n * @returns\n */\nexport function formatTime(value: Date): string {\n /*\n * Time formatting for older iOS devices. Prevents date from repeating.\n * Example: Last sync time: 24/11/2022 24/11/2022\n */\n if (typeof iosVersion === 'number' && iosVersion < 13.0) {\n const time = tenants.current.intlFormats.olderIOSTime.formatToParts(value)\n const newTime = time.map((t) => t.value).join('')\n return `${newTime}`\n }\n return tenants.current.intlFormats.time.format(value)\n}\n\n/**\n * Format a `Date` as a `string` that contains the date and time portions e.g.\n * _31/01/2020 5:31 pm_\n *\n * #### Example\n *\n * ```js\n * const date = new Date()\n * const text = localisationService.formatDatetime(date)\n * // Display text\n * ```\n *\n * @param value\n * @returns\n */\nexport function formatDatetime(value: Date) {\n return `${formatDate(value)} ${formatTime(value)}`\n}\n\n/**\n * Format a `Date` as a `string` that contains the date and time portions in a\n * long format e.g. _Thursday, 2 January 2020 5:31 pm_\n *\n * #### Example\n *\n * ```js\n * const date = new Date()\n * const text = localisationService.formatDatetime(date)\n * // Display text\n * ```\n *\n * @param value\n * @returns\n */\nexport function formatDatetimeLong(value: Date) {\n return `${formatDateLong(value)} ${formatTime(value)}`\n}\n\n/**\n * Format a `number` as a `string` represented as a readable number e.g.\n * _123,321.123_\n *\n * #### Example\n *\n * ```js\n * const amount = 1234.4321\n * const text = localisationService.formatCurrency(amount)\n * // Display text\n * ```\n *\n * @param value\n * @returns\n */\nexport function formatNumber(value: number): string {\n return tenants.current.intlFormats.number.format(value)\n}\n\n/**\n * Format a `number` as a `string` represented as a currency e.g. _$123.31_\n *\n * #### Example\n *\n * ```js\n * const amount = 123.321\n * const text = localisationService.formatCurrency(amount)\n * // Display text\n * ```\n *\n * @param value\n * @returns\n */\nexport function formatCurrency(value: number): string {\n return tenants.current.intlFormats.currency.format(value)\n}\n\n/**\n * Generate a `Date` based a `string` while adding/subtracting a number of days.\n * Use this function to generate a date with the correct time if only the date\n * part is required to be formatted for display purposes. Also supports passing\n * `'NOW'` as the value to get the current date with an offset.\n *\n * #### Example\n *\n * ```js\n * const dateOnly = localisationService.generateDate({\n * value: '2023-05-04',\n * dateOnly: true,\n * daysOffset: undefined,\n * })\n *\n * const date = localisationService.generateDate({\n * value: '2023-05-04T02:49:23.616Z',\n * dateOnly: false,\n * daysOffset: undefined,\n * })\n *\n * const now = localisationService.generateDate({\n * value: 'NOW',\n * dateOnly: false,\n * daysOffset: undefined,\n * })\n * ```\n *\n * @param options\n * @returns\n */\nexport function generateDate({\n daysOffset,\n value,\n}: {\n daysOffset: number | undefined\n value: string\n}): Date | undefined {\n if (value === 'NOW') {\n const date = new Date()\n if (daysOffset !== undefined) {\n date.setDate(date.getDate() + daysOffset)\n }\n return date\n } else {\n let date = parse(value, 'yyyy-MM-dd', new Date())\n if (Number.isNaN(date.getTime())) {\n date = parse(value, \"yyyy-MM-dd'T'HH:mm:ss.SSSX\", new Date())\n if (!Number.isNaN(date.getTime())) {\n return generateDateOffset({ date, daysOffset })\n }\n } else {\n return generateDateOffset({ date, daysOffset })\n }\n }\n}\n\nfunction generateDateOffset({\n date,\n daysOffset,\n}: {\n daysOffset: number | undefined\n date: Date\n}) {\n if (daysOffset !== undefined) {\n return add(date, { days: daysOffset })\n }\n return date\n}\n\n/**\n * Parse a date/datetime string for conditional logic evaluation. Date-only\n * values (`YYYY-MM-DD`) are interpreted in the user's local timezone.\n */\nexport function parseDate(value: string): Date {\n // Always return a Date so callers can use Number.isNaN(date.getTime()) to\n // detect unparseable values. generateDate returns undefined in that case.\n return (\n generateDate({\n value,\n daysOffset: undefined,\n }) ?? new Date(NaN)\n )\n}\n\n/**\n * Add calendar days to a date for conditional logic evaluation.\n */\nexport function addDaysToDate(date: Date, days: number): Date {\n return add(date, { days })\n}\n\nexport const replaceSubmissionFormatters: submissionService.ReplaceInjectablesFormatters =\n {\n formatDate: (v) => {\n const date = generateDate({\n value: v,\n daysOffset: undefined,\n })\n if (date) {\n return formatDate(date)\n }\n return ''\n },\n formatDateTime: (value) => formatDatetime(new Date(value)),\n formatTime: (value) => formatTime(new Date(value)),\n formatCurrency: (value) => formatCurrency(value),\n formatNumber: (value) => value.toString(),\n }\n\n/**\n * Replace the `{ELEMENT:<elementName>}` values in text after a successful form\n * submission as well as other replaceable parameters e.g. `submissionId`. The\n * replacements are suppose to be user friendly and for display purposes, e.g.\n * dates should be displayed in the user's desired format and timezone.\n *\n * @param text\n * @param options\n * @returns\n */\nexport function replaceInjectablesWithSubmissionValues(\n text: string,\n options: Omit<\n Parameters<\n typeof submissionService.replaceInjectablesWithSubmissionValues\n >[1],\n keyof submissionService.ReplaceInjectablesFormatters\n >,\n): ReturnType<typeof submissionService.replaceInjectablesWithSubmissionValues> {\n return submissionService.replaceInjectablesWithSubmissionValues(text, {\n ...options,\n ...replaceSubmissionFormatters,\n })\n}\n\n/**\n * Replace the `{ELEMENT:<elementName>}` values in text while a form is being\n * filled out. The replacements are suppose to be user friendly and for display\n * purposes, e.g. dates should be displayed in the user's desired format and\n * timezone.\n *\n * @param text\n * @param options\n * @returns\n */\nexport function replaceInjectablesWithElementValues(\n text: string,\n options: Omit<\n Parameters<typeof submissionService.replaceInjectablesWithElementValues>[1],\n keyof submissionService.ReplaceInjectablesFormatters\n >,\n): ReturnType<typeof submissionService.replaceInjectablesWithElementValues> {\n return submissionService.replaceInjectablesWithElementValues(text, {\n ...options,\n ...replaceSubmissionFormatters,\n })\n}\n"]}
|
|
@@ -24,7 +24,7 @@ export { HandlePaymentResult, PaymentReceiptItem, westpacQuickStream };
|
|
|
24
24
|
* @returns
|
|
25
25
|
*/
|
|
26
26
|
export declare function handlePaymentQuerystring(query: Record<string, unknown>): Promise<HandlePaymentResult>;
|
|
27
|
-
export declare function checkForPaymentSubmissionEvent(formSubmission: FormSubmission): {
|
|
27
|
+
export declare function checkForPaymentSubmissionEvent(formSubmission: FormSubmission, submissionTimestamp: string): {
|
|
28
28
|
paymentSubmissionEvent: SubmissionEventTypes.FormPaymentEvent;
|
|
29
29
|
amount: number;
|
|
30
30
|
} | undefined;
|
|
@@ -6,7 +6,7 @@ import BPOINTPaymentProvider from './services/payment-providers/BPOINTPaymentPro
|
|
|
6
6
|
import CPPayPaymentProvider from './services/payment-providers/CPPayPaymentProvider';
|
|
7
7
|
import NSWGovPayPaymentProvider from './services/payment-providers/NSWGovPayPaymentProvider';
|
|
8
8
|
import WestpacQuickStreamPaymentProvider, * as westpacQuickStream from './services/payment-providers/WestpacQuickStreamPaymentProvider';
|
|
9
|
-
import { replaceSubmissionFormatters } from './localisation-service';
|
|
9
|
+
import { addDaysToDate, parseDate, replaceSubmissionFormatters, } from './localisation-service';
|
|
10
10
|
import { getSchedulingBooking, removeSchedulingBooking, } from './services/schedulingHandlers';
|
|
11
11
|
const KEY = 'PAYMENT_SUBMISSION_RESULT';
|
|
12
12
|
export { westpacQuickStream };
|
|
@@ -71,8 +71,14 @@ export async function handlePaymentQuerystring(query) {
|
|
|
71
71
|
schedulingBooking,
|
|
72
72
|
};
|
|
73
73
|
}
|
|
74
|
-
export function checkForPaymentSubmissionEvent(formSubmission) {
|
|
75
|
-
const result = paymentService.checkForPaymentEvent(
|
|
74
|
+
export function checkForPaymentSubmissionEvent(formSubmission, submissionTimestamp) {
|
|
75
|
+
const result = paymentService.checkForPaymentEvent({
|
|
76
|
+
definition: formSubmission.definition,
|
|
77
|
+
submission: formSubmission.submission,
|
|
78
|
+
submissionTimestamp,
|
|
79
|
+
parseDate,
|
|
80
|
+
addDaysToDate,
|
|
81
|
+
});
|
|
76
82
|
if (result) {
|
|
77
83
|
console.log('Form has a payment submission event with amount', result);
|
|
78
84
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payment-service.js","sourceRoot":"","sources":["../../src/apps/payment-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACnD,OAAO,iBAAiB,MAAM,qCAAqC,CAAA;AACnE,OAAO,EAAE,4BAA4B,EAAE,MAAM,wBAAwB,CAAA;AACrE,OAAO,YAAY,MAAM,kBAAkB,CAAA;AAQ3C,OAAO,qBAAqB,MAAM,oDAAoD,CAAA;AACtF,OAAO,oBAAoB,MAAM,mDAAmD,CAAA;AACpF,OAAO,wBAAwB,MAAM,uDAAuD,CAAA;AAC5F,OAAO,iCAAiC,EAAE,KAAK,kBAAkB,MAAM,gEAAgE,CAAA;AACvI,OAAO,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAA;AACpE,OAAO,EACL,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,+BAA+B,CAAA;AAEtC,MAAM,GAAG,GAAG,2BAA2B,CAAA;AAEvC,OAAO,EAA2C,kBAAkB,EAAE,CAAA;AAEtE,SAAS,kBAAkB,CACzB,oBAA0C,EAC1C,sBAA6D;IAE7D,QAAQ,sBAAsB,CAAC,IAAI,EAAE,CAAC;QACpC,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,OAAO,IAAI,qBAAqB,CAC9B,sBAAsB,EACtB,oBAAoB,CACrB,CAAA;QACH,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,OAAO,IAAI,oBAAoB,CAC7B,sBAAsB,EACtB,oBAAoB,CACrB,CAAA;QACH,CAAC;QACD,KAAK,aAAa,CAAC,CAAC,CAAC;YACnB,OAAO,IAAI,wBAAwB,CACjC,sBAAsB,EACtB,oBAAoB,CACrB,CAAA;QACH,CAAC;QACD,KAAK,sBAAsB,CAAC,CAAC,CAAC;YAC5B,OAAO,IAAI,iCAAiC,CAC1C,sBAAsB,EACtB,oBAAoB,CACrB,CAAA;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,KAA8B;IAE9B,MAAM,gBAAgB,GACpB,MAAM,YAAY,CAAC,kBAAkB,CAA8B,GAAG,CAAC,CAAA;IACzE,2DAA2D;IAC3D,6CAA6C;IAC7C,sDAAsD;IACtD,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,MAAM,IAAI,iBAAiB,CACzB,4EAA4E,CAC7E,CAAA;IACH,CAAC;IACD,IAAI,CAAC,gBAAgB,CAAC,OAAO,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC;QAC3E,MAAM,IAAI,iBAAiB,CACzB,iFAAiF,CAClF,CAAA;IACH,CAAC;IACD,MAAM,eAAe,GAAG,kBAAkB,CACxC,gBAAgB,EAChB,gBAAgB,CAAC,OAAO,CAAC,eAAe,CACzC,CAAA;IACD,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,MAAM,IAAI,iBAAiB,CACzB,gFAAgF,CACjF,CAAA;IACH,CAAC;IAED,MAAM,0BAA0B,GAC9B,MAAM,eAAe,CAAC,wBAAwB,CAAC,KAAK,CAAC,CAAA;IAEvD,MAAM,iBAAiB,GAAG,MAAM,oBAAoB,CAClD,0BAA0B,CAAC,gBAAgB,CAAC,YAAY,CACzD,CAAA;IACD,IAAI,iBAAiB,IAAI,0BAA0B,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC;QAC1E,MAAM,uBAAuB,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAA;IAC/D,CAAC;IAED,OAAO;QACL,GAAG,0BAA0B;QAC7B,iBAAiB;KAClB,CAAA;AACH,CAAC;AAED,MAAM,UAAU,8BAA8B,CAAC,cAA8B;IAM3E,MAAM,MAAM,GAAG,cAAc,CAAC,oBAAoB,CAChD,cAAc,CAAC,UAAU,EACzB,cAAc,CAAC,UAAU,CAC1B,CAAA;IACD,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,iDAAiD,EAAE,MAAM,CAAC,CAAA;IACxE,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAAC,EACjD,MAAM,EACN,oBAAoB,EACpB,sBAAsB,EACtB,iBAAiB,EACjB,cAAc,GAOf;IACC,MAAM,eAAe,GAAG,kBAAkB,CACxC,oBAAoB,EACpB,sBAAsB,CACvB,CAAA;IACD,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,MAAM,IAAI,iBAAiB,CACzB,yFAAyF,CAC1F,CAAA;IACH,CAAC;IAED,MAAM,oBAAoB,GAAG,MAAM,4BAA4B,CAC7D,eAAe,EACf;QACE,MAAM;QACN,WAAW,EAAE,iBAAiB;QAC9B,YAAY,EAAE,oBAAoB,CAAC,YAAY;QAC/C,cAAc;KACf,CACF,CAAA;IAED,MAAM,OAAO,GAAG;QACd,eAAe,EAAE,sBAAsB;QACvC,iBAAiB;QACjB,aAAa,EAAE,oBAAoB,CAAC,aAAa;QACjD,cAAc;QACd,MAAM;KACP,CAAA;IACD,OAAO,CAAC,GAAG,CAAC,oDAAoD,EAAE,OAAO,CAAC,CAAA;IAE1E,MAAM,YAAY,CAAC,kBAAkB,CAAC,GAAG,EAAE;QACzC,GAAG,oBAAoB;QACvB,UAAU,EAAE,IAAI;QAChB,OAAO;KACR,CAAC,CAAA;IAEF,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,8BAA8B;;IAIlD,MAAM,oBAAoB,GACxB,MAAM,YAAY,CAAC,kBAAkB,CAA8B,GAAG,CAAC,CAAA;IAEzE,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC1B,MAAM,IAAI,iBAAiB,CACzB,oFAAoF,CACrF,CAAA;IACH,CAAC;IACD,IAAI,CAAC,CAAA,MAAA,oBAAoB,CAAC,OAAO,0CAAE,eAAe,CAAA,EAAE,CAAC;QACnD,MAAM,IAAI,iBAAiB,CACzB,yFAAyF,CAC1F,CAAA;IACH,CAAC;IAED,OAAO;QACL,oBAAoB;QACpB,sBAAsB,EAAE,MAAA,oBAAoB,CAAC,OAAO,0CAAE,eAAe;KACtE,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,0CAA0C,CACxD,qBAA4D;IAE5D,OAAO,cAAc,CAAC,0CAA0C,CAC9D,qBAAqB,EACrB,2BAA2B,CAC5B,CAAA;AACH,CAAC","sourcesContent":["import { paymentService } from '@oneblink/sdk-core'\nimport OneBlinkAppsError from './services/errors/oneBlinkAppsError'\nimport { generatePaymentConfiguration } from './services/api/payment'\nimport utilsService from './services/utils'\nimport { SubmissionEventTypes, SubmissionTypes } from '@oneblink/types'\nimport { FormSubmission, FormSubmissionResult } from './types/submissions'\nimport {\n HandlePaymentResult,\n PaymentProvider,\n PaymentReceiptItem,\n} from './types/payments'\nimport BPOINTPaymentProvider from './services/payment-providers/BPOINTPaymentProvider'\nimport CPPayPaymentProvider from './services/payment-providers/CPPayPaymentProvider'\nimport NSWGovPayPaymentProvider from './services/payment-providers/NSWGovPayPaymentProvider'\nimport WestpacQuickStreamPaymentProvider, * as westpacQuickStream from './services/payment-providers/WestpacQuickStreamPaymentProvider'\nimport { replaceSubmissionFormatters } from './localisation-service'\nimport {\n getSchedulingBooking,\n removeSchedulingBooking,\n} from './services/schedulingHandlers'\n\nconst KEY = 'PAYMENT_SUBMISSION_RESULT'\n\nexport { HandlePaymentResult, PaymentReceiptItem, westpacQuickStream }\n\nfunction getPaymentProvider(\n formSubmissionResult: FormSubmissionResult,\n paymentSubmissionEvent: SubmissionEventTypes.FormPaymentEvent,\n): PaymentProvider<SubmissionEventTypes.FormPaymentEvent> {\n switch (paymentSubmissionEvent.type) {\n case 'BPOINT': {\n return new BPOINTPaymentProvider(\n paymentSubmissionEvent,\n formSubmissionResult,\n )\n }\n case 'CP_PAY': {\n return new CPPayPaymentProvider(\n paymentSubmissionEvent,\n formSubmissionResult,\n )\n }\n case 'NSW_GOV_PAY': {\n return new NSWGovPayPaymentProvider(\n paymentSubmissionEvent,\n formSubmissionResult,\n )\n }\n case 'WESTPAC_QUICK_STREAM': {\n return new WestpacQuickStreamPaymentProvider(\n paymentSubmissionEvent,\n formSubmissionResult,\n )\n }\n }\n}\n\n/**\n * Pass in query string parameters after a redirect back to your app after a\n * payment is processed. This function will handle all payment submission events\n * supported by OneBlink. Will return a Transaction and the submission result\n * that was returned from `handlePaymentSubmissionEvent()` before redirecting to\n * `payment.hostedFormUrl`.\n *\n * #### Example\n *\n * ```js\n * import queryString from 'query-string'\n *\n * const query = queryString.parse(window.location.search)\n * const { transaction, submissionResult } =\n * await paymentService.handlePaymentQuerystring(query)\n * ```\n *\n * @param query\n * @returns\n */\nexport async function handlePaymentQuerystring(\n query: Record<string, unknown>,\n): Promise<HandlePaymentResult> {\n const submissionResult =\n await utilsService.getLocalForageItem<FormSubmissionResult | null>(KEY)\n // If the current transaction does not match the submission\n // we will display message to user indicating\n // they are looking for the wrong transaction receipt.\n if (!submissionResult) {\n throw new OneBlinkAppsError(\n 'It looks like you are attempting to view a receipt for an unknown payment.',\n )\n }\n if (!submissionResult.payment || !submissionResult.payment.submissionEvent) {\n throw new OneBlinkAppsError(\n 'It looks like you are attempting to view a receipt for a misconfigured payment.',\n )\n }\n const paymentProvider = getPaymentProvider(\n submissionResult,\n submissionResult.payment.submissionEvent,\n )\n if (!paymentProvider) {\n throw new OneBlinkAppsError(\n 'It looks like you are attempting to view a receipt for an unsupported payment.',\n )\n }\n\n const verifiedPaymentTransaction =\n await paymentProvider.verifyPaymentTransaction(query)\n\n const schedulingBooking = await getSchedulingBooking(\n verifiedPaymentTransaction.submissionResult.submissionId,\n )\n if (schedulingBooking && verifiedPaymentTransaction.transaction.isSuccess) {\n await removeSchedulingBooking(schedulingBooking.submissionId)\n }\n\n return {\n ...verifiedPaymentTransaction,\n schedulingBooking,\n }\n}\n\nexport function checkForPaymentSubmissionEvent(formSubmission: FormSubmission):\n | {\n paymentSubmissionEvent: SubmissionEventTypes.FormPaymentEvent\n amount: number\n }\n | undefined {\n const result = paymentService.checkForPaymentEvent(\n formSubmission.definition,\n formSubmission.submission,\n )\n if (result) {\n console.log('Form has a payment submission event with amount', result)\n }\n return result\n}\n\n/**\n * Handle a submission result with a payment submission event. Will throw an\n * error if a transaction has already been made using this submission result.\n * Will return `undefined` if the submission does not have an amount. Will\n * return the submission result passed in with a `payment` property if the\n * submission requires processing.\n *\n * #### Example\n *\n * ```js\n * const formSubmissionResult = {\n * submissionId: '89c6e98e-f56f-45fc-84fe-c4fc62331d34',\n * submissionTimestamp: '2020-07-29T01:03:26.573Z'\n * formsAppId: 1,\n * submission: {\n * form: 'data',\n * goes: 'here',\n * amount: 1.50,\n * }\n * definition: OneBlinkForm,\n * payment: null,\n * }\n * const paymentSubmissionEvent = {\n * type: 'CP_PAY',\n * configuration: {\n * elementId: '12663efc-4c6a-4e72-8505-559edfe3e92e',\n * gatewayId: '6658c5c4-e0db-483b-8af7-6a6464fe772c',\n * },\n * }\n * const paymentReceiptUrl = `${window.location.origin}/payment-receipt`\n * const paymentSubmissionResult = await paymentService.handlePaymentSubmissionEvent({\n * formSubmissionResult,\n * paymentSubmissionEvent,\n * paymentReceiptUrl,\n * })\n * if (paymentSubmissionResult) {\n * window.location.href = paymentSubmissionResult.payment.hostedFormUrl\n * }\n * ```\n *\n * @param options\n * @returns\n */\nexport async function handlePaymentSubmissionEvent({\n amount,\n formSubmissionResult,\n paymentSubmissionEvent,\n paymentReceiptUrl,\n paymentFormUrl,\n}: {\n amount: number\n formSubmissionResult: FormSubmissionResult\n paymentSubmissionEvent: SubmissionEventTypes.FormPaymentEvent\n paymentReceiptUrl: string\n paymentFormUrl: string | undefined\n}): Promise<FormSubmissionResult['payment']> {\n const paymentProvider = getPaymentProvider(\n formSubmissionResult,\n paymentSubmissionEvent,\n )\n if (!paymentProvider) {\n throw new OneBlinkAppsError(\n 'It looks like you are attempting to make a payment using an unsupported payment method.',\n )\n }\n\n const paymentConfiguration = await generatePaymentConfiguration(\n paymentProvider,\n {\n amount,\n redirectUrl: paymentReceiptUrl,\n submissionId: formSubmissionResult.submissionId,\n paymentFormUrl,\n },\n )\n\n const payment = {\n submissionEvent: paymentSubmissionEvent,\n paymentReceiptUrl,\n hostedFormUrl: paymentConfiguration.hostedFormUrl,\n paymentFormUrl,\n amount,\n }\n console.log('Created Payment configuration to start transaction', payment)\n\n await utilsService.setLocalForageItem(KEY, {\n ...formSubmissionResult,\n scheduling: null,\n payment,\n })\n\n return payment\n}\n\nexport async function getFormSubmissionResultPayment(): Promise<{\n formSubmissionResult: FormSubmissionResult\n paymentSubmissionEvent: SubmissionEventTypes.FormPaymentEvent\n}> {\n const formSubmissionResult =\n await utilsService.getLocalForageItem<FormSubmissionResult | null>(KEY)\n\n if (!formSubmissionResult) {\n throw new OneBlinkAppsError(\n 'It looks like you are attempting to complete a transaction for an unknown payment.',\n )\n }\n if (!formSubmissionResult.payment?.submissionEvent) {\n throw new OneBlinkAppsError(\n 'It looks like you are attempting to complete a transaction for a misconfigured payment.',\n )\n }\n\n return {\n formSubmissionResult,\n paymentSubmissionEvent: formSubmissionResult.payment?.submissionEvent,\n }\n}\n\n/**\n * Retrieve an array of detail items from a form submission payment.\n *\n * #### Example\n *\n * ```js\n * const detailItems =\n * paymentService.getDisplayDetailsFromFormSubmissionPayment(\n * formSubmissionPayment,\n * )\n * ```\n *\n * @param formSubmissionPayment\n * @returns\n */\nexport function getDisplayDetailsFromFormSubmissionPayment(\n formSubmissionPayment: SubmissionTypes.FormSubmissionPayment,\n) {\n return paymentService.getDisplayDetailsFromFormSubmissionPayment(\n formSubmissionPayment,\n replaceSubmissionFormatters,\n )\n}\n"]}
|
|
1
|
+
{"version":3,"file":"payment-service.js","sourceRoot":"","sources":["../../src/apps/payment-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { paymentService } from '@oneblink/sdk-core'\nimport OneBlinkAppsError from './services/errors/oneBlinkAppsError'\nimport { generatePaymentConfiguration } from './services/api/payment'\nimport utilsService from './services/utils'\nimport { SubmissionEventTypes, SubmissionTypes } from '@oneblink/types'\nimport { FormSubmission, FormSubmissionResult } from './types/submissions'\nimport {\n HandlePaymentResult,\n PaymentProvider,\n PaymentReceiptItem,\n} from './types/payments'\nimport BPOINTPaymentProvider from './services/payment-providers/BPOINTPaymentProvider'\nimport CPPayPaymentProvider from './services/payment-providers/CPPayPaymentProvider'\nimport NSWGovPayPaymentProvider from './services/payment-providers/NSWGovPayPaymentProvider'\nimport WestpacQuickStreamPaymentProvider, * as westpacQuickStream from './services/payment-providers/WestpacQuickStreamPaymentProvider'\nimport {\n addDaysToDate,\n parseDate,\n replaceSubmissionFormatters,\n} from './localisation-service'\nimport {\n getSchedulingBooking,\n removeSchedulingBooking,\n} from './services/schedulingHandlers'\n\nconst KEY = 'PAYMENT_SUBMISSION_RESULT'\n\nexport { HandlePaymentResult, PaymentReceiptItem, westpacQuickStream }\n\nfunction getPaymentProvider(\n formSubmissionResult: FormSubmissionResult,\n paymentSubmissionEvent: SubmissionEventTypes.FormPaymentEvent,\n): PaymentProvider<SubmissionEventTypes.FormPaymentEvent> {\n switch (paymentSubmissionEvent.type) {\n case 'BPOINT': {\n return new BPOINTPaymentProvider(\n paymentSubmissionEvent,\n formSubmissionResult,\n )\n }\n case 'CP_PAY': {\n return new CPPayPaymentProvider(\n paymentSubmissionEvent,\n formSubmissionResult,\n )\n }\n case 'NSW_GOV_PAY': {\n return new NSWGovPayPaymentProvider(\n paymentSubmissionEvent,\n formSubmissionResult,\n )\n }\n case 'WESTPAC_QUICK_STREAM': {\n return new WestpacQuickStreamPaymentProvider(\n paymentSubmissionEvent,\n formSubmissionResult,\n )\n }\n }\n}\n\n/**\n * Pass in query string parameters after a redirect back to your app after a\n * payment is processed. This function will handle all payment submission events\n * supported by OneBlink. Will return a Transaction and the submission result\n * that was returned from `handlePaymentSubmissionEvent()` before redirecting to\n * `payment.hostedFormUrl`.\n *\n * #### Example\n *\n * ```js\n * import queryString from 'query-string'\n *\n * const query = queryString.parse(window.location.search)\n * const { transaction, submissionResult } =\n * await paymentService.handlePaymentQuerystring(query)\n * ```\n *\n * @param query\n * @returns\n */\nexport async function handlePaymentQuerystring(\n query: Record<string, unknown>,\n): Promise<HandlePaymentResult> {\n const submissionResult =\n await utilsService.getLocalForageItem<FormSubmissionResult | null>(KEY)\n // If the current transaction does not match the submission\n // we will display message to user indicating\n // they are looking for the wrong transaction receipt.\n if (!submissionResult) {\n throw new OneBlinkAppsError(\n 'It looks like you are attempting to view a receipt for an unknown payment.',\n )\n }\n if (!submissionResult.payment || !submissionResult.payment.submissionEvent) {\n throw new OneBlinkAppsError(\n 'It looks like you are attempting to view a receipt for a misconfigured payment.',\n )\n }\n const paymentProvider = getPaymentProvider(\n submissionResult,\n submissionResult.payment.submissionEvent,\n )\n if (!paymentProvider) {\n throw new OneBlinkAppsError(\n 'It looks like you are attempting to view a receipt for an unsupported payment.',\n )\n }\n\n const verifiedPaymentTransaction =\n await paymentProvider.verifyPaymentTransaction(query)\n\n const schedulingBooking = await getSchedulingBooking(\n verifiedPaymentTransaction.submissionResult.submissionId,\n )\n if (schedulingBooking && verifiedPaymentTransaction.transaction.isSuccess) {\n await removeSchedulingBooking(schedulingBooking.submissionId)\n }\n\n return {\n ...verifiedPaymentTransaction,\n schedulingBooking,\n }\n}\n\nexport function checkForPaymentSubmissionEvent(\n formSubmission: FormSubmission,\n submissionTimestamp: string,\n):\n | {\n paymentSubmissionEvent: SubmissionEventTypes.FormPaymentEvent\n amount: number\n }\n | undefined {\n const result = paymentService.checkForPaymentEvent({\n definition: formSubmission.definition,\n submission: formSubmission.submission,\n submissionTimestamp,\n parseDate,\n addDaysToDate,\n })\n if (result) {\n console.log('Form has a payment submission event with amount', result)\n }\n return result\n}\n\n/**\n * Handle a submission result with a payment submission event. Will throw an\n * error if a transaction has already been made using this submission result.\n * Will return `undefined` if the submission does not have an amount. Will\n * return the submission result passed in with a `payment` property if the\n * submission requires processing.\n *\n * #### Example\n *\n * ```js\n * const formSubmissionResult = {\n * submissionId: '89c6e98e-f56f-45fc-84fe-c4fc62331d34',\n * submissionTimestamp: '2020-07-29T01:03:26.573Z'\n * formsAppId: 1,\n * submission: {\n * form: 'data',\n * goes: 'here',\n * amount: 1.50,\n * }\n * definition: OneBlinkForm,\n * payment: null,\n * }\n * const paymentSubmissionEvent = {\n * type: 'CP_PAY',\n * configuration: {\n * elementId: '12663efc-4c6a-4e72-8505-559edfe3e92e',\n * gatewayId: '6658c5c4-e0db-483b-8af7-6a6464fe772c',\n * },\n * }\n * const paymentReceiptUrl = `${window.location.origin}/payment-receipt`\n * const paymentSubmissionResult = await paymentService.handlePaymentSubmissionEvent({\n * formSubmissionResult,\n * paymentSubmissionEvent,\n * paymentReceiptUrl,\n * })\n * if (paymentSubmissionResult) {\n * window.location.href = paymentSubmissionResult.payment.hostedFormUrl\n * }\n * ```\n *\n * @param options\n * @returns\n */\nexport async function handlePaymentSubmissionEvent({\n amount,\n formSubmissionResult,\n paymentSubmissionEvent,\n paymentReceiptUrl,\n paymentFormUrl,\n}: {\n amount: number\n formSubmissionResult: FormSubmissionResult\n paymentSubmissionEvent: SubmissionEventTypes.FormPaymentEvent\n paymentReceiptUrl: string\n paymentFormUrl: string | undefined\n}): Promise<FormSubmissionResult['payment']> {\n const paymentProvider = getPaymentProvider(\n formSubmissionResult,\n paymentSubmissionEvent,\n )\n if (!paymentProvider) {\n throw new OneBlinkAppsError(\n 'It looks like you are attempting to make a payment using an unsupported payment method.',\n )\n }\n\n const paymentConfiguration = await generatePaymentConfiguration(\n paymentProvider,\n {\n amount,\n redirectUrl: paymentReceiptUrl,\n submissionId: formSubmissionResult.submissionId,\n paymentFormUrl,\n },\n )\n\n const payment = {\n submissionEvent: paymentSubmissionEvent,\n paymentReceiptUrl,\n hostedFormUrl: paymentConfiguration.hostedFormUrl,\n paymentFormUrl,\n amount,\n }\n console.log('Created Payment configuration to start transaction', payment)\n\n await utilsService.setLocalForageItem(KEY, {\n ...formSubmissionResult,\n scheduling: null,\n payment,\n })\n\n return payment\n}\n\nexport async function getFormSubmissionResultPayment(): Promise<{\n formSubmissionResult: FormSubmissionResult\n paymentSubmissionEvent: SubmissionEventTypes.FormPaymentEvent\n}> {\n const formSubmissionResult =\n await utilsService.getLocalForageItem<FormSubmissionResult | null>(KEY)\n\n if (!formSubmissionResult) {\n throw new OneBlinkAppsError(\n 'It looks like you are attempting to complete a transaction for an unknown payment.',\n )\n }\n if (!formSubmissionResult.payment?.submissionEvent) {\n throw new OneBlinkAppsError(\n 'It looks like you are attempting to complete a transaction for a misconfigured payment.',\n )\n }\n\n return {\n formSubmissionResult,\n paymentSubmissionEvent: formSubmissionResult.payment?.submissionEvent,\n }\n}\n\n/**\n * Retrieve an array of detail items from a form submission payment.\n *\n * #### Example\n *\n * ```js\n * const detailItems =\n * paymentService.getDisplayDetailsFromFormSubmissionPayment(\n * formSubmissionPayment,\n * )\n * ```\n *\n * @param formSubmissionPayment\n * @returns\n */\nexport function getDisplayDetailsFromFormSubmissionPayment(\n formSubmissionPayment: SubmissionTypes.FormSubmissionPayment,\n) {\n return paymentService.getDisplayDetailsFromFormSubmissionPayment(\n formSubmissionPayment,\n replaceSubmissionFormatters,\n )\n}\n"]}
|
|
@@ -3,11 +3,12 @@ import { createNylasExistingBookingSession } from './services/api/scheduling';
|
|
|
3
3
|
import { checkForPaymentSubmissionEvent, handlePaymentSubmissionEvent, } from './payment-service';
|
|
4
4
|
import { getSchedulingSubmissionResult, removeSchedulingSubmissionResult, setSchedulingBooking, } from './services/schedulingHandlers';
|
|
5
5
|
async function getPaymentConfiguration({ paymentReceiptUrl, paymentFormUrl, preventPayment, formSubmissionResult, schedulingBooking, }) {
|
|
6
|
+
var _a;
|
|
6
7
|
if (preventPayment || !paymentReceiptUrl) {
|
|
7
8
|
return null;
|
|
8
9
|
}
|
|
9
10
|
await setSchedulingBooking(schedulingBooking);
|
|
10
|
-
const paymentSubmissionEventConfiguration = checkForPaymentSubmissionEvent(formSubmissionResult);
|
|
11
|
+
const paymentSubmissionEventConfiguration = checkForPaymentSubmissionEvent(formSubmissionResult, (_a = formSubmissionResult.submissionTimestamp) !== null && _a !== void 0 ? _a : new Date().toISOString());
|
|
11
12
|
if (paymentSubmissionEventConfiguration) {
|
|
12
13
|
return await handlePaymentSubmissionEvent({
|
|
13
14
|
...paymentSubmissionEventConfiguration,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduling-service.js","sourceRoot":"","sources":["../../src/apps/scheduling-service.ts"],"names":[],"mappings":"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","sourcesContent":["import OneBlinkAppsError from './services/errors/oneBlinkAppsError'\nimport { createNylasExistingBookingSession } from './services/api/scheduling'\nimport {\n checkForPaymentSubmissionEvent,\n handlePaymentSubmissionEvent,\n} from './payment-service'\nimport { FormSubmissionResult } from './types/submissions'\nimport {\n SchedulingBooking,\n getSchedulingSubmissionResult,\n removeSchedulingSubmissionResult,\n setSchedulingBooking,\n} from './services/schedulingHandlers'\n\nasync function getPaymentConfiguration({\n paymentReceiptUrl,\n paymentFormUrl,\n preventPayment,\n formSubmissionResult,\n schedulingBooking,\n}: {\n paymentReceiptUrl: string | undefined\n paymentFormUrl: string | undefined\n preventPayment: boolean\n formSubmissionResult: FormSubmissionResult\n schedulingBooking: SchedulingBooking\n}) {\n if (preventPayment || !paymentReceiptUrl) {\n return null\n }\n\n await setSchedulingBooking(schedulingBooking)\n const paymentSubmissionEventConfiguration =\n checkForPaymentSubmissionEvent(formSubmissionResult)\n if (paymentSubmissionEventConfiguration) {\n return await handlePaymentSubmissionEvent({\n ...paymentSubmissionEventConfiguration,\n formSubmissionResult,\n paymentReceiptUrl,\n paymentFormUrl,\n })\n }\n\n return null\n}\n\nasync function getSchedulingFormSubmissionResult(\n submissionId: string,\n schedulingBooking: SchedulingBooking,\n) {\n const schedulingSubmissionResultConfiguration =\n await getSchedulingSubmissionResult()\n // If the current transaction does not match the submission\n // we will display message to user indicating\n // they are looking for the wrong transaction receipt.\n if (!schedulingSubmissionResultConfiguration) {\n throw new OneBlinkAppsError(\n 'It looks like you are attempting to view a scheduling receipt for an unknown booking.',\n )\n }\n\n const {\n formSubmissionResult,\n paymentReceiptUrl,\n paymentFormUrl,\n preventPayment,\n } = schedulingSubmissionResultConfiguration\n if (\n !formSubmissionResult ||\n !formSubmissionResult.scheduling ||\n !formSubmissionResult.scheduling.submissionEvent\n ) {\n throw new OneBlinkAppsError(\n 'It looks like you are attempting to view a scheduling receipt for a misconfigured booking.',\n )\n }\n\n if (formSubmissionResult.submissionId !== submissionId) {\n throw new OneBlinkAppsError(\n 'It looks like you are attempting to view a scheduling receipt for the incorrect booking.',\n )\n }\n\n formSubmissionResult.payment = await getPaymentConfiguration({\n paymentFormUrl,\n paymentReceiptUrl,\n preventPayment,\n formSubmissionResult,\n schedulingBooking,\n })\n\n await removeSchedulingSubmissionResult()\n\n return formSubmissionResult\n}\n\n/**\n * Pass in query string parameters after a redirect back to your app after a\n * booking is processed. Will return a SchedulingBooking and the submission\n * result from the original submission before redirecting to\n * `scheduling.bookingUrl`. If the booking has been rescheduled, the submission\n * result will not be returned.\n *\n * #### Example\n *\n * ```js\n * import queryString from 'query-string'\n *\n * const query = queryString.parse(window.location.search)\n *\n * const { booking, formSubmissionResult } =\n * await schedulingService.handleSchedulingQuerystring(query)\n * ```\n *\n * @param options\n * @returns\n */\nasync function handleSchedulingQuerystring({\n start_time,\n end_time,\n location,\n submissionId,\n isReschedule,\n}: Record<string, unknown>): Promise<{\n booking: SchedulingBooking\n formSubmissionResult?: FormSubmissionResult\n}> {\n if (\n typeof submissionId !== 'string' ||\n typeof start_time !== 'string' ||\n typeof end_time !== 'string' ||\n typeof location !== 'string'\n ) {\n throw new OneBlinkAppsError(\n 'Scheduling receipts cannot be displayed unless navigating here directly after a booking.',\n )\n }\n const booking: SchedulingBooking = {\n submissionId,\n startTime: new Date(parseInt(start_time) * 1000),\n endTime: new Date(parseInt(end_time) * 1000),\n location,\n isReschedule: isReschedule === 'true',\n }\n console.log('Parsed booking result', booking)\n\n if (isReschedule) {\n return {\n booking,\n }\n }\n\n const formSubmissionResult = await getSchedulingFormSubmissionResult(\n submissionId,\n booking,\n )\n\n return {\n formSubmissionResult,\n booking,\n }\n}\n\n/**\n * Pass in query string parameters after navigation to your app via a valid\n * cancellation link.\n *\n * #### Example\n *\n * ```js\n * import queryString from 'query-string'\n *\n * const query = queryString.parse(window.location.search)\n *\n * const bookingToCancel =\n * await schedulingService.handleCancelSchedulingBookingQuerystring(query)\n * ```\n *\n * @param options\n * @returns\n */\nfunction handleCancelSchedulingBookingQuerystring({\n nylasEditHash,\n submissionId,\n startTime,\n endTime,\n eventName,\n location,\n timezone,\n cancellationPolicy,\n}: Record<string, unknown>): {\n /** The nylas edit hash associated with the booking */\n nylasEditHash: string\n /** The unique identifier for the submission associated with the booking */\n submissionId: string\n /** The start time of the booking */\n startTime: Date\n /** The end time of the booking */\n endTime: Date\n /** The event name */\n eventName: string\n /** The location of the event */\n location: string\n /** The timezone the booking was booked in */\n timezone: string\n /**\n * The policy to display to users when asked why they are cancelling the\n * booking\n */\n cancellationPolicy?: string\n} {\n if (\n typeof submissionId !== 'string' ||\n typeof nylasEditHash !== 'string' ||\n typeof startTime !== 'string' ||\n typeof endTime !== 'string' ||\n typeof eventName !== 'string' ||\n typeof location !== 'string' ||\n typeof timezone !== 'string' ||\n (typeof cancellationPolicy !== 'string' && cancellationPolicy !== undefined)\n ) {\n throw new OneBlinkAppsError(\n 'Scheduling bookings cannot be cancelled unless navigating here from the correct link.',\n )\n }\n\n const booking = {\n nylasEditHash,\n submissionId,\n startTime: new Date(parseInt(startTime) * 1000),\n endTime: new Date(parseInt(endTime) * 1000),\n eventName,\n location,\n timezone,\n cancellationPolicy,\n }\n console.log('Parsed scheduling booking cancel data', booking)\n\n return booking\n}\n\n/**\n * Create a Nylas Session\n *\n * #### Example\n *\n * ```js\n * const {\n * sessionId,\n * configurationId,\n * bookingRef,\n * name,\n * email,\n * formSubmissionResult,\n * } = await schedulingService.createNylasNewBookingSession(\n * '89c6e98e-f56f-45fc-84fe-c4fc62331d34',\n * )\n * // use sessionId and configurationId/bookingRef to create or modify nylas bookings\n * // use formSubmissionResult to execute post submission action for form\n * ```\n *\n * @param submissionId\n * @param abortSignal\n * @returns\n */\nasync function createNylasNewBookingSession(\n submissionId: string,\n abortSignal: AbortSignal,\n): Promise<\n Awaited<ReturnType<typeof createNylasExistingBookingSession>> & {\n /**\n * A callback function run after the booking has been confirmed to prevent\n * the user from making another booking against this form submission and\n * execute post submission action.\n */\n onBookingConfirmed: (\n schedulingBooking: SchedulingBooking,\n ) => Promise<FormSubmissionResult>\n }\n> {\n const session = await createNylasExistingBookingSession(\n submissionId,\n abortSignal,\n )\n\n return {\n ...session,\n async onBookingConfirmed(schedulingBooking: SchedulingBooking) {\n return await getSchedulingFormSubmissionResult(\n submissionId,\n schedulingBooking,\n )\n },\n }\n}\n\nexport {\n SchedulingBooking,\n handleSchedulingQuerystring,\n handleCancelSchedulingBookingQuerystring,\n createNylasExistingBookingSession,\n createNylasNewBookingSession,\n getSchedulingFormSubmissionResult,\n}\n"]}
|
|
1
|
+
{"version":3,"file":"scheduling-service.js","sourceRoot":"","sources":["../../src/apps/scheduling-service.ts"],"names":[],"mappings":"AAAA,OAAO,iBAAiB,MAAM,qCAAqC,CAAA;AACnE,OAAO,EAAE,iCAAiC,EAAE,MAAM,2BAA2B,CAAA;AAC7E,OAAO,EACL,8BAA8B,EAC9B,4BAA4B,GAC7B,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EAEL,6BAA6B,EAC7B,gCAAgC,EAChC,oBAAoB,GACrB,MAAM,+BAA+B,CAAA;AAEtC,KAAK,UAAU,uBAAuB,CAAC,EACrC,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,iBAAiB,GAOlB;;IACC,IAAI,cAAc,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzC,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,oBAAoB,CAAC,iBAAiB,CAAC,CAAA;IAC7C,MAAM,mCAAmC,GAAG,8BAA8B,CACxE,oBAAoB,EACpB,MAAA,oBAAoB,CAAC,mBAAmB,mCAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CACrE,CAAA;IACD,IAAI,mCAAmC,EAAE,CAAC;QACxC,OAAO,MAAM,4BAA4B,CAAC;YACxC,GAAG,mCAAmC;YACtC,oBAAoB;YACpB,iBAAiB;YACjB,cAAc;SACf,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED,KAAK,UAAU,iCAAiC,CAC9C,YAAoB,EACpB,iBAAoC;IAEpC,MAAM,uCAAuC,GAC3C,MAAM,6BAA6B,EAAE,CAAA;IACvC,2DAA2D;IAC3D,6CAA6C;IAC7C,sDAAsD;IACtD,IAAI,CAAC,uCAAuC,EAAE,CAAC;QAC7C,MAAM,IAAI,iBAAiB,CACzB,uFAAuF,CACxF,CAAA;IACH,CAAC;IAED,MAAM,EACJ,oBAAoB,EACpB,iBAAiB,EACjB,cAAc,EACd,cAAc,GACf,GAAG,uCAAuC,CAAA;IAC3C,IACE,CAAC,oBAAoB;QACrB,CAAC,oBAAoB,CAAC,UAAU;QAChC,CAAC,oBAAoB,CAAC,UAAU,CAAC,eAAe,EAChD,CAAC;QACD,MAAM,IAAI,iBAAiB,CACzB,4FAA4F,CAC7F,CAAA;IACH,CAAC;IAED,IAAI,oBAAoB,CAAC,YAAY,KAAK,YAAY,EAAE,CAAC;QACvD,MAAM,IAAI,iBAAiB,CACzB,0FAA0F,CAC3F,CAAA;IACH,CAAC;IAED,oBAAoB,CAAC,OAAO,GAAG,MAAM,uBAAuB,CAAC;QAC3D,cAAc;QACd,iBAAiB;QACjB,cAAc;QACd,oBAAoB;QACpB,iBAAiB;KAClB,CAAC,CAAA;IAEF,MAAM,gCAAgC,EAAE,CAAA;IAExC,OAAO,oBAAoB,CAAA;AAC7B,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,KAAK,UAAU,2BAA2B,CAAC,EACzC,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,YAAY,GACY;IAIxB,IACE,OAAO,YAAY,KAAK,QAAQ;QAChC,OAAO,UAAU,KAAK,QAAQ;QAC9B,OAAO,QAAQ,KAAK,QAAQ;QAC5B,OAAO,QAAQ,KAAK,QAAQ,EAC5B,CAAC;QACD,MAAM,IAAI,iBAAiB,CACzB,0FAA0F,CAC3F,CAAA;IACH,CAAC;IACD,MAAM,OAAO,GAAsB;QACjC,YAAY;QACZ,SAAS,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC;QAChD,OAAO,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;QAC5C,QAAQ;QACR,YAAY,EAAE,YAAY,KAAK,MAAM;KACtC,CAAA;IACD,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAA;IAE7C,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO;YACL,OAAO;SACR,CAAA;IACH,CAAC;IAED,MAAM,oBAAoB,GAAG,MAAM,iCAAiC,CAClE,YAAY,EACZ,OAAO,CACR,CAAA;IAED,OAAO;QACL,oBAAoB;QACpB,OAAO;KACR,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,SAAS,wCAAwC,CAAC,EAChD,aAAa,EACb,YAAY,EACZ,SAAS,EACT,OAAO,EACP,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,kBAAkB,GACM;IAqBxB,IACE,OAAO,YAAY,KAAK,QAAQ;QAChC,OAAO,aAAa,KAAK,QAAQ;QACjC,OAAO,SAAS,KAAK,QAAQ;QAC7B,OAAO,OAAO,KAAK,QAAQ;QAC3B,OAAO,SAAS,KAAK,QAAQ;QAC7B,OAAO,QAAQ,KAAK,QAAQ;QAC5B,OAAO,QAAQ,KAAK,QAAQ;QAC5B,CAAC,OAAO,kBAAkB,KAAK,QAAQ,IAAI,kBAAkB,KAAK,SAAS,CAAC,EAC5E,CAAC;QACD,MAAM,IAAI,iBAAiB,CACzB,uFAAuF,CACxF,CAAA;IACH,CAAC;IAED,MAAM,OAAO,GAAG;QACd,aAAa;QACb,YAAY;QACZ,SAAS,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;QAC/C,OAAO,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;QAC3C,SAAS;QACT,QAAQ;QACR,QAAQ;QACR,kBAAkB;KACnB,CAAA;IACD,OAAO,CAAC,GAAG,CAAC,uCAAuC,EAAE,OAAO,CAAC,CAAA;IAE7D,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,KAAK,UAAU,4BAA4B,CACzC,YAAoB,EACpB,WAAwB;IAaxB,MAAM,OAAO,GAAG,MAAM,iCAAiC,CACrD,YAAY,EACZ,WAAW,CACZ,CAAA;IAED,OAAO;QACL,GAAG,OAAO;QACV,KAAK,CAAC,kBAAkB,CAAC,iBAAoC;YAC3D,OAAO,MAAM,iCAAiC,CAC5C,YAAY,EACZ,iBAAiB,CAClB,CAAA;QACH,CAAC;KACF,CAAA;AACH,CAAC;AAED,OAAO,EAEL,2BAA2B,EAC3B,wCAAwC,EACxC,iCAAiC,EACjC,4BAA4B,EAC5B,iCAAiC,GAClC,CAAA","sourcesContent":["import OneBlinkAppsError from './services/errors/oneBlinkAppsError'\nimport { createNylasExistingBookingSession } from './services/api/scheduling'\nimport {\n checkForPaymentSubmissionEvent,\n handlePaymentSubmissionEvent,\n} from './payment-service'\nimport { FormSubmissionResult } from './types/submissions'\nimport {\n SchedulingBooking,\n getSchedulingSubmissionResult,\n removeSchedulingSubmissionResult,\n setSchedulingBooking,\n} from './services/schedulingHandlers'\n\nasync function getPaymentConfiguration({\n paymentReceiptUrl,\n paymentFormUrl,\n preventPayment,\n formSubmissionResult,\n schedulingBooking,\n}: {\n paymentReceiptUrl: string | undefined\n paymentFormUrl: string | undefined\n preventPayment: boolean\n formSubmissionResult: FormSubmissionResult\n schedulingBooking: SchedulingBooking\n}) {\n if (preventPayment || !paymentReceiptUrl) {\n return null\n }\n\n await setSchedulingBooking(schedulingBooking)\n const paymentSubmissionEventConfiguration = checkForPaymentSubmissionEvent(\n formSubmissionResult,\n formSubmissionResult.submissionTimestamp ?? new Date().toISOString(),\n )\n if (paymentSubmissionEventConfiguration) {\n return await handlePaymentSubmissionEvent({\n ...paymentSubmissionEventConfiguration,\n formSubmissionResult,\n paymentReceiptUrl,\n paymentFormUrl,\n })\n }\n\n return null\n}\n\nasync function getSchedulingFormSubmissionResult(\n submissionId: string,\n schedulingBooking: SchedulingBooking,\n) {\n const schedulingSubmissionResultConfiguration =\n await getSchedulingSubmissionResult()\n // If the current transaction does not match the submission\n // we will display message to user indicating\n // they are looking for the wrong transaction receipt.\n if (!schedulingSubmissionResultConfiguration) {\n throw new OneBlinkAppsError(\n 'It looks like you are attempting to view a scheduling receipt for an unknown booking.',\n )\n }\n\n const {\n formSubmissionResult,\n paymentReceiptUrl,\n paymentFormUrl,\n preventPayment,\n } = schedulingSubmissionResultConfiguration\n if (\n !formSubmissionResult ||\n !formSubmissionResult.scheduling ||\n !formSubmissionResult.scheduling.submissionEvent\n ) {\n throw new OneBlinkAppsError(\n 'It looks like you are attempting to view a scheduling receipt for a misconfigured booking.',\n )\n }\n\n if (formSubmissionResult.submissionId !== submissionId) {\n throw new OneBlinkAppsError(\n 'It looks like you are attempting to view a scheduling receipt for the incorrect booking.',\n )\n }\n\n formSubmissionResult.payment = await getPaymentConfiguration({\n paymentFormUrl,\n paymentReceiptUrl,\n preventPayment,\n formSubmissionResult,\n schedulingBooking,\n })\n\n await removeSchedulingSubmissionResult()\n\n return formSubmissionResult\n}\n\n/**\n * Pass in query string parameters after a redirect back to your app after a\n * booking is processed. Will return a SchedulingBooking and the submission\n * result from the original submission before redirecting to\n * `scheduling.bookingUrl`. If the booking has been rescheduled, the submission\n * result will not be returned.\n *\n * #### Example\n *\n * ```js\n * import queryString from 'query-string'\n *\n * const query = queryString.parse(window.location.search)\n *\n * const { booking, formSubmissionResult } =\n * await schedulingService.handleSchedulingQuerystring(query)\n * ```\n *\n * @param options\n * @returns\n */\nasync function handleSchedulingQuerystring({\n start_time,\n end_time,\n location,\n submissionId,\n isReschedule,\n}: Record<string, unknown>): Promise<{\n booking: SchedulingBooking\n formSubmissionResult?: FormSubmissionResult\n}> {\n if (\n typeof submissionId !== 'string' ||\n typeof start_time !== 'string' ||\n typeof end_time !== 'string' ||\n typeof location !== 'string'\n ) {\n throw new OneBlinkAppsError(\n 'Scheduling receipts cannot be displayed unless navigating here directly after a booking.',\n )\n }\n const booking: SchedulingBooking = {\n submissionId,\n startTime: new Date(parseInt(start_time) * 1000),\n endTime: new Date(parseInt(end_time) * 1000),\n location,\n isReschedule: isReschedule === 'true',\n }\n console.log('Parsed booking result', booking)\n\n if (isReschedule) {\n return {\n booking,\n }\n }\n\n const formSubmissionResult = await getSchedulingFormSubmissionResult(\n submissionId,\n booking,\n )\n\n return {\n formSubmissionResult,\n booking,\n }\n}\n\n/**\n * Pass in query string parameters after navigation to your app via a valid\n * cancellation link.\n *\n * #### Example\n *\n * ```js\n * import queryString from 'query-string'\n *\n * const query = queryString.parse(window.location.search)\n *\n * const bookingToCancel =\n * await schedulingService.handleCancelSchedulingBookingQuerystring(query)\n * ```\n *\n * @param options\n * @returns\n */\nfunction handleCancelSchedulingBookingQuerystring({\n nylasEditHash,\n submissionId,\n startTime,\n endTime,\n eventName,\n location,\n timezone,\n cancellationPolicy,\n}: Record<string, unknown>): {\n /** The nylas edit hash associated with the booking */\n nylasEditHash: string\n /** The unique identifier for the submission associated with the booking */\n submissionId: string\n /** The start time of the booking */\n startTime: Date\n /** The end time of the booking */\n endTime: Date\n /** The event name */\n eventName: string\n /** The location of the event */\n location: string\n /** The timezone the booking was booked in */\n timezone: string\n /**\n * The policy to display to users when asked why they are cancelling the\n * booking\n */\n cancellationPolicy?: string\n} {\n if (\n typeof submissionId !== 'string' ||\n typeof nylasEditHash !== 'string' ||\n typeof startTime !== 'string' ||\n typeof endTime !== 'string' ||\n typeof eventName !== 'string' ||\n typeof location !== 'string' ||\n typeof timezone !== 'string' ||\n (typeof cancellationPolicy !== 'string' && cancellationPolicy !== undefined)\n ) {\n throw new OneBlinkAppsError(\n 'Scheduling bookings cannot be cancelled unless navigating here from the correct link.',\n )\n }\n\n const booking = {\n nylasEditHash,\n submissionId,\n startTime: new Date(parseInt(startTime) * 1000),\n endTime: new Date(parseInt(endTime) * 1000),\n eventName,\n location,\n timezone,\n cancellationPolicy,\n }\n console.log('Parsed scheduling booking cancel data', booking)\n\n return booking\n}\n\n/**\n * Create a Nylas Session\n *\n * #### Example\n *\n * ```js\n * const {\n * sessionId,\n * configurationId,\n * bookingRef,\n * name,\n * email,\n * formSubmissionResult,\n * } = await schedulingService.createNylasNewBookingSession(\n * '89c6e98e-f56f-45fc-84fe-c4fc62331d34',\n * )\n * // use sessionId and configurationId/bookingRef to create or modify nylas bookings\n * // use formSubmissionResult to execute post submission action for form\n * ```\n *\n * @param submissionId\n * @param abortSignal\n * @returns\n */\nasync function createNylasNewBookingSession(\n submissionId: string,\n abortSignal: AbortSignal,\n): Promise<\n Awaited<ReturnType<typeof createNylasExistingBookingSession>> & {\n /**\n * A callback function run after the booking has been confirmed to prevent\n * the user from making another booking against this form submission and\n * execute post submission action.\n */\n onBookingConfirmed: (\n schedulingBooking: SchedulingBooking,\n ) => Promise<FormSubmissionResult>\n }\n> {\n const session = await createNylasExistingBookingSession(\n submissionId,\n abortSignal,\n )\n\n return {\n ...session,\n async onBookingConfirmed(schedulingBooking: SchedulingBooking) {\n return await getSchedulingFormSubmissionResult(\n submissionId,\n schedulingBooking,\n )\n },\n }\n}\n\nexport {\n SchedulingBooking,\n handleSchedulingQuerystring,\n handleCancelSchedulingBookingQuerystring,\n createNylasExistingBookingSession,\n createNylasNewBookingSession,\n getSchedulingFormSubmissionResult,\n}\n"]}
|
|
@@ -24,7 +24,7 @@ type SchedulingBooking = {
|
|
|
24
24
|
export declare function getSchedulingBooking(submissionId: string | null): Promise<SchedulingBooking | undefined>;
|
|
25
25
|
export declare function removeSchedulingBooking(submissionId: string): Promise<void>;
|
|
26
26
|
export declare function setSchedulingBooking(schedulingBooking: SchedulingBooking): Promise<void>;
|
|
27
|
-
declare function checkForSchedulingSubmissionEvent(baseFormSubmission: BaseNewFormSubmission): SubmissionEventTypes.FormSchedulingEvent | undefined;
|
|
27
|
+
declare function checkForSchedulingSubmissionEvent(baseFormSubmission: BaseNewFormSubmission, submissionTimestamp: string): SubmissionEventTypes.FormSchedulingEvent | undefined;
|
|
28
28
|
declare function handleSchedulingSubmissionEvent({ formSubmissionResult, schedulingSubmissionEvent, schedulingUrlConfiguration, paymentReceiptUrl, paymentFormUrl, preventPayment, }: {
|
|
29
29
|
formSubmissionResult: FormSubmissionResult;
|
|
30
30
|
schedulingSubmissionEvent: SubmissionEventTypes.FormSchedulingEvent;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { generateSchedulingConfiguration } from './api/scheduling';
|
|
2
2
|
import utilsService from './utils';
|
|
3
3
|
import { schedulingService } from '@oneblink/sdk-core';
|
|
4
|
+
import { addDaysToDate, parseDate } from '../localisation-service';
|
|
4
5
|
const SCHEDULING_SUBMISSION_RESULT_KEY = 'SCHEDULING_SUBMISSION_RESULT';
|
|
5
6
|
export async function getSchedulingSubmissionResult() {
|
|
6
7
|
return await utilsService.getLocalForageItem(SCHEDULING_SUBMISSION_RESULT_KEY);
|
|
@@ -37,8 +38,14 @@ export async function setSchedulingBooking(schedulingBooking) {
|
|
|
37
38
|
schedulingBookingMap[schedulingBooking.submissionId] = schedulingBooking;
|
|
38
39
|
await setSchedulingBookingMap(schedulingBookingMap);
|
|
39
40
|
}
|
|
40
|
-
function checkForSchedulingSubmissionEvent(baseFormSubmission) {
|
|
41
|
-
const schedulingSubmissionEvent = schedulingService.checkForSchedulingEvent(
|
|
41
|
+
function checkForSchedulingSubmissionEvent(baseFormSubmission, submissionTimestamp) {
|
|
42
|
+
const schedulingSubmissionEvent = schedulingService.checkForSchedulingEvent({
|
|
43
|
+
definition: baseFormSubmission.definition,
|
|
44
|
+
submission: baseFormSubmission.submission,
|
|
45
|
+
submissionTimestamp,
|
|
46
|
+
parseDate,
|
|
47
|
+
addDaysToDate,
|
|
48
|
+
});
|
|
42
49
|
if (schedulingSubmissionEvent) {
|
|
43
50
|
console.log('Form has a scheduling submission event', schedulingSubmissionEvent);
|
|
44
51
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schedulingHandlers.js","sourceRoot":"","sources":["../../../src/apps/services/schedulingHandlers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,+BAA+B,EAAE,MAAM,kBAAkB,CAAA;AAClE,OAAO,YAAY,MAAM,SAAS,CAAA;AAElC,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"schedulingHandlers.js","sourceRoot":"","sources":["../../../src/apps/services/schedulingHandlers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,+BAA+B,EAAE,MAAM,kBAAkB,CAAA;AAClE,OAAO,YAAY,MAAM,SAAS,CAAA;AAElC,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAMtD,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAElE,MAAM,gCAAgC,GAAG,8BAA8B,CAAA;AAOvE,MAAM,CAAC,KAAK,UAAU,6BAA6B;IACjD,OAAO,MAAM,YAAY,CAAC,kBAAkB,CAAC,gCAAgC,CAAC,CAAA;AAChF,CAAC;AACD,MAAM,CAAC,KAAK,UAAU,gCAAgC;IACpD,MAAM,YAAY,CAAC,qBAAqB,CAAC,gCAAgC,CAAC,CAAA;AAC5E,CAAC;AACD,KAAK,UAAU,6BAA6B,CAC1C,0BAAsD;IAEtD,MAAM,YAAY,CAAC,kBAAkB,CACnC,gCAAgC,EAChC,0BAA0B,CAC3B,CAAA;AACH,CAAC;AAED,MAAM,sBAAsB,GAAG,oBAAoB,CAAA;AAcnD,KAAK,UAAU,uBAAuB;IACpC,OAAO,MAAM,YAAY,CAAC,kBAAkB,CAE1C,sBAAsB,CAAC,CAAA;AAC3B,CAAC;AAED,KAAK,UAAU,uBAAuB,CACpC,oBAAuD;IAEvD,MAAM,YAAY,CAAC,kBAAkB,CACnC,sBAAsB,EACtB,oBAAoB,CACrB,CAAA;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,YAA2B;IAE3B,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAM;IACR,CAAC;IACD,MAAM,oBAAoB,GAAG,MAAM,uBAAuB,EAAE,CAAA;IAC5D,OAAO,oBAAoB,aAApB,oBAAoB,uBAApB,oBAAoB,CAAG,YAAY,CAAC,CAAA;AAC7C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,YAAoB;IAChE,MAAM,oBAAoB,GAAG,MAAM,uBAAuB,EAAE,CAAA;IAC5D,IAAI,oBAAoB,aAApB,oBAAoB,uBAApB,oBAAoB,CAAG,YAAY,CAAC,EAAE,CAAC;QACzC,OAAO,oBAAoB,CAAC,YAAY,CAAC,CAAA;QACzC,MAAM,uBAAuB,CAAC,oBAAoB,CAAC,CAAA;IACrD,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,iBAAoC;IAEpC,MAAM,oBAAoB,GAAG,CAAC,MAAM,uBAAuB,EAAE,CAAC,IAAI,EAAE,CAAA;IACpE,oBAAoB,CAAC,iBAAiB,CAAC,YAAY,CAAC,GAAG,iBAAiB,CAAA;IACxE,MAAM,uBAAuB,CAAC,oBAAoB,CAAC,CAAA;AACrD,CAAC;AAED,SAAS,iCAAiC,CACxC,kBAAyC,EACzC,mBAA2B;IAE3B,MAAM,yBAAyB,GAAG,iBAAiB,CAAC,uBAAuB,CAAC;QAC1E,UAAU,EAAE,kBAAkB,CAAC,UAAU;QACzC,UAAU,EAAE,kBAAkB,CAAC,UAAU;QACzC,mBAAmB;QACnB,SAAS;QACT,aAAa;KACd,CAAC,CAAA;IACF,IAAI,yBAAyB,EAAE,CAAC;QAC9B,OAAO,CAAC,GAAG,CACT,wCAAwC,EACxC,yBAAyB,CAC1B,CAAA;IACH,CAAC;IACD,OAAO,yBAAyB,CAAA;AAClC,CAAC;AAED,KAAK,UAAU,+BAA+B,CAAC,EAC7C,oBAAoB,EACpB,yBAAyB,EACzB,0BAA0B,EAC1B,iBAAiB,EACjB,cAAc,EACd,cAAc,GAQf;IACC,OAAO,CAAC,GAAG,CACT,kEAAkE,CACnE,CAAA;IACD,IAAI,CAAC,oBAAoB,CAAC,YAAY,EAAE,CAAC;QACvC,MAAM,KAAK,CACT,4FAA4F,CAC7F,CAAA;IACH,CAAC;IAED,MAAM,+BAA+B,CAAC;QACpC,oBAAoB;QACpB,yBAAyB;QACzB,0BAA0B;KAC3B,CAAC,CAAA;IAEF,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,0BAA0B,CAAC,oBAAoB,CAAC,CAAA;IAC3E,UAAU,CAAC,YAAY,CAAC,GAAG,CAAC,cAAc,EAAE,oBAAoB,CAAC,YAAY,CAAC,CAAA;IAE9E,MAAM,UAAU,GAAG;QACjB,eAAe,EAAE,yBAAyB;QAC1C,UAAU,EAAE,UAAU,CAAC,QAAQ,EAAE;KAClC,CAAA;IACD,OAAO,CAAC,GAAG,CAAC,mDAAmD,EAAE,UAAU,CAAC,CAAA;IAC5E,MAAM,6BAA6B,CAAC;QAClC,oBAAoB,EAAE;YACpB,GAAG,oBAAoB;YACvB,UAAU;SACX;QACD,iBAAiB;QACjB,cAAc;QACd,cAAc;KACf,CAAC,CAAA;IAEF,OAAO,UAAU,CAAA;AACnB,CAAC;AAED,OAAO,EAEL,iCAAiC,EACjC,+BAA+B,GAChC,CAAA","sourcesContent":["import { generateSchedulingConfiguration } from './api/scheduling'\nimport utilsService from './utils'\nimport { SubmissionEventTypes } from '@oneblink/types'\nimport { schedulingService } from '@oneblink/sdk-core'\nimport {\n FormSubmissionResult,\n BaseNewFormSubmission,\n} from '../types/submissions'\nimport { SchedulingUrlConfiguration } from '../types/scheduling'\nimport { addDaysToDate, parseDate } from '../localisation-service'\n\nconst SCHEDULING_SUBMISSION_RESULT_KEY = 'SCHEDULING_SUBMISSION_RESULT'\ntype SchedulingSubmissionResult = {\n formSubmissionResult: FormSubmissionResult\n paymentReceiptUrl: string | undefined\n paymentFormUrl: string | undefined\n preventPayment: boolean\n}\nexport async function getSchedulingSubmissionResult(): Promise<SchedulingSubmissionResult | null> {\n return await utilsService.getLocalForageItem(SCHEDULING_SUBMISSION_RESULT_KEY)\n}\nexport async function removeSchedulingSubmissionResult() {\n await utilsService.removeLocalForageItem(SCHEDULING_SUBMISSION_RESULT_KEY)\n}\nasync function setSchedulingSubmissionResult(\n schedulingSubmissionResult: SchedulingSubmissionResult,\n) {\n await utilsService.setLocalForageItem(\n SCHEDULING_SUBMISSION_RESULT_KEY,\n schedulingSubmissionResult,\n )\n}\n\nconst SCHEDULING_BOOKING_KEY = 'SCHEDULING_BOOKING'\ntype SchedulingBooking = {\n /** The unique identifier for the submission associated with the booking */\n submissionId: string\n /** Date and time the booking starts */\n startTime: Date\n /** Date and time the booking ends */\n endTime: Date\n /** Location of booking */\n location: string | undefined\n /** `true` if the booking has been rescheduled, otherwise `false` */\n isReschedule: boolean\n}\n\nasync function getSchedulingBookingMap() {\n return await utilsService.getLocalForageItem<\n Record<string, SchedulingBooking>\n >(SCHEDULING_BOOKING_KEY)\n}\n\nasync function setSchedulingBookingMap(\n schedulingBookingMap: Record<string, SchedulingBooking>,\n) {\n await utilsService.setLocalForageItem(\n SCHEDULING_BOOKING_KEY,\n schedulingBookingMap,\n )\n}\n\nexport async function getSchedulingBooking(\n submissionId: string | null,\n): Promise<SchedulingBooking | undefined> {\n if (!submissionId) {\n return\n }\n const schedulingBookingMap = await getSchedulingBookingMap()\n return schedulingBookingMap?.[submissionId]\n}\n\nexport async function removeSchedulingBooking(submissionId: string) {\n const schedulingBookingMap = await getSchedulingBookingMap()\n if (schedulingBookingMap?.[submissionId]) {\n delete schedulingBookingMap[submissionId]\n await setSchedulingBookingMap(schedulingBookingMap)\n }\n}\n\nexport async function setSchedulingBooking(\n schedulingBooking: SchedulingBooking,\n) {\n const schedulingBookingMap = (await getSchedulingBookingMap()) || {}\n schedulingBookingMap[schedulingBooking.submissionId] = schedulingBooking\n await setSchedulingBookingMap(schedulingBookingMap)\n}\n\nfunction checkForSchedulingSubmissionEvent(\n baseFormSubmission: BaseNewFormSubmission,\n submissionTimestamp: string,\n): SubmissionEventTypes.FormSchedulingEvent | undefined {\n const schedulingSubmissionEvent = schedulingService.checkForSchedulingEvent({\n definition: baseFormSubmission.definition,\n submission: baseFormSubmission.submission,\n submissionTimestamp,\n parseDate,\n addDaysToDate,\n })\n if (schedulingSubmissionEvent) {\n console.log(\n 'Form has a scheduling submission event',\n schedulingSubmissionEvent,\n )\n }\n return schedulingSubmissionEvent\n}\n\nasync function handleSchedulingSubmissionEvent({\n formSubmissionResult,\n schedulingSubmissionEvent,\n schedulingUrlConfiguration,\n paymentReceiptUrl,\n paymentFormUrl,\n preventPayment,\n}: {\n formSubmissionResult: FormSubmissionResult\n schedulingSubmissionEvent: SubmissionEventTypes.FormSchedulingEvent\n schedulingUrlConfiguration: SchedulingUrlConfiguration\n paymentReceiptUrl: string | undefined\n paymentFormUrl: string | undefined\n preventPayment: boolean\n}): Promise<NonNullable<FormSubmissionResult['scheduling']>> {\n console.log(\n 'Attempting to handle submission with scheduling submission event',\n )\n if (!formSubmissionResult.submissionId) {\n throw Error(\n 'Cannot generate calendar booking configuration. Form Submission is missing \"submissionId\"',\n )\n }\n\n await generateSchedulingConfiguration({\n formSubmissionResult,\n schedulingSubmissionEvent,\n schedulingUrlConfiguration,\n })\n\n const bookingUrl = new URL(schedulingUrlConfiguration.schedulingBookingUrl)\n bookingUrl.searchParams.set('submissionId', formSubmissionResult.submissionId)\n\n const scheduling = {\n submissionEvent: schedulingSubmissionEvent,\n bookingUrl: bookingUrl.toString(),\n }\n console.log('Created scheduling configuration to start booking', scheduling)\n await setSchedulingSubmissionResult({\n formSubmissionResult: {\n ...formSubmissionResult,\n scheduling,\n },\n paymentReceiptUrl,\n paymentFormUrl,\n preventPayment,\n })\n\n return scheduling\n}\n\nexport {\n SchedulingBooking,\n checkForSchedulingSubmissionEvent,\n handleSchedulingSubmissionEvent,\n}\n"]}
|
|
@@ -18,8 +18,8 @@ function notifyJobSubmittedIfApplicable(formSubmission) {
|
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
export default async function submit({ formSubmission, isPendingQueueEnabled, paymentReceiptUrl, paymentFormUrl, schedulingUrlConfiguration, onProgress, shouldRunServerValidation, shouldRunExternalIdGeneration, abortSignal, pendingTimestamp, alwaysSubmitViaPendingQueue, completionTimestamp, }) {
|
|
21
|
-
const paymentSubmissionEventConfiguration = checkForPaymentSubmissionEvent(formSubmission);
|
|
22
|
-
const schedulingSubmissionEvent = checkForSchedulingSubmissionEvent(formSubmission);
|
|
21
|
+
const paymentSubmissionEventConfiguration = checkForPaymentSubmissionEvent(formSubmission, completionTimestamp);
|
|
22
|
+
const schedulingSubmissionEvent = checkForSchedulingSubmissionEvent(formSubmission, completionTimestamp);
|
|
23
23
|
try {
|
|
24
24
|
if (pendingTimestamp) {
|
|
25
25
|
await deletePendingQueueSubmission(pendingTimestamp);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"submit.js","sourceRoot":"","sources":["../../../src/apps/services/submit.ts"],"names":[],"mappings":"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","sourcesContent":["import { isOffline } from '../offline-service'\nimport {\n addFormSubmissionToPendingQueue,\n deletePendingQueueSubmission,\n} from './pending-queue'\nimport {\n checkForPaymentSubmissionEvent,\n handlePaymentSubmissionEvent,\n} from '../payment-service'\nimport { removeLocalDraftSubmission } from './draft-data-store'\nimport { removePrefillFormData } from '../prefill-service'\nimport {\n handleSchedulingSubmissionEvent,\n checkForSchedulingSubmissionEvent,\n} from './schedulingHandlers'\nimport {\n FormSubmission,\n FormSubmissionResult,\n ProgressListener,\n ProgressListenerEvent,\n} from '../types/submissions'\nimport { SchedulingUrlConfiguration } from '../types/scheduling'\nimport { checkIfAttachmentsAreUploading } from '../attachments-service'\nimport tenants from '../tenants'\nimport externalIdGeneration from './external-id-generation'\nimport serverValidateForm from './server-validation'\nimport OneBlinkAppsError from './errors/oneBlinkAppsError'\nimport { uploadFormSubmission } from './api/submissions'\nimport { syncDrafts } from '../draft-service'\nimport { notifyJobSubmitted } from '../job-service'\n\nfunction notifyJobSubmittedIfApplicable(formSubmission: FormSubmission) {\n if (formSubmission.jobId) {\n notifyJobSubmitted(formSubmission.jobId)\n }\n}\n\ntype SubmissionParams = {\n formSubmission: FormSubmission\n isPendingQueueEnabled: boolean\n shouldRunServerValidation: boolean\n shouldRunExternalIdGeneration: boolean\n paymentReceiptUrl: string | undefined\n paymentFormUrl: string | undefined\n schedulingUrlConfiguration?: SchedulingUrlConfiguration\n pendingTimestamp?: string\n alwaysSubmitViaPendingQueue?: boolean\n onProgress?: ProgressListener\n abortSignal?: AbortSignal\n}\n\nexport { SubmissionParams, ProgressListener, ProgressListenerEvent }\n\nexport default async function submit({\n formSubmission,\n isPendingQueueEnabled,\n paymentReceiptUrl,\n paymentFormUrl,\n schedulingUrlConfiguration,\n onProgress,\n shouldRunServerValidation,\n shouldRunExternalIdGeneration,\n abortSignal,\n pendingTimestamp,\n alwaysSubmitViaPendingQueue,\n completionTimestamp,\n}: SubmissionParams & {\n completionTimestamp: string\n}): Promise<FormSubmissionResult> {\n const paymentSubmissionEventConfiguration =\n checkForPaymentSubmissionEvent(formSubmission)\n\n const schedulingSubmissionEvent =\n checkForSchedulingSubmissionEvent(formSubmission)\n\n try {\n if (pendingTimestamp) {\n await deletePendingQueueSubmission(pendingTimestamp)\n }\n if (isOffline() || alwaysSubmitViaPendingQueue) {\n if (paymentSubmissionEventConfiguration || schedulingSubmissionEvent) {\n console.log(\n 'Offline or always submitting via pending queue - form has a payment/scheduling submission event that has not been processed yet, return offline',\n { paymentSubmissionEventConfiguration, schedulingSubmissionEvent },\n )\n return Object.assign({}, formSubmission, {\n isOffline: true,\n isInPendingQueue: false,\n submissionTimestamp: null,\n submissionId: null,\n payment: null,\n scheduling: null,\n isUploadingAttachments: false,\n })\n }\n\n if (!alwaysSubmitViaPendingQueue && !isPendingQueueEnabled) {\n console.log(\n 'Offline - app does not support pending queue, return offline',\n )\n return Object.assign({}, formSubmission, {\n isOffline: true,\n isInPendingQueue: false,\n submissionTimestamp: null,\n submissionId: null,\n payment: null,\n scheduling: null,\n isUploadingAttachments: false,\n })\n }\n\n console.log(\n 'Offline or always submitting via pending queue - saving submission to pending queue..',\n )\n await addFormSubmissionToPendingQueue(formSubmission)\n notifyJobSubmittedIfApplicable(formSubmission)\n return Object.assign({}, formSubmission, {\n isOffline: isOffline(),\n isInPendingQueue: true,\n submissionTimestamp: null,\n submissionId: null,\n payment: null,\n preventPayment: false,\n scheduling: null,\n isUploadingAttachments: false,\n })\n }\n\n const attachmentsStillUploading = checkIfAttachmentsAreUploading(\n formSubmission.definition,\n formSubmission.submission,\n )\n\n if (attachmentsStillUploading) {\n if (paymentSubmissionEventConfiguration || schedulingSubmissionEvent) {\n console.log(\n 'Attachments still uploading - form has a payment/scheduling submission event that has not been processed yet, return isUploading',\n { paymentSubmissionEventConfiguration, schedulingSubmissionEvent },\n )\n return Object.assign({}, formSubmission, {\n isOffline: false,\n isInPendingQueue: false,\n submissionTimestamp: null,\n submissionId: null,\n payment: null,\n preventPayment: false,\n scheduling: null,\n isUploadingAttachments: true,\n })\n }\n console.log(\n 'Attachments still uploading - saving submission to pending queue..',\n )\n await addFormSubmissionToPendingQueue(formSubmission)\n notifyJobSubmittedIfApplicable(formSubmission)\n return Object.assign({}, formSubmission, {\n isOffline: false,\n isInPendingQueue: true,\n submissionTimestamp: null,\n submissionId: null,\n payment: null,\n preventPayment: false,\n scheduling: null,\n isUploadingAttachments: true,\n })\n }\n\n if (shouldRunServerValidation) {\n await serverValidateForm(formSubmission)\n }\n if (shouldRunExternalIdGeneration) {\n const externalIdResult = await externalIdGeneration(formSubmission)\n if (externalIdResult.externalId) {\n formSubmission.externalId = externalIdResult.externalId\n }\n }\n\n const data = await uploadFormSubmission(\n formSubmission,\n completionTimestamp,\n onProgress,\n abortSignal,\n )\n\n const getDownloadSubmissionPdfUrls = () => {\n const allowPDFDownload =\n formSubmission.definition.postSubmissionReceipt?.allowPDFDownload\n if (!data.pdfAccessToken || !allowPDFDownload) {\n return {\n downloadSubmissionPdfUrl: undefined,\n downloadSubmissionPdfs: undefined,\n }\n }\n if (allowPDFDownload && !Array.isArray(allowPDFDownload)) {\n // Cater for legacy config\n const url = `${tenants.current.apiOrigin}/forms/${formSubmission.definition.id}/submissions/${data.submissionId}/pdf-document?accessToken=${data.pdfAccessToken}`\n return {\n downloadSubmissionPdfUrl: url,\n downloadSubmissionPdfs: [\n {\n id: 'default',\n configuration: allowPDFDownload,\n url,\n },\n ],\n }\n }\n\n return {\n downloadSubmissionPdfUrl: undefined,\n downloadSubmissionPdfs: allowPDFDownload.map((pdfConfiguration) => {\n const url = `${tenants.current.apiOrigin}/forms/${formSubmission.definition.id}/submissions/${data.submissionId}/pdf-document?accessToken=${data.pdfAccessToken}&configurationId=${pdfConfiguration.id}`\n return {\n ...pdfConfiguration,\n url,\n }\n }),\n }\n }\n\n const { downloadSubmissionPdfUrl, downloadSubmissionPdfs } =\n getDownloadSubmissionPdfUrls()\n\n const formSubmissionResult: FormSubmissionResult = {\n ...formSubmission,\n payment: null,\n scheduling: null,\n isOffline: false,\n isInPendingQueue: false,\n submissionTimestamp: data.submissionTimestamp,\n submissionId: data.submissionId,\n isUploadingAttachments: false,\n downloadSubmissionPdfUrl,\n downloadSubmissionPdfs,\n attachmentsAccessToken: data.attachmentsAccessToken,\n }\n\n if (schedulingSubmissionEvent && schedulingUrlConfiguration) {\n formSubmissionResult.scheduling = await handleSchedulingSubmissionEvent({\n formSubmissionResult,\n schedulingSubmissionEvent,\n schedulingUrlConfiguration,\n paymentReceiptUrl,\n paymentFormUrl,\n preventPayment: data.preventPayment,\n })\n } else if (\n paymentSubmissionEventConfiguration &&\n paymentReceiptUrl &&\n !data.preventPayment\n ) {\n formSubmissionResult.payment = await handlePaymentSubmissionEvent({\n ...paymentSubmissionEventConfiguration,\n formSubmissionResult,\n paymentReceiptUrl,\n paymentFormUrl,\n })\n }\n\n //currently cannot have drafts without a forms app\n if (formSubmission.formSubmissionDraftId && formSubmission.formsAppId) {\n await removeLocalDraftSubmission(formSubmission.formSubmissionDraftId)\n syncDrafts({\n formsAppId: formSubmission.formsAppId,\n throwError: false,\n })\n }\n if (formSubmission.preFillFormDataId) {\n await removePrefillFormData(formSubmission.preFillFormDataId)\n }\n\n notifyJobSubmittedIfApplicable(formSubmission)\n\n return formSubmissionResult\n } catch (error: OneBlinkAppsError | unknown) {\n if (error instanceof OneBlinkAppsError) {\n if (error.isOffline) {\n if (\n !isPendingQueueEnabled ||\n schedulingSubmissionEvent ||\n paymentSubmissionEventConfiguration\n ) {\n console.warn(\n 'Offline error thrown - app or form does not support pending queue, return offline',\n error,\n )\n return Object.assign({}, formSubmission, {\n isOffline: true,\n isInPendingQueue: false,\n submissionTimestamp: null,\n submissionId: null,\n payment: null,\n scheduling: null,\n isUploadingAttachments: false,\n preventPayment: false,\n })\n }\n\n console.warn(\n 'Offline error thrown - saving submission to pending queue..',\n error,\n )\n await addFormSubmissionToPendingQueue(formSubmission)\n notifyJobSubmittedIfApplicable(formSubmission)\n return Object.assign({}, formSubmission, {\n isOffline: true,\n isInPendingQueue: true,\n submissionTimestamp: null,\n submissionId: null,\n payment: null,\n scheduling: null,\n isUploadingAttachments: false,\n preventPayment: false,\n })\n }\n\n // If the error has already been handled as a\n // OneBlinkAppsError, we can throw it as is.\n throw error\n }\n\n throw new OneBlinkAppsError(\n 'An error has occurred with your submission, please contact Support if this problem persists.',\n {\n title: 'Unexpected Error',\n originalError: error as Error,\n },\n )\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"submit.js","sourceRoot":"","sources":["../../../src/apps/services/submit.ts"],"names":[],"mappings":"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","sourcesContent":["import { isOffline } from '../offline-service'\nimport {\n addFormSubmissionToPendingQueue,\n deletePendingQueueSubmission,\n} from './pending-queue'\nimport {\n checkForPaymentSubmissionEvent,\n handlePaymentSubmissionEvent,\n} from '../payment-service'\nimport { removeLocalDraftSubmission } from './draft-data-store'\nimport { removePrefillFormData } from '../prefill-service'\nimport {\n handleSchedulingSubmissionEvent,\n checkForSchedulingSubmissionEvent,\n} from './schedulingHandlers'\nimport {\n FormSubmission,\n FormSubmissionResult,\n ProgressListener,\n ProgressListenerEvent,\n} from '../types/submissions'\nimport { SchedulingUrlConfiguration } from '../types/scheduling'\nimport { checkIfAttachmentsAreUploading } from '../attachments-service'\nimport tenants from '../tenants'\nimport externalIdGeneration from './external-id-generation'\nimport serverValidateForm from './server-validation'\nimport OneBlinkAppsError from './errors/oneBlinkAppsError'\nimport { uploadFormSubmission } from './api/submissions'\nimport { syncDrafts } from '../draft-service'\nimport { notifyJobSubmitted } from '../job-service'\n\nfunction notifyJobSubmittedIfApplicable(formSubmission: FormSubmission) {\n if (formSubmission.jobId) {\n notifyJobSubmitted(formSubmission.jobId)\n }\n}\n\ntype SubmissionParams = {\n formSubmission: FormSubmission\n isPendingQueueEnabled: boolean\n shouldRunServerValidation: boolean\n shouldRunExternalIdGeneration: boolean\n paymentReceiptUrl: string | undefined\n paymentFormUrl: string | undefined\n schedulingUrlConfiguration?: SchedulingUrlConfiguration\n pendingTimestamp?: string\n alwaysSubmitViaPendingQueue?: boolean\n onProgress?: ProgressListener\n abortSignal?: AbortSignal\n}\n\nexport { SubmissionParams, ProgressListener, ProgressListenerEvent }\n\nexport default async function submit({\n formSubmission,\n isPendingQueueEnabled,\n paymentReceiptUrl,\n paymentFormUrl,\n schedulingUrlConfiguration,\n onProgress,\n shouldRunServerValidation,\n shouldRunExternalIdGeneration,\n abortSignal,\n pendingTimestamp,\n alwaysSubmitViaPendingQueue,\n completionTimestamp,\n}: SubmissionParams & {\n completionTimestamp: string\n}): Promise<FormSubmissionResult> {\n const paymentSubmissionEventConfiguration = checkForPaymentSubmissionEvent(\n formSubmission,\n completionTimestamp,\n )\n\n const schedulingSubmissionEvent = checkForSchedulingSubmissionEvent(\n formSubmission,\n completionTimestamp,\n )\n\n try {\n if (pendingTimestamp) {\n await deletePendingQueueSubmission(pendingTimestamp)\n }\n if (isOffline() || alwaysSubmitViaPendingQueue) {\n if (paymentSubmissionEventConfiguration || schedulingSubmissionEvent) {\n console.log(\n 'Offline or always submitting via pending queue - form has a payment/scheduling submission event that has not been processed yet, return offline',\n { paymentSubmissionEventConfiguration, schedulingSubmissionEvent },\n )\n return Object.assign({}, formSubmission, {\n isOffline: true,\n isInPendingQueue: false,\n submissionTimestamp: null,\n submissionId: null,\n payment: null,\n scheduling: null,\n isUploadingAttachments: false,\n })\n }\n\n if (!alwaysSubmitViaPendingQueue && !isPendingQueueEnabled) {\n console.log(\n 'Offline - app does not support pending queue, return offline',\n )\n return Object.assign({}, formSubmission, {\n isOffline: true,\n isInPendingQueue: false,\n submissionTimestamp: null,\n submissionId: null,\n payment: null,\n scheduling: null,\n isUploadingAttachments: false,\n })\n }\n\n console.log(\n 'Offline or always submitting via pending queue - saving submission to pending queue..',\n )\n await addFormSubmissionToPendingQueue(formSubmission)\n notifyJobSubmittedIfApplicable(formSubmission)\n return Object.assign({}, formSubmission, {\n isOffline: isOffline(),\n isInPendingQueue: true,\n submissionTimestamp: null,\n submissionId: null,\n payment: null,\n preventPayment: false,\n scheduling: null,\n isUploadingAttachments: false,\n })\n }\n\n const attachmentsStillUploading = checkIfAttachmentsAreUploading(\n formSubmission.definition,\n formSubmission.submission,\n )\n\n if (attachmentsStillUploading) {\n if (paymentSubmissionEventConfiguration || schedulingSubmissionEvent) {\n console.log(\n 'Attachments still uploading - form has a payment/scheduling submission event that has not been processed yet, return isUploading',\n { paymentSubmissionEventConfiguration, schedulingSubmissionEvent },\n )\n return Object.assign({}, formSubmission, {\n isOffline: false,\n isInPendingQueue: false,\n submissionTimestamp: null,\n submissionId: null,\n payment: null,\n preventPayment: false,\n scheduling: null,\n isUploadingAttachments: true,\n })\n }\n console.log(\n 'Attachments still uploading - saving submission to pending queue..',\n )\n await addFormSubmissionToPendingQueue(formSubmission)\n notifyJobSubmittedIfApplicable(formSubmission)\n return Object.assign({}, formSubmission, {\n isOffline: false,\n isInPendingQueue: true,\n submissionTimestamp: null,\n submissionId: null,\n payment: null,\n preventPayment: false,\n scheduling: null,\n isUploadingAttachments: true,\n })\n }\n\n if (shouldRunServerValidation) {\n await serverValidateForm(formSubmission)\n }\n if (shouldRunExternalIdGeneration) {\n const externalIdResult = await externalIdGeneration(formSubmission)\n if (externalIdResult.externalId) {\n formSubmission.externalId = externalIdResult.externalId\n }\n }\n\n const data = await uploadFormSubmission(\n formSubmission,\n completionTimestamp,\n onProgress,\n abortSignal,\n )\n\n const getDownloadSubmissionPdfUrls = () => {\n const allowPDFDownload =\n formSubmission.definition.postSubmissionReceipt?.allowPDFDownload\n if (!data.pdfAccessToken || !allowPDFDownload) {\n return {\n downloadSubmissionPdfUrl: undefined,\n downloadSubmissionPdfs: undefined,\n }\n }\n if (allowPDFDownload && !Array.isArray(allowPDFDownload)) {\n // Cater for legacy config\n const url = `${tenants.current.apiOrigin}/forms/${formSubmission.definition.id}/submissions/${data.submissionId}/pdf-document?accessToken=${data.pdfAccessToken}`\n return {\n downloadSubmissionPdfUrl: url,\n downloadSubmissionPdfs: [\n {\n id: 'default',\n configuration: allowPDFDownload,\n url,\n },\n ],\n }\n }\n\n return {\n downloadSubmissionPdfUrl: undefined,\n downloadSubmissionPdfs: allowPDFDownload.map((pdfConfiguration) => {\n const url = `${tenants.current.apiOrigin}/forms/${formSubmission.definition.id}/submissions/${data.submissionId}/pdf-document?accessToken=${data.pdfAccessToken}&configurationId=${pdfConfiguration.id}`\n return {\n ...pdfConfiguration,\n url,\n }\n }),\n }\n }\n\n const { downloadSubmissionPdfUrl, downloadSubmissionPdfs } =\n getDownloadSubmissionPdfUrls()\n\n const formSubmissionResult: FormSubmissionResult = {\n ...formSubmission,\n payment: null,\n scheduling: null,\n isOffline: false,\n isInPendingQueue: false,\n submissionTimestamp: data.submissionTimestamp,\n submissionId: data.submissionId,\n isUploadingAttachments: false,\n downloadSubmissionPdfUrl,\n downloadSubmissionPdfs,\n attachmentsAccessToken: data.attachmentsAccessToken,\n }\n\n if (schedulingSubmissionEvent && schedulingUrlConfiguration) {\n formSubmissionResult.scheduling = await handleSchedulingSubmissionEvent({\n formSubmissionResult,\n schedulingSubmissionEvent,\n schedulingUrlConfiguration,\n paymentReceiptUrl,\n paymentFormUrl,\n preventPayment: data.preventPayment,\n })\n } else if (\n paymentSubmissionEventConfiguration &&\n paymentReceiptUrl &&\n !data.preventPayment\n ) {\n formSubmissionResult.payment = await handlePaymentSubmissionEvent({\n ...paymentSubmissionEventConfiguration,\n formSubmissionResult,\n paymentReceiptUrl,\n paymentFormUrl,\n })\n }\n\n //currently cannot have drafts without a forms app\n if (formSubmission.formSubmissionDraftId && formSubmission.formsAppId) {\n await removeLocalDraftSubmission(formSubmission.formSubmissionDraftId)\n syncDrafts({\n formsAppId: formSubmission.formsAppId,\n throwError: false,\n })\n }\n if (formSubmission.preFillFormDataId) {\n await removePrefillFormData(formSubmission.preFillFormDataId)\n }\n\n notifyJobSubmittedIfApplicable(formSubmission)\n\n return formSubmissionResult\n } catch (error: OneBlinkAppsError | unknown) {\n if (error instanceof OneBlinkAppsError) {\n if (error.isOffline) {\n if (\n !isPendingQueueEnabled ||\n schedulingSubmissionEvent ||\n paymentSubmissionEventConfiguration\n ) {\n console.warn(\n 'Offline error thrown - app or form does not support pending queue, return offline',\n error,\n )\n return Object.assign({}, formSubmission, {\n isOffline: true,\n isInPendingQueue: false,\n submissionTimestamp: null,\n submissionId: null,\n payment: null,\n scheduling: null,\n isUploadingAttachments: false,\n preventPayment: false,\n })\n }\n\n console.warn(\n 'Offline error thrown - saving submission to pending queue..',\n error,\n )\n await addFormSubmissionToPendingQueue(formSubmission)\n notifyJobSubmittedIfApplicable(formSubmission)\n return Object.assign({}, formSubmission, {\n isOffline: true,\n isInPendingQueue: true,\n submissionTimestamp: null,\n submissionId: null,\n payment: null,\n scheduling: null,\n isUploadingAttachments: false,\n preventPayment: false,\n })\n }\n\n // If the error has already been handled as a\n // OneBlinkAppsError, we can throw it as is.\n throw error\n }\n\n throw new OneBlinkAppsError(\n 'An error has occurred with your submission, please contact Support if this problem persists.',\n {\n title: 'Unexpected Error',\n originalError: error as Error,\n },\n )\n }\n}\n"]}
|
|
@@ -204,7 +204,8 @@ function FormElementCalculation({ element, onChange, value }) {
|
|
|
204
204
|
return;
|
|
205
205
|
}
|
|
206
206
|
try {
|
|
207
|
-
|
|
207
|
+
const result = calculation.eval(formSubmissionModel);
|
|
208
|
+
return typeof result === 'number' ? result : undefined;
|
|
208
209
|
}
|
|
209
210
|
catch {
|
|
210
211
|
//do nothing
|
|
@@ -214,10 +215,10 @@ function FormElementCalculation({ element, onChange, value }) {
|
|
|
214
215
|
// MODEL LISTENER
|
|
215
216
|
React.useEffect(() => {
|
|
216
217
|
const newValue = calculateContent(formSubmissionModel);
|
|
217
|
-
if (value === newValue || (value === undefined && isNaN(newValue))) {
|
|
218
|
+
if (value === newValue || (value === undefined && Number.isNaN(newValue))) {
|
|
218
219
|
return;
|
|
219
220
|
}
|
|
220
|
-
if (!isNaN(newValue)) {
|
|
221
|
+
if (typeof newValue === 'number' && !Number.isNaN(newValue)) {
|
|
221
222
|
onChange(element, {
|
|
222
223
|
value: newValue,
|
|
223
224
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormElementCalculation.js","sourceRoot":"","sources":["../../src/form-elements/FormElementCalculation.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport ExpressionParser from 'morph-expressions'\nimport escapeString from 'escape-string-regexp'\nimport useFormSubmissionModel from '../hooks/useFormSubmissionModelContext'\nimport { FormTypes, SubmissionTypes } from '@oneblink/types'\nimport { Sentry } from '../apps'\nimport { localisationService } from '../apps'\nimport { FormElementValueChangeHandler } from '../types/form'\nimport { formElementsService } from '@oneblink/sdk-core'\nimport QuillHTML from '../components/QuillHTML'\nimport MaterialIcon from '../components/MaterialIcon'\nimport useFormDefinition from '../hooks/useFormDefinition'\n\ntype Props = {\n element: FormTypes.CalculationElement\n onChange: FormElementValueChangeHandler<number>\n value: unknown | undefined\n}\n\nconst isUnenteredValue = (value: unknown | undefined) => {\n return !value && value !== 0\n}\n\nconst isObjectWithValue = (obj: unknown): obj is { value: unknown } => {\n return typeof obj === 'object' && obj !== null && 'value' in obj\n}\n\n// workaround for .toFixed() not rounding floating point numbers correctly\nfunction roundToFixed(number: number, decimals: number) {\n const multiplier = Math.pow(10, decimals)\n const roundedNumber = Math.round(number * multiplier) / multiplier\n return roundedNumber.toFixed(decimals)\n}\n\nfunction FormElementCalculation({ element, onChange, value }: Props) {\n const { formSubmissionModel } = useFormSubmissionModel()\n const form = useFormDefinition()\n\n const htmlValue = React.useMemo(() => {\n let htmlTemplate\n\n if (!isNaN(value as number)) {\n htmlTemplate = element.defaultValue\n } else {\n console.log(\n '[Calculation] Was not a number... setting pre-calculation display',\n )\n htmlTemplate = element.preCalculationDisplay\n }\n\n const numberValue = typeof value === 'number' ? value : 0\n return (htmlTemplate || '').replace(\n /{result}/gi,\n element.displayAsCurrency\n ? localisationService.formatCurrency(numberValue)\n : localisationService.formatNumber(numberValue),\n )\n }, [element, value])\n\n const registerProperty = React.useCallback(\n (\n exprParser: typeof ExpressionParser,\n {\n replacement,\n nestedElementNames,\n }: {\n replacement: string\n nestedElementNames: string[]\n },\n ) => {\n exprParser.registerProperty(\n replacement,\n (submission: SubmissionTypes.S3SubmissionData['submission']) => {\n const defaultAccumulator = submission[nestedElementNames[0]]\n return nestedElementNames.reduce(\n (\n elementValue: unknown | undefined,\n elementName: string,\n index: number,\n ) => {\n // Numbers can just be returned as is\n if (typeof elementValue === 'number') {\n return elementValue\n }\n\n // attempt to get a number from the element value as a string.\n // NaN is accounted for is the calculation\n // so we can return that from here\n if (typeof elementValue === 'string') {\n // The string could be an iso date string, or a string\n // resembling a date. We need to parse the value as an ISO string\n // and as a date in the format below to cover all calculation checks\n // with 'date', 'datetime' and 'time' elements. If the string is not\n // one of these, then we want to parse it as a float.\n\n const parsedIsoDate = localisationService.generateDate({\n value: elementValue,\n daysOffset: undefined,\n })\n if (parsedIsoDate) {\n return parsedIsoDate.getTime()\n }\n const parsedDate = localisationService.generateDate({\n value: elementValue,\n daysOffset: undefined,\n })\n if (parsedDate) {\n return parsedDate.getTime()\n }\n\n return parseFloat(elementValue)\n }\n\n if (Array.isArray(elementValue)) {\n // If there are no entries, we can return null\n // to prevent the calculation from running.\n if (!elementValue.length) {\n return NaN\n }\n\n // An array could be an element that allows multiple\n // values e.g. checkboxes. If thats that case, we just\n // add them all together and move on\n const elementValues = elementValue.map((entry) =>\n parseFloat(entry),\n )\n if (elementValues.every((entry) => !Number.isNaN(entry))) {\n return elementValues.reduce(\n (number, entry) => number + entry,\n 0,\n )\n }\n\n // Other wise attempt to process it as a repeatable set\n // If we found another repeatable set to process,\n // pass it to the next element name to\n // iterate over the entries\n\n // If we are processing the entries in a repeatable set,\n // we can sum the numbers elements in the entries\n const nextElementName = nestedElementNames[index + 1]\n\n let isNestedRepeatableSet = false\n const nestedElementValues = elementValue.reduce(\n (nestedElementValues, entry) => {\n if (entry) {\n const nextElementValue = entry[nextElementName]\n if (Array.isArray(nextElementValue)) {\n if (nextElementValue.length) {\n nestedElementValues.push(...nextElementValue)\n isNestedRepeatableSet = true\n }\n } else {\n nestedElementValues.push(nextElementValue)\n }\n }\n return nestedElementValues\n },\n [],\n )\n\n // If the nested element values are all arrays, we can pass them on to the next iteration\n if (isNestedRepeatableSet) {\n return nestedElementValues\n }\n\n return nestedElementValues.reduce(\n (total: number, nestedElementValue: unknown | undefined) => {\n if (Number.isNaN(total)) {\n return NaN\n }\n const value = parseFloat(nestedElementValue as string)\n if (Number.isNaN(value)) {\n return NaN\n }\n return total + value\n },\n 0,\n )\n }\n\n // if the value is an object, we take the element name and check to see\n // if this element is a nested form element. If so, we take the next nested element name,\n // find its value in the object and return it for the next iteration to handle\n if (typeof elementValue === 'object') {\n const formFormElement = formElementsService.findFormElement(\n form.elements,\n (e) =>\n e.type === 'form' && e.name === nestedElementNames[index],\n )\n const nextElementName = nestedElementNames[index + 1]\n if (formFormElement && nextElementName) {\n return (elementValue as Record<string, unknown>)[\n nextElementName\n ]\n }\n }\n\n // \"compliance\" form element has an object value with a \"value\" property.\n if (\n isObjectWithValue(elementValue) &&\n typeof elementValue.value === 'string'\n ) {\n return parseFloat(elementValue.value)\n }\n\n // We did not find a number value from the known elements,\n // we will assume we are at the end of the line.\n return NaN\n },\n defaultAccumulator,\n )\n },\n )\n },\n [form.elements],\n )\n\n const { calculation, hasError } = React.useMemo(() => {\n const exprParser = new ExpressionParser()\n exprParser.registerFunction('ROUND', (value: number, precision: number) => {\n if (!Number.isNaN(value) && Number.isFinite(value)) {\n return parseFloat(roundToFixed(value, precision))\n }\n return null\n })\n exprParser.registerFunction('ROUND_DOWN', (value: number) => {\n if (!Number.isNaN(value) && Number.isFinite(value)) {\n return Math.floor(value)\n }\n return null\n })\n exprParser.registerFunction('ROUND_UP', (value: number) => {\n if (!Number.isNaN(value) && Number.isFinite(value)) {\n return Math.ceil(value)\n }\n return null\n })\n exprParser.registerFunction(\n 'ISNULL',\n (value: unknown | undefined, defaultValue: number) => {\n if (isUnenteredValue(value)) {\n return defaultValue || 0\n }\n return value\n },\n )\n\n try {\n if (!element.calculation) throw new Error('Element has no calculation.')\n const elementNames: string[] = []\n formElementsService.matchElementsTagRegex(\n element.calculation,\n ({ elementName }) => {\n elementNames.push(elementName)\n },\n )\n\n const code = elementNames.reduce((code, elementName, index) => {\n const regex = new RegExp(escapeString(`{ELEMENT:${elementName}}`), 'g')\n const replacement = `a${index}`\n registerProperty(exprParser, {\n replacement,\n nestedElementNames: elementName.split('|'),\n })\n return code.replace(regex, replacement)\n }, element.calculation || '')\n\n return {\n calculation: exprParser.parse(code.trim()),\n hasError: false,\n }\n } catch (e) {\n console.warn(\n 'Error while setting up parsing for calculation element',\n element,\n e,\n )\n Sentry.captureException(e)\n return {\n calculation: null,\n hasError: true,\n }\n }\n }, [element, registerProperty])\n\n const calculateContent = React.useCallback(\n (formSubmissionModel: SubmissionTypes.S3SubmissionData['submission']) => {\n if (!calculation) {\n return\n }\n try {\n return calculation.eval(formSubmissionModel)\n } catch {\n //do nothing\n }\n return\n },\n [calculation],\n )\n\n // MODEL LISTENER\n React.useEffect(() => {\n const newValue = calculateContent(formSubmissionModel)\n if (value === newValue || (value === undefined && isNaN(newValue))) {\n return\n }\n if (!isNaN(newValue)) {\n onChange(element, {\n value: newValue,\n })\n } else {\n onChange(element, {\n value: undefined,\n })\n }\n }, [element, formSubmissionModel, onChange, value, calculateContent])\n\n return (\n <div className=\"cypress-calculation-element\">\n <div className=\"ob-form__element ob-calculation\">\n <QuillHTML\n html={htmlValue}\n className=\"cypress-calculation-result ob-calculation__content\"\n />\n {hasError && (\n <div\n className=\"notification cypress-calculation-is-invalid\"\n role=\"alert\"\n >\n <div className=\"columns is-vcentered\">\n <div className=\"column is-narrow\">\n <MaterialIcon className=\"has-text-warning\">error</MaterialIcon>\n </div>\n <div className=\"column\">\n <p>There is an error in the calculation for this element.</p>\n </div>\n </div>\n </div>\n )}\n </div>\n </div>\n )\n}\n\nexport default React.memo(FormElementCalculation)\n"]}
|
|
1
|
+
{"version":3,"file":"FormElementCalculation.js","sourceRoot":"","sources":["../../src/form-elements/FormElementCalculation.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport ExpressionParser from 'morph-expressions'\nimport escapeString from 'escape-string-regexp'\nimport useFormSubmissionModel from '../hooks/useFormSubmissionModelContext'\nimport { FormTypes, SubmissionTypes } from '@oneblink/types'\nimport { Sentry } from '../apps'\nimport { localisationService } from '../apps'\nimport { FormElementValueChangeHandler } from '../types/form'\nimport { formElementsService } from '@oneblink/sdk-core'\nimport QuillHTML from '../components/QuillHTML'\nimport MaterialIcon from '../components/MaterialIcon'\nimport useFormDefinition from '../hooks/useFormDefinition'\n\ntype Props = {\n element: FormTypes.CalculationElement\n onChange: FormElementValueChangeHandler<number>\n value: unknown | undefined\n}\n\nconst isUnenteredValue = (value: unknown | undefined) => {\n return !value && value !== 0\n}\n\nconst isObjectWithValue = (obj: unknown): obj is { value: unknown } => {\n return typeof obj === 'object' && obj !== null && 'value' in obj\n}\n\n// workaround for .toFixed() not rounding floating point numbers correctly\nfunction roundToFixed(number: number, decimals: number) {\n const multiplier = Math.pow(10, decimals)\n const roundedNumber = Math.round(number * multiplier) / multiplier\n return roundedNumber.toFixed(decimals)\n}\n\nfunction FormElementCalculation({ element, onChange, value }: Props) {\n const { formSubmissionModel } = useFormSubmissionModel()\n const form = useFormDefinition()\n\n const htmlValue = React.useMemo(() => {\n let htmlTemplate\n\n if (!isNaN(value as number)) {\n htmlTemplate = element.defaultValue\n } else {\n console.log(\n '[Calculation] Was not a number... setting pre-calculation display',\n )\n htmlTemplate = element.preCalculationDisplay\n }\n\n const numberValue = typeof value === 'number' ? value : 0\n return (htmlTemplate || '').replace(\n /{result}/gi,\n element.displayAsCurrency\n ? localisationService.formatCurrency(numberValue)\n : localisationService.formatNumber(numberValue),\n )\n }, [element, value])\n\n const registerProperty = React.useCallback(\n (\n exprParser: ExpressionParser<\n SubmissionTypes.S3SubmissionData['submission']\n >,\n {\n replacement,\n nestedElementNames,\n }: {\n replacement: string\n nestedElementNames: string[]\n },\n ) => {\n exprParser.registerProperty(\n replacement,\n (submission: SubmissionTypes.S3SubmissionData['submission']) => {\n const defaultAccumulator = submission[nestedElementNames[0]]\n return nestedElementNames.reduce(\n (\n elementValue: unknown | undefined,\n elementName: string,\n index: number,\n ) => {\n // Numbers can just be returned as is\n if (typeof elementValue === 'number') {\n return elementValue\n }\n\n // attempt to get a number from the element value as a string.\n // NaN is accounted for is the calculation\n // so we can return that from here\n if (typeof elementValue === 'string') {\n // The string could be an iso date string, or a string\n // resembling a date. We need to parse the value as an ISO string\n // and as a date in the format below to cover all calculation checks\n // with 'date', 'datetime' and 'time' elements. If the string is not\n // one of these, then we want to parse it as a float.\n\n const parsedIsoDate = localisationService.generateDate({\n value: elementValue,\n daysOffset: undefined,\n })\n if (parsedIsoDate) {\n return parsedIsoDate.getTime()\n }\n const parsedDate = localisationService.generateDate({\n value: elementValue,\n daysOffset: undefined,\n })\n if (parsedDate) {\n return parsedDate.getTime()\n }\n\n return parseFloat(elementValue)\n }\n\n if (Array.isArray(elementValue)) {\n // If there are no entries, we can return null\n // to prevent the calculation from running.\n if (!elementValue.length) {\n return NaN\n }\n\n // An array could be an element that allows multiple\n // values e.g. checkboxes. If thats that case, we just\n // add them all together and move on\n const elementValues = elementValue.map((entry) =>\n parseFloat(entry),\n )\n if (elementValues.every((entry) => !Number.isNaN(entry))) {\n return elementValues.reduce(\n (number, entry) => number + entry,\n 0,\n )\n }\n\n // Other wise attempt to process it as a repeatable set\n // If we found another repeatable set to process,\n // pass it to the next element name to\n // iterate over the entries\n\n // If we are processing the entries in a repeatable set,\n // we can sum the numbers elements in the entries\n const nextElementName = nestedElementNames[index + 1]\n\n let isNestedRepeatableSet = false\n const nestedElementValues = elementValue.reduce(\n (nestedElementValues, entry) => {\n if (entry) {\n const nextElementValue = entry[nextElementName]\n if (Array.isArray(nextElementValue)) {\n if (nextElementValue.length) {\n nestedElementValues.push(...nextElementValue)\n isNestedRepeatableSet = true\n }\n } else {\n nestedElementValues.push(nextElementValue)\n }\n }\n return nestedElementValues\n },\n [],\n )\n\n // If the nested element values are all arrays, we can pass them on to the next iteration\n if (isNestedRepeatableSet) {\n return nestedElementValues\n }\n\n return nestedElementValues.reduce(\n (total: number, nestedElementValue: unknown | undefined) => {\n if (Number.isNaN(total)) {\n return NaN\n }\n const value = parseFloat(nestedElementValue as string)\n if (Number.isNaN(value)) {\n return NaN\n }\n return total + value\n },\n 0,\n )\n }\n\n // if the value is an object, we take the element name and check to see\n // if this element is a nested form element. If so, we take the next nested element name,\n // find its value in the object and return it for the next iteration to handle\n if (typeof elementValue === 'object') {\n const formFormElement = formElementsService.findFormElement(\n form.elements,\n (e) =>\n e.type === 'form' && e.name === nestedElementNames[index],\n )\n const nextElementName = nestedElementNames[index + 1]\n if (formFormElement && nextElementName) {\n return (elementValue as Record<string, unknown>)[\n nextElementName\n ]\n }\n }\n\n // \"compliance\" form element has an object value with a \"value\" property.\n if (\n isObjectWithValue(elementValue) &&\n typeof elementValue.value === 'string'\n ) {\n return parseFloat(elementValue.value)\n }\n\n // We did not find a number value from the known elements,\n // we will assume we are at the end of the line.\n return NaN\n },\n defaultAccumulator,\n )\n },\n )\n },\n [form.elements],\n )\n\n const { calculation, hasError } = React.useMemo(() => {\n const exprParser = new ExpressionParser<\n SubmissionTypes.S3SubmissionData['submission']\n >()\n exprParser.registerFunction('ROUND', (value: number, precision: number) => {\n if (!Number.isNaN(value) && Number.isFinite(value)) {\n return parseFloat(roundToFixed(value, precision))\n }\n return null\n })\n exprParser.registerFunction('ROUND_DOWN', (value: number) => {\n if (!Number.isNaN(value) && Number.isFinite(value)) {\n return Math.floor(value)\n }\n return null\n })\n exprParser.registerFunction('ROUND_UP', (value: number) => {\n if (!Number.isNaN(value) && Number.isFinite(value)) {\n return Math.ceil(value)\n }\n return null\n })\n exprParser.registerFunction(\n 'ISNULL',\n (value: unknown | undefined, defaultValue: number) => {\n if (isUnenteredValue(value)) {\n return defaultValue || 0\n }\n return value\n },\n )\n\n try {\n if (!element.calculation) throw new Error('Element has no calculation.')\n const elementNames: string[] = []\n formElementsService.matchElementsTagRegex(\n element.calculation,\n ({ elementName }) => {\n elementNames.push(elementName)\n },\n )\n\n const code = elementNames.reduce((code, elementName, index) => {\n const regex = new RegExp(escapeString(`{ELEMENT:${elementName}}`), 'g')\n const replacement = `a${index}`\n registerProperty(exprParser, {\n replacement,\n nestedElementNames: elementName.split('|'),\n })\n return code.replace(regex, replacement)\n }, element.calculation || '')\n\n return {\n calculation: exprParser.parse(code.trim()),\n hasError: false,\n }\n } catch (e) {\n console.warn(\n 'Error while setting up parsing for calculation element',\n element,\n e,\n )\n Sentry.captureException(e)\n return {\n calculation: null,\n hasError: true,\n }\n }\n }, [element, registerProperty])\n\n const calculateContent = React.useCallback(\n (formSubmissionModel: SubmissionTypes.S3SubmissionData['submission']) => {\n if (!calculation) {\n return\n }\n try {\n const result = calculation.eval(formSubmissionModel)\n return typeof result === 'number' ? result : undefined\n } catch {\n //do nothing\n }\n return\n },\n [calculation],\n )\n\n // MODEL LISTENER\n React.useEffect(() => {\n const newValue = calculateContent(formSubmissionModel)\n if (value === newValue || (value === undefined && Number.isNaN(newValue))) {\n return\n }\n if (typeof newValue === 'number' && !Number.isNaN(newValue)) {\n onChange(element, {\n value: newValue,\n })\n } else {\n onChange(element, {\n value: undefined,\n })\n }\n }, [element, formSubmissionModel, onChange, value, calculateContent])\n\n return (\n <div className=\"cypress-calculation-element\">\n <div className=\"ob-form__element ob-calculation\">\n <QuillHTML\n html={htmlValue}\n className=\"cypress-calculation-result ob-calculation__content\"\n />\n {hasError && (\n <div\n className=\"notification cypress-calculation-is-invalid\"\n role=\"alert\"\n >\n <div className=\"columns is-vcentered\">\n <div className=\"column is-narrow\">\n <MaterialIcon className=\"has-text-warning\">error</MaterialIcon>\n </div>\n <div className=\"column\">\n <p>There is an error in the calculation for this element.</p>\n </div>\n </div>\n </div>\n )}\n </div>\n </div>\n )\n}\n\nexport default React.memo(FormElementCalculation)\n"]}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Sentry } from '../apps';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { conditionalLogicService } from '@oneblink/sdk-core';
|
|
4
|
-
import cleanFormSubmissionModel from '../services/cleanFormSubmissionModel';
|
|
5
4
|
export default function useConditionalLogic({ formElements, submission, enableSubmission, }) {
|
|
6
5
|
const [conditionalLogicError, setConditionalLogicError] = React.useState();
|
|
7
6
|
const errorCallback = React.useCallback((error) => {
|
|
@@ -9,32 +8,18 @@ export default function useConditionalLogic({ formElements, submission, enableSu
|
|
|
9
8
|
Sentry.captureException(error);
|
|
10
9
|
setConditionalLogicError(error);
|
|
11
10
|
}, []);
|
|
12
|
-
const formElementsConditionallyShown = React.useMemo(() => {
|
|
13
|
-
|
|
11
|
+
const { formElementsConditionallyShown, submissionConditionallyEnabled } = React.useMemo(() => {
|
|
12
|
+
const { formElementsConditionallyShown, isSubmissionEnabled } = conditionalLogicService.generateFormElementsConditionallyShown({
|
|
14
13
|
formElements,
|
|
15
14
|
submission,
|
|
15
|
+
enableSubmission,
|
|
16
16
|
errorCallback,
|
|
17
17
|
});
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const { requiresAllConditionalPredicates, conditionalPredicates } = enableSubmission;
|
|
24
|
-
const { model } = cleanFormSubmissionModel(submission, formElements, formElementsConditionallyShown, true);
|
|
25
|
-
return conditionalLogicService.evaluateConditionalPredicates({
|
|
26
|
-
isConditional: true,
|
|
27
|
-
requiresAllConditionalPredicates,
|
|
28
|
-
conditionalPredicates,
|
|
29
|
-
formElements,
|
|
30
|
-
submission: model,
|
|
31
|
-
});
|
|
32
|
-
}, [
|
|
33
|
-
formElements,
|
|
34
|
-
enableSubmission,
|
|
35
|
-
formElementsConditionallyShown,
|
|
36
|
-
submission,
|
|
37
|
-
]);
|
|
18
|
+
return {
|
|
19
|
+
formElementsConditionallyShown,
|
|
20
|
+
submissionConditionallyEnabled: isSubmissionEnabled,
|
|
21
|
+
};
|
|
22
|
+
}, [formElements, submission, enableSubmission, errorCallback]);
|
|
38
23
|
return {
|
|
39
24
|
conditionalLogicError,
|
|
40
25
|
formElementsConditionallyShown,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useConditionalLogic.js","sourceRoot":"","sources":["../../src/hooks/useConditionalLogic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAEhC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"useConditionalLogic.js","sourceRoot":"","sources":["../../src/hooks/useConditionalLogic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAEhC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAA;AAE5D,MAAM,CAAC,OAAO,UAAU,mBAAmB,CAAC,EAC1C,YAAY,EACZ,UAAU,EACV,gBAAgB,GAKjB;IACC,MAAM,CAAC,qBAAqB,EAAE,wBAAwB,CAAC,GAAG,KAAK,CAAC,QAAQ,EAErE,CAAA;IAEH,MAAM,aAAa,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,KAAY,EAAE,EAAE;QACvD,OAAO,CAAC,IAAI,CAAC,wCAAwC,EAAE,KAAK,CAAC,CAAA;QAC7D,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAA;QAC9B,wBAAwB,CAAC,KAAK,CAAC,CAAA;IACjC,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,MAAM,EAAE,8BAA8B,EAAE,8BAA8B,EAAE,GACtE,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QACjB,MAAM,EAAE,8BAA8B,EAAE,mBAAmB,EAAE,GAC3D,uBAAuB,CAAC,sCAAsC,CAAC;YAC7D,YAAY;YACZ,UAAU;YACV,gBAAgB;YAChB,aAAa;SACd,CAAC,CAAA;QAEJ,OAAO;YACL,8BAA8B;YAC9B,8BAA8B,EAAE,mBAAmB;SACpD,CAAA;IACH,CAAC,EAAE,CAAC,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,aAAa,CAAC,CAAC,CAAA;IAEjE,OAAO;QACL,qBAAqB;QACrB,8BAA8B;QAC9B,8BAA8B;KAC/B,CAAA;AACH,CAAC","sourcesContent":["import { Sentry } from '../apps'\nimport { FormTypes, SubmissionTypes } from '@oneblink/types'\nimport * as React from 'react'\nimport { conditionalLogicService } from '@oneblink/sdk-core'\n\nexport default function useConditionalLogic({\n formElements,\n submission,\n enableSubmission,\n}: {\n formElements: FormTypes.FormElement[]\n submission: SubmissionTypes.S3SubmissionData['submission']\n enableSubmission: FormTypes.Form['enableSubmission']\n}) {\n const [conditionalLogicError, setConditionalLogicError] = React.useState<\n Error | undefined\n >()\n\n const errorCallback = React.useCallback((error: Error) => {\n console.warn('Error while checking conditional logic', error)\n Sentry.captureException(error)\n setConditionalLogicError(error)\n }, [])\n\n const { formElementsConditionallyShown, submissionConditionallyEnabled } =\n React.useMemo(() => {\n const { formElementsConditionallyShown, isSubmissionEnabled } =\n conditionalLogicService.generateFormElementsConditionallyShown({\n formElements,\n submission,\n enableSubmission,\n errorCallback,\n })\n\n return {\n formElementsConditionallyShown,\n submissionConditionallyEnabled: isSubmissionEnabled,\n }\n }, [formElements, submission, enableSubmission, errorCallback])\n\n return {\n conditionalLogicError,\n formElementsConditionallyShown,\n submissionConditionallyEnabled,\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oneblink/apps-react",
|
|
3
3
|
"description": "Helper functions for OneBlink apps in ReactJS.",
|
|
4
|
-
"version": "11.1.
|
|
4
|
+
"version": "11.1.1-beta.1",
|
|
5
5
|
"author": "OneBlink <developers@oneblink.io> (https://oneblink.io)",
|
|
6
6
|
"bugs": {
|
|
7
7
|
"url": "https://github.com/oneblink/apps-react/issues"
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"@emotion/react": "^11.14.0",
|
|
13
13
|
"@emotion/styled": "^11.14.1",
|
|
14
14
|
"@nylas/react": "^3.1.2",
|
|
15
|
-
"@oneblink/sdk-core": "^
|
|
15
|
+
"@oneblink/sdk-core": "^10.0.0-beta.2",
|
|
16
16
|
"@oneblink/storage": "^7.1.2-beta.2",
|
|
17
17
|
"@react-google-maps/api": "^2.20.8",
|
|
18
18
|
"@react-input/mask": "^2.0.4",
|