admin/controllers/refund/index.js

/* ============================================================================ *\
|| ########################################################################## ||
|| # 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 axios = require('axios')

const adminRefundModule = require('../../modules/refund').default

const schemaModule = require('./schema').default
const { jsonResponse } = require('../logger')
/**
 * Get single cart details
 *
 * @memberOf adminside.refund
 * @param {adminRefundModule.allCartItems} modules
 * @param {adminRefundModule.getCartDetails} modules
 * @param {adminRefundModule.cartLocationDetails} modules
 */
const getSingleCartDetails = async (req, returnCartID) => {
    req.body.returncart_id = returnCartID
    const [cartItems, cartValues, cartLocation] = await Promise.all([
        adminRefundModule.allCartItems(req, req.body, 1),
        adminRefundModule.getCartDetails(req.body.returncart_id),
        adminRefundModule.cartLocationDetails(req.body.returncart_id),
    ])
    const responseData = { cartItems, cartValues: cartValues[0], cartLocation: cartLocation[0] }
    return responseData
}

/**
 * Get Item Pay Records
 *
 * @memberOf adminside.refund
 * @param {adminRefundModule.getPayRecords} modules
 */
const getItemPayRecords = async (items) => {
    async function changingdata(item) {
        const [payRecords] = await Promise.all([adminRefundModule.getPayRecords(item.cart_id)])
        const payItems = {
            itemId: item.item_id,
            name: item.title.substring(0, 31),
            description: item.desc_proc,
            quantity: item.qty,
            unitPrice: item.buynowamount,
            taxable: 'true',
        }

        return { payItems, payRecords, project: item }
    }
    const promises = items.map(changingdata)
    items = await Promise.all(promises)
    return items
}

/**
 * Get Item Pay Records
 *
 * @memberOf adminside.refund
 * @param {String} type
 * @param {Object} cardDetails
 * @param {Object} lineItem
 * @param {Object} cartValues
 * @param {Object} refTransId
 * @param {adminRefundModule.insertPayLogRequest} modules
 * @param {adminRefundModule.updatePayLogRequest} modules
 * @returns {Object}
 */
