front/controllers/product/index.js

/* eslint-disable consistent-return */
/* eslint-disable no-nested-ternary */
/* ============================================================================ *\
|| ########################################################################## ||
|| # Auction Software Marketplace          Release: 0.6   Build 0.7         # ||
|| # ---------------------------------------------------------------------- # ||
|| # License # 35YAHCNR9344X6O666C123AB                                     # ||
|| # ---------------------------------------------------------------------- # ||
|| # Copyright ©2014–2021 Develop Scripts LLC. All Rights Reserved          # ||
|| # This file may not be redistributed in whole or significant part.       # ||
|| # ------------- AUCTION SOFTWARE IS NOT FREE SOFTWARE ------------------ # ||
|| # http://www.auctionsoftwaremarketplace.com|support@auctionsoftware.com  # ||
|| # ---------------------------------------------------------------------- # ||
|| ########################################################################## ||
\* ============================================================================ */

/* eslint-disable prefer-destructuring */
/* eslint-disable no-param-reassign */
const jwt = require('jsonwebtoken')
const request = require('request')

const productModule = require('../../modules/product').default
const auctionModule = require('../../modules/auction').default
// const auctionController = require('../auction/index');
const commonFunction = require('../../../common/function').default
const schemaModule = require('./schema').default
const { jsonResponse, errorResponse } = require('../logger')
const ttwBidModule = require('../../modules/ttwBid').default
const Chartmetric = require('../../modules/chartmetric').default

/**
 * Sort values in the format for frontend
 *
 * @memberOf frontend.product
 * @param {object} sortValues sortValues which has to be fetched
 * @param {object} responseData All response which is to be filtered
 */
const getSortValues = async (sortValues, responseData) => {
    const returnResponse = responseData
    returnResponse.sorts = {}

    const processAllItems = async (items) => {
        const tableValue = global.configColumns[items]
        if (tableValue.search && tableValue.enabled) {
            returnResponse.sorts[`sort${tableValue.ext_name}`] = sortValues[0][
                `sort${tableValue.ext_name}`
            ]
                ? sortValues[0][`sort${tableValue.ext_name}`].split(',')
                : []
        }
    }

    await commonFunction.asyncForEach(Object.keys(global.configColumns), async (element) => {
        await processAllItems(element)
    })
    return returnResponse
}

/**
 * Get Dynamic contects for the pagination for frontend
 *
 * @memberOf frontend.product
 * @param {object} req req data with images which has to be uploaded
 * @param {number} sortValues Sort values
 * @param {number} responseData response Data which has to be retrieved
 */
const getdynamicinnercontents = async (req, sortValues, responseData) => {
    let returnResponse = responseData
    returnResponse.totalRecords = returnResponse.totalRecords[0]
        ? returnResponse.totalRecords[0].totallength
        : 0
    if (sortValues) {
        returnResponse = await getSortValues(sortValues, responseData)
    }

    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
}

/**
 * Add image link to the data
 *
 * @memberOf frontend.product
 * @param {array} items Items array in which image url is added to the name
 */
const shortDescribeSCHOnlyAvatar = async (items) => {
    function changingdata(item) {
        item.avatarorg =
            item.file_name === '' || item.file_name === null
                ? `${global.s3_static_image_url}images/pics-coming.jpg`
                : `${global.s3_static_image_url}uploads/product/${item.file_name}`
        return item
    }
    const promises = items.map(changingdata)
    items = await Promise.all(promises)
    return items
}

/**
 * Array of elements which add all bidding data
 *
 * @memberOf frontend.product
 * @param {object} req req object
 * @param {array} items Items array in which image url is added to the name
 */
