Skip to content

Instantly share code, notes, and snippets.

@meshv94
Created July 9, 2025 07:28
Show Gist options
  • Select an option

  • Save meshv94/e00e685c4f3fe2f4f358748b84afab50 to your computer and use it in GitHub Desktop.

Select an option

Save meshv94/e00e685c4f3fe2f4f358748b84afab50 to your computer and use it in GitHub Desktop.

Revisions

  1. meshv94 created this gist Jul 9, 2025.
    658 changes: 658 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,658 @@
    exports.grocery_payment_new = async (req, res) => {

    try {
    const schema = Joi.object().keys({
    allCart_id: Joi.array().min(1).required(),
    deliveryType: Joi.string().required(),
    address_id: Joi.string().optional(),
    total_price: Joi.number().required(),
    promo_code: Joi.string().allow("").optional(),
    payment_mode: Joi.string().allow("").optional(),
    delivery_date: Joi.string().required(),
    delivery_option: Joi.string().allow("").optional(),
    order_id: Joi.string().allow("").optional(),
    time_slot: Joi.string().allow("").optional(),
    starttime: Joi.number().required(),
    endtime: Joi.number().required(),
    // expresstime: Joi.number().required(),
    payment_token: Joi.number().optional(),
    deliveryCharge: Joi.number().optional(),
    // convienceCharge: Joi.number().optional(),
    // weight: Joi.number().required(),
    sqr_amount: Joi.number().allow("").optional(),
    order_comments: Joi.string().allow("").optional(),
    // no_of_person: Joi.number().allow("").optional(),
    // no_of_child: Joi.number().allow("").optional(),
    ussd_phone_number: Joi.number().allow("").optional(),
    // has_cutlery: Joi.boolean().optional(),
    item_out_of_stock_options: Joi.number().allow("").optional(),
    service_fees: Joi.number().allow(0).optional(),
    service_fees_list: Joi.string().allow("").optional()
    });
    const validateQuery = Joi.validate(req.body, schema, { abortEarly: true });

    if (validateQuery.error) {
    if (validateQuery.error.details && validateQuery.error.details[0].message) {
    res.status(200).json({ status_code: status.BAD_REQUEST, message: validateQuery.error.details[0].message });
    } else {
    res.status(200).json({ status_code: status.BAD_REQUEST, message: validateQuery.error.message });
    }
    return;
    }

    var { deliveryCharge, allCart_id, deliveryType, address_id, promo_code, total_price, payment_mode, delivery_date, delivery_option, time_slot, starttime, endtime, payment_token, ussd_phone_number } = req.body

    var service_fees = (req.body.service_fees)?req.body.service_fees:0
    var service_fees_list = (req.body.service_fees_list)?req.body.service_fees_list:""
    //comment this n add new one on 25-12-2021 as check non-operating module wise logic
    // var checkifItsHoliday = await checkIsHoliday(delivery_date, starttime)
    var checkifItsHoliday = await checkIsHoliday(delivery_date, starttime, 'NewGrocery')

    if (checkifItsHoliday == "yes") {
    var reqLanguage = req.headers.language
    var sendHolidayMessage = settingsFoodHolidayMessageSw

    if (reqLanguage == "en") {
    sendHolidayMessage = settingsFoodHolidayMessageEn
    }

    res.status(200).json({ status_code: 400, message: sendHolidayMessage })
    return
    }

    const isItemOutOfStock = await checkCartItemOutOfStock(allCart_id);

    if (isItemOutOfStock.is_item_out_of_stock) {
    return res.status(200).send({ status_code: 422, message: isItemOutOfStock.error_msg });
    }

    var promo_code_discount = 0
    var cash_discount = 0

    if (promo_code) {

    if (promo_code != "") {
    var checkIsPromoExpired = "No"
    var loggedInUserId = req.user._id
    var promoDetails = await getAppliedPromocode(loggedInUserId, "New Grocery", "applied", "");

    // console.log("::::::: promo_code promoDetails promoDetails promoDetails :::: ", promoDetails)

    if (promoDetails) {
    if (promoDetails.promocode_id != null) {
    promo_code_discount = promoDetails.discount

    if (promoDetails.promo_code_type == "Cash Discount") {
    cash_discount = promoDetails.discount
    }

    if (promoDetails.free_delivery_charge == true) {
    deliveryCharge = 0
    }

    /* Check promo code allowed payment methods */
    var paymentMethod = await convertPaymentMethod(payment_mode)
    var allowedPaymentMethods = promoDetails.promocode_id.payment_methods
    if (allowedPaymentMethods.includes(paymentMethod) == false) {
    res.status(200).json({ status_code: 400, message: req.lang.Invalid_Promo_code })
    return
    }

    /* check minimum order */

    var totalOrderAmount = total_price + deliveryCharge

    if (totalOrderAmount < promoDetails.promocode_id.minimumOrder) {
    res.status(200).json({ status_code: 400, message: req.lang.Invalid_Promo_code + " Minimum amount to use this promocode is " + promoDetails.promocode_id.minimumOrder })
    return
    }

    } else {
    checkIsPromoExpired = "Yes"
    }
    } else {
    checkIsPromoExpired = "Yes"
    }

    if (checkIsPromoExpired == "Yes") {
    res.status(200).json({ status_code: 400, message: req.lang.Promo_code_expired })
    return
    }
    }
    }

    var sqr_amount = 0
    if (typeof sqr_amount != 'undefined' && req.body.sqr_amount) {
    sqr_amount = req.body.sqr_amount
    }

    var userComments = ""
    if (typeof req.body.order_comments != 'undefined' && req.body.order_comments) {
    userComments = req.body.order_comments
    }

    // var noOfPerson = ""
    // var noOfChilds = ""

    // if (typeof req.body.no_of_person != 'undefined' && req.body.no_of_person && req.body.no_of_person != '') {
    // noOfPerson = req.body.no_of_person
    // }
    // if (typeof req.body.no_of_child != 'undefined' && req.body.no_of_child && req.body.no_of_child != '') {
    // noOfChilds = req.body.no_of_child
    // }

    var charges = await calculateConvenienceCharge(allCart_id, deliveryType)
    var convienceCharge = charges.packagingCharge
    var dukaConvienceCharge = charges.convienceCharge

    var reCalcTotalPrice = await reCalculateGroceryCartTotal(allCart_id)

    var totalCalculatedAmount = reCalcTotalPrice + convienceCharge + service_fees

    var ussd_phone_number = ""
    if (typeof ussd_phone_number != 'undefined' && req.body.ussd_phone_number) {
    ussd_phone_number = req.body.ussd_phone_number
    console.log("ussd_phone_number inside", ussd_phone_number)
    }

    if (starttime == 0 || starttime == "0") {
    starttime = moment.tz(moment(), 'Africa/Dar_es_Salaam').format('HH'); //h or HH
    }

    if (time_slot == "" || time_slot == null) {
    if (deliveryType == "Home_Delivery") {
    let currentNowTime = moment().add(8, 'm').tz(newLocalTimeZone).format('H:mm');
    let currentNowEnd = moment().add(2, 'hours').tz(newLocalTimeZone).format('H:mm');

    // "time_slot":"19:00 hours - 22:00 hours",
    time_slot = currentNowTime + " hours - " + currentNowEnd + " hours"

    }
    else if (deliveryType == 'Pick_Up') {

    let currentNowTimeAM = moment().add(8, 'm').tz(newLocalTimeZone).format('hh:mm a');
    let currentNowEndAM = moment().add(2, 'hours').tz(newLocalTimeZone).format('hh:mm a');

    //10:00 am to 11:00 am //h:mm a
    time_slot = currentNowTimeAM + " to " + currentNowEndAM
    }
    }

    // console.log("created time_slot: Place Order ", time_slot)

    let settings = await GroceryvendorLocation(allCart_id)

    if (settings) {

    if (deliveryType != 'Pick_Up') {
    // let settings = await SettingsModel.findOne({type:"User"})
    if (req.body.total_price < settings.minimum_order) {

    commonFun.sendNotification(req.user, EN.Minimum_Order_REST, EN.Minimum_Order_REST, SW.Minimum_Order_REST, 3, "Minimum Order", new Date(), 0, "")

    var lang = req.user.selected_language

    var message = EN.Minimum_Order_REST

    if (lang == 'sw')
    message = SW.Minimum_Order_REST

    /*
    sendNotification(req.user, EN.Minimum_order_error + "" + formatNumber(settings.minimum_order), EN.Minimum_order_error + "" + formatNumber(settings.minimum_order), SW.Minimum_order_error + "" + formatNumber(settings.minimum_order), 3, "Minimum Order", new Date(), 0, "")
    var lang = req.user.selected_language
    var message = EN.Minimum_order_error + "" + formatNumber(settings.minimum_order)
    if (lang == 'sw')
    message = SW.Minimum_order_error + "" + formatNumber(settings.minimum_order)

    */
    res.status(200).send({ status_code: 400, message: message }) //:"minimum order violated"
    return
    }
    }

    var checkRestStatus = await getGroceryVendorOpenStatus(settings._id)
    // console.log("checkRestStatus checkRestStatuscheckRestStatus checkRestStatus ", checkRestStatus)
    // add delivery_date in condition on 03-12-2021 as allow later order for close restaurant
    if ((checkRestStatus == "0" && delivery_date == 'NOW') || (checkRestStatus == 0 && delivery_date == 'NOW')) {
    // if (checkRestStatus == "0" || checkRestStatus == 0) {
    var ResStatusMsg = (EN.Restuarant_Not_available).replace("%RestaurantName%", settings.name).replace("%RestOpenHours%", settings.open_time).replace("%RestclosingHours%", settings.close_time)
    if (req.selected_language == "en") {
    ResStatusMsg = (EN.Restuarant_Not_available).replace("%RestaurantName%", settings.name).replace("%RestOpenHours%", settings.open_time).replace("%RestclosingHours%", settings.close_time)

    } else {
    ResStatusMsg = (SW.Restuarant_Not_available).replace("%RestaurantName%", settings.name).replace("%RestOpenHours%", settings.open_time).replace("%RestclosingHours%", settings.close_time)
    }
    res.status(200).send({ status_code: 400, message: ResStatusMsg })
    return
    }

    }

    //check if user has quickrewards balance or not
    var requestMsidn = ""

    if (NODEENV != "development") {
    if (sqr_amount) {
    if (sqr_amount > 0) {
    requestMsidn = "255" + req.user.mobile_number
    var checkQRBalance = await getUserQuickRewardsbalance(requestMsidn)
    checkQRBalance = 1111
    if (checkQRBalance == 0) {
    res.status(200).send({ status_code: 400, message: "Insufficient Balance" })
    return
    }
    }
    }
    }

    // const inactive_status = await checkFIROrRestInactiveStatus(allCart_id);

    // if (!inactive_status.is_fir_or_rest_active) {
    // return res.status(200).send({ status_code: 400, message: inactive_status.error_msg });
    // }

    let order_id = await generate(5);
    let transid = order_id

    var { allCart_id, total_price } = req.body

    total_price = totalCalculatedAmount

    var cartdata = { allCart_id, transid, total_price }

    cartdata.user_id = req.user._id

    // let findQueryCustAcceptedOrder = {
    // 'user_id': cartdata.user_id,
    // 'status': { $nin: ["Order Placed", "New", "Cancelled", "Pending"] },
    // "isPlaced": true,
    // }

    // let customer_accepted_order_length = await GroceryCartHistoryModel.find(findQueryCustAcceptedOrder).count()
    // var is_first_order = true
    // if (customer_accepted_order_length > 0) {
    // is_first_order = false
    // //isFirstOrder
    // }

    var data = { transid: transid, allCart_id: allCart_id, total_price: total_price, user_id: req.user._id, is_paid: false, isPlaced: false, isCancelled: false, deliveryCharge: deliveryCharge, convienceCharge: convienceCharge, is_modified: "0", order_comments: userComments, service_fees:service_fees, service_fees_list, service_fees_list, dukaConvienceCharge:dukaConvienceCharge}

    carthistory = new GroceryCartHistoryModel(data)

    let carthi = await carthistory.save()
    .then(async (saveData) => {
    return saveData
    }).catch(async err => {
    console.log(err)
    })

    // var delivery_date = await get_delivery_date_grocery(delivery_date, starttime)
    var populatequery = {
    path: 'product_id',
    populate: {
    path: 'grocery_vendor_id',
    model: "groceryvendors",
    }
    }
    console.log('$allCart_id[0]$',allCart_id[0])
    let check_data = await GroceryCartModel.findOne({ _id: allCart_id[0] }).populate(populatequery)
    console.log('$check_data.product_id.grocery_vendor_id.is_selected_day_vendor$',check_data.product_id.grocery_vendor_id.is_selected_day_vendor)
    var delivery_date = await get_delivery_date_grocery(delivery_date, starttime,check_data.product_id.grocery_vendor_id.is_selected_day_vendor,check_data.delivery_date)

    // return false
    if (deliveryType == "Home_Delivery") {
    if (!req.body.address_id || req.body.address_id == '') {
    responses.sendErrorDuka("Address missing 18755 ", res)
    return
    }
    }

    let result = await grocery_masterpass_selcom_place_order_new(order_id, deliveryCharge, allCart_id, deliveryType, address_id, promo_code, total_price, payment_mode, delivery_date, delivery_option, time_slot, starttime, endtime, payment_token, req.user, sqr_amount)

    console.log(order_id, + " place order result: 18762---" + result)

    if (result == "true") {
    var billingAddress = {}
    if (address_id === "" || address_id.length === 0 || !address_id || deliveryType == "Pick_Up") { // add condition on 1-2-2022 as send user data in billing data
    var billingAddress = await AddressModel.findOne({ user_id: req.user._id })
    } else {
    var billingAddress = await AddressModel.findOne({ _id: address_id })
    }
    var postcode_or_pobox = "12345"

    var billing = {
    firstname: billingAddress.name,
    lastname: billingAddress.name,
    address_1: billingAddress.detail_address,
    city: billingAddress.city,
    state_or_region: billingAddress.area,
    postcode_or_pobox: postcode_or_pobox,
    // country:billingAddress.country_code,
    country: "TZ",
    phone: "255" + req.user.mobile_number
    // phone: "255656724750"
    }

    if (billing.postcode_or_pobox == "" || billing.postcode_or_pobox == "0" || billing.postcode_or_pobox == null) {
    billing.postcode_or_pobox = 12345
    }

    if (billing.state_or_region == "" || billing.state_or_region == "0" || billing.state_or_region == null) {
    billing.state_or_region = "N/A"
    }

    let result = ""

    var gateway_buyer_uuid = req.user.gateway_buyer_uuid
    var buyer_userid = req.user._id
    var no_of_items = 10

    var redirect_url = Buffer.from(web_server_url + "redirect.html").toString('base64')
    var webhook = Buffer.from(server_url + "v2/new_grocery_add_card_callback").toString('base64')
    const webhook_selcom_pesa=server_url + "v2/new_grocery_add_card_callback"
    var currency = "TZS"

    var buyer_name = req.user.name
    var buyer_email = req.user.emailId.trim()
    // var buyer_phone = req.user.mobile_number
    var buyer_phone = "255" + req.user.mobile_number

    var findQryResturant = { transid: transid }
    // var foodVendorDetails = await getResturantDetails(findQryResturant);
    var vendor = DUKA_Food_VENDOR

    var payable_amount_qr = total_price
    payable_amount_qr = total_price + Number(deliveryCharge) + parseInt(dukaConvienceCharge) - Number(cash_discount)

    if (buyer_email == "") {
    buyer_email = buyer_phone + DEFAULT_EMAIL_DOMAIN
    }

    const requestBody = {
    "vendor": vendor,
    "order_id": order_id,
    "buyer_name": buyer_name,
    "buyer_userid": buyer_userid,
    "buyer_email": buyer_email,
    "buyer_phone": buyer_phone,
    // "amount": total_price,
    "amount": payable_amount_qr,
    "currency": currency,
    // "billing": billing,
    "no_of_items": no_of_items,
    "webhook": webhook,
    "redirect_url": redirect_url,
    // "tillvendor": resturantTillvendor,
    "sqr_amount": sqr_amount,
    "payment_methods": "ALL",
    "billing.firstname": billing.firstname,
    "billing.lastname": billing.lastname,
    "billing.address_1": billing.address_1,
    "billing.city": billing.city,
    "billing.state_or_region": billing.state_or_region,
    "billing.postcode_or_pobox": billing.postcode_or_pobox,
    "billing.country": billing.country,
    "billing.phone": billing.phone,
    "merchant_remarks": payment_mode
    }

    console.log(order_id, "before grocery_payment_new flight: card create order>>>>")

    let resultdelcomapi = await selcomapigw.sendRequest(NODEENV, '/v1/checkout/create-order', 'post', DUKA_FOOD_API_KEY, DUKA_FOOD_API_SECRET, order_id, requestBody).then(result => {

    if (result) {
    console.log(order_id, " Result Success grocery_payment_new ", result)
    if (result.result == "SUCCESS") {
    groceryCreateOrder(total_price, transid, req.user._id, sqr_amount).then(
    async orderResultData => {
    console.log(order_id, " Neew Order==> ", orderResultData)
    if (ussd_phone_number != "") {

    let Order_list_data = await OrderQueueModel.find({ allCart_id: { $in: allCart_id }, payment_mode: "Mobile Money", isCancelled: false});
    console.log('Allcart_id ==>', allCart_id)
    console.log('Mobile Money Water OrderQueueData', Order_list_data.length, Order_list_data)
    if(Order_list_data.length > 0){
    return res.status(415).json({
    status_code: 415,
    message: Order_list_data[0].isPlaced ? "Your Order has already been placed" : "Your Mobile Money request is still under process kindly wait for some time"
    });
    }

    if(payment_mode=="Selcom Pesa"){
    let newrewestres = await commonFun.selcomPesaPay(order_id, ussd_phone_number).then(async resultUssd => {
    console.log(order_id, "push result ", resultUssd);
    await commonFun.saveMobileMoneyLogs(order_id, requestBody, resultUssd );
    if (resultUssd.result == "SUCCESS") {
    GroceryCartHistoryModel.findByIdAndUpdate({ _id: orderResultData._id }, { selcom_reference: resultUssd.reference }).then(
    async cart => {
    }
    )
    try {
    // var suborderId = await logSuborder( orderResultData._id, req)
    var suborderId = await logTempSuborder( orderResultData._id, req)
    } catch (error) {
    return res.status(200).json({ status_code: 416, message: "Your Order is already placed!" })
    }

    console.log(order_id, 'response trandid-------- 17723 ----', suborderId)

    var subOrderDetail = await OrderQueueModel.find({ linkedTransid: suborderId }).exec()
    suborderId = subOrderDetail[0].transid
    var success_res = req.lang.Order_Placed_Successfully_msg.replace("%number%", suborderId);

    const data = {
    response: {
    reference: resultUssd.reference,
    resultcode: resultUssd.resultcode,
    result: resultUssd.result,
    order_id: suborderId,
    transid: subOrderDetail[0]._id
    },
    message: success_res,
    status_code: 200
    }
    try{
    await SelcomPesaUserModel.create({
    user_id: req.user._id,
    user_name: resultUssd.data[0].name,
    mobile_no: resultUssd.data[0].msisdn
    });
    }catch(e){
    console.log("Error In Selcom Pesa Details Saving",e)
    }
    console.log(order_id, "response to user 17740 --", data)
    res.status(200).json(data)
    //res.send(data)
    } else if (resultUssd.result == "FAIL") {
    const dataError = {
    response: {
    reference: resultUssd.reference,
    resultcode: resultUssd.resultcode,
    result: resultUssd.result,
    order_id: orderResultData.transid,
    transid: orderResultData._id
    },
    message: resultUssd.message,
    status_code: parseInt(resultUssd.resultcode)
    }
    console.log(order_id, "response to user failure 17756--", dataError)
    //res.send(dataError)
    res.status(200).json(dataError)
    }
    }).catch(error => {
    var body = JSON.stringify(error)
    console.log("error response data***********\n: ", error)
    console.log(error)
    const dataError = {
    response: {
    reference: "",
    resultcode: "",
    result: "",
    order_id: orderResultData.transid,
    transid: orderResultData._id
    },
    message: "Something went wrong",
    status_code: 424
    }
    console.log("response to user failure 17777", dataError)
    //res.send(dataError)
    res.status(200).json(dataError)
    })
    }else{
    let newrewestres = await commonFun.ussd_push(transid, ussd_phone_number).then(async resultUssd => {
    console.log(order_id, "push result ", resultUssd);
    await commonFun.saveMobileMoneyLogs(order_id, requestBody, resultUssd );
    if (resultUssd.result == "SUCCESS") {
    GroceryCartHistoryModel.findByIdAndUpdate({ _id: orderResultData._id }, { selcom_reference: resultUssd.reference }).then(
    async cart => {
    }
    )
    try {
    // var suborderId = await logSuborder( orderResultData._id, req)
    var suborderId = await logTempSuborder( orderResultData._id, req)
    } catch (error) {
    return res.status(200).json({ status_code: 416, message: "Your Order is already placed!" })
    }

    console.log(order_id, 'response trandid-------- 17723 ----', suborderId)

    var subOrderDetail = await OrderQueueModel.find({ linkedTransid: suborderId }).exec()
    suborderId = subOrderDetail[0].transid
    var success_res = req.lang.Order_Placed_Successfully_msg.replace("%number%", suborderId);

    const data = {
    response: {
    reference: resultUssd.reference,
    resultcode: resultUssd.resultcode,
    result: resultUssd.result,
    order_id: suborderId,
    transid: subOrderDetail[0]._id
    },
    message: success_res,
    status_code: 200
    }

    console.log(order_id, "response to user 17740 --", data)
    res.status(200).json(data)
    //res.send(data)
    } else if (resultUssd.result == "FAIL") {
    const dataError = {
    response: {
    reference: resultUssd.reference,
    resultcode: resultUssd.resultcode,
    result: resultUssd.result,
    order_id: orderResultData.transid,
    transid: orderResultData._id
    },
    message: resultUssd.message,
    status_code: parseInt(resultUssd.resultcode)
    }
    console.log(order_id, "response to user failure 17756--", dataError)
    //res.send(dataError)
    res.status(200).json(dataError)
    }
    }).catch(error => {
    var body = JSON.stringify(error)
    console.log("error response data***********\n: ", error)
    console.log(error)
    const dataError = {
    response: {
    reference: "",
    resultcode: "",
    result: "",
    order_id: orderResultData.transid,
    transid: orderResultData._id
    },
    message: "Something went wrong",
    status_code: 424
    }
    console.log("response to user failure 17777", dataError)
    //res.send(dataError)
    res.status(200).json(dataError)
    })
    }
    } else {
    try {
    // var suborderId = await logSuborder( orderResultData._id, req)
    var suborderId = await logTempSuborder( orderResultData._id, req)
    } catch (error) {
    return res.status(200).json({ status_code: 416, message: "Your Order is already placed!" })
    }

    // add below on 18-11-2021 as separate transid for linked order logic
    var subOrderDetail = await OrderQueueModel.find({ linkedTransid: suborderId }).exec()
    suborderId = subOrderDetail[0].transid
    var success_res = req.lang.Order_Placed_Successfully_msg.replace("%number%", suborderId);
    const resData = {
    response: {
    result: result.result,
    order_id: suborderId,
    payment_token: result.data[0].payment_token,
    payment_status: "PENDING",
    qr: result.data[0].qr,
    till_number: ''
    },
    message: success_res,
    status_code: 200
    }
    console.log(order_id, ' resData ---- 17800 ----', resData)
    res.status(200).json(resData)
    }
    })
    } else {
    const resData = {
    response: {
    result: result.result,
    order_id: order_id,
    payment_token: '',
    payment_status: '',
    qr: '',
    till_number: ''
    },
    message: "invalid after create order api",
    status_code: 424
    }
    console.log(order_id, ' resData ---- 17819 ----', resData)
    res.status(200).json(resData)
    }
    } else {
    const resData = {
    response: {
    result: result.result,
    order_id: order_id,
    payment_token: '',
    payment_status: '',
    qr: '',
    till_number: ''
    },
    message: "result not true after create order api",
    status_code: 424
    }

    res.status(200).json(resData)
    }

    })
    } else {
    const toSend = {
    response: {
    result: result.result,
    order_id: order_id,
    payment_token: '',
    payment_status: '',
    qr: '',
    till_number: ''
    },
    message: "something went wrong",
    status_code: 424
    }

    res.status(200).json(toSend)
    }
    } catch (e) {
    console.log("food grocery_payment_new checkout/create-order")
    console.log("AfterError Inside outer")
    console.log(e)
    responses.sendErrorDuka(err.message, res)
    }
    }