params = Input::all(); $this->params = $this->params['params']; $this->reputationManagementService = $reputationManagementService; } public function getChannel(Request $request) { $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; try { $criteria = [ 'criteria' => [ ['field' => 'status', 'condition' => '=', 'value' => 1], ] ]; $reputationManagementChannel = $this->reputationManagementService->selectChannel($criteria, ['id', 'name', 'logo', 'parameter', 'logo']); $reputationManagementChannel = $reputationManagementChannel['status'] == 'success' && !empty($reputationManagementChannel['data']) ? $reputationManagementChannel['data'] : []; $reputationManagementMappingCriteria = [ 'criteria' => [ ['field' => 'property_id', 'condition' => '=', 'value' => $this->params['property_id']], ['field' => 'status', 'condition' => '=', 'value' => 1], ], 'with' => ['fetchStatus'], ]; $reputationManagementMapping = $this->reputationManagementService->selectChannelMapping($reputationManagementMappingCriteria); $reputationManagementMapping = $reputationManagementMapping['status'] == 'success' && !empty($reputationManagementMapping['data']) ? $reputationManagementMapping['data'] : []; $reputationManagementMappingCollect = collect($reputationManagementMapping); $reputationManagementList = []; foreach ($reputationManagementChannel as $reputationManagementChannelKey => $reputationManagementChannel) { $reputationManagementMapping = $reputationManagementMappingCollect->where('channel_id', $reputationManagementChannel['id'])->first(); $reputationManagementDetail = null; $isSelected = $reputationManagementMapping ? true : false; if ($reputationManagementMapping) { $reputationManagementDetail = [ 'fetchStatus' => $reputationManagementMapping['fetch_status'], 'parameterArray' => $reputationManagementMapping['parameterArray'] ]; } $reputationManagementList[] = [ //'code' => $webComponent['code'], 'id' => $reputationManagementChannel['id'], 'name' => $reputationManagementChannel['name'], 'logo' => $reputationManagementChannel['logo'], 'logoUrl' => $reputationManagementChannel['logoUrl'], 'parameterArray' => $reputationManagementChannel['parameterArray'], 'is_selected' => $isSelected, 'channelDetail' => $reputationManagementDetail ]; } $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $reputationManagementList]; } catch (ApiErrorException $e) { $response['message'] = implode(', ', $e->getMessageArr()); $response['statusCode'] = 400; } catch (Exception $e) { $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); Log::error($message); $response['message'] = $e->getMessage(); $response['statusCode'] = 500; } return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); } public function syncChannel(Request $request) { $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; try { $criteria = [ 'criteria' => [ ['field' => 'id', 'condition' => '=', 'value' => $this->params['channel_id']], ['field' => 'status', 'condition' => '=', 'value' => 1], ], 'firstRow' => true ]; $reputationManagementChannel = $this->reputationManagementService->selectChannel($criteria, ['id', 'name', 'logo', 'parameter', 'logo']); $reputationManagementChannel = $reputationManagementChannel['status'] == 'success' && !empty($reputationManagementChannel['data']) ? $reputationManagementChannel['data'] : []; if (empty($reputationManagementChannel)) { throw new ApiErrorException(lang('Channel data not found')); } //Parameter Check if (!empty($this->params['channelDetail'])) { $parameterCheck = array_diff(array_keys($reputationManagementChannel['parameterArray']), array_keys($this->params['channelDetail']['parameter'])); if (!empty($parameterCheck)) { throw new ApiErrorException(lang('Missing or incorrect parameter')); } } $reputationManagementChannelMappingCriteria = [ 'criteria' => [ ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($this->params, 'property_id')], ['field' => 'channel_id', 'condition' => '=', 'value' => fillOnUndefined($this->params, 'channel_id')], ['field' => 'status', 'condition' => '=', 'value' => 1], ], 'firstRow' => true ]; $reputationManagementChannelMapping = $this->reputationManagementService->selectChannelMapping($reputationManagementChannelMappingCriteria); $reputationManagementChannelMapping = $reputationManagementChannelMapping['status'] == 'success' && !empty($reputationManagementChannelMapping['data']) ? $reputationManagementChannelMapping['data'] : []; //Parameter Check DB::beginTransaction(); if ($reputationManagementChannelMapping) { //Remove if (empty($this->params['channelDetail'])) { $syncReputationManagementChannelMapping = $this->reputationManagementService->deleteChannelMapping($reputationManagementChannelMapping['id']); if ($syncReputationManagementChannelMapping['status'] != 'success') { throw new Exception('api-unknown_error'); } } else { //Update $updateParam = [ 'property_id' => fillOnUndefined($this->params, 'property_id'), 'channel_id' => fillOnUndefined($this->params, 'channel_id'), 'parameter' => fillOnUndefined($this->params['channelDetail'], 'parameter') ? json_encode($this->params['channelDetail']['parameter']) : null, 'fetch_status' => fillOnUndefined($reputationManagementChannelMapping, 'fetch_status'), 'updated_by' => $request->auth->id, ]; $syncReputationManagementChannelMapping = $this->reputationManagementService->updateChannelMapping($reputationManagementChannelMapping['id'], $updateParam); if ($syncReputationManagementChannelMapping['status'] != 'success') { throw new ApiErrorException($syncReputationManagementChannelMapping['message']); } } } else { $createParam = [ 'property_id' => fillOnUndefined($this->params, 'property_id'), 'channel_id' => fillOnUndefined($this->params, 'channel_id'), 'parameter' => fillOnUndefined($this->params['channelDetail'], 'parameter') ? json_encode($this->params['channelDetail']['parameter']) : null, 'fetch_status' => 3, 'status' => 1, 'created_by' => $request->auth->id, ]; $syncReputationManagementChannelMapping = $this->reputationManagementService->createChannelMapping($createParam); if ($syncReputationManagementChannelMapping['status'] != 'success') { throw new ApiErrorException($syncReputationManagementChannelMapping['message']); } //First Fetch Review dispatch(new PropertyReviewServiceJob($createParam['property_id'], $createParam['channel_id'])); } $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => null]; } catch (ApiErrorException $e) { $response['message'] = implode(', ', $e->getMessageArr()); $response['statusCode'] = 400; } catch (Exception $e) { $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); Log::error($message); $response['message'] = $e->getMessage(); $response['statusCode'] = 500; } if ($response['status']) { DB::commit(); } else { DB::rollBack(); } return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); } public function getReview(Request $request) { $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; try { $propertyReviewCriteria = [ 'criteria' => [ ['field' => 'property_id', 'condition' => '=', 'value' => $this->params['property_id']], ['field' => 'status', 'condition' => '=', 'value' => 1], ], 'with' => ['channel', 'channel', 'categoryMapping.category'], 'orderBy' => [ ['field' => 'review_date', 'value' => 'DESC'] ], ]; if (isset($this->params['filter']) && !empty(isset($this->params['filter']))) { if (isset($this->params['filter']['channel_id'])) { $propertyReviewCriteria['criteria'][] = ['field' => 'channel_id', 'condition' => '=', 'value' => $this->params['filter']['channel_id']]; } if (isset($this->params['filter']['start_date'])) { $propertyReviewCriteria['criteria'][] = ['field' => 'review_date', 'condition' => '>', 'value' => $this->params['filter']['start_date']]; } if (isset($this->params['filter']['end_date'])) { $propertyReviewCriteria['criteria'][] = ['field' => 'review_date', 'condition' => '<=', 'value' => $this->params['filter']['end_date']]; } if (isset($this->params['filter']['sentiment'])) { $propertyReviewCriteria['criteria'][] = ['field' => 'sentiment', 'condition' => '=', 'value' => $this->params['filter']['sentiment']]; } if (isset($this->params['filter']['keyword'])) { $propertyReviewCriteria['whereOr'][] = ['field' => 'author', 'condition' => 'LIKE', 'value' => '%' . $this->params['filter']['keyword'] . '%']; $propertyReviewCriteria['whereOr'][] = ['field' => 'title', 'condition' => 'LIKE', 'value' => '%' . $this->params['filter']['keyword'] . '%']; $propertyReviewCriteria['whereOr'][] = ['field' => 'review', 'condition' => 'LIKE', 'value' => '%' . $this->params['filter']['keyword'] . '%']; } } //Just Last 1 Year $propertyReviewCriteria['criteria'][] = ['field' => 'review_date', 'condition' => '>', 'value' => Carbon::now()->subYear()->toDateString()]; $propertyReviewCriteriaCount = $propertyReviewCriteria; $propertyReviewCriteriaCount['count'] = true; $propertyReviewCount = $this->reputationManagementService->select($propertyReviewCriteriaCount, ['id']); $propertyReviewCriteria['skip'] = fillOnUndefined($this->params, 'page', 0) ? ($this->params['page'] - 1) : 0; $propertyReviewCriteria['take'] = fillOnUndefined($this->params, 'per_page', 20); $propertyReviewCriteria['skip'] = $propertyReviewCriteria['skip'] * $propertyReviewCriteria['take']; $column = ['id', 'property_id', 'channel_id', 'author', 'title', 'review', 'review_date', 'rating', 'top_rating', 'score', 'sentiment', 'language']; $propertyReview = $this->reputationManagementService->select($propertyReviewCriteria, $column); $propertyReview = $propertyReview['status'] == 'success' && !empty($propertyReview['data']) ? $propertyReview['data'] : []; $propertyReviewList = [ 'total' => $propertyReviewCount['data'], 'page' => $this->params['page'], 'count' => count($propertyReview), 'review' => $propertyReview ]; $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyReviewList]; } catch (ApiErrorException $e) { $response['message'] = implode(', ', $e->getMessageArr()); $response['statusCode'] = 400; } catch (Exception $e) { $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); Log::error($message); $response['message'] = $e->getMessage(); $response['statusCode'] = 500; } return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); } public function getReviewStatistics(Request $request) { $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; try { $propertyReviewCriteria = [ 'criteria' => [ ['field' => 'property_id', 'condition' => '=', 'value' => $this->params['property_id']], ['field' => 'status', 'condition' => '=', 'value' => 1], ], 'with' => ['channel', 'channel', 'categoryMapping.category', 'keywordMapping'], 'orderBy' => [ ['field' => 'review_date', 'value' => 'DESC'] ], ]; if (isset($this->params['filter']) && !empty(isset($this->params['filter']))) { if (isset($this->params['filter']['channel_id'])) { $propertyReviewCriteria['criteria'][] = ['field' => 'channel_id', 'condition' => '=', 'value' => $this->params['filter']['channel_id']]; } if (isset($this->params['filter']['start_date'])) { $propertyReviewCriteria['criteria'][] = ['field' => 'review_date', 'condition' => '>', 'value' => $this->params['filter']['start_date']]; } if (isset($this->params['filter']['end_date'])) { $propertyReviewCriteria['criteria'][] = ['field' => 'review_date', 'condition' => '<=', 'value' => $this->params['filter']['end_date']]; } } //Just Last 1 Year $propertyReviewCriteria['criteria'][] = ['field' => 'review_date', 'condition' => '>', 'value' => Carbon::now()->subYear()->toDateString()]; $column = ['id', 'property_id', 'channel_id', 'review_date', 'rating', 'top_rating', 'score', 'sentiment', 'language']; $propertyReview = $this->reputationManagementService->select($propertyReviewCriteria, $column); $propertyReview = $propertyReview['status'] == 'success' && !empty($propertyReview['data']) ? $propertyReview['data'] : []; $propertyReviewStatistics['reviewScore'] = collect($propertyReview)->average('score'); $propertyReviewStatistics['reviewScore'] = (float)number_format($propertyReviewStatistics['reviewScore'], 2, '.', ''); $reviewSentimentGroup = collect($propertyReview)->groupBy('sentiment')->map->count(); $reviewSentimentGroup = $reviewSentimentGroup ? $reviewSentimentGroup->toArray() : null; $reviewSentiment['positive'] = isset($reviewSentimentGroup[1]) ? $reviewSentimentGroup[1] : 0; $reviewSentiment['negative'] = isset($reviewSentimentGroup[0]) ? $reviewSentimentGroup[0] : 0; $propertyReviewStatistics['reviewScoreBySystem'] = null; if (($reviewSentiment['positive'] + $reviewSentiment['negative']) > 0) { $propertyReviewStatistics['reviewScoreBySystem'] = $reviewSentiment['positive'] / ($reviewSentiment['positive'] + $reviewSentiment['negative']) * 100; $propertyReviewStatistics['reviewScoreBySystem'] = (float)number_format($propertyReviewStatistics['reviewScoreBySystem'], 2, '.', ''); } //$reviewCategoryScoreBySystem $reviewCategoryMapping = []; $reviewCategoryScoreBySystem = []; $reviewKeywordScoreBySystem = []; foreach ($propertyReview as $review) { foreach ($review['category_mapping'] as $reviewCategory) { if (!isset($reviewCategoryScoreBySystem[$reviewCategory['category_id']])) { $reviewCategoryScoreBySystem[$reviewCategory['category_id']][0] = 0; $reviewCategoryScoreBySystem[$reviewCategory['category_id']][1] = 0; } $reviewCategoryScoreBySystem[$reviewCategory['category_id']][$reviewCategory['sentiment']]++; $reviewCategoryMapping[$reviewCategory['category_id']]['name'] = $reviewCategory['category']['name']; $reviewCategoryMapping[$reviewCategory['category_id']]['score'][$review['review_date']] = $review['score']; if (!isset($reviewCategoryMapping[$reviewCategory['category_id']]['sentimentScore'][Carbon::parse($review['review_date'])->format('Y-m')])) { $reviewCategoryMapping[$reviewCategory['category_id']]['sentimentScore'][Carbon::parse($review['review_date'])->format('Y-m')][0] = 0; $reviewCategoryMapping[$reviewCategory['category_id']]['sentimentScore'][Carbon::parse($review['review_date'])->format('Y-m')][1] = 0; } $reviewCategoryMapping[$reviewCategory['category_id']]['sentimentScore'][Carbon::parse($review['review_date'])->format('Y-m')][$reviewCategory['sentiment']]++; } foreach ($review['keyword_mapping'] as $reviewKeyword) { if (!isset($reviewKeywordScoreBySystem[md5($reviewKeyword['keyword'])])) { $reviewKeywordScoreBySystem[md5($reviewKeyword['keyword'])]['positive'] = 0; $reviewKeywordScoreBySystem[md5($reviewKeyword['keyword'])]['negative'] = 0; $reviewKeywordScoreBySystem[md5($reviewKeyword['keyword'])]['keyword'] = $reviewKeyword['keyword']; } if ($reviewKeyword['sentiment'] == 1) { $reviewKeywordScoreBySystem[md5($reviewKeyword['keyword'])]['positive']++; } elseif ($reviewKeyword['sentiment'] == 0) { $reviewKeywordScoreBySystem[md5($reviewKeyword['keyword'])]['negative']++; } } } $propertyReviewCategoryCriteria = [ 'criteria' => [ ['field' => 'status', 'condition' => '=', 'value' => 1], ] ]; $propertyReviewCategory = $this->reputationManagementService->selectCategory($propertyReviewCategoryCriteria); $propertyReviewCategory = $propertyReviewCategory['status'] == 'success' ? $propertyReviewCategory['data'] : []; $propertyReviewCategoryScore = []; foreach ($propertyReviewCategory as $reviewCategory) { if (empty($reviewCategoryScoreBySystem)) { continue; } if (isset($reviewCategoryScoreBySystem[$reviewCategory['id']]) && array_sum($reviewCategoryScoreBySystem[$reviewCategory['id']]) < 5) { continue; } $propertyReviewCategoryScore[$reviewCategory['id']] = [ 'name' => $reviewCategory['name'], 'language_key' => $reviewCategory['language_key'], ]; $propertyReviewCategoryScore[$reviewCategory['id']]['score'] = null; if (isset($reviewCategoryScoreBySystem[$reviewCategory['id']])) { $propertyReviewCategoryScore[$reviewCategory['id']]['score'] = (float)number_format($reviewCategoryScoreBySystem[$reviewCategory['id']][1] / array_sum($reviewCategoryScoreBySystem[$reviewCategory['id']]) * 100, 2, '.', ''); $propertyReviewCategoryScore[$reviewCategory['id']]['positive'] = $reviewCategoryScoreBySystem[$reviewCategory['id']][1]; $propertyReviewCategoryScore[$reviewCategory['id']]['negative'] = $reviewCategoryScoreBySystem[$reviewCategory['id']][0]; $propertyReviewCategoryScore[$reviewCategory['id']]['total'] = array_sum($reviewCategoryScoreBySystem[$reviewCategory['id']]); krsort($reviewCategoryMapping[$reviewCategory['id']]['score']); $propertyReviewCategoryScore[$reviewCategory['id']]['scoreLastNumber'] = array_slice($reviewCategoryMapping[$reviewCategory['id']]['score'], 0, 10); //Group By Month /*$propertyReviewCategoryGroupScore = []; foreach ($reviewCategoryMapping[$reviewCategory['id']]['score'] as $reviewDateTime => $reviewScore) { $propertyReviewCategoryGroupScore[Carbon::parse($reviewDateTime)->format('m-Y')][] = $reviewScore; } $propertyReviewCategoryGroupScoreAverage = []; foreach ($propertyReviewCategoryGroupScore as $reviewPeriod => $reviewPeriodScore) { $propertyReviewCategoryGroupScoreAverage[$reviewPeriod] = round(collect($reviewPeriodScore)->avg()); }*/ //Group By Month //Group By Month ksort($reviewCategoryMapping[$reviewCategory['id']]['sentimentScore']); $propertyReviewCategoryGroupScoreAverage = []; foreach ($reviewCategoryMapping[$reviewCategory['id']]['sentimentScore'] as $reviewPeriod => $reviewPeriodScore) { $categorySentimentScore = (float)number_format($reviewPeriodScore[1] / array_sum($reviewPeriodScore) * 100, 2, '.', ''); if ($categorySentimentScore <= 0) { continue; } $propertyReviewCategoryGroupScoreAverage[$reviewPeriod] = round($categorySentimentScore); } //Group By Month $propertyReviewCategoryScore[$reviewCategory['id']]['scoreMonthlyGroup'] = $propertyReviewCategoryGroupScoreAverage; $propertyReviewCategoryScore[$reviewCategory['id']]['scoreMonthlyGroupAverage'] = (float)number_format(collect($propertyReviewCategoryGroupScoreAverage)->average(), 2, '.', ''); } } $propertyReviewStatistics['reviewCategoryScoreBySystem'] = array_values($propertyReviewCategoryScore); //$reviewCategoryScoreBySystem foreach ($reviewKeywordScoreBySystem as $reviewKeywordKey => $reviewKeyword) { if (($reviewKeyword['positive'] + $reviewKeyword['negative']) < 3) { unset($reviewKeywordScoreBySystem[$reviewKeywordKey]); continue; } if (isset($reviewKeywordScoreBySystem[$reviewKeywordKey])) { $reviewKeywordScoreBySystem[$reviewKeywordKey]['score'] = (float)number_format($reviewKeywordScoreBySystem[$reviewKeywordKey]['positive'] / array_sum($reviewKeywordScoreBySystem[$reviewKeywordKey]) * 100, 2, '.', ''); } } $propertyReviewStatistics['reviewKeywordScoreBySystem'] = array_values($reviewKeywordScoreBySystem); //Dashboard Summary $propertyReviewStatistics['dashboard'] = []; $currentWeekStart = Carbon::now()->startOfWeek(Carbon::MONDAY)->toDateString(); $currentWeekFinish = Carbon::now()->addWeek()->startOfWeek(Carbon::MONDAY)->toDateString(); //TOTAL $totalReview = count($propertyReview); $extraReviewCount = collect($propertyReview)->where('review_date', '>', $currentWeekStart)->count(); $propertyReviewStatistics['dashboard'] ['total'] = [ 'count' => $totalReview, 'extraReviewCount' => $extraReviewCount ]; //POSITIVE $totalReviewPositive = collect($propertyReview)->where('sentiment', 1)->count(); $extraPositiveReviewCount = collect($propertyReview)->where('review_date', '>', $currentWeekStart)->where('sentiment', 1)->count(); $propertyReviewStatistics['dashboard'] ['positive'] = [ 'count' => $totalReviewPositive, 'extraReviewCount' => $extraPositiveReviewCount ]; //NEGATIVE $totalReviewNegative = collect($propertyReview)->where('sentiment', '!=', 1)->count(); $extraNegativeReviewCount = collect($propertyReview)->where('review_date', '>', $currentWeekStart)->where('sentiment', '!=', 1)->count(); $propertyReviewStatistics['dashboard'] ['negative'] = [ 'count' => $totalReviewNegative, 'extraReviewCount' => $extraNegativeReviewCount ]; //BEST $bestReview = collect($propertyReviewCategoryScore)->sortByDesc('positive')->first(); $propertyReviewStatistics['dashboard'] ['best'] = [ 'name' => $bestReview['name'], 'language_key' => $bestReview['language_key'], 'score' => $bestReview['score'], 'positive' => $bestReview['positive'], 'negative' => $bestReview['negative'], 'total' => $bestReview['total'], ]; $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyReviewStatistics]; } catch (ApiErrorException $e) { $response['message'] = implode(', ', $e->getMessageArr()); $response['statusCode'] = 400; } catch (Exception $e) { $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); Log::error($message); $response['message'] = $e->getMessage(); $response['statusCode'] = 500; } return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); } }