const shortDescribeSCH = async (req, items) => {
    async function changingdata(item) {
        const userId = req.user ? req.user.id : 0
        const productId = item.id

        const [
            // results0,
            results1,
            results2,
            results4,
            results5,
            results6,
            results7,
        ] = await Promise.all([
            // productModule.fetchAllAttachments(productId),
            productModule.checkbidPlacedwhoutlogin(productId),
            productModule.getProxyDetails(productId, 'get_highest_biduser'),
            productModule.bidsawarded(productId, userId),
            productModule.getUserProxyAmt(productId, userId),
            productModule.isbuyerbidstarted(productId, userId),
            productModule.bidHistory(productId, 0),
        ])
        item.bidwinneruser = 0
        item.proxy_bid_details = results2[0]

        item.bid_or_not = results6.length
        item.biddercurrentbid = results6.length > 0 ? results6[0].proposed_amount : 0
        item.bidderproxyant = 0
        if (results5.length > 0) {
            if (results5[0].prev_maxamount) {
                item.bidderproxyant = results5[0].prev_maxamount
            }
        }

        item.current_bid = item.wprice
        item.incrementamt = commonFunction.calculateArrayIncrement(item.current_bid)
        if (results1.length > 0) {
            item.cbidtext = item.market_status !== 'open' ? 'Sold Price' : 'Current Price'
            item.next_bid = commonFunction.sumFloat(item.wprice, item.incrementamt)
        } else {
            item.cbidtext = item.market_status !== 'open' ? 'Sold Price' : 'Starting Price'
            item.next_bid = commonFunction.sumFloat(item.wprice, 0)
        }
        if (results1.length > 0 && typeof req.user !== 'undefined') {
            if (results1.length > 0 && item.proxy_bid_details.user_id === req.user.id) {
                item.incrementamt = commonFunction.calculateArrayIncrement(
                    item.proxy_bid_details.maxamount,
                )
                item.next_bid = commonFunction.sumFloat(
                    item.proxy_bid_details.maxamount,
                    item.incrementamt,
                )
            } else if (results1[0].user_id === req.user.id) {
                item.next_bid = commonFunction.sumFloat(item.wprice, item.incrementamt)
            }
        }

        if (results6.length > 0 && results2.length > 0) {
            if (item.auctiontype === 'live') {
                if (item.proxy_bid_details.user_id === req.user.id) {
                    if (item.market_status === 'open') {
                        if (item.wprice < item.proxy_bid_details.maxamount) {
                            item.bidtopstatus = 'winner'
                        } else {
                            item.bidtopstatus = 'winner'
                        }
                    } else if (item.booked === 1) {
                        item.bidwinneruser = item.buynowed !== req.user.id ? 0 : 1
                        item.bidtopstatus = item.buynowed !== req.user.id ? 'lost' : 'won'
                    } else {
                        item.bidwinneruser = results4.length === 0 ? 0 : 1
                        item.bidtopstatus = results4.length === 0 ? 'lost' : 'won'
                    }
                } else if (item.market_status === 'open') {
                    if (
                        results6[0].proposal === 'tie_bid' &&
                        results6[0].proposed_amount === item.proxy_bid_details.maxamount
                    ) {
                        item.bidtopstatus = 'outbid'
                    } else {
                        item.bidtopstatus = 'outbid'
                    }
                } else if (item.booked === 1) {
                    item.bidwinneruser = item.buynowed !== req.user.id ? 0 : 1
                    item.bidtopstatus = item.buynowed !== req.user.id ? 'lost' : 'won'
                } else {
                    item.bidwinneruser = results4.length === 0 ? 0 : 1
                    item.bidtopstatus = results4.length === 0 ? 'lost' : 'won'
                }
            } else {
                item.bidtopstatus = ''
            }
        } else {
            item.bidtopstatus = ''
        }

        item.avatarorg =
            item.file_name === '' || item.file_name === null
                ? `${global.s3_static_image_url}images/pics-coming.jpg`
                : `${global.s3_static_image_url}uploads/product/${item.file_name}`

        // item.allattachmentlist = results0
        item.bid_count = results7.length
        item.bidhistory = results7
        return item
    }
    const promises = items.map(changingdata)
    items = await Promise.all(promises)
    return items
}

const getAttachmentList = async (req, items) => {
    async function changingdata(item) {
        const productId = item.id
        const [results0] = await Promise.all([productModule.fetchAllAttachments(productId)])
        item.allattachmentlist = results0
        return item
    }
    const promises = items.map(changingdata)
    items = await Promise.all(promises)
    return items
}

