File: /var/www/javago_test/src/services/cafe/cafe.services.js
import AddonSizeCafeItemDB from "../../models/addon_size_cafe_items.model.js"
import PreDefinedImageDB from "../../models/pre_defined_item_images.model.js"
import CafeMenuItemSizeDB from "../../models/cafe_menu_item_sizes.model.js"
import userFavoriteCafes from "../../models/user_favorite_cafes.model.js"
import SuggestedItemDB from "../../models/suggested_items.model.js"
import CafeMenuItemDB from "../../models/cafe_menu_items.model.js"
import CafeTimingDB from "../../models/cafe_timings.model.js"
import cafeFilters from "../../models/cafe_filters.model.js"
import AddonSizeDB from "../../models/addon_sizes.model.js"
import CafeMenuDB from "../../models/cafe_menu.model.js"
import sequelize from "../../config/database.config.js"
import AddonDB from "../../models/addons.model.js"
import SizeDB from "../../models/sizes.model.js"
import LoyaltyStampDB from "../../models/manage_loyalty_stamps.model.js"
import OrderDB from "../../models/orders.model.js"
import CafeDB from "../../models/cafes.model.js"
import { json, Op } from "sequelize"
import { config } from "../../config/config.js"
import moment from "moment";
let USER_SEARCH_LIMIT = config.limit;
let distance = config.distance;
// get all cafe listing
export async function getAllCafeList(data) {
try {
let todayDayId = new Date().getDay();
let currentTime = moment().format('HH:mm');
if ([null, undefined, '', 0].includes(data.page)) data.page = 1
data.page = parseInt(data.page);
const haversine = `(
3959 * acos(
cos(radians(${data.latitude}))
* cos(radians(latitude))
* cos(radians(longitude) - radians(${data.longitude}))
+ sin(radians(${data.latitude})) * sin(radians(latitude))
)
)`;
let whereObject = {
deleted_at: 0,
is_active: 1,
signup_completed: 1,
profile_completed: 1,
menu_completed: 1,
loyalty_completed: 1,
// is_active: 1,
// '$employee.manager.id$': id
};
//2 vegan
if (data.filter_flag == 2) {
whereObject.cafe_filter = {
[Op.like]: ['%3%']
}
}
// 3 bubble tea
else if (data.filter_flag == 3) {
whereObject.cafe_filter = {
[Op.like]: ['%4%']
}
}
// 4 desserts
else if (data.filter_flag == 4) {
whereObject.cafe_filter = {
[Op.like]: ['%5%']
}
}
// 5 sandwiches
else if (data.filter_flag == 5) {
whereObject.cafe_filter = {
[Op.like]: ['%6%']
}
} else {
}
let cafeDetails = await CafeDB.paginate(
{
page: data.page,
paginate: parseInt(USER_SEARCH_LIMIT),
where: whereObject,
include: [
{
model: userFavoriteCafes, as: 'user_favorite_cafes',
where: {
user_id: data.user_id,
is_favorite: 1
},
attributes: ['is_favorite', 'user_id'],
required: false
},
{
model: CafeTimingDB,
as: 'time_sheet_data',
required: false,
where: {
day: todayDayId,
open_time: {
[Op.lte]: currentTime
},
close_time: {
[Op.gte]: currentTime
},
},
}
],
attributes: ['id', 'cafe_name', 'cafe_type', 'bio', 'cafe_tax', 'phone', 'banner_image', 'address', 'latitude', 'longitude', [sequelize.literal(`round(${haversine})`), 'distance'],],
order: [
['distance', 'asc'],
],
subQuery: false,
// having: sequelize.literal(`distance <= ${distance}`),
}
);
cafeDetails = JSON.stringify(cafeDetails)
cafeDetails = JSON.parse(cafeDetails)
for (let i = 0; i < cafeDetails.docs.length; i++) {
cafeDetails.docs[i].is_favorite = cafeDetails.docs[i].user_favorite_cafes.length > 0 ? 1 : 0;
cafeDetails.docs[i].is_open = ((cafeDetails.docs[i].time_sheet_data).length) ? 1 : 0;
cafeDetails.docs[i].distance = cafeDetails.docs[i].distance ? cafeDetails.docs[i].distance : 0
let checkTotalOrder = await OrderDB.count({
where: {
user_id: data.user_id,
cafe_id: parseInt(cafeDetails.docs[i].id),
status: 2,
cafe_coupon_expired_time: 0
}
})
let nonUniversal = await LoyaltyStampDB.findOne({
where: {
cafe_id: parseInt(cafeDetails.docs[i].id),
is_universal: 0
},
attributes: ['stamp_no']
})
cafeDetails.docs[i].reward = nonUniversal ? nonUniversal.stamp_no - checkTotalOrder : 0;
}
(cafeDetails.docs).sort(
(p1, p2) =>
(p1.is_open < p2.is_open) ? 1 : (p1.is_open > p2.is_open) ? -1 : 0);
return cafeDetails;
} catch (error) {
throw new Error(error)
}
}
// feature cafe list
export async function getFeatureCafeList(data) {
try {
let todayDayId = new Date().getDay();
let currentTime = moment().format('HH:mm');
if ([null, undefined, '', 0].includes(data.page)) data.page = 1
data.page = parseInt(data.page);
const haversine = `(
3959 * acos(
cos(radians(${data.latitude}))
* cos(radians(latitude))
* cos(radians(longitude) - radians(${data.longitude}))
+ sin(radians(${data.latitude})) * sin(radians(latitude))
)
)`;
let whereObject = {
deleted_at: 0,
is_active: 1,
signup_completed: 1,
profile_completed: 1,
menu_completed: 1,
loyalty_completed: 1,
};
let cafeDetails = await CafeDB.paginate(
{
page: data.page,
paginate: parseInt(USER_SEARCH_LIMIT),
where: whereObject,
include: [
{
model: userFavoriteCafes, as: 'user_favorite_cafes',
where: {
user_id: data.user_id,
is_favorite: 1
},
attributes: ['is_favorite', 'user_id'],
required: false
},
{
model: CafeTimingDB,
as: 'time_sheet_data',
required: false,
where: {
day: todayDayId,
open_time: {
[Op.lte]: currentTime
},
close_time: {
[Op.gte]: currentTime
},
},
}
],
attributes: {
include: [[sequelize.literal(`(
SELECT COUNT(*)
FROM orders where orders.cafe_id = cafes.id
)`),
'totalOrder'], 'id', 'cafe_name', 'cafe_type', 'bio', 'cafe_tax', 'phone', 'banner_image', 'address', 'latitude', 'longitude', [sequelize.literal(`round(${haversine})`), 'distance']],
exclude: ['cafe_filter', 'website', 'otp', 'cafe_type', 'is_active', 'approved', 'signup_completed', 'profile_completed', 'menu_completed', 'loyalty_completed', 'is_listed', 'is_open', 'deleted_at', 'created_at', 'updated_at', 'remember_token', 'postcode', 'password']
},
order: [
['totalOrder', 'ASC'],
],
subQuery: false,
// having: sequelize.literal(`distance <= ${distance}`),
}
);
cafeDetails = JSON.stringify(cafeDetails)
cafeDetails = JSON.parse(cafeDetails)
for (let i = 0; i < cafeDetails.docs.length; i++) {
cafeDetails.docs[i].is_favorite = cafeDetails.docs[i].user_favorite_cafes.length > 0 ? 1 : 0;
cafeDetails.docs[i].is_open = ((cafeDetails.docs[i].time_sheet_data).length) ? 1 : 0;
cafeDetails.docs[i].distance = cafeDetails.docs[i].distance ? cafeDetails.docs[i].distance : 0
let checkTotalOrder = await OrderDB.count({
where: {
user_id: data.user_id,
cafe_id: parseInt(cafeDetails.docs[i].id),
status: 2,
loyalty_stamp_id: null,
}
})
let nonUniversal = await LoyaltyStampDB.findOne({
where: {
cafe_id: parseInt(cafeDetails.docs[i].id),
is_universal: 0
},
attributes: ['stamp_no']
})
cafeDetails.docs[i].reward = nonUniversal.stamp_no - checkTotalOrder;
}
(cafeDetails.docs).sort(
(p1, p2) =>
(p1.is_open < p2.is_open) ? 1 : (p1.is_open > p2.is_open) ? -1 : 0);
return cafeDetails;
} catch (error) {
throw new Error(error)
}
}
// get favorites cafe listing
export async function getFavoritesCafeList(data) {
try {
let todayDayId = new Date().getDay();
let currentTime = moment().format('HH:mm');
if ([null, undefined, '', 0].includes(data.page)) data.page = 1
data.page = parseInt(data.page);
const haversine = `(
3959 * acos(
cos(radians(${data.latitude}))
* cos(radians(latitude))
* cos(radians(longitude) - radians(${data.longitude}))
+ sin(radians(${data.latitude})) * sin(radians(latitude))
)
)`;
let cafeDetails = await CafeDB.paginate(
{
where: {
deleted_at: 0,
is_active: 1,
signup_completed: 1,
profile_completed: 1,
menu_completed: 1,
loyalty_completed: 1,
},
include: [
{
model: userFavoriteCafes, as: 'user_favorite_cafes',
required: true,
where: {
is_favorite: 1,
user_id: parseInt(data.user_id)
},
attributes: ['is_favorite', 'user_id'],
},
{
model: CafeTimingDB,
as: 'time_sheet_data',
required: false,
where: {
day: todayDayId,
open_time: {
[Op.lte]: currentTime
},
close_time: {
[Op.gte]: currentTime
},
},
}
],
attributes: ['id', 'cafe_name', 'cafe_type', 'bio', 'cafe_tax', 'phone', 'banner_image', 'address', 'latitude', 'longitude', [sequelize.literal(`round(${haversine})`), 'distance'],],
order: [
['distance', 'asc'],
],
page: data.page,
paginate: parseInt(USER_SEARCH_LIMIT),
subQuery: false,
}
);
cafeDetails = JSON.stringify(cafeDetails)
cafeDetails = JSON.parse(cafeDetails)
for (let i = 0; i < cafeDetails.docs.length; i++) {
cafeDetails.docs[i].is_favorite = cafeDetails.docs[i].user_favorite_cafes.length > 0 ? 1 : 0;
cafeDetails.docs[i].is_open = ((cafeDetails.docs[i].time_sheet_data).length) ? 1 : 0
cafeDetails.docs[i].distance = cafeDetails.docs[i].distance ? cafeDetails.docs[i].distance : 0
let checkTotalOrder = await OrderDB.count({
where: {
user_id: data.user_id,
cafe_id: parseInt(cafeDetails.docs[i].id),
status: 2,
cafe_coupon_expired_time: 0
}
})
let nonUniversal = await LoyaltyStampDB.findOne({
where: {
cafe_id: parseInt(cafeDetails.docs[i].id),
is_universal: 0
},
attributes: ['stamp_no']
})
cafeDetails.docs[i].reward = nonUniversal ? nonUniversal.stamp_no - checkTotalOrder : 0;
}
(cafeDetails.docs).sort(
(p1, p2) =>
(p1.is_open < p2.is_open) ? 1 : (p1.is_open > p2.is_open) ? -1 : 0);
return cafeDetails;
} catch (error) {
throw new Error(error)
}
}
//get cafe by search cafe name
// get favorites cafe listing
export async function getCafeByName(data) {
try {
let todayDayId = new Date().getDay();
let currentTime = moment().format('HH:mm')
const haversine = `(
3959 * acos(
cos(radians(${data.latitude}))
* cos(radians(latitude))
* cos(radians(longitude) - radians(${data.longitude}))
+ sin(radians(${data.latitude})) * sin(radians(latitude))
)
)`;
let cafeDetails = await CafeDB.paginate(
{
page: parseInt(data.page),
paginate: parseInt(USER_SEARCH_LIMIT),
where: {
deleted_at: 0,
is_active: 1,
signup_completed: 1,
profile_completed: 1,
menu_completed: 1,
loyalty_completed: 1,
cafe_name: {
[Op.like]: `%${data.cafe_name}%`
}
},
include: [
{
model: userFavoriteCafes, as: 'user_favorite_cafes',
required: false,
where: {
is_favorite: 1,
user_id: parseInt(data.user_id)
},
attributes: ['is_favorite', 'user_id'],
},
{
model: CafeTimingDB,
as: 'time_sheet_data',
required: false,
where: {
day: todayDayId,
open_time: {
[Op.lte]: currentTime
},
close_time: {
[Op.gte]: currentTime
},
},
}
],
attributes: ['id', 'cafe_name', 'cafe_type', 'bio', 'cafe_tax', 'phone', 'banner_image', 'address', 'latitude', 'longitude', [sequelize.literal(`round(${haversine})`), 'distance'],],
order: [
['distance', 'asc'],
['id', 'desc']
],
subQuery: false,
}
);
cafeDetails = JSON.stringify(cafeDetails)
cafeDetails = JSON.parse(cafeDetails)
for (let i = 0; i < cafeDetails.docs.length; i++) {
cafeDetails.docs[i].is_favorite = cafeDetails.docs[i].user_favorite_cafes.length > 0 ? 1 : 0;
let checkTotalOrder = await OrderDB.count({
where: {
user_id: data.user_id,
cafe_id: parseInt(cafeDetails.docs[i].id),
status: 2,
cafe_coupon_expired_time: 0
}
})
let nonUniversal = await LoyaltyStampDB.findOne({
where: {
cafe_id: parseInt(cafeDetails.docs[i].id),
is_universal: 0
},
attributes: ['stamp_no']
})
cafeDetails.docs[i].reward = nonUniversal ? nonUniversal.stamp_no - checkTotalOrder : 0;
}
return cafeDetails;
} catch (error) {
throw new Error(error)
}
}
// find cafe in favorites list
export async function findFavoriteCafeById(cafe_id, user_id) {
try {
let cafeDetails = await userFavoriteCafes.findAll({
where: {
cafe_id: parseInt(cafe_id),
user_id: parseInt(user_id)
},
});
return cafeDetails;
} catch (error) {
throw new Error(error)
}
}
//favorite or unfavorite cafe
export async function favoriteCafeUpdate(user_id, cafe_id, updateData) {
try {
return await userFavoriteCafes.update(updateData, {
where: {
cafe_id: cafe_id,
user_id: user_id
},
});
} catch (error) {
throw new Error(error);
}
}
export async function deleteFavoriteCafe(user_id, cafe_id) {
try {
return await userFavoriteCafes.destroy({
where: {
cafe_id: cafe_id,
user_id: user_id
}
});
} catch (error) {
throw new Error(error);
}
}
export async function favoriteCafeAdd(favoriteCafeData) {
try {
return await userFavoriteCafes.create(favoriteCafeData);
} catch (error) {
throw new Error(error);
}
}
// request cafe API
export async function requestCafe(cafeData) {
try {
return await CafeDB.create(cafeData);
} catch (error) {
throw new Error(error);
}
}
// find request cafe API
export async function findRequestCafe(cafeData) {
try {
return await CafeDB.findOne({
where: {
email: cafeData.email
}
});
} catch (error) {
throw new Error(error);
}
}
// get cafe filter list
export async function cafeFilterList(data) {
try {
let option = {
where: {
is_active: 1
},
page: data.page,
paginate: 10,
attributes: ['id', 'name', 'image', 'color', 'light_color'],
order: [['id', 'ASC']],
}
return await cafeFilters.paginate(option);
} catch (error) {
throw new Error(error)
}
}
// get cafe item category
export async function getCafeItemCatgory(data) {
try {
if (['', null, undefined, 0].includes(data.page)) {
data.page = 1
}
data.page = parseInt(data.page)
let whereObject = {}
whereObject.cafe_id = parseInt(data.cafe_id)
whereObject.cafe_menu_deleted_at = 0
let option = {
where: whereObject,
page: data.page,
paginate: 10,
attributes: ['id', 'cafe_id', 'menu_name'],
order: [['id', 'DESC']],
}
let result = [];
result = await CafeMenuDB.paginate(option)
return result
} catch (error) {
throw new Error(error)
}
}
// get cafe item list by category ID
export async function getCafeItemList(data) {
try {
if (['', null, undefined, 0].includes(data.page)) {
data.page = 1
}
if (['', null, undefined].includes(parseInt(data.filter))) {
data.filter = ''
}
let whereObject = {}
whereObject.cafe_menu_id = parseInt(data.menu_id)
whereObject.item_deleted_at = 0
whereObject.status = 1
if (data.filter) {
whereObject.item_type = {
[Op.in]: (data.filter).split(",")
}
}
let option = {
where: whereObject,
page: parseInt(data.page),
paginate: 10,
include: [
{
model: PreDefinedImageDB,
as: 'image_data',
attributes: ['item_name', 'item_image'],
required: true
},
{
model: AddonSizeCafeItemDB,
include: [
{
model: AddonSizeDB,
attributes: ['addon_size_name', 'addon_size_price'],
required: false,
where: {
addon_size_deleted_at: 0
},
include: [
{
model: AddonDB,
required: false,
attributes: ['id', 'addon_name'],
}
]
}
],
required: false,
attributes: ['id', 'addon_size_id'],
},
{
model: CafeMenuItemSizeDB,
required: false,
attributes: ['id', 'item_size_price', 'size_id'],
include: [
{
model: SizeDB,
attributes: ['id', 'size_name']
}
]
}
],
attributes: ['id', 'cafe_id', 'cafe_menu_id', 'item_name', 'item_price', 'item_description', 'item_type'],
order: [['id', 'DESC']],
}
let result = await CafeMenuItemDB.paginate(option)
result = JSON.stringify(result)
result = JSON.parse(result)
for (let index = 0; index < result.docs.length; index++) {
const element = result.docs[index];
(element.cafe_menu_item_sizes).unshift({
id: 0,
item_size_price: element.item_price,
size_id: 0,
size: {
id: 0,
size_name: 'Regular'
}
})
element.cafe_menu_item_sizes.sort((a, b) => (a.size.id > b.size.id) ? 1 : ((b.size.id > a.size.id) ? -1 : 0))
delete result.addon_size_cafe_items
}
return result
} catch (error) {
throw new Error(error)
}
}
// cafe details
export async function getCafeDetails(id, userData) {
try {
const haversine = `(
3959 * acos(
cos(radians(${userData.user_latitude}))
* cos(radians(latitude))
* cos(radians(longitude) - radians(${userData.user_longitude}))
+ sin(radians(${userData.user_latitude})) * sin(radians(latitude))
)
)`;
let result = await CafeDB.findOne({
where: {
id: parseInt(id)
},
attributes: ['id', 'cafe_name', 'phone', 'cafe_tax', 'bio', 'email', 'banner_image', 'address', 'latitude', 'longitude', [sequelize.literal(`round(${haversine})`), 'distance']],
include: [
{
model: CafeTimingDB,
as: 'time_sheet_data'
},
{
model: userFavoriteCafes, as: 'user_favorite_cafes',
where: {
user_id: userData.user_id,
is_favorite: 1
},
attributes: ['is_favorite', 'user_id'],
required: false
}
],
})
if (result) {
result = JSON.stringify(result)
result = JSON.parse(result)
result.is_favorite = result.user_favorite_cafes.length > 0 ? 1 : 0;
}
return result
} catch (error) {
throw new Error(error)
}
}
// get cafe item details
export async function getCafeItemDetails(id) {
try {
let result = await CafeMenuItemDB.findOne({
where: {
id: id,
status: 1,
item_deleted_at: 0
},
include: [
{
model: CafeDB,
as: 'cafe_data',
attributes: ['cafe_name', 'phone', 'cafe_tax']
},
{
model: PreDefinedImageDB,
as: 'image_data',
attributes: ['item_name', 'item_image'],
},
{
model: AddonSizeCafeItemDB,
include: [
{
model: AddonSizeDB,
attributes: ['addon_size_name', 'addon_size_price'],
where: {
addon_size_deleted_at: 0
},
include: [
{
model: AddonDB,
attributes: ['id', 'addon_name'],
}
]
}
],
attributes: ['id', 'addon_size_id']
},
{
model: CafeMenuItemSizeDB,
attributes: ['id', 'item_size_price', 'size_id'],
include: [
{
model: SizeDB,
attributes: ['id', 'size_name']
}
]
}
],
attributes: ['id', 'item_name', 'item_description', 'item_image_id', 'item_image_id', 'item_type', 'item_price'],
})
if (result) {
result = JSON.stringify(result)
result = JSON.parse(result)
let tmp = [];
let addon_size_cafe_items = [];
for (let index = 0; index < result.addon_size_cafe_items.length; index++) {
const element = result.addon_size_cafe_items[index];
if (!tmp.includes(element.addon_size.addon.id)) {
tmp.push(element.addon_size.addon.id)
let addon_sizes = [{
addon_id: element.addon_size.addon.id,
addon_name: element.addon_size.addon.addon_name,
id: element.id,
addon_size_id: element.addon_size_id,
addon_size_name: element.addon_size.addon_size_name,
addon_size_price: element.addon_size.addon_size_price,
}]
addon_size_cafe_items.push({
addon_id: element.addon_size.addon.id,
addon_name: element.addon_size.addon.addon_name,
list: addon_sizes
})
} else {
let index = addon_size_cafe_items.findIndex(size => size.addon_id == element.addon_size.addon.id)
addon_size_cafe_items[index]['list'].push({
addon_id: element.addon_size.addon.id,
addon_name: element.addon_size.addon.addon_name,
id: element.id,
addon_size_id: element.addon_size_id,
addon_size_name: element.addon_size.addon_size_name,
addon_size_price: element.addon_size.addon_size_price,
})
}
}
(result.cafe_menu_item_sizes).unshift({
id: 0,
item_size_price: result.item_price,
size_id: 0,
size: {
id: 0,
size_name: 'Regular'
}
})
result.cafe_menu_item_sizes.sort((a, b) => (a.size.id > b.size.id) ? 1 : ((b.size.id > a.size.id) ? -1 : 0))
delete result.addon_size_cafe_items
result.addon_size_cafe_items = addon_size_cafe_items
}
return result
} catch (error) {
throw new Error(error)
}
}
// cafe suggested item list
export async function cafeItemSuggestedList(data) {
try {
let result = await SuggestedItemDB.paginate({
paginate: 10,
page: parseInt(data.page),
where: {
item_id: {
[Op.in]: (data.item_id).split(",")
}
},
include: [
{
model: CafeMenuItemDB,
where: {
status: 1,
item_deleted_at: 0
},
required: true,
attributes: ['id', 'item_name', 'item_description', 'item_image_id', 'item_type', 'item_price'],
include: [
{
model: PreDefinedImageDB,
as: 'image_data',
attributes: ['item_name', 'item_image'],
required: true
},
{
model: AddonSizeCafeItemDB,
include: [
{
model: AddonSizeDB,
required: false,
attributes: ['addon_size_name', 'addon_size_price'],
where: {
addon_size_deleted_at: 0
},
include: [
{
model: AddonDB,
required: false,
attributes: ['id', 'addon_name'],
}
]
}
],
required: false,
attributes: ['id', 'addon_size_id']
},
{
model: CafeMenuItemSizeDB,
required: false,
attributes: ['id', 'item_size_price', 'size_id'],
include: [
{
model: SizeDB,
attributes: ['id', 'size_name']
}
]
}
],
},
],
attributes: ['id', 'item_id']
})
return result
} catch (error) {
throw new Error(error)
}
}