front/controllers/shipping/arta/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 FormData = require('form-data')
const cartCommonCtrl = require('../../cart/common')
const buynowCommonCtrl = require('../../buynow/common')
const artaCommonCtrl = require('./common')

const commonFunction = require('../../../../common/function').default

const artaShippingModule = require('../../../modules/shipping/arta').default
const userController = require('../../user')

let artaShipping = {
    enabled: 0,
}
if (require('config').has('artaShipping')) {
    artaShipping = require('config').get('artaShipping')
}

const schemaModule = require('./schema').default
const { jsonResponse } = require('../../logger')
/**
 *apiCall
 *
 * @memberOf frontend.payment.northcapital
 * @param {string} method method (post, get, etc..)
 * @param {string} url requsturl
 * @param {object} data request data
 * @param {object} headertype header type
 * @param {string} baseurl base url
 *  matches method with response
 */
const apiCall = async (method, url, data, headertype, baseurl) => {
    let responseData = {}
    let siteUrl = `${artaShipping.url}/`
    if (baseurl) {
        siteUrl = `${artaShipping.url}/${baseurl}/`
    }

    let type = ''
    let headers = {}

    if (headertype && headertype === 'formdata') {
        type = 'multipart/form-data'
        headers = {
            ...headers,
            ...data.getHeaders(),
        }
    } else {
        type = 'application/json'
    }

    headers = {
        ...headers,
        'content-type': type,
        Authorization: `ARTA_APIKey ${artaShipping.apiKey}`,
    }

    const options = {
        method,
        headers,
        data,
        url: `${siteUrl}${url}`,
    }
    console.log('options', options)
    try {
        const axiosResponse = await axios(options)
        console.log('axiosResponse', axiosResponse)
        console.log('axiosResponse.status', axiosResponse.status)
        if (axiosResponse.status === 200 || axiosResponse.status === 201) {
            console.log('axiosResponse Success', axiosResponse.data.quote_types)
            console.log('axiosResponse Success', axiosResponse.data.quotes)
            responseData = {
                status: 'success',
                responseType: 1,
                message: 'Details successfully retrieved!',
                responseData: axiosResponse.data,
            }
        } else {
            responseData = {
                status: 'error',
                responseType: 4,
                message: 'Ship Engine Error.',
                responseData: { error: axiosResponse.data.errors },
            }
        }
    } catch (err) {
        console.log('axiosResponse', err.response.data)
        responseData = {
            status: 'error',
            responseType: 4,
            message: 'Arta Shipping Error.',
            responseData: { error: err.response.data.errors },
        }
    }
    return responseData
}
/**
 * generate Request Data
 *
 * @memberOf frontend.shipping.arta
 * @param {refundModule.insertPayLogRequest} method
 */
const metadataObjects = async () => {
    const formData = {}
    const [responseData] = await Promise.all([apiCall('get', 'objects', formData, '', 'metadata')])
    return responseData
}
/**
 * meta data insurance
 *
 * @memberOf frontend.shipping.arta
 * @param {frontend.shipping.arta.apiCall} method
 */
const metadataInsurances = async () => {
    const formData = {}
    const [responseData] = await Promise.all([
        apiCall('get', 'insurances', formData, '', 'metadata'),
    ])
    return responseData
}
/**
 * metadata access restrictions
 *
 * @memberOf frontend.shipping.arta
 * @param {frontend.shipping.arta.apiCall} method
 */
const metadataAccessRestrictions = async () => {
    const formData = {}
    const [responseData] = await Promise.all([
        apiCall('get', 'location_access_restrictions', formData, '', 'metadata'),
    ])
    return responseData
}
/**
 * meta data packing
 *
 * @memberOf frontend.shipping.arta
 * @param {frontend.shipping.arta.apiCall} method
 */
const metadataPackings = async () => {
    const formData = {}
    const [responseData] = await Promise.all([apiCall('get', 'packings', formData, '', 'metadata')])
    return responseData
}
/**
 * meta data quotes
 *
 * @memberOf frontend.shipping.arta
 * @param {frontend.shipping.arta.apiCall} method
 */
const metadataQuotes = async () => {
    const formData = {}
    const [responseData] = await Promise.all([apiCall('get', 'quotes', formData, '', 'metadata')])
    return responseData
}
/**
 * meta data quotes
 *
 * @memberOf frontend.shipping.arta
 * @param {frontend.shipping.arta.apiCall} method
 */
const metadataServices = async () => {
    const formData = {}
    const [responseData] = await Promise.all([apiCall('get', 'services', formData, '', 'metadata')])
    return responseData
}
/**
 * ransport metadata
 *
 * @memberOf frontend.shipping.arta
 * @param {frontend.shipping.arta.apiCall} method
 */