const getItemPropsArray = async (req, records) => {
    if (records.length) {
        const baseTableUsed = global.configColumns.itemPropsArray
        const customTableUsed = { enabled: 0 }
        const chartmetric = new Chartmetric()

        await commonFunction.asyncForEach(records, async (value, indexRec) => {
            const [[record]] = await Promise.all([
                commonFunction.fetchFilteredDataFunction(
                    {
                        ...req,
                        ...{
                            body: {
                                ...value,
                                filters: {
                                    project_id: {
                                        value: value.id,
                                        field: 'ipa.project_id',
                                        type: 'in',
                                    },
                                    is_deleted: {
                                        value: 1,
                                        field: 'ipa.is_deleted',
                                        type: 'notin',
                                    },
                                },
                            },
                        },
                    },
                    baseTableUsed,
                    customTableUsed,
                ),
            ])
            if (indexRec === 0 && (!req.body.from || req.body.from !== 'search')) {
                await commonFunction.asyncForEach(record, async (value, index) => {
                    if (index === 0 && value.track_id) await chartmetric.getToken()
                    if (value.track_id)
                        record[index] = {
                            ...value,
                            chartmetric: await chartmetric.getTrackInfo({
                                track_id: value.track_id,
                            }),
                        }
                })
            }
            value.itemPropsArray = record
            return value
        })

        return records
    }
    return records
}

/**
 * Get all Return Invoice Details
 *
 * @memberOf frontend.product
 * @param {object} req req object
 * @param {productModule.allReturnInvoiceItems} modules
 * @param {productModule.getReturnInvoiceCartDetails} modules
 * @param {productModule.getAllReturnTransactions} modules
 * @param {productModule.getReturnAppointmentDetails} modules
 * @param {productModule.getReturnLocationDetails} modules
 * @param {array} items Items array in which image url is added to the name
 */
const getReturnInvoiceDetails = async (req) => {
    let responseData = {}
    let [invoiceItems] = await Promise.all([productModule.allReturnInvoiceItems(req, req.body, 1)])
    if (invoiceItems.length > 0) {
        req.body.returncart_id = invoiceItems[0].returncart_id
        const [cartValues, allTransactions, appointmentDetail, locationDetail] = await Promise.all([
            productModule.getReturnInvoiceCartDetails(req.body.returncart_id),
            productModule.getAllReturnTransactions(req.body.returncart_id),
            productModule.getReturnAppointmentDetails(req.body.returncart_id),
            productModule.getReturnLocationDetails(req.body.returncart_id),
        ])
        invoiceItems = await shortDescribeSCHOnlyAvatar(invoiceItems)
        responseData = {
            status: 'success',
            responseType: 1,
            message: 'Invoice items retrieved!',
            responseData: {
                invoiceItems,
                cartValues: cartValues[0],
                allTransactions,
                appointmentDetail: appointmentDetail[0],
                locationDetail: locationDetail[0],
            },
        }
    } else {
        responseData = {
            status: 'error',
            responseType: 2,
            message: 'No record found!',
        }
    }
    return responseData
}

/**
 * Get all Invoice Details
 *
 * @memberOf frontend.product
 * @param {object} req req object
 * @param {productModule.getInvoiceCartDetails} modules
 * @param {productModule.getAllTransactions} modules
 * @param {productModule.getAppointmentDetails} modules
 * @param {productModule.getLocationDetails} modules
 * @param {array} items Items array in which image url is added to the name
 */