const generateRequestData = async (type, cardDetails, lineItem, cartValues, refTransId) => {
    let request = {}
    request.createTransactionRequest = {}
    request.createTransactionRequest.merchantAuthentication = {
        name: global.authorize.api_login_id,
        transactionKey: global.authorize.transaction_key,
    }
    const results = await Promise.all([
        adminRefundModule.insertPayLogRequest(cartValues.id, cartValues.user_id, type, 'authorize'),
    ])
    request.createTransactionRequest.refId = results[0].insertId
    request.createTransactionRequest.transactionRequest = {}
    if (type === 'priorAuthCaptureTransaction') {
        request.createTransactionRequest.transactionRequest.transactionType = type
        request.createTransactionRequest.transactionRequest.amount = cardDetails.card_amount
        request.createTransactionRequest.transactionRequest.refTransId = refTransId
    } else if (type === 'getTransactionDetailsRequest') {
        request = {}
        request.getTransactionDetailsRequest = {}
        request.getTransactionDetailsRequest.merchantAuthentication = {
            name: global.authorize.api_login_id,
            transactionKey: global.authorize.transaction_key,
        }
        request.getTransactionDetailsRequest.refId = results[0].insertId.toString()
        request.getTransactionDetailsRequest.transId = refTransId
    } else if (type === 'refundTransaction') {
        request.createTransactionRequest.transactionRequest.transactionType = type
        request.createTransactionRequest.transactionRequest.amount = cardDetails.card_amount
        request.createTransactionRequest.transactionRequest.currencyCode = 'USD'
        let cardNumber = cardDetails.card_number
        cardNumber = cardNumber.substr(cardNumber.length - 4)
        cardNumber = parseInt(cardNumber, 10)
        request.createTransactionRequest.transactionRequest.payment = {
            creditCard: {
                cardNumber,
                expirationDate: cardDetails.card_expiry,
            },
        }
        request.createTransactionRequest.transactionRequest.refTransId = refTransId

        request.createTransactionRequest.transactionRequest.lineItems = {
            lineItem,
        }
        request.createTransactionRequest.transactionRequest.tax = {
            amount: cartValues.total_tax,
            name: 'Sales Tax',
        }
        request.createTransactionRequest.transactionRequest.customer = {
            id: cartValues.user_id,
        }
        request.createTransactionRequest.transactionRequest.billTo = {
            firstName: cartValues.bill_first_name,
            lastName: cartValues.bill_first_name,
            address: cartValues.bill_address1,
            city: cartValues.bill_city,
            state: cartValues.bill_state,
            zip: cartValues.bill_zipcode,
            country: 'USA',
        }
        request.createTransactionRequest.transactionRequest.customerIP = '192.168.1.1'

        request.createTransactionRequest.transactionRequest.userFields = {
            userField: [
                {
                    name: 'refId',
                    value: results[0].insertId,
                },
            ],
        }
    } else if (type === 'refundTransactionCard') {
        request.createTransactionRequest.transactionRequest.transactionType = 'refundTransaction'
        request.createTransactionRequest.transactionRequest.amount = cardDetails.card_amount
        request.createTransactionRequest.transactionRequest.currencyCode = 'USD'
        request.createTransactionRequest.transactionRequest.payment = {
            creditCard: {
                cardNumber: cardDetails.card_number,
                expirationDate: cardDetails.card_expiry,
            },
        }
        request.createTransactionRequest.transactionRequest.lineItems = {
            lineItem,
        }
        request.createTransactionRequest.transactionRequest.tax = {
            amount: cartValues.total_tax,
            name: 'Sales Tax',
        }
        request.createTransactionRequest.transactionRequest.customer = {
            id: cartValues.user_id,
        }
        request.createTransactionRequest.transactionRequest.billTo = {
            firstName: cartValues.bill_first_name,
            lastName: cartValues.bill_first_name,
            address: cartValues.bill_address1,
            city: cartValues.bill_city,
            state: cartValues.bill_state,
            zip: cartValues.bill_zipcode,
            country: 'USA',
        }
        request.createTransactionRequest.transactionRequest.customerIP = '192.168.1.1'
    } else {
        request.createTransactionRequest.transactionRequest.transactionType = type
        request.createTransactionRequest.transactionRequest.amount = cardDetails.card_amount
        request.createTransactionRequest.transactionRequest.payment = {
            creditCard: {
                cardNumber: cardDetails.card_number,
                expirationDate: cardDetails.card_expiry,
                cardCode: cardDetails.card_cvv,
            },
        }

        request.createTransactionRequest.transactionRequest.lineItems = {
            lineItem,
        }
        request.createTransactionRequest.transactionRequest.tax = {
            amount: cartValues.total_tax,
            name: 'Sales Tax',
        }
        request.createTransactionRequest.transactionRequest.customer = {
            id: cartValues.user_id,
        }
        request.createTransactionRequest.transactionRequest.billTo = {
            firstName: cartValues.bill_first_name,
            lastName: cartValues.bill_first_name,
            address: cartValues.bill_address1,
            city: cartValues.bill_city,
            state: cartValues.bill_state,
            zip: cartValues.bill_zipcode,
            country: 'USA',
        }
        request.createTransactionRequest.transactionRequest.customerIP = '192.168.1.1'

        request.createTransactionRequest.transactionRequest.userFields = {
            userField: [
                {
                    name: 'refId',
                    value: results[0].insertId,
                },
            ],
        }
    }
    console.log('request', request)
    return request
}

