Skip to main content

Pre-Submit Validation

Powered by RevOps Functions

Pre-Submit Validation powered by Functions provides you with the flexibility to write custom TypeScript code to validate deals before submission. The power of TypeScript allows for complete customization to validate your business requirements and RevOps will effortlessly handle your deployment and execution. This guide provides detailed instructions on how to implement this functionality effectively.

Beta Feature

Pre-Submit Validation is a limited access beta feature. Please contact your Account Manager if you are interested in joining the beta. The information in this document is a work in progress and is subject to change.

Please provide any questions or feedback to support@revops.io or via your Slack Connect channel if applicable. Additional features and functionality will be added in the future.

Getting Started

This guide covers specifics on the Pre-Submit function type. For more information about functions, visit RevOps Functions and review our Getting Started guide.

Basic Pre-Submit Function

A RevOps function is a named JavaScript/TypeScript function that is provided deal data and returns a list of errors or warnings to the submitting user.

export const validateDealBeforeSubmission = (
data: PreSubmitTestData
): PreSubmitResponse => {
const errors: PreSubmitResponse = [];

const paymentMethod = data.deal.terms.find(
(term) => term.name === "Payment Method"
) as OptionTerm | undefined;
const paymentTerms = data.deal.terms.find(
(term) => term.name === "Payment Terms"
) as OptionTerm | undefined;

if (paymentMethod?.value === "credit-card" && paymentTerms?.value !== "1") {
errors.push({ message: "Credit Card payments must be Due Upon Receipt" });
}

return errors;
};

In the example above, the function ensures the comparability of two separate terms. Any deals that are set to charge via Credit Card and required to use Due Upon Receipt payment terms. The sales rep must then decide if they want to change the payment method or payment terms to continue to submission.

Demonstration of validation flow and successfully correcting the error

Requirements and Details

  1. Function Name and Parameters

    • Your code must export a function named validateDealBeforeSubmission. You can only export this function once.
    • This function will be invoked with a data parameter of type PreSubmitTestData containing all relevant attributes of terms and line items.
    • The function should return type PreSubmitResponse.
      • This type includes:
        TypeSample - ValidSample - Invalid
        string"""Enterprise and Business cannot be mixed"
        string[][]["Enterprise and Business cannot be mixed"]
        { message: string; blocking?: boolean; enableMarkdown?: boolean }[][][{ message: "Enterprise and Business cannot be mixed" }]
        [{ message: "Enterprise and Business cannot be mixed", blocking: true }]
        [{ message: "Enterprise and Business cannot be mixed", blocking: false }]
    • Your function may also be async and return the appropriate Promise . When utilizing promises, you should only ever successfully resolve the promise. Promises that are rejected will be treated as an execution error.
  2. Language Options

    • RevOps Functions are powered by TypeScript (TS), which utilizes the same syntax as JavaScript (JS) with additional syntax for type checking. The Functions editor includes built in type definitions and type checking to highlight potential issues with your code.
    • Users may choose to write in JavaScript and not include types, although we do not recommend it.
  3. Testing Functions

    • The Functions editor includes a section to test the result of your function based on a saved deal.
    • The tester will show you the results as would appear during the submission process and allow you to inspect the data passed to the function.
    • Output from console.log , console.warn , and console.error is automatically captured and made available in the tester and to admins during deal submission.
  4. Deal Submission Process

    • When a user submits a new deal for approval, your custom validation function will run.

    • If no validation errors are returned, the user will be able to add an optional escalation message and submit for approval.

    • If any errors are returned, they will be displayed to the user. Errors will be grouped between blocking feedback and non-blocking feedback. If only non-blocking feedback is returned, users will be able to submit for approval after reviewing the messages.

    • Save as draft is always permitted, regardless of the errors. Account administrators are always able to submit for approval.

    • If the function is disabled, validation will be bypassed. Built in validation such as email validation and required terms will continue to run.

    • If the function fails to execute, the error behavior setting on the function is respected. Account administrators are always able to submit for approval.

Advanced Formatting

For complex error messages, you can choose to enable limited markdown support.

The following markdown features are supported:

FeatureExampleNotes
Headings#### Heading 4All headings are displayed at the same size
External Links[see internal documentation](https://example.com/our-docs)All links must begin with https://. Links will open in a new tab.
Bold Text**critical detail**
Italic Text*critical detail*
Line Breaks\nLine breaks are supported with or without markdown being enabled.
TablesSee below
Table Example
| Nulla lectus arcu           	| Maecenas euismod metus at   	|
|----------------------------- |----------------------------- |
| consectetur adipiscing elit | dolor consectetur rutrum |
| Lorem ipsum | elementum eu efficitur eget |
Callout

Pre-Submit validation supports a limited set of markdown. Only the functionality noted above is supported.

Operators and Variables are not supported in this context. Instead, use the equivalent TypeScript functionality.

When returning your error response, include enableMarkdown: true.

Example Error Response
const error = {
message:
"# Invalid Payment Term Combination\n" +
"Credit Card payments must be due upon receipt.\n" +
"**Either** update the payment terms to be *Due Upon Receipt* **or** update the payment method to *not* be credit card.\n\n" +
"| Payment Method | Allowed Payment Terms |\n" +
"|-|-|\n" +
"| ACH, Wire | NET-30, NET-45, NET-60, NET-75, NET-90 |\n" +
"| Check | NET-30, NET-45, NET-60 |\n" +
"| Credit Card | Due Upon Receipt |\n" +
"Review the [Internal Policy](https://example.com/our-policy) for more information.",
enableMarkdown: true,
};

This would display to the user as:

Samples

A variety of samples can be found in Function Examples.

Exception Handling

If your code execution results in an unhandled exception, you can choose whether or not the execution failure should block submission. Administrators can always submit.

Type Definitions

Type information can be found in Type Definitions.

Additional Resources

Additional information about Functions, including its limitations and best practices, can be found in RevOps Functions.