const getInvoiceDetails = async (req) => {
    let responseData = {}
    let [invoiceItems] = await Promise.all([productModule.allInvoiceItems(req, req.body, 1)])
    if (invoiceItems.length > 0) {
        req.body.cart_id = invoiceItems[0].cart_id
        const [cartValues, allTransactions, appointmentDetail, locationDetail] = await Promise.all([
            productModule.getInvoiceCartDetails(req.body.cart_id),
            productModule.getAllTransactions(req.body.cart_id),
            productModule.getAppointmentDetails(req.body.cart_id),
            productModule.getLocationDetails(req.body.cart_id),
        ])
        invoiceItems = await shortDescribeSCHOnlyAvatar(invoiceItems)
        responseData = {
            status: 'success',
            responseType: 1,
            message: 'Invoice items retrieved!',
            responseData: {
                invoiceItems,
                cartValues: cartValues[0],
                allTransactions,
                appointmentDetail: appointmentDetail[0],
                locationDetail: locationDetail[0],
            },
        }
    } else {
        responseData = {
            status: 'error',
            responseType: 2,
            message: 'No record found!',
        }
    }
    return responseData
}

const auctionWatchList = async (items, userID) => {
    const itemsChanged = []
    const getProjectID = async (item) => {
        const [projectID] = await Promise.all([
            auctionModule.getAuctionWatchListDetails(item.auctionlot_id, userID),
        ])
        item.following_auction =
            typeof projectID[0] !== 'undefined' ? projectID[0].following_auction : 0
        itemsChanged.push(item)
        return true
    }
    await commonFunction.asyncForEach(items, async (element) => {
        await getProjectID(element)
    })
    return itemsChanged
}

const dashboardFunction = async (req) => {
    await schemaModule.search().validateSync(req.body)
    let [records, totalRecords, sortValues] = await Promise.all([
        productModule.searchDashboardProducts(req, req.body, 1),
        productModule.searchDashboardProducts(req, req.body, 0),
        productModule.getSearchSortCategories(req, req.body),
    ])
    totalRecords = [{ totallength: totalRecords.length }]
    let responseData = { records, totalRecords }
    records = await getAttachmentList(req, records)
    records = await shortDescribeSCH(req, records)
    responseData = await getdynamicinnercontents(req, sortValues, responseData)
    return responseData
}

const ttwDashboardFunction = async (req) => {
    await schemaModule.search().validateSync(req.body)
    let [records, totalRecords, sortValues] = await Promise.all([
        productModule.ttwSearchDashboardProducts(req, req.body, 1),
        productModule.ttwSearchDashboardProducts(req, req.body, 0),
        productModule.getSearchSortCategories(req, req.body),
    ])
    // records = await getTTWBids(req,records)
    let responseData = { records, totalRecords }
    records = await getAttachmentList(req, records)
    records = await shortDescribeSCH(req, records)
    responseData = await getdynamicinnercontents(req, sortValues, responseData)
    return responseData
}

const ttwBidAsc = async (item, user_id = 0) => {
    const arrayList = []
    const masterEntry = []
    const dublicate = []
    let masterQty = 0
    let currentBidIncrement = item.sprice || 10
    const isUserHaveHardBid = []
    const [bids] = await Promise.all([ttwBidModule.ttwBidDetail(item.id)])
    return new Promise(async (reslove) => {
        if (bids.length === 0) {
            reslove({
                bids: [],
                masterQty: 0,
                masterEntry: [],
                currentBidIncrement,
                isUserHaveHardBid,
            })
            return true
        }
        const finder = (list, parent) => {
            if (parent === 0) {
                reslove({
                    bids: arrayList,
                    masterQty,
                    masterEntry,
                    currentBidIncrement,
                    isUserHaveHardBid,
                })
                return true
            }
            const child = list.find((x) => x.id === parent)
            if (child && bids[0].bid_position === child.bid_position) {
                masterQty += child.proposed_amount
                masterEntry.push(child)
            }
            if (child) arrayList.push(child)
            if (!child || dublicate.indexOf(child.rgt) > -1) {
                reslove({
                    bids: arrayList,
                    masterQty,
                    masterEntry,
                    currentBidIncrement,
                    isUserHaveHardBid,
                })
                return false
            }
            dublicate.push(child.rgt)

            if (child && child.proposal === 'hard') isUserHaveHardBid.push(child.user_id)
            if (arrayList.length !== bids.length) {
                finder(bids, arrayList[arrayList.length - 1].rgt)
            } else {
                reslove({
                    bids: arrayList,
                    masterQty,
                    masterEntry,
                    currentBidIncrement,
                    isUserHaveHardBid,
                })
            }
        }
        masterQty += bids[0].proposed_amount
        currentBidIncrement = bids[0].currentbid_increment
        if (bids[0].proposal === 'hard') isUserHaveHardBid.push(bids[0].user_id)
        masterEntry.push(bids[0])
        arrayList.push(bids[0])
        finder(bids, arrayList[arrayList.length - 1].rgt)
    })
}

