common/function/index.js

const moment = require('moment')
const dateFormat = require('dateformat')
const csc = require('country-state-city').default

const commonModule = require('../modules/tables').default
const mysqclass = require('./mysqli').default
const commonSQL = require('../sql').default

const sendgridModule = require('../thirdparty/sendgrid').default
const twilioModule = require('../thirdparty/twilio').default

const customCommonFunction = require('../../../../custom/common/function').default
const commonProduct = require('../products').default

const dateFormatGlobal = 'MM-DD-YYYY'
const dateTimeFormat = 'MM-DD-YYYY h:mm a'

/**
 * @class class to handle common functions
 */
class commonFunction {
    /**
     * event trigger function
     * @param {object} data data object
     * @param {email} sendToEmail send to email
     * @param {string} sendToPhone send to phone
     * @param {string} tempName temp name
     * @param {boolean} isAdmin is admin
     * @param {number} notifyID notify id
     * @param {number} userID user id
     * @param {string} suffix suffix
     */
    static async eventTriggerFuction(
        data,
        sendToEmail,
        sendToPhone,
        tempName,
        isAdmin = 1,
        notifyID = 0,
        userID = 0,
        suffix = '',
    ) {
        let result = []
        if (notifyID > 0 && userID > 0) {
            result = await Promise.all([
                this.checkallnotifyExtra(userID, notifyID, 'email'),
                this.checkallnotifyExtra(userID, notifyID, 'sms'),
            ])
        }
        if (
            global.configFeatures.multi_template_project_field &&
            global.configFeatures.multi_template_project_field.enabled === 1
        ) {
            if (suffix !== '' && suffix !== 'live') {
                tempName = `${tempName}_${suffix}`
            }
        }
        if (
            (notifyID > 0 &&
                userID > 0 &&
                ((result[0] && result[0].length) || (result[1] && result[1].length))) ||
            notifyID === 0
        ) {
            const results = await Promise.all([
                this.getemplateData(tempName, 'email'),
                this.getemplateData(tempName, 'sms'),
            ])
            if (
                sendToEmail &&
                ((notifyID > 0 && userID > 0 && result[0] && result[0].length) || notifyID === 0) &&
                results[0].length > 0
            ) {
                const results1 = await Promise.all([this.getemplatePhrase(results[0][0].id)])
                let templatemsg = results[0][0].template
                let subjectmessage = results[0][0].subject
                templatemsg = templatemsg.replace(
                    new RegExp(`{{event.siteurl}}`, 'g'),
                    global.react_url.front_end,
                )
                templatemsg = templatemsg.replace(
                    new RegExp(`{{event.adminurl}}`, 'g'),
                    global.react_url.admin_end,
                )
                await this.asyncForEach(results1[0], async (element) => {
                    templatemsg = templatemsg.replace(
                        new RegExp(`{{event.${element.phrases}}}`, 'g'),
                        `${this.changeDataType(data[element.reference], element.type)}`,
                    )
                    subjectmessage = subjectmessage.replace(
                        new RegExp(`{{event.${element.phrases}}}`, 'g'),
                        `${this.changeDataType(data[element.reference], element.type)}`,
                    )
                })
                await sendgridModule.sendEmail(
                    subjectmessage,
                    sendToEmail,
                    templatemsg,
                    isAdmin,
                    userID,
                )
            }

            if (
                sendToPhone &&
                ((notifyID > 0 && userID > 0 && result[1] && result[1].length) || notifyID === 0) &&
                results[1].length > 0
            ) {
                const results2 = await Promise.all([this.getemplatePhrase(results[1][0].id)])
                let templatemsg = results[1][0].template
                await this.asyncForEach(results2[0], async (element) => {
                    templatemsg = templatemsg.replace(
                        `{{event.${element.phrases}}}`,
                        `${this.changeDataType(data[element.reference], element.type)}`,
                    )
                })
                twilioModule.sendsms(templatemsg, sendToPhone, userID)
            }
        }
        return true
    }
    /**
     * Json response
     * @param {object} res response
     * @param {string} status status
     * @param {string} message message
     */
    static jsonResponse(res, status, message) {
        const finalresultjson = {}
        finalresultjson.status = status
        finalresultjson.message = message
        res.json(finalresultjson)
        res.end()
        return false
    }
    /**
     * sum the two float values
     * @param {number} data data
     * @param {number} data2 data2
     * @returns {number}
     */
    static sumFloat(data, data2) {
        const dataReturn = parseFloat(data) + parseFloat(data2)
        return parseFloat(dataReturn)
    }
    /**
     * multiply the two float values
     * @param {number} data data
     * @param {number} data2 data2
     * @returns {number}
     */
    static multipleFloat(data, data2) {
        const dataReturn = parseFloat(data) * parseFloat(data2)
        return parseFloat(dataReturn)
    }
    /**
     * capitalize
     * @param {string} data data
     * @returns {string}
     *
     */
    static capitalize(data) {
        let dataReturn = '-'
        if (data) {
            dataReturn = data.charAt(0).toUpperCase() + data.slice(1)
        }
        return dataReturn
    }
    /**
     * currency format
     * @param {string} data data
     * @returns {string}
     *
     */
    static currencyFormat(data) {
        let dataReturn = '-'
        if (data) {
            dataReturn = `US $${parseFloat(data).toLocaleString('en-US')}`
        }
        return dataReturn
    }
    /**
     * date format function
     * @param {string} data data
     * @returns {string}
     *
     */
    static dateFormatFunction(data) {
        let dataReturn = '-'
        if (data) {
            if (moment(data).isValid()) {
                dataReturn = `${moment(data).format(dateFormatGlobal)}`
            }
        }
        return dataReturn
    }
    /**
     * date time format function
     * @param {string} data data
     * @returns {string}
     *
     */
    static dateTimeFormatFunction(data) {
        let dataReturn = '-'
        if (data) {
            if (moment(data).isValid()) {
                dataReturn = `${moment(data).format(dateTimeFormat)}`
            }
        }
        return dataReturn
    }
    /**
     *
     * @param {array} array async function array
     * @param {Function} callback call back
     * @returns {promise}
     */
    static async asyncForEach(array, callback) {
        for (let index = 0; index < array.length; index += 1) {
            await callback(array[index], index, array)
        }
    }
    /**
     * calculate array increment
     * @param {number} amount amount
     */
    static calculateArrayIncrement(amount) {
        const amounttoCheck = parseInt(amount, 10)
        let tosendAmount = 0
        if (global.configurations.allBidIncrements.length > 0) {
            global.configurations.allBidIncrements.forEach((element) => {
                if (
                    parseInt(element.from_amount, 10) <= amounttoCheck &&
                    parseInt(element.to_amount, 10) >= amounttoCheck
                ) {
                    tosendAmount = parseInt(element.increment, 10)
                }
            })

            if (tosendAmount === 0) {
                if (global.configurations.bidIncrementDefault.length > 0) {
                    tosendAmount = global.configurations.bidIncrementDefault[0].increment
                }
            }
        } else if (global.configurations.bidIncrementDefault.length > 0) {
            tosendAmount = global.configurations.bidIncrementDefault[0].increment
        }
        return tosendAmount
    }
    /**
     * get config variables
     * @param {number} variable amount
     */
    static async getconfigvariables(variable) {
        const mysql = {}
        const escapeData = [variable]
        const strQuery = await mysqclass.mysqli(mysql, 'get_one_configuration_variables')
        const value = await global.mysql.query(strQuery, escapeData)
        return value
    }
    /**
     * mail temps
     * @param {string} event
     * @param {string} language
     */
    static async mailtemps(event, language) {
        const mysql = {}
        const escapeData = [event]
        let row = ''
        if (language && language === 'Spanish') {
            row = 'im_40_spanish'
        } else {
            row = 'im_40_english'
        }
        const strQuery = await mysqclass.mysqli(mysql, row)
        const dataReturn = await global.mysql.query(strQuery, escapeData)
        return dataReturn
    }
    /**
     * smstemps
     * @param {string} event
     * @param {string} language
     */
    static async smstemps(event) {
        const mysql = {}
        const escapeData = [event]
        const strQuery = await mysqclass.mysqli(mysql, 'im_86')
        const dataReturn = await global.mysql.query(strQuery, escapeData)
        return dataReturn
    }
    /**
     * shorten
     * @param {object} data data
     * @param {number} num number
     */
    static shorten(data, num) {
        if (data === '' || data == null) {
            return data
        }
        const { length } = data
        const returnData = length > num ? `${data.substr(0, num - 1)}..` : data
        return returnData
    }
    /**
     * check mail notify
     * @param {object} req request object
     * @param {number} nid nid
     */
    static async checkmailnotify(req, nid) {
        const mysql = {}
        const escapeData = [req.user.id, nid]
        const strQuery = await mysqclass.mysqli(mysql, 'im_77')
        const dataReturn = await global.mysql.query(strQuery, escapeData)
        return dataReturn
    }
    /**
     * check mail notify extra
     * @param {number} uid userid
     * @param {number} nid id
     */
    static async checkmailnotifyExtra(uid, nid) {
        const mysql = {}
        const escapeData = [uid, nid]
        const strQuery = await mysqclass.mysqli(mysql, 'im_61')
        const dataReturn = await global.mysql.query(strQuery, escapeData)
        return dataReturn
    }
    /**
     * check sms notify
     * @param {object} req request
     * @param {number} nid nid
     */
    static async checksmsnotify(req, nid) {
        const mysql = {}
        const escapeData = [req.user.id, nid]
        const strQuery = await mysqclass.mysqli(mysql, 'im_78')
        const dataReturn = await global.mysql.query(strQuery, escapeData)
        return dataReturn
    }
    /**
     * check soms notify extra
     * @param {number} nid nid
     * @param {number} uid user id
     */
    static async checksmsnotifyExtra(nid, uid) {
        const mysql = {}
        const escapeData = [uid, nid]
        const strQuery = await mysqclass.mysqli(mysql, 'im_661')
        const dataReturn = await global.mysql.query(strQuery, escapeData)
        return dataReturn
    }
    /**
     * get dymanic inner contents
     * @param {object} req reuest
     * @param {object} responseData response data
     */
    static async getdynamicinnercontents(req, responseData) {
        const returnResponse = responseData
        returnResponse.totalRecords = returnResponse.totalRecords[0]
            ? returnResponse.totalRecords[0].totallength || returnResponse.totalRecords[0].length
            : 0
        let disp = (parseInt(req.body.page, 10) - 1) * req.body.limit + 1
        const afifen =
            (parseInt(req.body.page, 10) - 1) * req.body.limit + parseInt(req.body.limit, 10)
        const orgifen = afifen > returnResponse.totalRecords ? returnResponse.totalRecords : afifen
        disp = returnResponse.totalRecords === 0 ? 0 : disp
        returnResponse.setDisp = `${disp}-${orgifen}`
        return returnResponse
    }
    /**
     * get avatar loop
     * @param {object} items items
     * @param {string} folderName folder name
     */
    static async getAvatarLoop(items, folderName) {
        let itemData = items
        function changingdata(item) {
            const itemIns = item
            itemIns.avatarorg =
                item.file_name === '' || item.file_name === null
                    ? `${global.s3_static_image_url}images/pics-coming.jpg`
                    : `${global.s3_static_image_url}uploads/${folderName}/${item.file_name}`
            return itemIns
        }
        const promises = items.map(changingdata)
        itemData = await Promise.all(promises)
        return items
    }
    /**
     * get valid id
     * @param {number} editID
     */
    static getValidID(editID) {
        return typeof editID === 'undefined' || editID === 0 || editID === '0' || editID === ''
            ? null
            : editID
    }
    /**
     * table function
     * @param {object} req request
     * @param {string} baseTableUsed base table userd
     * @param {string} customTableUsed custom table used
     * @param {object} defaultAddition default addition
     * @param {array} ignoreArray ignore array
     * @param {array} customIgnoreArray custom ignore array
     * @param {commonModule.customTableFunction} object
     * @param {commonModule.baseTableFunction} object
     */
    static async tableFunction(
        req,
        baseTableUsed,
        customTableUsed,
        defaultAddition,
        ignoreArray,
        customIgnoreArray,
    ) {
        let baseTableResult = ''
        let customTableResult = ''
        ignoreArray = ignoreArray || []
        customIgnoreArray = customIgnoreArray || []
        baseTableResult = await Promise.all([
            commonModule.baseTableFunction(
                req,
                baseTableUsed,
                defaultAddition,
                (ignoreArray = req.body.id ? ['id', ...ignoreArray] : ignoreArray),
            ),
        ])
        if (customTableUsed.enabled) {
            if (customTableUsed.foreign_key) {
                if (req.body.id) {
                    req.body[customTableUsed.foreign_key] = req.body.id
                } else {
                    req.body[customTableUsed.foreign_key] = baseTableResult[0].insertId
                }
            } else if (baseTableUsed.foreign_key) {
                if (req.body.id) {
                    req.body[baseTableUsed.foreign_key] = req.body.id
                } else {
                    req.body[baseTableUsed.foreign_key] = baseTableResult[0].insertId
                }
            }

            customTableResult = await Promise.all([
                commonModule.customTableFunction(
                    req,
                    customTableUsed,
                    baseTableUsed,
                    defaultAddition,
                    (customIgnoreArray = req.body.id
                        ? ['user_id', ...customIgnoreArray]
                        : customIgnoreArray),
                ),
            ])
        }
        return [baseTableResult[0], customTableResult ? customTableResult[0] : null]
    }
    /**
     * fetch table function
     * @param {object} req request object
     * @param {string} baseTableUsed base table used
     * @param {string} customTableUsed custom table used
     * @param {string} tableName table name
     * @param {commonModule.fetchTableFunction} object
     */
    static async fetchTableFunction(req, baseTableUsed, customTableUsed, tableName) {
        const [records] = await Promise.all([
            commonModule.fetchTableFunction(req.body.id, baseTableUsed, customTableUsed, tableName),
        ])
        return [records[0]]
    }
    /**
     * fetch filtered data function
     * @param {object} req request object
     * @param {string} baseTableUsed base table used
     * @param {string} customTableUsed custom table used
     * @param {string} tableName table name
     * @param {commonModule.fetchFilteredDataFunction} object
     */
    static async fetchFilteredDataFunction(req, baseTableUsed, customTableUsed, isNoLimt) {
        const [records] = await Promise.all([
            commonModule.fetchFilteredDataFunction(req, baseTableUsed, customTableUsed, isNoLimt),
        ])
        return [records]
    }
    /**
     * date time format convert
     * @param {string} date date
     */
    static dateTimeFormatConvert(date) {
        const dataReturn = dateFormat(new Date(date), 'yyyy-mm-dd HH:MM:ss')
        return dataReturn
    }
    /**
     * date time convert
     * @param {string} date
     */
    static dateTimeConvert(date) {
        const dataReturn = dateFormat(new Date(date), 'yyyy-mm-dd HH:MM:ss')
        return dataReturn
    }
    /**
     * post all type of listing
     * @param {object} req request
     * @param {object} data data
     * @param {string} baseTableUsed base table usedd
     */
    static async postalltypeoflisting(req, data, baseTableUsed) {
        const mysqli = {}
        let escapeData = []
        const postData = data
        const acceptedObjects = baseTableUsed.array_columns
        const defaultKeys = ['created_at', 'updated_at']
        const defaultValues = [
            dateFormat(new Date(), 'yyyy-mm-dd HH:MM:ss'),
            dateFormat(new Date(), 'yyyy-mm-dd HH:MM:ss'),
        ]
        const valueInsert = commonSQL.InsertSQLFunction(
            postData,
            acceptedObjects,
            defaultKeys,
            defaultValues,
        )
        mysqli.keys = valueInsert.keys
        escapeData = valueInsert.escapeData
        mysqli.values = valueInsert.values
        mysqli.tables = baseTableUsed.ext_name
        const strQuery = await mysqclass.mysqli(mysqli, 'insert_tables')
        const dataPromise = await global.mysql.query(strQuery, escapeData)
        return dataPromise
    }
    /**
     * nofify check
     * @param {object} req request object
     */
    static async notifycheck(req) {
        const mysql = {}
        const escapeData = [req.body.refer_id, req.body.refer_field, req.body.type]
        const strQuery = await mysqclass.mysqli(mysql, 'select_from_notification_flag')
        const dataReturn = await global.mysql.query(strQuery, escapeData)
        return dataReturn
    }
    /**
     * nofify insert
     * @param {object} req request object
     */
    static async notifyinsert(req) {
        const mysql = {}
        const dateNow = dateFormat(new Date(), 'yyyy-mm-dd HH:MM:ss')
        const escapeData = [
            req.body.refer_id,
            req.body.refer_field,
            req.body.type,
            dateNow,
            1,
            req.body.isCommon ? req.body.isCommon : 0,
            req.body.notification_id ? req.body.notification_id : 0,
        ]
        const strQuery = await mysqclass.mysqli(mysql, 'insert_into_notification_flag')
        const dataReturn = await global.mysql.query(strQuery, escapeData)
        return dataReturn
    }
    /**
     * nofify insert cron
     * @param {object} wonNotify won notify
     */
    static async notifyinsertCron(wonNotify) {
        const mysql = {}
        const dateNow = dateFormat(new Date(), 'yyyy-mm-dd HH:MM:ss')
        const escapeData = [
            wonNotify.refer_id,
            wonNotify.refer_field,
            wonNotify.type,
            dateNow,
            1,
            0,
            0,
        ]
        const strQuery = await mysqclass.mysqli(mysql, 'insert_into_notification_flag')
        const dataReturn = await global.mysql.query(strQuery, escapeData)
        return dataReturn
    }
    /**
     * change data type
     * @param {object} data data
     * @param {string} type string
     */
    static changeDataType(data, type) {
        let returnData = data || ''
        if (type === 'currency') {
            returnData = customCommonFunction.currencyFormat(returnData)
        } else if (type === 'uscurrency') {
            returnData = this.currencyFormat(returnData)
        } else if (type === 'date') {
            returnData = customCommonFunction.dateFormatFunction(returnData)
        } else if (type === 'datetime') {
            returnData = customCommonFunction.dateTimeZoneFormatFunction(returnData)
        }
        return returnData
    }
    /**
     * get template phrase
     * @param {number} tID template id
     */
    static async getemplatePhrase(tID) {
        const mysql = {}
        const escapeData = [tID]
        const strQuery = await mysqclass.mysqli(mysql, 'get_template_phrase')
        const dataReturn = await global.mysql.query(strQuery, escapeData)
        return dataReturn
    }
    /**
     * get template data
     * @param {string} tName template name
     * @param {string} trigerType trigger type
     */
    static async getemplateData(tName, trigerType) {
        const mysql = {}
        const trigerType2 = trigerType || 'email'
        const escapeData = [tName, trigerType2]
        const strQuery = await mysqclass.mysqli(mysql, 'get_template_data')
        const dataReturn = await global.mysql.query(strQuery, escapeData)
        return dataReturn
    }
    /**
     * check all notify extra
     * @param {numebr} uid user id
     * @param {numebr} nid nid
     * @param {string} trigerType trigger type
     */
    static async checkallnotifyExtra(uid, nid, trigerType) {
        const mysql = {}
        let row = ''
        const escapeData = [uid, nid]
        if (trigerType === 'email') {
            row = 'im_61'
        } else {
            row = 'im_661'
        }
        const strQuery = await mysqclass.mysqli(mysql, row)
        const dataReturn = await global.mysql.query(strQuery, escapeData)
        return dataReturn
    }
    /**
     * common select parent table
     * @param {object} data data
     * @param {number} baseid base id
     * @param {number} proid project id
     * @param {string} baseTableUsed base table used
     */
    static async commonselectparenttable(data, baseid, proid, baseTableUsed) {
        const mysqli = {}
        const proId = proid.toString().split(',')
        const escapeData = [proId]
        mysqli.keys = data
        mysqli.values = `${baseid} IN (?)`
        mysqli.tables = baseTableUsed.ext_name
        mysqli.group_by = ''
        mysqli.order_by = ''
        mysqli.limit_by = ''
        const strQuery = await mysqclass.mysqli(mysqli, 'select_tables')

        const dataReturn = await global.mysql.query(strQuery, escapeData)
        return dataReturn
    }
    /**
     * get state ISO code
     * @param {string} stateName state name
     * @param {string} countryCode country code
     */
    static getStateISOCode(stateName, countryCode) {
        let dataReturn = csc
            .getStatesOfCountry(countryCode)
            .filter((inner) => inner.name === stateName)
        if (dataReturn.length) {
            dataReturn = dataReturn[0].isoCode
        } else {
            dataReturn = ''
        }

        return dataReturn
    }
    /**
     * user details
     * @param {number} id user id
     */
    static async userDetails(id) {
        const mysql = {}
        const baseTableUsed = global.configColumns.users
        const customTableUsed = global.configColumns.custom_users
        const generatedData = commonProduct.generateJoinWithColum(baseTableUsed, customTableUsed, [
            'id',
        ])
        generatedData.rowstoFetch.push('un.email as email_notification')
        generatedData.rowstoFetch.push('un.sms as sms_notification')
        generatedData.customTableJoin += ' left join user_notification as un on un.user_id = u.id'
        mysql.customTableJoin = generatedData.customTableJoin
        mysql.columns = generatedData.rowstoFetch
        mysql.mainTableJoin = generatedData.mainTableJoin
        const escapeData = [id]
        const strQuery = await mysqclass.mysqli(mysql, 'im_token')
        const data = await global.mysql.query(strQuery, escapeData)
        return data
    }
}

module.exports.default = commonFunction