low-code-service
Version:
to handle workflow execution, handlebars execution and condition execution for low code service
306 lines (260 loc) • 8.93 kB
text/typescript
import * as HandleBars from 'handlebars';
const { parseBoolean } = require('../condition-executor/condition-handler');
const momentTimezone = require('moment-timezone');
const lodash = require('lodash');
function getEwayBillValues(ewayBill) {
const invoiceDate = lodash.get(ewayBill, 'invoice_date') || lodash.get(ewayBill, 'invoiceDate') || '';
const invoiceNumber = lodash.get(ewayBill, 'invoice_number') || lodash.get(ewayBill, 'invoiceNumber') || '';
const invoiceValue = lodash.get(ewayBill, 'invoiceValue') || lodash.get(ewayBill, 'invoice_amount') || lodash.get(ewayBill, 'invoice_value') || '';
const ewbNumber = lodash.get(ewayBill, 'ewb_number') || lodash.get(ewayBill, 'ewbNumber') || '';
const expiryDate = lodash.get(ewayBill, 'expiry_date') || lodash.get(ewayBill, 'validTill') || '';
const ewbCreationDate = lodash.get(ewayBill, 'creationTime') || lodash.get(ewayBill, 'creation_time') || '';
return {
invoiceDate,
invoiceNumber,
invoiceValue,
ewbNumber,
expiryDate,
ewbCreationDate,
};
}
// registering all the helpers for Handlerbar
(async function() {
// ifEquals helper for comparing two strings
HandleBars.registerHelper('ifEquals', (a, b) => {
return (a ? a.toUpperCase() : '') === b.toUpperCase();
});
// exists helper for checking value is some truthy value and not falsy
HandleBars.registerHelper('exists', (val) => {
return !(val === undefined || val === null);
});
// toUpperCase helper for converting string to uppper case
HandleBars.registerHelper('toUpperCase', (val) => {
return val.toUpperCase();
});
// toLowerCase helper for converting string to lower case
HandleBars.registerHelper('toLowerCase', (val) => {
return val.toLowerCase();
});
// "not" helper use with if
HandleBars.registerHelper('not', function(val) {
return !val;
});
HandleBars.registerHelper('lookupByIndex', function(array, index) {
return array[index];
});
HandleBars.registerHelper('multiply', function(value, multiplier) {
if (!value || !multiplier) {
return 0;
}
return (Number(value) * Number(multiplier)) || 0;
});
HandleBars.registerHelper('dateConvertor', function(value, fromFormat, fromTimezone, toFormat, toTimezone) {
let moment;
if (value) {
moment = momentTimezone(value, fromFormat, fromTimezone);
} else {
moment = momentTimezone();
}
moment = moment.tz(toTimezone);
if (toFormat === 'timestamp') {
return moment.valueOf();
}
return moment.format(toFormat);
});
HandleBars.registerHelper('getBasicAuth', function(username, password) {
try {
const buff = new Buffer(username + ':' + password);
const base64data = buff.toString('base64');
return base64data;
} catch (err) {
return null;
}
});
HandleBars.registerHelper('concat', function() {
return Array.prototype.slice.call(arguments, 0, -1).join('');
});
HandleBars.registerHelper('toNumber', function(value) {
return Number(value);
});
HandleBars.registerHelper('toString', function(value) {
return String(value);
});
HandleBars.registerHelper('toBoolean', function(value) {
return parseBoolean(value);
});
HandleBars.registerHelper('getEwayBillValues', function(ewayBill) {
return getEwayBillValues(ewayBill);
});
HandleBars.registerHelper('getInvoiceValues', function(ewayBillList, consignmentExtraDetails) {
let invoiceNumber = '';
let invoiceDate = '';
let ewbNumber = '';
let invoiceAmount: any = '';
let expiryDate = '';
let ewbCreationDate = '';
if (Array.isArray(ewayBillList) && ewayBillList.length) {
const ewayBillValues = getEwayBillValues(ewayBillList[0]);
invoiceNumber = ewayBillValues.invoiceNumber;
invoiceDate = ewayBillValues.invoiceDate;
ewbNumber = ewayBillValues.ewbNumber;
invoiceAmount = ewayBillValues.invoiceValue;
expiryDate = ewayBillValues.expiryDate;
ewbCreationDate = ewayBillValues.ewbCreationDate;
}
if (consignmentExtraDetails.eway_bill) {
const ewayBillValues = getEwayBillValues(consignmentExtraDetails.eway_bill);
if (!invoiceNumber) invoiceNumber = ewayBillValues.invoiceNumber;
if (!invoiceDate) invoiceDate = ewayBillValues.invoiceDate;
if (!ewbNumber) ewbNumber = ewayBillValues.ewbNumber;
if (!expiryDate) expiryDate = ewayBillValues.expiryDate;
if (!ewbCreationDate) ewbCreationDate = ewayBillValues.ewbCreationDate;
}
if (!invoiceNumber) {
invoiceNumber = lodash.get(consignmentExtraDetails, 'invoice_number', '');
}
if (!invoiceDate) {
invoiceDate = lodash.get(consignmentExtraDetails, 'invoice_date', '');
}
if (!invoiceAmount) {
invoiceAmount = lodash.get(consignmentExtraDetails, 'invoice_amount', '');
}
return {
invoiceNumber,
invoiceDate,
ewbNumber,
invoiceAmount,
expiryDate,
ewbCreationDate,
};
});
HandleBars.registerHelper('sumProperty', function(piecesDetail, property) {
if (!piecesDetail || !Array.isArray(piecesDetail)) return 0;
return piecesDetail.reduce((sum, item) => {
if (!item) return sum;
const value = item[property];
if (value === undefined || value === null) return sum;
const numValue = parseFloat(value);
return sum + (isNaN(numValue) ? 0 : numValue);
}, 0);
});
HandleBars.registerHelper('getRegexMatch', function(str, pattern, groupIndex=0, flags='') {
if (typeof str !== 'string') {
return '';
}
if (str === '') {
return '';
}
let index: number;
if (typeof groupIndex === 'string') {
index = parseInt(groupIndex, 10);
} else if (typeof groupIndex === 'number') {
index = groupIndex;
} else {
return '';
}
if (isNaN(index)) {
return '';
}
try {
const patternStr = String(pattern);
const validFlags = flags.replace(/[^gimsuyd]/g, '');
const regex = new RegExp(patternStr, validFlags);
const match = str.match(regex);
if (match && match[index] !== undefined) {
return match[index];
} else {
return '';
}
} catch (error) {
return '';
}
});
HandleBars.registerHelper('arrayProperty', function (array, options) {
const {
operation,
property,
value,
order = 'asc',
dataType,
checkType = 'any'
} = options.hash;
if (!Array.isArray(array)) {
return operation === 'exists' ? false : [];
}
function getNestedValue(obj, path) {
return path.split('.').reduce((acc, key) => acc?.[key], obj);
}
function isValidValue(val, type) {
if (val == null) return false;
switch ((type || '').toLowerCase()) {
case 'string':
return typeof val === 'string' && val.trim() !== '';
case 'number':
return typeof val === 'number' && !isNaN(val);
case 'boolean':
return typeof val === 'boolean';
case 'array':
return Array.isArray(val) && val.length > 0;
case 'object':
return typeof val === 'object' && !Array.isArray(val) && Object.keys(val).length > 0;
case 'any':
default:
if (Array.isArray(val)) return val.length > 0;
if (typeof val === 'object') return Object.keys(val).length > 0;
return Boolean(val);
}
}
switch (operation) {
case 'exists':
if (checkType === 'every') {
return array.every(item => isValidValue(getNestedValue(item, property), dataType));
} else {
return array.some(item => isValidValue(getNestedValue(item, property), dataType));
}
case 'map':
return array.map(item => getNestedValue(item, property));
case 'filter':
return array.filter(item => getNestedValue(item, property) == value);
case 'find':
return array.find(item => getNestedValue(item, property) == value);
case 'sort':
return array.slice().sort((a, b) => {
const aVal = getNestedValue(a, property);
const bVal = getNestedValue(b, property);
if (aVal == null && bVal == null) return 0;
if (aVal == null) return 1;
if (bVal == null) return -1;
if (order === 'desc') {
return aVal < bVal ? 1 : aVal > bVal ? -1 : 0;
}
return aVal > bVal ? 1 : aVal < bVal ? -1 : 0;
});
case 'unique':
const seen = new Set();
return array.filter(item => {
const val = getNestedValue(item, property);
if (seen.has(val)) return false;
seen.add(val);
return true;
});
case 'sum':
return array.reduce((acc, item) => {
const val = getNestedValue(item, property);
const num = parseFloat(val);
return acc + (isNaN(num) ? 0 : num);
}, 0);
default:
return array;
}
});
})();
export const getTemplateData = (template: string, data: any) => {
const compiledTemplate = HandleBars.compile(template);
return compiledTemplate(data);
};
export const cleanHandleBarTemplate = (dataToClean, defaultBody) => {
dataToClean = dataToClean.replace('\n', '');
dataToClean = dataToClean.replace('\t', '');
return dataToClean || defaultBody;
};