diff --git a/Server-Side Components/Business Rules/Currency conversion to USD/Readme.md b/Server-Side Components/Business Rules/Currency conversion to USD/Readme.md new file mode 100644 index 0000000000..91e0c69819 --- /dev/null +++ b/Server-Side Components/Business Rules/Currency conversion to USD/Readme.md @@ -0,0 +1,11 @@ +This script automates the conversion of an annual budget value from a selected currency to USD using exchange rates stored in the fx_rate table. It performs the following steps: + +Extracts the currency code from the budget_currency field. +Validates the input amount and currency. +Checks if the currency is already USD; if so, it directly stores the amount. +Queries the fx_currency table to confirm the currency exists. +Retrieves the most recent exchange rate for both the selected currency and USD. +Calculates the converted amount using the formula: +USD Amount = (Original Amount / Source Rate) × USD Rate +Stores the result in the u_annual_budget_usd field. +Includes error handling for missing or invalid data. diff --git a/Server-Side Components/Business Rules/Currency conversion to USD/currency conversion.js b/Server-Side Components/Business Rules/Currency conversion to USD/currency conversion.js new file mode 100644 index 0000000000..0504a6ab80 --- /dev/null +++ b/Server-Side Components/Business Rules/Currency conversion to USD/currency conversion.js @@ -0,0 +1,72 @@ +(function executeRule(current, previous /*null when async*/) { + + // Extract the first 3 characters of the budget currency code (e.g., "INR", "EUR") + var currencyCode = current.budget_currency ? current.budget_currency.toString().substring(0, 3) : ''; + + // Convert the annual budget value to a float + var amount = parseFloat(current.annual_budget); + + // Validate input: If currency code is missing or amount is not a valid number, clear the USD field and exit + if (!currencyCode || isNaN(amount)) { + current.u_annual_budget_usd = ''; + return; + } + + // If the currency is already USD, no conversion needed — store the original amount + if (currencyCode === 'USD') { + current.u_annual_budget_usd = amount; + return; + } + + // Check if the currency exists in the fx_currency table + var currencyGR = new GlideRecord('fx_currency'); + currencyGR.addQuery('code', currencyCode); + currencyGR.query(); + + // If currency is not found, clear the USD field and exit + if (!currencyGR.next()) { + current.u_annual_budget_usd = ''; + return; + } + + // Get the latest exchange rate for the selected currency from fx_rate table + var fxGR = new GlideRecord('fx_rate'); + fxGR.addQuery('currency.code', currencyCode); + fxGR.orderByDesc('sys_updated_on'); // Sort by most recent update + fxGR.setLimit(1); // Limit to the latest record + fxGR.query(); + + // If no exchange rate found, clear the USD field and exit + if (!fxGR.next()) { + current.u_annual_budget_usd = ''; + return; + } + + var rate = parseFloat(fxGR.getValue('rate')); // Exchange rate for selected currency + + // Get the latest exchange rate for USD from fx_rate table + var fxGR1 = new GlideRecord('fx_rate'); + fxGR1.addQuery('currency.code', 'USD'); + fxGR1.orderByDesc('sys_updated_on'); // Sort by most recent update + fxGR1.setLimit(1); // Limit to the latest record + fxGR1.query(); + + // If no USD exchange rate found, clear the USD field and exit + if (!fxGR1.next()) { + current.u_annual_budget_usd = ''; + return; + } + + var usdRate = parseFloat(fxGR1.getValue('rate')); // USD base rate + + // Perform conversion only if both rates are valid and non-zero + if (!isNaN(rate) && !isNaN(usdRate) && rate !== 0) { + var convertedAmount = (amount / rate) * usdRate; // Convert to USD + current.u_annual_budget_usd = convertedAmount; // Store the converted value + } else { + gs.info("Invalid exchange rate values"); + current.u_annual_budget_usd = ''; + } + +})(current, previous); +`` diff --git a/Server-Side Components/Business Rules/Mask Sensitive Data in Description b/Server-Side Components/Business Rules/Mask Sensitive Data in Description new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/Server-Side Components/Business Rules/Mask Sensitive Data in Description @@ -0,0 +1 @@ + diff --git a/Server-Side Components/Business Rules/Mask Sensitive Data in Description Field/MaskSensitiviteData.js b/Server-Side Components/Business Rules/Mask Sensitive Data in Description Field/MaskSensitiviteData.js new file mode 100644 index 0000000000..8a033efad5 --- /dev/null +++ b/Server-Side Components/Business Rules/Mask Sensitive Data in Description Field/MaskSensitiviteData.js @@ -0,0 +1,49 @@ +(function executeRule(current, previous /*null when async*/) { + + + + // Only run if description has a value + if (current.description) { + var desc = current.description.toString(); + + + // Regex patterns for sensitive data + var ccRegex = /\b\d{13,16}\b/g; // 13–16 continuous digits + var ccSpaced = /\b(\d{4}[- ]?){3}\d{4}\b/g; // 4-4-4-4 with spaces/dashes + var ssnRegex = /\b\d{3}-\d{2}-\d{4}\b/g; // US SSN + var phoneRegex = /(\+?\d{1,2}[- ]?)?\(?\d{3}\)?[- ]?\d{3}[- ]?\d{4}/g; // phone + + var masked = desc; + + // Apply masking with messages + if (ccRegex.test(desc)) { + gs.addInfoMessage("Credit card pattern found → masking"); + masked = masked.replace(ccRegex, "****-****-****-****"); + } + + if (ccSpaced.test(desc)) { + gs.addInfoMessage("Spaced/dashed credit card pattern found → masking"); + masked = masked.replace(ccSpaced, "****-****-****-****"); + } + + if (ssnRegex.test(desc)) { + gs.addInfoMessage("SSN pattern found → masking"); + masked = masked.replace(ssnRegex, "***-**-****"); + } + + if (phoneRegex.test(desc)) { + gs.addInfoMessage("Phone number pattern found → masking"); + masked = masked.replace(phoneRegex, "**********"); + } + + // If changes were made, update the description + if (masked !== desc) { + current.description = masked; + gs.addInfoMessage("Final masked description: " + masked); + gs.log("Masking rule triggered on record: " + current.number, "MaskingRule"); + } else { + gs.addInfoMessage("No sensitive data detected, nothing masked."); + } + } + +})(current, previous); diff --git a/Server-Side Components/Business Rules/Mask Sensitive Data in Description Field/readme.md b/Server-Side Components/Business Rules/Mask Sensitive Data in Description Field/readme.md new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/Server-Side Components/Business Rules/Mask Sensitive Data in Description Field/readme.md @@ -0,0 +1 @@ + diff --git a/Server-Side Components/Business Rules/Readme.md b/Server-Side Components/Business Rules/Readme.md new file mode 100644 index 0000000000..71a0f2c2a0 --- /dev/null +++ b/Server-Side Components/Business Rules/Readme.md @@ -0,0 +1 @@ +Automatically replaces sensitive patterns (like credit card numbers) with masked text