diff --git a/Flow Actions/Generate unique value based on sequence/next-unique-sequence.js b/Flow Actions/Generate unique value based on sequence/next-unique-sequence.js new file mode 100644 index 0000000000..b5ae650100 --- /dev/null +++ b/Flow Actions/Generate unique value based on sequence/next-unique-sequence.js @@ -0,0 +1,103 @@ +(function execute(inputs, outputs) { + // ... code ... + try { + var records = []; // Initialize an array to store records. + var tableGR = new GlideRecord(inputs.table); // Create a GlideRecord for the specified table. + tableGR.query(); // Execute the query to retrieve records. + while (tableGR.next()) { + if (tableGR.hasOwnProperty(inputs.column)) { + // Check if the record has the specified column. + records.push(tableGR[inputs.column].getDisplayValue()); // Add the column's display value to the records array. + } + } + + if (records.length > 0) { + // If there are records in the array. + outputs.value = records[records.length - 1]; // Set the output to the last record's value. + + while (true) { + outputs.value = nextSequence(outputs.value, inputs.useLowerUpperBoth); // Generate the next sequence value. + if (!records.includes(outputs.value)) { + // Check if the generated value is not in the records array. + break; // Exit the loop. + } + } + } else { + // If there are no records. + outputs.value = inputs.default_value; // Set the output to the default value. + } + } catch (e) { + outputs.value = null; // Handle any exceptions by setting the output to null. + } + +})(inputs, outputs); + +// Function to generate the next sequence based on the input value and options. +function nextSequence(input, useLowerUpperBoth) { + if (/\d+$/.test(input.toString())) { + // If the input ends with digits. + var postfix = input.match(/\d+$/)[0]; // Extract the digits. + var initLength = postfix.length; + postfix = parseInt(postfix); + ++postfix; + if (postfix.toString().length < initLength) { + postfix = padStart(postfix.toString(), initLength, '0'); // Ensure consistent length by padding with zeros. + } + return input.replace(/\d+$/, postfix); // Replace the digits with the incremented value. + } else { + // If the input ends with alphabetic characters. + var postfix = input.match(/[A-Za-z]+$/)[0]; // Extract the alphabetic characters. + var index = postfix.length - 1; + while (true) { + if (index === -1) { + // If all characters have been processed. + var charCode = postfix.charCodeAt(0); + if (useLowerUpperBoth === true) { + postfix = 'A' + postfix; + } else { + postfix = (charCode < 96 ? 'A' : 'a') + postfix; + } + break; + } + var charCode = postfix.charCodeAt(index); + + if (useLowerUpperBoth) { + // If both lower and upper case characters are allowed. + if (charCode == 90) { + postfix = replaceAt(postfix, index, String.fromCharCode(97)); + break; + } else if (charCode == 122) { + postfix = replaceAt(postfix, index, String.fromCharCode(97)); + index--; + } else { + postfix = replaceAt(postfix, index, String.fromCharCode(charCode + 1)); + break; + } + } else { + // If only upper case characters are allowed. + if (charCode == 90) { + postfix = replaceAt(postfix, index, String.fromCharCode(65)); + index--; + } else if (charCode == 122) { + postfix = replaceAt(postfix, index, String.fromCharCode(97)); + index--; + } else { + postfix = replaceAt(postfix, index, String.fromCharCode(charCode + 1)); + break; + } + } + } + + return input.replace(/[A-Za-z]+$/, postfix); // Replace the alphabetic characters with the updated value. + } +} + +// Function to replace a character at a specific index in a string. +function replaceAt(str, index, ch) { + return str.substring(0, index) + ch + str.substring(index + 1); +} + +// Function to pad a string with a specified character to a certain length. +function padStart(str, length, init) { + return str.length < length ? padStart(init + str, length, init) : str; +} diff --git a/Flow Actions/Generate unique value based on sequence/readme.md b/Flow Actions/Generate unique value based on sequence/readme.md new file mode 100644 index 0000000000..701f3db792 --- /dev/null +++ b/Flow Actions/Generate unique value based on sequence/readme.md @@ -0,0 +1,24 @@ +# Generate Unique Value Based on Sequence + +The `execute()` function in action is generates a unique sequence value based on the existing sequence in a column of a table. This function inside a action script is designed to be used in database environments. It takes the following input parameters: + +- `table`: The name of the table to generate the unique value for. +- `column`: The name of the column to generate the unique value for. +- `default_value`: The default value to use if there are no records in the table. +- `useLowerUpperBoth`: A Boolean value indicating whether to use both lower and upper case characters when generating the next sequence value. + +## Function Behavior + +1. The function begins by querying the specified table to retrieve all the values in the specified column. + +2. If there are records in the table: + - The function then generates the next sequence value based on the last value in the column. + - It automatically detects the type of sequence value to generate based on the postfix of the last value in the column: + - If the postfix ends with digits, the function generates a numeric sequence value. + - If the postfix ends with alphabetic characters, the function generates an alphabetic sequence value. + - If the `useLowerUpperBoth` parameter is set to `true`, the function will use both lower and upper case characters when generating alphabetic sequence values. + - If the `useLowerUpperBoth` parameter is set to `false`, the function will only use upper case characters when generating alphabetic sequence values. + +3. If there are no records in the table, the function returns the `default_value`. + +4. The function handles any exceptions by setting the output value to `null`.