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.
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)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment