Files
cheerstothe_season_2.0/app/Services/APIs/CustomerAPIs/RestaurantApiServices.php
Hritikkk9 6a00d7119f server up
2024-07-16 12:10:31 +00:00

566 lines
24 KiB
PHP

<?php
namespace App\Services\APIs\CustomerAPIs;
use Illuminate\Support\Facades\DB;
use App\Models\CustomerFavouriteRestaurant;
use App\Models\IamPrincipal;
use App\Models\IamPrincipalRestaurantRole;
use App\Models\ManageRestaurant;
use App\Models\RedeemRestaurant;
use App\Helpers\onesignalhelper;
use App\Models\RestaurantTimeInterval;
use App\Models\TimeInterval;
use Carbon\Carbon;
use Exception;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use App\Jobs\FetchOperatingHours;
use GuzzleHttp\Client;
use GuzzleHttp\Promise;
use GuzzleHttp\Promise\Utils;
class RestaurantApiServices
{
public function getCoordinates($customerIamId)
{
try {
// $perPage = request()->get('per_page', 10000);
$restaurants = ManageRestaurant::with('closedRestaurant')
->select(
'id',
'name',
'image',
'address',
'short_id',
'latitude',
'longtitude'
)
->where('is_active', '1')->get();
$client = new Client();
$promises = [];
$googlePlaceApiKey = config('constants.googlePlaces.api_key');
foreach ($restaurants as &$restaurant) {
$restaurant['image'] = ListingImageUrl('restaurant_images', $restaurant['image']);
$isFavourite = CustomerFavouriteRestaurant::where('principal_xid', $customerIamId)
->where('restaurant_xid', $restaurant['id'])
->exists();
$restaurant['is_favourite'] = $isFavourite;
$cacheKey = 'restaurant_hours_' . $restaurant['name'];
if (Cache::has($cacheKey)) {
$restaurant['operating_hours'] = Cache::get($cacheKey);
} else {
// Prepare the first request to get the place_id
$promises[$restaurant['name']] = $client->getAsync('https://maps.googleapis.com/maps/api/place/findplacefromtext/json', [
'query' => [
'fields' => 'place_id',
'input' => $restaurant['name'],
'inputtype' => 'textquery',
'key' => $googlePlaceApiKey
]
]);
}
}
// Execute all the first requests concurrently
$results = Utils::settle($promises)->wait();
$detailPromises = [];
foreach ($restaurants as &$restaurant) {
if (isset($results[$restaurant['name']]['value'])) {
$response = $results[$restaurant['name']]['value'];
$placeData = json_decode($response->getBody(), true);
if (isset($placeData['candidates'][0]['place_id'])) {
$placeId = $placeData['candidates'][0]['place_id'];
// Prepare the second request to get the operating hours
$detailPromises[$restaurant['name']] = $client->getAsync('https://maps.googleapis.com/maps/api/place/details/json', [
'query' => [
'fields' => 'opening_hours',
'place_id' => $placeId,
'key' => $googlePlaceApiKey
]
]);
} else {
$restaurant['operating_hours'] = "N/A";
}
}
}
// Execute all the second requests concurrently
$detailResults = Utils::settle($detailPromises)->wait();
foreach ($restaurants as &$restaurant) {
if (isset($detailResults[$restaurant['name']]['value'])) {
$response = $detailResults[$restaurant['name']]['value'];
$data = json_decode($response->getBody(), true);
if (isset($data['result']['opening_hours']['weekday_text'])) {
$hours = $data['result']['opening_hours']['weekday_text'];
Cache::put('restaurant_hours_' . $restaurant['name'], $hours, now()->addHours(24));
$restaurant['operating_hours'] = $hours;
} else {
$restaurant['operating_hours'] = "N/A";
}
}
}
return jsonResponseWithSuccessMessage(__('auth.data_fetched_successfully'), $restaurants, 200);
} catch (Exception $ex) {
Log::error('Restaurant Get service failed : ' . $ex->getMessage());
return jsonResponseWithErrorMessageApi(__('auth.something_went_wrong'), 500);
}
}
public function addToFavourite($customerIamId, $request)
{
try {
DB::beginTransaction();
$restaurant = ManageRestaurant::where('short_id', $request->id)->where('is_active', '1')->first();
if (!$restaurant) {
return jsonResponseWithErrorMessage(__('auth.restaurant_data_not_found'), 404);
}
$existingFavourite = CustomerFavouriteRestaurant::where('principal_xid', $customerIamId)
->where('restaurant_xid', $restaurant->id)
->first();
if ($existingFavourite) {
return jsonResponseWithErrorMessage(__('auth.restaurant_already_favourite'), 409);
}
$favRestaurant = new CustomerFavouriteRestaurant();
$favRestaurant->principal_xid = $customerIamId;
$favRestaurant->restaurant_xid = $restaurant->id;
$favRestaurant->save();
DB::commit();
return jsonResponseWithSuccessMessage(__('auth.data_updated_successfully'), 200);
} catch (\Exception $ex) {
DB::rollBack();
Log::error('Favourite Restaurant service failed: ' . $ex->getMessage());
return jsonResponseWithErrorMessageApi(__('auth.something_went_wrong'), 500);
}
}
public function listFavRestaurant($customerIamId)
{
try {
$list = CustomerFavouriteRestaurant::where('principal_xid', $customerIamId)->get()->toArray();
$customerFavouriteRestaurants = CustomerFavouriteRestaurant::where('principal_xid', $customerIamId)
->pluck('restaurant_xid')
->toArray();
$restaurants = ManageRestaurant::with('operatingHours')->where('is_active', '1')->whereIn('id', $customerFavouriteRestaurants)->get();
foreach ($restaurants as &$res) {
$res['image'] = ListingImageUrl('restaurant_images', $res['image']);
}
return jsonResponseWithSuccessMessage(__('auth.data_updated_successfully'), $restaurants, 200);
} catch (Exception $ex) {
Log::error('List of Favourite Restaurant service failed : ' . $ex->getMessage());
return jsonResponseWithErrorMessageApi(__('auth.something_went_wrong'), 500);
}
}
//
public function DetailRestaurant($customerIamId, $id)
{
try {
$rest = ManageRestaurant::select('id', 'short_id', 'name', 'description', 'restaurant_id', 'address', 'image', 'bio', 'try_on_1', 'try_on_2', 'try_on_3', 'try_on_4', 'exclusion', 'latitude', 'longtitude', 'state_xid')
->where('short_id', $id)
->where('is_active', '1')
->first();
if ($rest) {
$rest->image = ListingImageUrl('restaurant_images', $rest->image);
$isFavourite = CustomerFavouriteRestaurant::where('principal_xid', $customerIamId)
->where('restaurant_xid', $rest->id)
->exists();
$rest->is_favourite = $isFavourite;
$redeem = RedeemRestaurant::where('iam_principal_xid', $customerIamId)
->where('manage_restaurants_xid', $rest->id)
->where('is_redeem', "1")
->first();
$restTime = RestaurantTimeInterval::where('manage_restaurants_xid', $rest->id)->first();
$restTimeHours = $restTime->time_hours;
// Initialize Guzzle HTTP client
$client = new Client();
$googlePlaceApiKey = config('constants.googlePlaces.api_key');
// Cache key for operating hours
$cacheKey = 'restaurant_hours_' . $rest->name;
if (Cache::has($cacheKey)) {
$rest->operating_hours = Cache::get($cacheKey);
} else {
// Prepare the first request to get the place_id
$placeResponse = $client->get('https://maps.googleapis.com/maps/api/place/findplacefromtext/json', [
'query' => [
'fields' => 'place_id',
'input' => $rest->name,
'inputtype' => 'textquery',
'key' => $googlePlaceApiKey
]
]);
$placeData = json_decode($placeResponse->getBody(), true);
if (isset($placeData['candidates'][0]['place_id'])) {
$placeId = $placeData['candidates'][0]['place_id'];
// Prepare the second request to get the operating hours
$detailResponse = $client->get('https://maps.googleapis.com/maps/api/place/details/json', [
'query' => [
'fields' => 'opening_hours',
'place_id' => $placeId,
'key' => $googlePlaceApiKey
]
]);
$detailData = json_decode($detailResponse->getBody(), true);
if (isset($detailData['result']['opening_hours']['weekday_text'])) {
$hours = $detailData['result']['opening_hours']['weekday_text'];
Cache::put($cacheKey, $hours, now()->addHours(24));
$rest->operating_hours = $hours;
} else {
$rest->operating_hours = "N/A";
}
} else {
$rest->operating_hours = "N/A";
}
}
if ($redeem) {
$rest->is_Redeemed = true;
$rest->redeem_date = \Carbon\Carbon::parse($redeem->redeem_date)->addHours($restTimeHours)->toDateTimeString();
} else {
$rest->is_Redeemed = false;
$rest->redeem_date = null;
}
}
if (!$rest) {
return jsonResponseWithErrorMessage(__('auth.restaurant_data_not_found'), 404);
}
return jsonResponseWithSuccessMessage(__('auth.data_fetched_successfully'), $rest, 200);
} catch (Exception $e) {
Log::error("Error fetching restaurant data: " . $e->getMessage());
return jsonResponseWithErrorMessage(__('auth.something_went_wrong'), 500);
}
}
public function removeFromFavourite($customerIamId, $request)
{
try {
DB::beginTransaction();
$restaurant = ManageRestaurant::where('short_id', $request->id)->where('is_active', '1')->first();
if (!$restaurant) {
return jsonResponseWithErrorMessage(__('auth.restaurant_data_not_found'), 404);
}
$existingFavourite = CustomerFavouriteRestaurant::where('principal_xid', $customerIamId)
->where('restaurant_xid', $restaurant->id)
->first();
if (!$existingFavourite) {
return jsonResponseWithErrorMessage(__('auth.data_not_found'), 404);
}
if ($existingFavourite) {
$existingFavourite->delete();
}
DB::commit();
return jsonResponseWithSuccessMessage(__('auth.data_updated_successfully'), 200);
} catch (\Exception $ex) {
DB::rollBack();
Log::error('Favourite Restaurant service failed: ' . $ex->getMessage());
return jsonResponseWithErrorMessageApi(__('auth.something_went_wrong'), 500);
}
}
public function searchFromFavourite($customerIamId, $request)
{
try {
$customerFavouriteRestaurants = CustomerFavouriteRestaurant::where('principal_xid', $customerIamId)
->pluck('restaurant_xid')
->toArray();
$restaurantsQuery = ManageRestaurant::with('operatingHours')
->where('is_active', '1')
->whereIn('id', $customerFavouriteRestaurants);
$searchData = $request->input('search_data');
if (!empty($searchData)) {
$restaurantsQuery->where(function ($query) use ($searchData) {
$query->where('name', 'like', "%$searchData%")
->orWhere('description', 'like', "%$searchData%")
->orWhere('address', 'like', "%$searchData%")
->orWhereHas('state', function ($stateQuery) use ($searchData) {
$stateQuery->where('name', 'like', "%$searchData%");
});
});
}
$restaurants = $restaurantsQuery->get();
foreach ($restaurants as &$res) {
$res['image'] = ListingImageUrl('restaurant_images', $res['image']);
}
return jsonResponseWithSuccessMessageApi(__('auth.restaurant_search'), $restaurants, 200);
} catch (Exception $ex) {
Log::error('Search from favourite restaurant service failed: ' . $ex->getMessage());
return response()->json([
'message' => __('auth.something_went_wrong')
], 500);
}
}
public function redeemRestaurant($customerIamId, $request)
{
try {
$restaurantId = $request->id;
$restaurant = ManageRestaurant::with('operatingHours')->where('short_id', $restaurantId)->first();
if (!$restaurant) {
return jsonResponseWithErrorMessageApi(__('auth.restaurant_not_found'), 404);
}
// Check if the restaurant has already been redeemed
$restaurantExist = RedeemRestaurant::where('manage_restaurants_xid', $restaurant->id)
->where('iam_principal_xid', $customerIamId)
->where('is_redeem', 1)
->first();
if ($restaurantExist) {
return jsonResponseWithErrorMessageApi(__('auth.restaurant_already_redeemed'), 403);
}
$stateLimitation = TimeInterval::where('manage_state_xid', $restaurant->state_xid)->first();
$stateMaxLimitation = $stateLimitation ? $stateLimitation->quantity : 0;
$stateMaxIntervalLimitation = $stateLimitation ? $stateLimitation->time_interval : "month";
$restaurantLimitation = RestaurantTimeInterval::where('manage_restaurants_xid', $restaurant->id)->first();
$restaurantMaxLimitation = $restaurantLimitation ? $restaurantLimitation->quantity : 0;
$restaurantMaxIntervalLimitation = $restaurantLimitation ? $restaurantLimitation->time_interval : "month";
// Calculate the state interval start date
$stateIntervalStartDate = $this->calculateIntervalStartDate($stateMaxIntervalLimitation);
// Count the redeems within the state interval
$redeemCountState = RedeemRestaurant::where('state_xid', $restaurant->state_xid)
->where('iam_principal_xid', $customerIamId)
->count();
if ($redeemCountState >= $stateMaxLimitation) {
return jsonResponseWithErrorMessageApi(__('auth.state_limit_reached'), 403);
}
// Calculate the restaurant interval start date
$restaurantIntervalStartDate = $this->calculateIntervalStartDate($restaurantMaxIntervalLimitation);
// Count the redeems within the restaurant interval
$redeemCountRestaurant = RedeemRestaurant::where('manage_restaurants_xid', $restaurant->id)
->where('is_redeem', 1)
->where('iam_principal_xid', $customerIamId)
->count();
if ($redeemCountRestaurant >= $restaurantMaxLimitation) {
return jsonResponseWithErrorMessageApi(__('auth.restaurant_limit_reached'), 403);
}
// Get the last redeem time
$lastRedeem = RedeemRestaurant::where('iam_principal_xid', $customerIamId)
->where('state_xid', $restaurant->state_xid)
->where('is_redeem', 1)
->orderBy('redeem_date', 'desc')
->first();
$restTime = RestaurantTimeInterval::select('time_hours')->where('manage_restaurants_xid', $restaurant->id)->first();
$stateTime = TimeInterval::select('time_hours')->where('manage_state_xid', $restaurant->state_xid)->first();
$restTimeHours = $restTime ? $restTime->time_hours : 0;
$stateTimeHours = $stateTime ? $stateTime->time_hours : 0;
if ($lastRedeem) {
$lastRedeemTime = Carbon::parse($lastRedeem->redeem_date);
$currentTime = Carbon::now();
$stateAllowedRedeemTime = $lastRedeemTime->copy()->addHours($stateTimeHours);
$restAllowedRedeemTime = $lastRedeemTime->copy()->addHours($restTimeHours);
if ($currentTime < $stateAllowedRedeemTime) {
$remainingTime = $currentTime->diff($stateAllowedRedeemTime);
$hours = $remainingTime->h;
$minutes = $remainingTime->i;
return jsonResponseWithErrorMessageApi(__('auth.redeem_not_allowed_yet') . " {$hours} hours and {$minutes} minutes remaining.", 403);
}
if ($currentTime < $restAllowedRedeemTime) {
$remainingTime = $currentTime->diff($restAllowedRedeemTime);
$hours = $remainingTime->h;
$minutes = $remainingTime->i;
return jsonResponseWithErrorMessageApi(__('auth.redeem_not_allowed_yet') . " {$hours} hours and {$minutes} minutes remaining.", 403);
}
}
// Create a new redeem entry if it doesn't exist
$redeemRestaurant = new RedeemRestaurant();
$redeemRestaurant->iam_principal_xid = $customerIamId;
$redeemRestaurant->manage_restaurants_xid = $restaurant->id;
$redeemRestaurant->state_xid = $restaurant->state_xid;
$redeemRestaurant->is_redeem = 1; // Redeem restaurant
$redeemRestaurant->redeem_date = now();
$redeemRestaurant->is_redeemption_undone = 0;
$redeemRestaurant->redeemption_undone_date = null;
$redeemRestaurant->save();
$imagePath = ListingImageUrl('restaurant_images', $restaurant->image);
$customerTitle = "Your Redemption was successful for " . $restaurant->name;
$customerMessage = $restaurant->name . " Voucher Redeemed Successfully";
$customerContentType = 'Voucher_Redemption';
$customerImageUrl = $imagePath;
$customerData = IamPrincipal::where('id', $customerIamId)
->where('notification_status', 1)
->where('principal_type_xid', 3)
->first();
$restaurants = IamPrincipalRestaurantRole::select('id', 'principal_xid')
->where('restaurant_xid', $restaurant->id)
->get();
foreach ($restaurants as $restaurantRole) {
$restUser = IamPrincipal::where('id', $restaurantRole->principal_xid)
->where('notification_status', 1)
->where('principal_type_xid', 4)
->first();
if ($restUser) {
$restImagePath = ListingImageUrl('restaurant_images', $restaurant->image);
$restTitle = "New redemption for " . $restaurant->name;
$restMessage = $restaurant->name . " new voucher Redeemed Successfully";
$restContent_type = 'Voucher_Redemption';
$restImageUrl = $restImagePath;
// Sending notification to restaurant
onesignalhelper::restSendNotificationApi(
$restUser->one_signal_player_id,
$restTitle,
$restMessage,
$restContent_type,
$restImageUrl,
$id = null
);
onesignalhelper::StoreNotificationDetails($restUser->id, $restContent_type, $restTitle, $restImageUrl);
}
}
if ($customerData) {
// Sending notification to customer
onesignalhelper::sendNotificationApi(
$customerData->one_signal_player_id,
$customerTitle,
$customerMessage,
$customerContentType,
$customerImageUrl,
$id = null
);
onesignalhelper::StoreNotificationDetails($customerData->id, $customerContentType, $customerTitle, $customerImageUrl);
}
return jsonResponseWithSuccessMessageApi(__('success.restaurant_redeem'), $redeemRestaurant, 200);
} catch (Exception $ex) {
Log::error('Restaurant Redeem service failed: ' . $ex->getMessage());
return jsonResponseWithErrorMessageApi(__('auth.something_went_wrong'), 500);
}
}
private function calculateIntervalStartDate($interval)
{
$now = Carbon::now();
switch ($interval) {
case 'day':
return $now->copy()->subDay();
case 'week':
return $now->copy()->subWeek();
case 'month':
default:
return $now->copy()->subMonth();
}
}
public function searchRestaurant($customerIamId, $request)
{
try {
$restaurantsQuery = ManageRestaurant::with(['operatingHours', 'state'])
->where('is_active', '1');
$searchData = $request->input('search_data');
if (!empty($searchData)) {
$restaurantsQuery->where(function ($query) use ($searchData) {
$query->where('name', 'like', "%$searchData%")
->orWhere('description', 'like', "%$searchData%")
->orWhere('address', 'like', "%$searchData%")
->orWhereHas('state', function ($stateQuery) use ($searchData) {
$stateQuery->where('name', 'like', "%$searchData%");
});
});
}
$restaurants = $restaurantsQuery->get();
foreach ($restaurants as &$res) {
$res['image'] = ListingImageUrl('restaurant_images', $res['image']);
$res['is_favourite'] = CustomerFavouriteRestaurant::where('principal_xid', $customerIamId)
->where('restaurant_xid', $res->id)
->exists();
}
return jsonResponseWithSuccessMessageApi(__('auth.restaurant_search'), $restaurants, 200);
} catch (Exception $ex) {
Log::error('Search from restaurant service failed: ' . $ex->getMessage());
return response()->json([
'message' => __('auth.something_went_wrong')
], 500);
}
}
}