front/controllers/invoice/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 commonFunction = require('../../../common/function').default
const invoiceModule = require('../../modules/invoice').default
const cartModule = require('../../modules/cart').default
const buynowCommonCtrl = require('../buynow/common')
const appointmentCtrl = require('../appointment')
const schemaModule = require('./schema').default
const { jsonResponse, errorResponse } = require('../logger')

const getdynamicinnercontents = async (req, responseData) => {
    const returnResponse = responseData
    returnResponse.totalRecords = returnResponse.totalRecords[0]
        ? returnResponse.totalRecords[0].totallength
        : 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 all Invoice Details
 *
 * @memberOf frontend.product
 * @param {object} req request object
 * @param {invoiceModule.getInvoiceCartDetails} modules
 * @param {invoiceModule.getAllTransactions} modules
 */
const getInvoiceDetails = async (req) => {
    let responseData = {}
    let appointmentDetail = ''
    let billingAddress = ''
    let invoiceUser = ''
    let invoiceAddress = ''

    const [invoiceItems] = await Promise.all([invoiceModule.allInvoiceItems(req, req.body, 1)])

    if (
        typeof global.configFeatures.invoice_user_details !== 'undefined' &&
        global.configFeatures.invoice_user_details.enabled
    ) {
        if (invoiceItems[0].invoice_address_id) {
            if (invoiceItems[0].buynowpaid) {
                // For paid user
                ;[invoiceAddress] = await Promise.all([
                    invoiceModule.invoicePaidUserAddress(invoiceItems[0].invoice_address_id),
                ])
                ;[invoiceUser] = await Promise.all([
                    invoiceModule.invoiceUser(invoiceItems[0].user_id),
                ])
            } else {
                // For unpaid users
                ;[invoiceAddress] = await Promise.all([
                    invoiceModule.invoiceUnpaidUserAddress(invoiceItems[0].invoice_address_id),
                ])
                ;[invoiceUser] = await Promise.all([
                    invoiceModule.invoiceUser(invoiceItems[0].user_id),
                ])
            }
        } else if (invoiceItems[0].user_id) {
            // For draft
            ;[invoiceUser] = await Promise.all([invoiceModule.invoiceUser(invoiceItems[0].user_id)])
        }
    }

    if (
        typeof global.configFeatures.invoice_address !== 'undefined' &&
        global.configFeatures.invoice_address.enabled
    ) {
        billingAddress = await Promise.all([
            invoiceModule.billingAddress(invoiceItems[0].invoice_bill_detail_id),
        ])
        if (billingAddress[0]) {
            billingAddress = billingAddress[0][0]
        }
    }
    if (
        typeof global.configurations.variables.schedule_appointment !== 'undefined' &&
        global.configurations.variables.schedule_appointment
    ) {
        ;[appointmentDetail] = await Promise.all([
            appointmentCtrl.getAppointmentDetails(invoiceItems[0].appointment_id, req),
        ])
    }

    if (invoiceItems.length > 0) {
        req.body.invoice_id = invoiceItems[0].common_invoice
        const [allTransactions] = await Promise.all([
            invoiceModule.getAllTransactions(req.body.invoice_id),
        ])
        const cartValue = {
            per_total: 0,
            total_amount: 0,
            total_tax: 0,
            total_shipping: 0,
            total_premium: 0,
            total_paid: 0,
            total_deposit: 0,
            total_due_amount: 0,
            admin_fee_percent: 0,
            admin_fee: 0,
            common_invoice: req.body.invoice_id,
            cart_paiddate: invoiceItems[0].paid_date,
            cart_paid: invoiceItems[0].paid,
            cart_payment: 'online',
        }

        await commonFunction.asyncForEach(invoiceItems, async (items) => {
            await buynowCommonCtrl.getCartTotal(cartValue, items, 'invoice')
        })

        responseData = {
            status: 'success',
            responseType: 1,
            message: 'Invoice items retrieved!',
            responseData: {
                invoiceItems,
                appointmentDetail,
                cartValues: cartValue,
                allTransactions,
                billingAddress,
                invoiceUser,
                invoiceAddress,
            },
        }
    } else {
        responseData = {
            status: 'error',
            responseType: 2,
            message: 'No record found!',
        }
    }
    return responseData
}

module.exports = {
    /**
     * Get Invoice details
     *
     * @memberOf frontend.invoice
     * @param {frontend.invoice.getInvoiceDetails} modules
     */
    getInvoiceDetails,
    /**
     * Get single Invoice Details
     *
     * @memberOf frontend.product
     * @param {object} req request object
     * @param {object} res response object
     * @param {frontend.invoice.getInvoiceCartDetails} 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 all Invoice Details
     *
     * @memberOf frontend.product
     * @param {object} req request object
     * @param {object} res response object
     * @param {invoiceModule.searchInvoiceProducts} modules
     * @param {frontend.invoice.getdynamicinnercontents} modules
     */
    allinvoices: async (req, res) => {
        try {
            await schemaModule.search().validateSync(req.body)
            let [records, totalRecords] = await Promise.all([
                invoiceModule.searchInvoiceProducts(req, req.body, 1),
                invoiceModule.searchInvoiceProducts(req, req.body, 0),
            ])
            totalRecords = [{ totallength: totalRecords.length }]
            let responseData = { records, totalRecords }
            responseData = await getdynamicinnercontents(req, responseData)
            jsonResponse(res, 'success', {
                responseType: 1,
                message: 'Details successfully retrieved!',
                responseData,
            })
        } catch (e) {
            errorResponse(e, res)
        }
    },
    /**
     * Get all transactions
     *
     * @memberOf frontend.product
     * @param {object} req request object
     * @param {object} res response object
     * @param {invoiceModule.searchTransaction} modules
     * @param {frontend.invoice.getdynamicinnercontents} modules
     */
    alltransactions: async (req, res) => {
        try {
            await schemaModule.search().validateSync(req.body)
            let [records, totalRecords] = await Promise.all([
                invoiceModule.searchTransaction(req, req.body, 1),
                invoiceModule.searchTransaction(req, req.body, 0),
            ])
            totalRecords = [{ totallength: totalRecords.length }]
            let responseData = { records, totalRecords }
            responseData = await getdynamicinnercontents(req, responseData)
            jsonResponse(res, 'success', {
                responseType: 1,
                message: 'Details successfully retrieved!',
                responseData,
            })
        } catch (e) {
            errorResponse(e, res)
        }
    },
    /**
     * update Invoice
     *
     * @memberOf frontend.product
     * @param {object} req request object
     * @param {object} res response object
     * @param {invoiceModule.searchTransaction} modules
     * @param {frontend.invoice.getdynamicinnercontents} modules
     */
    updateInvoice: async (req, res) => {
        try {
            const response = {}
            await schemaModule.search().validateSync(req.body)
            const [responseData] = await Promise.all([getInvoiceDetails(req)])
            await commonFunction.asyncForEach(
                responseData.responseData.invoiceItems,
                async (singleItem) => {
                    if (
                        parseFloat(singleItem.total_premium) !== parseFloat(req.body.buyer_premium)
                    ) {
                        singleItem.projects_buyer_premium =
                            (req.body.buyer_premium / req.body.per_total) * 100
                        await Promise.all([
                            cartModule.updateBuyerPremium(
                                singleItem.projects_buyer_premium,
                                singleItem.projects_id,
                            ),
                        ])
                    }

                    // payload builder
                    const item = { ...singleItem, ...req.body }

                    // re-calculate
                    const cartCalculation = await buynowCommonCtrl.cartItemsCalculations(item)

                    if (req.body.changed_user_id) {
                        item.changed_user_id = req.body.changed_user_id
                    }
                    // update buynow
                    await Promise.all([cartModule.updateInvoice({ ...item, ...cartCalculation })])
                },
            )

            jsonResponse(res, 'success', {
                responseType: 1,
                message: ' Successfully Updated!',
                responseData: response,
            })
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },
}