const metadataTransport = async () => {
    const formData = {}
    const [responseData] = await Promise.all([
        apiCall('get', 'parcel_transport_services', formData, '', 'metadata'),
    ])
    return responseData
}
/**
 * objectMaterials metadata
 *
 * @memberOf frontend.shipping.arta
 * @param {frontend.shipping.arta.apiCall} method
 */
const metadataObjectMaterials = async () => {
    const formData = {}
    const [responseData] = await Promise.all([
        apiCall('get', 'object_materials', formData, '', 'metadata'),
    ])
    return responseData
}

const buynowTableAction = async (req) => {
    req.body.id = commonFunction.getValidID(req.body.id)

    const baseTableUsed = global.configColumns.buynow
    const customTableUsed = { enabled: 0 }

    const [results] = await Promise.all([
        commonFunction.tableFunction(req, baseTableUsed, customTableUsed),
    ])
    return results
}

module.exports = {
    metadataObjects,
    metadataPackings,
    metadataQuotes,
    metadataServices,
    metadataObjectMaterials,
    /**
     * get Quote Requst
     *
     * @memberOf frontend.shipping.arta
     * @param {artaShippingModule.getShippingIDDetails} method
     * @param {artaCommonCtrl.quoteRequest} method
     * @param {artaShippingModule.getShippingIDDetails} method
     */
    getQuoteRequest: async (req, res) => {
        try {
            const [cartData] = await Promise.all([
                cartCommonCtrl.getSingleCartDetails(
                    req,
                    req.body.cart_id,
                    null,
                    req.body.invoice_id,
                    req.body.invoice_address_id,
                ),
            ])
            const cartItemDetails = cartData.cartItems[0]
            const [shippingData] = await Promise.all([
                artaShippingModule.getShippingIDDetails(
                    cartItemDetails.id,
                    cartItemDetails.invoice_address_id,
                ),
            ])

            if (shippingData.length && !req.body.re_initiate) {
                jsonResponse(res, 'success', {
                    responseType: 1,
                    message: 'Shipping Quote successfull!',
                    responseData: [
                        {
                            quote_id: shippingData[0].quote_id,
                            apiResponse: JSON.parse(shippingData[0].response),
                        },
                    ],
                })
            } else {
                const responseData = {
                    status: 'success',
                    responseType: 1,
                    message: 'Shipping Quote successfull!',
                    responseData: [],
                }
                await commonFunction.asyncForEach(cartData.cartItems, async (singleItem) => {
                    const item = { ...singleItem }
                    item.buyer_id = item.user_id
                    const addedItem = { ...item, ...req.body.shipping_changes }
                    const [quoteResponse] = await Promise.all([
                        artaCommonCtrl.quoteRequest({ item: addedItem }),
                    ])
                    if (quoteResponse.status === 'error') {
                        responseData.status = 'error'
                        responseData.responseType = 4
                        responseData.message = 'Error while retrieving shipping quote!'
                    }

                    await Promise.all([
                        artaShippingModule.insertShippingResponse(
                            cartItemDetails.id,
                            cartItemDetails.invoice_address_id,
                            quoteResponse.responseData,
                        ),
                    ])
                    responseData.responseData.push({
                        quote_id: 0,
                        apiResponse: quoteResponse.responseData,
                    })
                })

                console.log('responseData', responseData)
                jsonResponse(res, responseData.status, {
                    responseType: responseData.responseType,
                    message: responseData.message,
                    responseData: responseData.responseData,
                })
            }
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },
    /**
     * shipping quote confirm
     *
     * @memberOf frontend.shipping.arta
     * @param {artaShippingModule.getShippingIDDetails} method
     * @param {artaCommonCtrl.quoteRequest} method
     */
    confirmShippingQuote: async (req, res) => {
        try {
            const [cartData] = await Promise.all([
                cartCommonCtrl.getSingleCartDetails(
                    req,
                    req.body.cart_id,
                    null,
                    req.body.invoice_id,
                    req.body.invoice_address_id,
                ),
            ])

            const cartItemDetails = cartData.cartItems[0]

            await Promise.all([
                artaShippingModule.updateShippingID(
                    req.body.shipping_data,
                    cartItemDetails.id,
                    cartItemDetails.invoice_address_id,
                ),
            ])

            cartItemDetails.product_type = 'live'
            const cartValues = await buynowCommonCtrl.cartItemsCalculations(cartItemDetails)
            await Promise.all([
                buynowCommonCtrl.updateBuyNowCalculations(
                    cartValues,
                    cartItemDetails.id,
                    cartItemDetails.user_id,
                ),
            ])

            // const dataReq = {
            //     body: {
            //         id: cartItemDetails.id,
            //         shipping_percent: parseFloat(
            //             (req.body.shipping_data.total * 100) / cartItemDetails.amount,
            //         ).toFixed(2),
            //         shipping_amount: parseFloat(req.body.shipping_data.total).toFixed(2),
            //     },
            // }
            // await Promise.all([buynowTableAction(dataReq)])

            jsonResponse(res, 'success', {
                responseType: 1,
                message: 'Successfully selected',
            })
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },
    /**
     * shipping quote confirm
     *
     * @memberOf frontend.shipping.arta
     * @param {object} req request object
     * @param {object} res response object
     * @param {artaShippingModule.getShippingIDDetails} method
     * @param {artaCommonCtrl.quoteRequest} method
     */
    getMetadaObject: async (req, res) => {
        try {
            const [responseData] = await Promise.all([metadataObjects(req)])
            jsonResponse(res, responseData.status, {
                responseType: responseData.responseType,
                message: responseData.message,
                responseData: responseData.responseData,
            })
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },
    /**
     * get metadata access
     *
     * @memberOf frontend.shipping.arta
     * @param {object} req request object
     * @param {object} res response object
     * @param {shipping.arta.metadataAccessRestrictions} method
     */
    getMetadaAccess: async (req, res) => {
        try {
            const [responseData] = await Promise.all([metadataAccessRestrictions(req)])
            jsonResponse(res, responseData.status, {
                responseType: responseData.responseType,
                message: responseData.message,
                responseData: responseData.responseData,
            })
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },
    /**
     * get metadata Insurance
     *
     * @memberOf frontend.shipping.arta
     * @param {object} req request object
     * @param {object} res response object
     * @param {shipping.arta.metadataInsurances} method
     */
    getMetadaInsurance: async (req, res) => {
        try {
            const [responseData] = await Promise.all([metadataInsurances(req)])
            jsonResponse(res, responseData.status, {
                responseType: responseData.responseType,
                message: responseData.message,
                responseData: responseData.responseData,
            })
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },
    /**
     * get metadata ObjectMaterials
     *
     * @memberOf frontend.shipping.arta
     * @param {object} req request object
     * @param {object} res response object
     * @param {shipping.arta.metadataInsurances} method
     */
    getMetadaObjectMaterials: async (req, res) => {
        try {
            const [responseData] = await Promise.all([metadataObjectMaterials(req)])
            jsonResponse(res, responseData.status, {
                responseType: responseData.responseType,
                message: responseData.message,
                responseData: responseData.responseData,
            })
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },
    /**
     * get metadata packings
     *
     * @memberOf frontend.shipping.arta
     * @param {object} req request object
     * @param {object} res response object
     * @param {shipping.arta.metadataPackings} method
     */
    getMetadaPackings: async (req, res) => {
        try {
            const [responseData] = await Promise.all([metadataPackings(req)])
            jsonResponse(res, responseData.status, {
                responseType: responseData.responseType,
                message: responseData.message,
                responseData: responseData.responseData,
            })
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },
    /**
     * get metadata Quotes
     *
     * @memberOf frontend.shipping.arta
     * @param {object} req request object
     * @param {object} res response object
     * @param {shipping.arta.metadataQuotes} method
     */
    getMetadaQuotes: async (req, res) => {
        try {
            const [responseData] = await Promise.all([metadataQuotes(req)])
            jsonResponse(res, responseData.status, {
                responseType: responseData.responseType,
                message: responseData.message,
                responseData: responseData.responseData,
            })
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },
    /**
     * get metadata services
     *
     * @memberOf frontend.shipping.arta
     * @param {object} req request object
     * @param {object} res response object
     * @param {shipping.arta.metadataServices} method
     */
    getMetadaServices: async (req, res) => {
        try {
            const [responseData] = await Promise.all([metadataServices(req)])
            jsonResponse(res, responseData.status, {
                responseType: responseData.responseType,
                message: responseData.message,
                responseData: responseData.responseData,
            })
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },
    /**
     * get metadata Transports
     *
     * @memberOf frontend.shipping.arta
     * @param {object} req request object
     * @param {object} res response object
     * @param {shipping.arta.metadataTransport} method
     */
    getMetadaTransports: async (req, res) => {
        try {
            const [responseData] = await Promise.all([metadataTransport(req)])
            jsonResponse(res, responseData.status, {
                responseType: responseData.responseType,
                message: responseData.message,
                responseData: responseData.responseData,
            })
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },
}