const featureProxyList = (data, itrate = 2, reverser = false) => {
    return new Promise(async (reslove) => {
        const [proxyItems] = await Promise.all([ttwBidModule.getttwproxybid(data)])
        const featureProxy = { bids: {}, users: [] }
        let cuserRealtimeIncerment = data.currentbid_increment

        await commonFunction.asyncForEach([...Array(itrate).keys()], async (_, index) => {
            const tempProxy = proxyItems
            if (index && !reverser)
                cuserRealtimeIncerment += commonFunction.calculateArrayIncrement(data.bid_position)

            if (reverser) {
                const temList = await tempProxy.filter((bid) => bid.user_id === data.user_id)
                let qty = 0
                commonFunction.asyncForEach(proxyItems, (itemData) => {
                    if (temList.length && temList[0].maxamount <= itemData.maxamount) {
                        featureProxy.bids[temList[0].maxamount] = featureProxy.bids[
                            temList[0].maxamount
                        ]
                            ? featureProxy.bids[temList[0].maxamount]
                            : []
                        featureProxy.bids[temList[0].maxamount].push(itemData)
                        featureProxy.users.push(temList[0].user_id)
                        qty += temList[0].maxqty
                    }
                    featureProxy.masterQty = qty
                })
            } else {
                const temList = await tempProxy.filter(
                    (bid) => bid.maxamount >= cuserRealtimeIncerment,
                )
                if (temList.length) featureProxy.bids[cuserRealtimeIncerment] = temList
                if (
                    featureProxy.bids[cuserRealtimeIncerment] &&
                    featureProxy.bids[cuserRealtimeIncerment].length
                )
                    featureProxy.users = await featureProxy.bids[cuserRealtimeIncerment].map(
                        (bid) => bid.user_id,
                    )
            }
        })
        reslove(featureProxy)
    })
}

const ttwBidsObject = (req, obj) => {
    const resultObj = {}
    const curreTotal = {}
    const userBidTotal = {}
    return new Promise(async (reslove) => {
        await commonFunction.asyncForEach(obj.ttwBids, (bid) => {
            resultObj[bid.currentbid_increment] = resultObj[bid.currentbid_increment]
                ? resultObj[bid.currentbid_increment]
                : []
            resultObj[bid.currentbid_increment].push(bid)
            //
            curreTotal[bid.currentbid_increment] = curreTotal[bid.currentbid_increment]
                ? curreTotal[bid.currentbid_increment]
                : 0
            if (req.user && req.user.id === bid.user_id)
                curreTotal[bid.currentbid_increment] += bid.init_proposed_amount
            else curreTotal[bid.currentbid_increment] += bid.proposed_amount

            userBidTotal[bid.user_id] = userBidTotal[bid.user_id] ? userBidTotal[bid.user_id] : 0
            userBidTotal[bid.user_id] += bid.proposed_amount
        })
        reslove({ bidListObj: resultObj, bidTotalObj: curreTotal, userBidTotal })
    })
}

