123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294 |
- import datetime
- import openpyxl
- from rest_framework import status
- from rest_framework.views import APIView
- from rest_framework.response import Response
- from gauth.models import Location, LocationManager
- from django.http import Http404
- from django.shortcuts import render, redirect
- from django.views.generic import View
- from django.contrib import messages
- from user.forms import StaffRegistrationForm, StaffSheetDateForm, GoogleReviewsFilter, FacebookReviewsFilter
- from review.models import Review
- from yelp.models import YelpReview
- from facebook_app.models import FacebookReview
- from name_extractor.models import Staff
- from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
- from django.shortcuts import get_object_or_404
- from .analytics import weekly_positive_review_count, get_weeks, weekly_negative_review_count
- from name_extractor.utils import extract_names_from_reviews, make_all_staffs_point_zero
- from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
- from user.utils import (
- get_google_review_report,
- get_facebook_report,
- get_yelp_review_report,
- date_str2datetime
- )
- from .forms import ImportStaffSpreadSheet
- LOC_SYN = {
- 'cypress-1960': 'cypress',
- 'collegestation': 'college station'
- }
- class LocationListView(View, PermissionRequiredMixin):
- permission_required = 'is_staff'
- def post(self, request, *args, **kwargs):
- form = ImportStaffSpreadSheet(request.POST, request.FILES)
- if form.is_valid():
- staff_file = form.cleaned_data.get('staff_file')
- wb = openpyxl.load_workbook(staff_file)
- worksheet = wb.worksheets[0]
- rows = worksheet.values
- col_names = next(rows)
- try:
- name_idx, loc_idx, dept_idx = col_names.index('Name'), col_names.index('Location'), col_names.index('Job Title')
- except ValueError:
- messages.warning(request, "Columns in missing. Check columns ['Name', 'Location', 'Job Title'] again.")
- return redirect('location-list')
- # Clear all previously registered staffs
- staffs = Staff.objects.all()
- staffs.delete()
- for row in rows:
- try:
- name, loc, dept = row[name_idx], row[loc_idx], row[dept_idx]
- except IndexError:
- pass
- if loc.lower() in ['alllocations', '#n/a']:
- continue
- if loc.lower() in LOC_SYN.keys():
- loc = LOC_SYN[loc.lower()]
- location = Location.objects.filter(care_name__icontains=loc).first()
- if location:
- Staff.objects.create(
- name=name,
- location=location,
- department=dept
- )
- messages.success(request, 'Staff file upload successfully.')
- return redirect('location-list')
- def get(self, request, *args, **kwargs):
- locations = Location.objects.all()
- form = ImportStaffSpreadSheet()
- context = {
- 'all_locations': locations,
- 'file_upload_form': form
- }
- return render(request, 'locations.html', context=context)
- class LocationAnalytics(LoginRequiredMixin, View):
- def get(self, request, location_id, *args, **kwargs):
- location = Location.objects.get(pk=location_id)
- google_report = get_google_review_report(location_id)
- facebook_report = get_facebook_report(location_id)
- yelp_report = get_yelp_review_report(location_id)
- context = {
- 'location': location,
- 'google_this_month_pos': google_report.get('this_month_pos'),
- 'google_last_month_pos': google_report.get('last_month_pos'),
- 'facebook_this_month_pos': facebook_report.get('this_month_pos'),
- 'facebook_last_month_pos': facebook_report.get('last_month_pos'),
- 'google_this_month_neg': google_report.get('this_month_neg'),
- 'google_last_month_neg': google_report.get('last_month_neg'),
- 'facebook_this_month_neg': facebook_report.get('this_month_neg'),
- 'facebook_last_month_neg': facebook_report.get('last_month_neg'),
- 'yelp': yelp_report
- }
- return render(request, 'manager-dashboard.html', context=context)
- class ReviewListLocationWise(View):
- def get(self, request, platform, location_id, *args, **kwargs):
- location = Location.objects.get(pk=location_id)
- if platform == 'google':
- form = GoogleReviewsFilter()
- reviews = Review.objects.filter(location_id=location_id).order_by('-update_time')
- elif platform == 'facebook':
- form = FacebookReviewsFilter()
- reviews = FacebookReview.objects.filter(page__location_id=location_id).order_by('-create_time')
- elif platform == 'yelp':
- form = GoogleReviewsFilter()
- reviews = YelpReview.objects.filter(location__location_id=location_id).order_by('-date_posted')
- else:
- raise Http404()
- page = request.GET.get('page', 1)
- paginator = Paginator(reviews, 50)
- try:
- reviews = paginator.page(page)
- except PageNotAnInteger:
- reviews = paginator.page(1)
- except EmptyPage:
- reviews = paginator.page(paginator.num_pages)
- context = {'reviews': reviews, 'platform': platform, 'location': location, 'form': form}
- return render(request, 'review-list-man.html', context=context)
- def post(self, request, platform, location_id, *args, **kwargs):
- location = Location.objects.get(pk=location_id)
- if platform == 'google':
- form = GoogleReviewsFilter(data=request.POST)
- start_date = date_str2datetime(request.POST.get('start_date'))
- end_date = date_str2datetime(request.POST.get('end_date'))
- if end_date < start_date:
- start_date, end_date = end_date, start_date
- star_rating = int(request.POST.get('star_ratings'))
- reviews = Review.objects.filter(location_id=location_id).order_by('-update_time')
- if start_date and end_date:
- if star_rating > 5:
- reviews = reviews.filter(create_time__range=(start_date, end_date))
- else:
- reviews = reviews.filter(create_time__range=(start_date, end_date), star_rating=star_rating)
- elif platform == 'yelp':
- form = GoogleReviewsFilter(data=request.POST)
- start_date = date_str2datetime(request.POST.get('start_date'))
- end_date = date_str2datetime(request.POST.get('end_date'))
- if end_date < start_date:
- start_date, end_date = end_date, start_date
- star_rating = int(request.POST.get('star_ratings'))
- reviews = YelpReview.objects.filter(location__location_id=location_id).order_by('-date_posted')
- if start_date and end_date:
- if star_rating > 5:
- reviews = reviews.filter(date_posted__range=(start_date, end_date))
- else:
- reviews = reviews.filter(date_posted__range=(start_date, end_date), rating=star_rating)
- elif platform == 'facebook':
- form = FacebookReviewsFilter(request.POST)
- start_date = date_str2datetime(request.POST.get('start_date'))
- end_date = date_str2datetime(request.POST.get('end_date'))
- star_rating = int(request.POST.get('star_ratings'))
- reviews = FacebookReview.objects.filter(page__location_id=location_id).order_by('-create_time')
- if start_date and end_date:
- if star_rating > 5:
- reviews = reviews.filter(create_time__range=(start_date, end_date))
- else:
- reviews = reviews.filter(create_time__range=(start_date, end_date), recommendation_type=bool(star_rating))
- else:
- raise Http404()
- page = request.GET.get('page', 1)
- paginator = Paginator(reviews, 50)
- try:
- reviews = paginator.page(page)
- except PageNotAnInteger:
- reviews = paginator.page(1)
- except EmptyPage:
- reviews = paginator.page(paginator.num_pages)
- context = {'reviews': reviews, 'platform': platform, 'location': location, 'form': form}
- return render(request, 'review-list-man.html', context=context)
- class ReviewAnalyticsGraph(View):
- def get(self, request, location_id, *args, **kwargs):
- location = Location.objects.get(pk=location_id)
- return render(request, 'location-wise-reviews-man.html', context={'location': location})
- class StaffLeaderBoard(View):
- def get(self, request, location_id, *args, **kwargs):
- location = Location.objects.get(pk=location_id)
- staffs = Staff.objects.filter(location=location).order_by('-total_units')
- form = StaffRegistrationForm()
- date_form = StaffSheetDateForm()
- context = {
- 'location': location,
- 'staffs': staffs,
- 'date_form': date_form,
- 'form': form
- }
- return render(request, 'staff_list_man.html', context)
- def post(self, request, location_id, *args, **kwargs):
- form = StaffRegistrationForm(request.POST)
- if form.is_valid():
- name = form.cleaned_data.get('name')
- department = form.cleaned_data.get('department')
- nick_names = form.cleaned_data.get('nick_names')
- staff = Staff.objects.create(
- name=name,
- location_id=location_id,
- department=department,
- nick_names=nick_names
- )
- messages.success(request, f'A new staff {staff} has been created!')
- return redirect('staff-leaderboard-man', location_id=location_id)
- class SyncStaffLeaderBoard(View):
- def post(self, request, location_id, *args, **kwargs):
- start_date = date_str2datetime(request.POST.get('start_date'))
- end_date = date_str2datetime(request.POST.get('end_date'))
- extract_names_from_reviews(
- start_date=start_date,
- end_date=end_date,
- location_id=location_id
- )
- return redirect('staff-leaderboard-man', location_id=location_id)
- class StaffDelete(View):
- def get(self, request, staff_id, *args, **kwargs):
- staff = get_object_or_404(Staff, id=staff_id)
- staff.delete()
- return redirect('staff-leaderboard-man', location_id=staff.location_id)
- class AllLocationSummary(APIView):
- def get(self, request, *args, **kwargs):
- days = request.GET['days']
- if not days:
- return Response({'error': 'No location Found'}, status=status.HTTP_400_BAD_REQUEST)
- locations = Location.objects.all()
- review_counts = []
- for location in locations:
- loc_json = {
- 'name': location.care_name,
- 'positive': [
- location.last_week_pos_google_review_count,
- location.last_week_pos_facebook_review_count,
- location.last_week_pos_yelp_review_count
- ],
- 'negative': [
- location.last_week_neg_google_review_count,
- location.last_week_neg_facebook_review_count,
- location.last_week_neg_yelp_review_count
- ]
- }
- review_counts.append(loc_json)
- response = {
- 'labels': ['Google', 'Facebook', 'Yelp'],
- 'review_counts': review_counts,
- }
- return Response(response)
- class ReviewAnalysis(APIView):
- def get(self, request, *args, **kwargs):
- now = datetime.datetime.now()
- pos_ratings, labels = weekly_positive_review_count()
- neg_ratings = weekly_negative_review_count()
- weeks = get_weeks(now.year, now.isocalendar()[1])
- weeks = [datetime.date.fromisocalendar(w[1], w[0], 7) for w in weeks]
- response = {
- "weeks": weeks,
- "pos_data": pos_ratings,
- "neg_data": neg_ratings,
- "labels": labels
- }
- return Response(response)
|