const makeApiCall = async (data, type) => {
    let responseData = {}
    const url = global.authorize.endpoint
    const options = {
        method: 'POST',
        headers: { 'content-type': 'application/json' },
        data,
        url,
    }
    const response = await axios(options)
    console.log('authResponseFirstCard', response.data)
    let paymentResponse = {}
    if (type === 'getTransactionDetailsRequest') {
        paymentResponse = response.data.transaction
    } else {
        paymentResponse = response.data.transactionResponse
    }
    if (paymentResponse) {
        adminRefundModule.updatePayLogRequest(
            {
                response: JSON.stringify(paymentResponse),
                transactionID: paymentResponse.transId,
                refTransactionID: paymentResponse.refTransID,
            },
            response.data.refId,
            0,
        )
    }

    if (
        paymentResponse &&
        (parseInt(paymentResponse.responseCode, 10) === 1 ||
            parseInt(paymentResponse.responseCode, 10) === 4)
    ) {
        responseData = {
            status: 'success',
            responseType: 1,
            message: 'Payment succesfully completed!',
            responseData: { paymentResponse },
        }
    } else if (paymentResponse && paymentResponse.errors) {
        responseData = {
            status: 'error',
            responseType: 2,
            message: paymentResponse.errors[0].errorText,
        }
    } else if (response.data.messages.message.length) {
        responseData = {
            status: 'error',
            responseType: 3,
            message: response.data.messages.message[0].text,
        }
    } else {
        responseData = {
            status: 'error',
            responseType: 4,
            message: 'Payment Gateway Error.',
        }
    }
    return responseData
}

const paymentSuccess = async (cartID, userID, req) => {
    await Promise.all([
        adminRefundModule.markReturnCartPaid(cartID, 1),
        adminRefundModule.markBuyNowRefundConfirm(cartID, 1),
    ])
    const responseData = {}
    return responseData
}

const getTransactionDetails = async (items, cartDetails) => {
    async function changingdata(item) {
        const dataFirstCard = await generateRequestData(
            'getTransactionDetailsRequest',
            null,
            cartDetails.cartItems,
            cartDetails.cartValues,
            item.trans_id,
        )
        const [authResponseFirstCard] = await Promise.all([
            makeApiCall(dataFirstCard, 'getTransactionDetailsRequest'),
        ])
        return authResponseFirstCard
    }
    const promises = items.map(changingdata)
    items = await Promise.all(promises)
    return items
}

const checkTransactionDetails = async (data) => {
    const cartWithTotal = data
    const cartWithTotalObject = data.payRecords.filter((item) => {
        return parseFloat(item.amount) - parseFloat(data.project.buynowamount) > 0
    })
    cartWithTotal.payRecords = cartWithTotalObject
    return cartWithTotal
}

const checkRefundEach = async (items, cartDetails) => {
    async function refundEachItems(item) {
        const allPayRecords = await checkTransactionDetails(item)
        return allPayRecords
    }
    const promises = items.map(refundEachItems)
    items = await Promise.all(promises)
    return items
}

const refundEach = async (items, cartDetails) => {
    async function refundEachItems(item) {
        const allPayRecords = await getTransactionDetails(item.payRecords, cartDetails)
        const detailsFirstCard = {
            card_amount: cartDetails.cartValues.total_amount,
            card_number:
                allPayRecords[0].responseData.paymentResponse.payment.creditCard.cardNumber,
            card_expiry:
                allPayRecords[0].responseData.paymentResponse.payment.creditCard.expirationDate,
        }

        const captureDataFirstCard = await generateRequestData(
            'refundTransaction',
            detailsFirstCard,
            item.payItems,
            cartDetails.cartValues,
            allPayRecords[0].responseData.paymentResponse.transId,
        )
        const [captureResponseFirstCard] = await Promise.all([makeApiCall(captureDataFirstCard)])
        if (captureResponseFirstCard.status === 'success') {
            await Promise.all([
                adminRefundModule.authorizeInsertPayRecord(
                    detailsFirstCard,
                    cartDetails.cartValues,
                    captureResponseFirstCard.responseData.paymentResponse,
                ),
            ])
        }
        return captureResponseFirstCard
    }
    const promises = items.map(refundEachItems)
    items = await Promise.all(promises)
    return items
}