const getTTWBids = async (req, items, isHistory = false) => {
    async function getTtwBids(item) {
        let {
            bids,
            masterQty,
            masterEntry,
            currentBidIncrement,
            isUserHaveHardBid,
        } = await ttwBidAsc(item, req.user ? req.user.id : 0)
        const tepmPosition = bids.length ? bids[0].bid_position : 0
        const featureProxy = await featureProxyList(
            {
                id: item.id,
                bid_position: tepmPosition,
                currentbid_increment:
                    masterQty <= item.qty
                        ? currentBidIncrement + commonFunction.calculateArrayIncrement(tepmPosition)
                        : currentBidIncrement,
                user_id: req.user ? req.user.id : 0,
            },
            1,
            true,
        )
        item.proxy_bid_details = featureProxy
        item.isUserHaveHardBid = isUserHaveHardBid
        item.ttwBids = bids || []
        item.masterQty = masterQty === item.qty ? 0 : masterQty
        item.currentbid_increment = isHistory
            ? item.currentbid_increment
            : masterQty === item.qty && bids.length
            ? (currentBidIncrement += commonFunction.calculateArrayIncrement(bids[0].bid_position))
            : currentBidIncrement
        item.next_currentbid_increment =
            item.currentbid_increment +
            commonFunction.calculateArrayIncrement(bids.length ? bids[0].bid_position : 1)

        const { bidListObj, bidTotalObj, userBidTotal } = await ttwBidsObject(req, item)
        item.ttwBidsObject = bidListObj
        item.ttwBidsTotalObject = bidTotalObj
        item.userBidTotal = userBidTotal
        item.myBids = []

        if (item.auctiontype === 'ttw') {
            const [ttwRecord, myBids] = await Promise.all([
                productModule.ttwBidHistory({ body: { id: item.id } }, 1),
                productModule.ttwBidHistory(
                    {
                        body: {
                            id: item.id,
                            user_id: req.user ? req.user.id : 0,
                            limit: 5,
                            page: 1,
                        },
                    },
                    0,
                ),
            ])
            item.bid_count = ttwRecord.length
            item.myBids = myBids

            if (item.market_status === 'sold' && item.myBids.length) {
                const isWon = item.myBids.filter((bid) => bid.proposed_amount > 0)
                item.bidtopstatus = isWon.length ? 'won' : 'lost'
            }
        }
        if (item.market_status === 'sold') {
            const [secondHighestBid] = await Promise.all([
                productModule.getSecondHighestBidderTTW(item.id),
            ])
            item.buynowamount =
                secondHighestBid.length && secondHighestBid[0].currentbid_increment
                    ? secondHighestBid[0].currentbid_increment
                    : item.wprice
        }

        if (req.user && req.user.id)
            item.proxy_data = req.session[`${item.id}proxybid${req.user.id}`]

        item.isPublicVisible = true
        item.isPrivateVisible = false
        item.qty = item.qty
        if (item.ttw_offer_project_id) {
            const isIn = await ttwBidModule.ttwWinners({ ...req, id: item.ttw_offer_project_id })
            item.isPublicVisible = new Date(item.public_start_date) <= new Date()

            if (isIn.length && !(new Date(item.public_start_date) <= new Date())) {
                item.privateQty = 0
                isIn.forEach((data) => {
                    item.privateQty +=
                        data.update_proposed_amount > 0
                            ? data.update_proposed_amount
                            : data.proposed_amount
                })
            }

            item.isPrivateVisible = isIn.length > 0 && new Date(item.date_added) <= new Date()

            if (item.isPrivateVisible) {
                const soldQty = await productModule.getPrivateSoldQty(req, item.id)
                item.privateSold = soldQty.length && soldQty[0].qty ? soldQty[0].qty : 0
                item.privateBooked = 0
            }
        }
        item.masterEntry =
            masterQty < item.qty
                ? [
                      ...masterEntry,
                      {
                          proposed_amount: item.qty - masterQty,
                          currentbid_increment: masterEntry.length ? item.currentbid_increment : 10,
                          id: 0,
                      },
                  ]
                : masterQty
        return item
    }
    const promises = items.map(getTtwBids)
    items = await Promise.all(promises)
    return items
}