const shortDescribeSCH = async (items) => {
    function changingdata(item) {
        const payItems = {
            itemId: item.item_id,
            name: item.title.substring(0, 31),
            description: item.desc_proc,
            quantity: item.qty,
            unitPrice: item.buynowamount,
            taxable: 'true',
        }
        return payItems
    }
    const promises = items.map(changingdata)
    items = await Promise.all(promises)
    return items
}

module.exports = {
    /**
     * Authorize Refund
     *
     * @memberOf adminside.refund
     * @param {adminside.refund.getItemPayRecords} modules
     * @param {adminside.refund.generateRequestData} modules
     * @param {adminRefundModule.authorizeInsertPayRecord} modules
     */
    authorizeRefund: async (req, res) => {
        try {
            const [cartDetails] = await Promise.all([
                getSingleCartDetails(req, req.body.returncart_id),
            ])
            const refundItems = await getItemPayRecords(cartDetails.cartItems)
            const checkRefund = await checkRefundEach(refundItems, cartDetails)
            const refundEachItemResponse = await refundEach(checkRefund, cartDetails)
            await Promise.all([
                paymentSuccess(cartDetails.cartValues.id, cartDetails.cartValues.user_id, req),
            ])
            jsonResponse(res, 'success', refundEachItemResponse)
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 5,
                message: 'Internal Server error!',
            })
        }
    },
    /**
     * Authorize Refund With Card
     *
     * @memberOf adminside.refund
     * @param {adminside.refund.getItemPayRecords} modules
     * @param {adminside.refund.shortDescribeSCH} modules
     * @param {adminRefundModule.generateRequestData} modules
     * @param {adminRefundModule.authorizeInsertPayRecord} modules
     */
    authorizeRefundWithCard: async (req, res) => {
        try {
            const [cartDetails] = await Promise.all([
                getSingleCartDetails(req, req.body.returncart_id),
            ])

            if (cartDetails.cartValues.payment === 'card') {
                console.log('recartDetails.cartItemsfundItems', cartDetails)
                const refundItems = await getItemPayRecords(cartDetails.cartItems)
                console.log('refundItems', refundItems)
                cartDetails.cartItems = await shortDescribeSCH(cartDetails.cartItems)
                let detailsFirstCard = {}
                detailsFirstCard = {
                    card_number: cartDetails.cartValues.card_number,
                    card_expiry: cartDetails.cartValues.card_expiry,
                    card_amount: cartDetails.cartValues.total_amount,
                }

                const captureDataFirstCard = await generateRequestData(
                    'refundTransactionCard',
                    detailsFirstCard,
                    cartDetails.cartItems,
                    cartDetails.cartValues,
                )

                const [captureResponseFirstCard] = await Promise.all([
                    makeApiCall(captureDataFirstCard),
                ])

                if (captureResponseFirstCard.status === 'success') {
                    await Promise.all([
                        adminRefundModule.authorizeInsertPayRecord(
                            detailsFirstCard,
                            cartDetails.cartValues,
                            captureResponseFirstCard.responseData.paymentResponse,
                        ),
                        paymentSuccess(
                            cartDetails.cartValues.id,
                            cartDetails.cartValues.user_id,
                            req,
                        ),
                    ])
                    jsonResponse(res, captureResponseFirstCard.status, captureResponseFirstCard)
                } else {
                    jsonResponse(res, captureResponseFirstCard.status, captureResponseFirstCard)
                }
                jsonResponse(res, 'success', {
                    responseType: 1,
                    message: 'Checkout Successfully completed!',
                })
            } else if (cartDetails.cartValues.payment === 'cash') {
                await Promise.all([
                    paymentSuccess(cartDetails.cartValues.id, cartDetails.cartValues.user_id, req),
                ])
                jsonResponse(res, 'success', {
                    responseType: 1,
                    message: 'Checkout Successfully completed!',
                })
            }
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 5,
                message: 'Internal Server error!',
            })
        }
    },
}