module.exports = {
    dashboardFunction,
    /**
     * Search Product
     *
     * @memberOf frontend.product
     * @param {productModule.searchProducts} modules
     * @param {productModule.getSearchSortCategories} modules
     */
    search: async (req, res) => {
        try {
            await schemaModule.search().validateSync(req.body)
            let [records, totalRecords, sortValues] = await Promise.all([
                productModule.searchProducts(req, req.body, 1),
                productModule.searchProducts(req, req.body, 0),
                productModule.getSearchSortCategories(req, req.body),
            ])
            let responseData = { records, totalRecords }
            records = await getAttachmentList(req, records)
            if (typeof global.configFeatures.itemPropsArray !== 'undefined') {
                if (parseInt(global.configFeatures.itemPropsArray.enabled, 10) === 1) {
                    records = await getItemPropsArray(req, records)
                }
            }
            if (
                global.configFeatures.load_bidding_details &&
                global.configFeatures.load_bidding_details.enabled
            ) {
                records = await shortDescribeSCH(req, records)
            }
            if (
                global.configFeatures.load_ttw_bidding_details &&
                global.configFeatures.load_ttw_bidding_details.enabled
            ) {
                records = await getTTWBids(req, records)
            }
            if (
                global.configFeatures.auction_watch_list &&
                global.configFeatures.auction_watch_list.enabled
            ) {
                const userID = typeof req.user !== 'undefined' ? req.user.id : 0
                records = await auctionWatchList(records, userID)
            }
            responseData = await getdynamicinnercontents(req, sortValues, responseData)
            jsonResponse(res, 'success', {
                responseType: 1,
                message: 'Details successfully retrieved!',
                responseData,
            })
        } catch (e) {
            errorResponse(e, res)
        }
    },
    /**
     * Get Active Sorts Details
     *
     * @memberOf frontend.product
     * @param {frontend.product.getSortValues} modules
     * @param {productModule.getSearchSortCategories} modules
     */
    activeSorts: async (req, res) => {
        try {
            await schemaModule.search().validateSync(req.body)
            const [sortValues] = await Promise.all([
                productModule.getSearchSortCategories(req, req.body),
            ])
            let responseData = {}
            responseData = await getSortValues(sortValues, responseData)
            jsonResponse(res, 'success', {
                responseType: 1,
                message: 'Details successfully retrieved!',
                responseData,
            })
        } catch (e) {
            errorResponse(e, res)
        }
    },
    /**
     * Get Invoice details
     *
     * @memberOf frontend.product
     * @param {frontend.product.getInvoiceDetails} modules
     */
    invoice: async (req, res) => {
        try {
            await schemaModule.search().validateSync(req.body)
            const [responseData] = await Promise.all([getInvoiceDetails(req)])
            jsonResponse(res, responseData.status, responseData)
        } catch (e) {
            errorResponse(e, res)
        }
    },
    /**
     * Get Return Invoice details
     *
     * @memberOf frontend.product
     * @param {frontend.product.getReturnInvoiceDetails} modules
     */
    returninvoice: async (req, res) => {
        try {
            await schemaModule.search().validateSync(req.body)
            const [responseData] = await Promise.all([getReturnInvoiceDetails(req)])
            jsonResponse(res, responseData.status, responseData)
        } catch (e) {
            errorResponse(e, res)
        }
    },
    /**
     * Get Dashboard details
     *
     * @memberOf frontend.product
     * @param {productModule.searchDashboardProducts} modules
     * @param {productModule.getSearchSortCategories} modules
     */
    dashboard: async (req, res) => {
        try {
            const [responseData] = await Promise.all([dashboardFunction(req)])
            jsonResponse(res, 'success', {
                responseType: 1,
                message: 'Details successfully retrieved!',
                responseData,
            })
        } catch (e) {
            errorResponse(e, res)
        }
    },
    /**
     * Get All Invoice
     *
     * @memberOf frontend.product
     * @param {productModule.searchInvoiceProductsNew} modules
     */
    allinvoices: async (req, res) => {
        try {
            await schemaModule.search().validateSync(req.body)
            const [records, totalRecords] = await Promise.all([
                productModule.searchInvoiceProductsNew(req, req.body, 1),
                productModule.searchInvoiceProductsNew(req, req.body, 0),
            ])
            let responseData = { records, totalRecords }
            responseData = await getdynamicinnercontents(req, null, responseData)
            jsonResponse(res, 'success', {
                responseType: 1,
                message: 'Details successfully retrieved!',
                responseData,
            })
        } catch (e) {
            errorResponse(e, res)
        }
    },
    /**
     * Get All Returns
     *
     * @memberOf frontend.product
     * @param {productModule.searchReturnProducts} modules
     */
    allreturns: async (req, res) => {
        try {
            await schemaModule.search().validateSync(req.body)
            const [records, totalRecords] = await Promise.all([
                productModule.searchReturnProducts(req, req.body, 1),
                productModule.searchReturnProducts(req, req.body, 0),
            ])
            let responseData = { records, totalRecords }
            responseData = await getdynamicinnercontents(req, null, responseData)
            jsonResponse(res, 'success', {
                responseType: 1,
                message: 'Details successfully retrieved!',
                responseData,
            })
        } catch (e) {
            errorResponse(e, res)
        }
    },
    /**
     * Get All Bid History
     *
     * @memberOf frontend.product
     * @param {productModule.bidHistoryViewPage} modules
     */
    bidhistory: async (req, res) => {
        let records = []
        let totalRecords = []
        try {
            ;[records, totalRecords] = await Promise.all([
                productModule.bidHistoryViewPage(req, 0),
                productModule.bidHistoryViewPage(req, 1),
            ])
            if (typeof global.configurations.variables.bid_history_email !== 'undefined') {
                if (parseInt(global.configurations.variables.bid_history_email, 10) === 1) {
                    records.map((bid) => {
                        bid.name_secret = `${bid.email[0]}`
                        return bid
                    })
                } else {
                    records.map((bid) => {
                        bid.name_secret = `${bid.first_name[0]}***${
                            bid.last_name[bid.last_name.length - 1]
                        }`
                        return bid
                    })
                }
            } else {
                records.map((bid) => {
                    bid.name_secret = `${bid.first_name[0]}***${
                        bid.last_name[bid.last_name.length - 1]
                    }`
                    return bid
                })
            }

            totalRecords = [{ totallength: totalRecords.length }]
        } catch (e) {
            errorResponse(e, res)
        } finally {
            let responseData = { records, totalRecords }
            responseData = await getdynamicinnercontents(req, null, responseData)
            jsonResponse(res, 'success', {
                responseType: 1,
                message: 'Details successfully retrieved!',
                responseData,
            })
        }
    },
    /**
     * Get All Bid History
     *
     * @memberOf frontend.product
     * @param {productModule.bidHistoryViewPage} modules
     */
    ttwBidhistory: async (req, res) => {
        let records = []
        let totalRecords = []
        try {
            ;[records, totalRecords] = await Promise.all([
                productModule.ttwBidHistory(req, 0),
                productModule.ttwBidHistory(req, 1),
            ])
            if (records.length) {
                records = await getTTWBids(req, records, true)
                records.map((bid) => {
                    const firstName =
                        bid.first_name && bid.first_name.length ? bid.first_name[0] : ''
                    const lastName =
                        bid.last_name && bid.last_name.length
                            ? bid.last_name[bid.last_name.length - 1]
                            : ''
                    bid.name_secret = `${firstName}***${lastName}`
                    return bid
                })
            }

            totalRecords = [{ totallength: totalRecords.length }]
        } catch (e) {
            errorResponse(e, res)
        } finally {
            let responseData = { records, totalRecords }
            responseData = await getdynamicinnercontents(req, null, responseData)
            jsonResponse(res, 'success', {
                responseType: 1,
                message: 'Details successfully retrieved!',
                responseData,
            })
        }
    },

    ttwDashboard: async (req, res) => {
        try {
            const [responseData] = await Promise.all([ttwDashboardFunction(req)])
            responseData.records = await getTTWBids(req, responseData.records, true)
            jsonResponse(res, 'success', {
                responseType: 1,
                message: 'Details successfully retrieved!',
                responseData,
            })
        } catch (e) {
            errorResponse(e, res)
        }
    },
}

module.exports.biddingDetails = shortDescribeSCH