def sms_dashboard(request, on_index=None): """SMS dashboard gives the following information * No of SMSCampaigns for logged in user * Total phonebook contacts * Total SMSCampaigns contacts * Amount of contact reached today * Disposition of sms via pie chart * SMS count shown on graph by days/hours **Attributes**: * ``template`` - mod_sms/sms_dashboard.html * ``form`` - SMSDashboardForm """ # All sms_campaign for logged in User sms_campaign_id_list = SMSCampaign.objects.values_list('id', flat=True).filter(user=request.user).order_by('id') # Contacts count which are active and belong to those phonebook(s) which is # associated with all sms campaign pb_active_contact_count = Contact.objects.filter( phonebook__smscampaign__in=sms_campaign_id_list, status=CONTACT_STATUS.ACTIVE).count() form = SMSDashboardForm(request.user, request.POST or None) total_record = dict() total_sms_count = 0 total_unsent = 0 total_sent = 0 total_delivered = 0 total_failed = 0 total_no_route = 0 total_unauthorized = 0 select_graph_for = 'sms count' # default search_type = SEARCH_TYPE.D_Last_24_hours # default Last 24 hours selected_sms_campaign = '' if sms_campaign_id_list: selected_sms_campaign = sms_campaign_id_list[0] # default sms campaign id # selected_sms_campaign should not be empty if selected_sms_campaign: if form.is_valid(): selected_sms_campaign = request.POST['smscampaign'] search_type = request.POST['search_type'] end_date = datetime.utcnow().replace(tzinfo=utc) start_date = calculate_date(search_type) # date_length is used to do group by starting_date if int(search_type) >= SEARCH_TYPE.B_Last_7_days: # all options except 30 days date_length = 13 if int(search_type) == SEARCH_TYPE.C_Yesterday: # yesterday now = datetime.utcnow().replace(tzinfo=utc) start_date = datetime(now.year, now.month, now.day, 0, 0, 0, 0).replace(tzinfo=utc) \ - relativedelta(days=1) end_date = datetime(now.year, now.month, now.day, 23, 59, 59, 999999).replace(tzinfo=utc) \ - relativedelta(days=1) if int(search_type) >= SEARCH_TYPE.E_Last_12_hours: date_length = 16 else: date_length = 10 # Last 30 days option select_data = { "send_date": "SUBSTR(CAST(send_date as CHAR(30)),1," + str(date_length) + ")"} # This calls list is used by pie chart list_sms = SMSMessage.objects.filter( sender=request.user, sms_campaign_id=selected_sms_campaign, send_date__range=(start_date, end_date))\ .extra(select=select_data)\ .values('send_date', 'status')\ .annotate(Count('send_date'))\ .order_by('send_date') for i in list_sms: # convert unicode date string into date if i['status'] == 'Unsent': total_unsent += i['send_date__count'] elif i['status'] == 'Sent': total_sent += i['send_date__count'] elif i['status'] == 'Delivered': total_delivered += i['send_date__count'] elif i['status'] == 'Failed': total_failed += i['send_date__count'] elif i['status'] == 'No_Route': total_no_route += i['send_date__count'] else: total_unauthorized += i['send_date__count'] # Unauthorized total_sms_count += i['send_date__count'] list_sms = SMSMessage.objects.filter( sender=request.user, sms_campaign_id=selected_sms_campaign, send_date__range=(start_date, end_date))\ .extra(select=select_data).values('send_date')\ .annotate(Count('send_date')).order_by('send_date') mintime = start_date maxtime = end_date sms_dict = {} sms_dict_with_min = {} for data in list_sms: if int(search_type) >= SEARCH_TYPE.B_Last_7_days: ctime = datetime(int(data['send_date'][0:4]), int(data['send_date'][5:7]), int(data['send_date'][8:10]), int(data['send_date'][11:13]), 0, 0, 0).replace(tzinfo=utc) if int(search_type) >= SEARCH_TYPE.E_Last_12_hours: ctime = datetime(int(data['send_date'][0:4]), int(data['send_date'][5:7]), int(data['send_date'][8:10]), int(data['send_date'][11:13]), int(data['send_date'][14:16]), 0, 0).replace(tzinfo=utc) else: ctime = datetime(int(data['send_date'][0:4]), int(data['send_date'][5:7]), int(data['send_date'][8:10]), 0, 0, 0, 0).replace(tzinfo=utc) if ctime > maxtime: maxtime = ctime elif ctime < mintime: mintime = ctime # all options except 30 days if int(search_type) >= SEARCH_TYPE.B_Last_7_days: sms_dict[int(ctime.strftime("%Y%m%d%H"))] = { 'sms_count': data['send_date__count'] } sms_dict_with_min[int(ctime.strftime("%Y%m%d%H%M"))] = { 'sms_count': data['send_date__count'] } else: # Last 30 days option sms_dict[int(ctime.strftime("%Y%m%d"))] = { 'sms_count': data['send_date__count'] } dateList = date_range(mintime, maxtime, q=search_type) i = 0 total_record = {} for date in dateList: inttime = int(date.strftime("%Y%m%d")) # last 7 days | yesterday | last 24 hrs if (int(search_type) == SEARCH_TYPE.B_Last_7_days or int(search_type) == SEARCH_TYPE.C_Yesterday or int(search_type) == SEARCH_TYPE.D_Last_24_hours): for option in range(0, 24): day_time = int(str(inttime) + str(option).zfill(2)) graph_day = datetime(int(date.strftime("%Y")), int(date.strftime("%m")), int(date.strftime("%d")), int(str(option).zfill(2))).replace(tzinfo=utc) dt = int(1000 * time.mktime(graph_day.timetuple())) total_record[dt] = {'sms_count': 0} if day_time in sms_dict.keys(): total_record[dt]['sms_count'] += sms_dict[day_time]['sms_count'] # last 12 hrs | last 6 hrs | last 1 hrs elif (int(search_type) == SEARCH_TYPE.E_Last_12_hours or int(search_type) == SEARCH_TYPE.F_Last_6_hours or int(search_type) == SEARCH_TYPE.G_Last_hour): for hour in range(0, 24): for minute in range(0, 60): hr_time = int(str(inttime) + str(hour).zfill(2) + str(minute).zfill(2)) graph_day = datetime(int(date.strftime("%Y")), int(date.strftime("%m")), int(date.strftime("%d")), int(str(hour).zfill(2)), int(str(minute).zfill(2))).replace(tzinfo=utc) dt = int(1000 * time.mktime(graph_day.timetuple())) total_record[dt] = {'sms_count': 0} if hr_time in sms_dict_with_min.keys(): total_record[dt]['sms_count'] += sms_dict_with_min[hr_time]['sms_count'] else: # Last 30 days option graph_day = datetime(int(date.strftime("%Y")), int(date.strftime("%m")), int(date.strftime("%d"))).replace(tzinfo=utc) dt = int(1000 * time.mktime(graph_day.timetuple())) total_record[dt] = {'sms_count': 0} if inttime in sms_dict.keys(): total_record[dt]['sms_count'] += sms_dict[inttime]['sms_count'] # sorting on date col total_record = total_record.items() total_record = sorted(total_record, key=lambda k: k[0]) # lineWithFocusChart final_charttype = "lineWithFocusChart" xdata = [] ydata = [] for i in total_record: xdata.append(i[0]) ydata.append(i[1]['sms_count']) tooltip_date = "%d %b %y %H:%M %p" extra_serie1 = { "tooltip": {"y_start": "", "y_end": " SMS"}, "date_format": tooltip_date } final_chartdata = { 'x': xdata, 'name1': 'SMS', 'y1': ydata, 'extra1': extra_serie1, } # Contacts which are successfully messaged for running sms campaign reached_contact = 0 if sms_campaign_id_list: now = datetime.utcnow().replace(tzinfo=utc) start_date = datetime(now.year, now.month, now.day, 0, 0, 0, 0).replace(tzinfo=utc) end_date = datetime(now.year, now.month, now.day, 23, 59, 59, 999999).replace(tzinfo=utc) sms_campaign_subscriber = SMSCampaignSubscriber.objects.filter( sms_campaign_id__in=sms_campaign_id_list, status=SMS_SUBSCRIBER_STATUS.COMPLETE, updated_date__range=(start_date, end_date)).count() reached_contact += sms_campaign_subscriber # PieChart sms_analytic_charttype = "pieChart" xdata = [] ydata = [] sms_analytic_chartdata = {'x': xdata, 'y1': ydata} if total_sms_count != 0: for i in SMS_MESSAGE_STATUS: xdata.append(i[0].upper()) # Y-axis order depend upon SMS_MESSAGE_STATUS # 'UNSENT', 'SENT', 'DELIVERED', 'FAILED', 'NO_ROUTE', 'UNAUTHORIZED' ydata = [ percentage(total_unsent, total_sms_count), percentage(total_sent, total_sms_count), percentage(total_delivered, total_sms_count), percentage(total_failed, total_sms_count), percentage(total_no_route, total_sms_count), percentage(total_unauthorized, total_sms_count), ] color_list = [ COLOR_SMS_DISPOSITION['UNSENT'], COLOR_SMS_DISPOSITION['SENT'], COLOR_SMS_DISPOSITION['DELIVERED'], COLOR_SMS_DISPOSITION['FAILED'], COLOR_SMS_DISPOSITION['NO_ROUTE'], COLOR_SMS_DISPOSITION['UNAUTHORIZED'], ] extra_serie = { "tooltip": {"y_start": "", "y_end": " %"}, "color_list": color_list } kwargs1 = {} kwargs1['resize'] = True sms_analytic_chartdata = { 'x': xdata, 'y1': ydata, 'extra1': extra_serie, 'kwargs1': kwargs1, } data = { 'form': form, 'SEARCH_TYPE': SEARCH_TYPE, 'pb_active_contact_count': pb_active_contact_count, 'reached_contact': reached_contact, 'total_record': total_record, 'select_graph_for': select_graph_for, 'total_sms_count': total_sms_count, 'total_unsent': total_unsent, 'total_sent': total_sent, 'total_delivered': total_delivered, 'total_failed': total_failed, 'total_no_route': total_no_route, 'total_unauthorized': total_unauthorized, 'unsent_color': COLOR_SMS_DISPOSITION['UNSENT'], 'sent_color': COLOR_SMS_DISPOSITION['SENT'], 'delivered_color': COLOR_SMS_DISPOSITION['DELIVERED'], 'failed_color': COLOR_SMS_DISPOSITION['FAILED'], 'no_route_color': COLOR_SMS_DISPOSITION['NO_ROUTE'], 'unauthorized_color': COLOR_SMS_DISPOSITION['UNAUTHORIZED'], 'final_chartcontainer': 'lineplusbarwithfocuschart_container', 'final_chartdata': final_chartdata, 'final_charttype': final_charttype, 'final_extra': { 'x_is_date': True, 'x_axis_format': '%d %b %Y', 'tag_script_js': True, 'jquery_on_ready': False, }, 'sms_analytic_chartcontainer': 'piechart_container', 'sms_analytic_charttype': sms_analytic_charttype, 'sms_analytic_chartdata': sms_analytic_chartdata, 'sms_analytic_extra': { 'x_is_date': False, 'x_axis_format': '', 'tag_script_js': True, 'jquery_on_ready': False, }, } if on_index == 'yes': return data return render_to_response('mod_sms/sms_dashboard.html', data, context_instance=RequestContext(request))
def customer_dashboard(request, on_index=None): """Customer dashboard gives the following information * Total Campaigns contacts * Amount of contact reached today * Disposition of calls via pie chart * Call records & Duration of calls are shown on graph by days/hours **Attributes**: * ``template`` - frontend/dashboard.html * ``form`` - DashboardForm """ logging.debug('Start Dashboard') # All campaign for logged in User campaign_id_list = Campaign.objects.values_list( 'id', flat=True).filter(user=request.user).order_by('id') # Contacts count which are active and belong to those phonebook(s) which is # associated with all campaign pb_active_contact_count = Contact.objects\ .filter(phonebook__campaign__in=campaign_id_list, status=CONTACT_STATUS.ACTIVE).count() form = DashboardForm(request.user, request.POST or None) logging.debug('Got Campaign list') total_record = dict() total_duration_sum = 0 total_billsec_sum = 0 total_call_count = 0 total_answered = 0 total_not_answered = 0 total_busy = 0 total_cancel = 0 total_congestion = 0 total_failed = 0 search_type = SEARCH_TYPE.D_Last_24_hours # default Last 24 hours selected_campaign = '' if campaign_id_list: selected_campaign = campaign_id_list[0] # default campaign id # selected_campaign should not be empty if selected_campaign: if form.is_valid(): selected_campaign = request.POST['campaign'] search_type = request.POST['search_type'] end_date = datetime.utcnow().replace(tzinfo=utc) start_date = calculate_date(search_type) # date_length is used to do group by starting_date if int(search_type ) >= SEARCH_TYPE.B_Last_7_days: # all options except 30 days date_length = 13 if int(search_type) == SEARCH_TYPE.C_Yesterday: # yesterday tday = datetime.utcnow().replace(tzinfo=utc) start_date = datetime(tday.year, tday.month, tday.day, 0, 0, 0, 0)\ .replace(tzinfo=utc) - relativedelta(days=1) end_date = datetime(tday.year, tday.month, tday.day, 23, 59, 59, 999999)\ .replace(tzinfo=utc) - relativedelta(days=1) if int(search_type) >= SEARCH_TYPE.E_Last_12_hours: date_length = 16 else: date_length = 10 # Last 30 days option select_data = { "starting_date": "SUBSTR(CAST(starting_date as CHAR(30)),1,%s)" % str(date_length) } # This calls list is used by pie chart calls = VoIPCall.objects\ .filter(callrequest__campaign=selected_campaign, duration__isnull=False, user=request.user, starting_date__range=(start_date, end_date))\ .extra(select=select_data)\ .values('starting_date', 'disposition')\ .annotate(Count('starting_date'))\ .order_by('starting_date') logging.debug('Aggregate VoIPCall') for i in calls: total_call_count += i['starting_date__count'] if i['disposition'] == CALL_DISPOSITION.ANSWER or i[ 'disposition'] == 'NORMAL_CLEARING': total_answered += i['starting_date__count'] elif i['disposition'] == CALL_DISPOSITION.BUSY or i[ 'disposition'] == 'USER_BUSY': total_busy += i['starting_date__count'] elif i['disposition'] == CALL_DISPOSITION.NOANSWER or i[ 'disposition'] == 'NO_ANSWER': total_not_answered += i['starting_date__count'] elif i['disposition'] == CALL_DISPOSITION.CANCEL or i[ 'disposition'] == 'ORIGINATOR_CANCEL': total_cancel += i['starting_date__count'] elif i['disposition'] == CALL_DISPOSITION.CONGESTION or i[ 'disposition'] == 'NORMAL_CIRCUIT_CONGESTION': total_congestion += i['starting_date__count'] else: # VOIP CALL FAILED total_failed += i['starting_date__count'] # following calls list is without disposition & group by call date calls = VoIPCall.objects\ .filter(callrequest__campaign=selected_campaign, duration__isnull=False, user=request.user, starting_date__range=(start_date, end_date))\ .extra(select=select_data)\ .values('starting_date')\ .annotate(Sum('duration'))\ .annotate(Sum('billsec'))\ .annotate(Avg('duration'))\ .annotate(Count('starting_date'))\ .order_by('starting_date') logging.debug('Aggregate VoIPCall (2)') mintime = start_date maxtime = end_date calls_dict = {} calls_dict_with_min = {} for call in calls: total_duration_sum += call['duration__sum'] total_billsec_sum += call['billsec__sum'] if int(search_type) >= SEARCH_TYPE.B_Last_7_days: ctime = datetime(int(call['starting_date'][0:4]), int(call['starting_date'][5:7]), int(call['starting_date'][8:10]), int(call['starting_date'][11:13]), 0, 0, 0).replace(tzinfo=utc) if int(search_type) >= SEARCH_TYPE.E_Last_12_hours: ctime = datetime(int(call['starting_date'][0:4]), int(call['starting_date'][5:7]), int(call['starting_date'][8:10]), int(call['starting_date'][11:13]), int(call['starting_date'][14:16]), 0, 0).replace(tzinfo=utc) else: ctime = datetime(int(call['starting_date'][0:4]), int(call['starting_date'][5:7]), int(call['starting_date'][8:10]), 0, 0, 0, 0).replace(tzinfo=utc) if ctime > maxtime: maxtime = ctime elif ctime < mintime: mintime = ctime # all options except 30 days if int(search_type) >= SEARCH_TYPE.B_Last_7_days: calls_dict[int(ctime.strftime("%Y%m%d%H"))] =\ { 'call_count': call['starting_date__count'], 'duration_sum': call['duration__sum'], 'duration_avg': float(call['duration__avg']), } calls_dict_with_min[int(ctime.strftime("%Y%m%d%H%M"))] =\ { 'call_count': call['starting_date__count'], 'duration_sum': call['duration__sum'], 'duration_avg': float(call['duration__avg']), } else: # Last 30 days option calls_dict[int(ctime.strftime("%Y%m%d"))] =\ { 'call_count': call['starting_date__count'], 'duration_sum': call['duration__sum'], 'duration_avg': float(call['duration__avg']), } logging.debug('After Call Loops') dateList = date_range(mintime, maxtime, q=search_type) for date in dateList: inttime = int(date.strftime("%Y%m%d")) # last 7 days | yesterday | last 24 hrs if int(search_type) == SEARCH_TYPE.B_Last_7_days \ or int(search_type) == SEARCH_TYPE.C_Yesterday \ or int(search_type) == SEARCH_TYPE.D_Last_24_hours: for option in range(0, 24): day_time = int(str(inttime) + str(option).zfill(2)) graph_day = datetime( int(date.strftime("%Y")), int(date.strftime("%m")), int(date.strftime("%d")), int(str(option).zfill(2))).replace(tzinfo=utc) dt = int(1000 * time.mktime(graph_day.timetuple())) total_record[dt] = { 'call_count': 0, 'duration_sum': 0, 'duration_avg': 0.0, } if day_time in calls_dict.keys(): total_record[dt]['call_count'] += calls_dict[day_time][ 'call_count'] total_record[dt]['duration_sum'] += calls_dict[ day_time]['duration_sum'] total_record[dt]['duration_avg'] += float( calls_dict[day_time]['duration_avg']) # last 12 hrs | last 6 hrs | last 1 hr elif (int(search_type) == SEARCH_TYPE.E_Last_12_hours or int(search_type) == SEARCH_TYPE.F_Last_6_hours or int(search_type) == SEARCH_TYPE.G_Last_hour): for hour in range(0, 24): for minute in range(0, 60): hr_time = int( str(inttime) + str(hour).zfill(2) + str(minute).zfill(2)) graph_day = datetime( int(date.strftime("%Y")), int(date.strftime("%m")), int(date.strftime("%d")), int(str(hour).zfill(2)), int(str(minute).zfill(2))).replace(tzinfo=utc) dt = int(1000 * time.mktime(graph_day.timetuple())) total_record[dt] = { 'call_count': 0, 'duration_sum': 0, 'duration_avg': 0.0, } if hr_time in calls_dict_with_min.keys(): total_record[dt][ 'call_count'] += calls_dict_with_min[hr_time][ 'call_count'] total_record[dt][ 'duration_sum'] += calls_dict_with_min[ hr_time]['duration_sum'] total_record[dt]['duration_avg'] += float( calls_dict_with_min[hr_time]['duration_avg']) else: # Default: Last 30 days option graph_day = datetime( int(date.strftime("%Y")), int(date.strftime("%m")), int(date.strftime("%d"))).replace(tzinfo=utc) dt = int(1000 * time.mktime(graph_day.timetuple())) total_record[dt] = { 'call_count': 0, 'duration_sum': 0, 'duration_avg': 0, } if inttime in calls_dict.keys(): total_record[dt]['call_count'] += calls_dict[inttime][ 'call_count'] total_record[dt]['duration_sum'] += calls_dict[inttime][ 'duration_sum'] total_record[dt]['duration_avg'] += float( calls_dict[inttime]['duration_avg']) logging.debug('After dateList Loops') # sorting on date col total_record = total_record.items() total_record = sorted(total_record, key=lambda k: k[0]) # lineplusbarwithfocuschart final_charttype = "linePlusBarChart" xdata = [] ydata = [] ydata2 = [] for i in total_record: xdata.append(i[0]) ydata.append(i[1]['call_count']) ydata2.append(i[1]['duration_sum']) tooltip_date = "%d %b %y %H:%M %p" kwargs1 = {} kwargs1['bar'] = True extra_serie1 = { "tooltip": { "y_start": "", "y_end": " calls" }, "date_format": tooltip_date } extra_serie2 = { "tooltip": { "y_start": "", "y_end": " sec" }, "date_format": tooltip_date } final_chartdata = { 'x': xdata, 'name1': 'Calls', 'y1': ydata, 'extra1': extra_serie1, 'kwargs1': kwargs1, 'name2': 'Duration', 'y2': ydata2, 'extra2': extra_serie2, } # Contacts which are successfully called for running campaign reached_contact = 0 if campaign_id_list: tday = datetime.utcnow().replace(tzinfo=utc) start_date = datetime(tday.year, tday.month, tday.day, 0, 0, 0, 0).replace(tzinfo=utc) end_date = datetime(tday.year, tday.month, tday.day, 23, 59, 59, 999999).replace(tzinfo=utc) reached_contact = Subscriber.objects\ .filter(campaign_id__in=campaign_id_list, # status=5, updated_date__range=(start_date, end_date))\ .count() # PieChart hangup_analytic_charttype = "pieChart" xdata = [] ydata = [] hangup_analytic_chartdata = {'x': xdata, 'y1': ydata} if total_call_count != 0: for i in CALL_DISPOSITION: xdata.append(i[0]) # Y-axis order depend upon CALL_DISPOSITION # 'ANSWER', 'BUSY', 'CANCEL', 'CONGESTION', 'FAILED', 'NOANSWER' ydata = [ percentage(total_answered, total_call_count), percentage(total_busy, total_call_count), percentage(total_cancel, total_call_count), percentage(total_congestion, total_call_count), percentage(total_failed, total_call_count), percentage(total_not_answered, total_call_count) ] color_list = [ COLOR_DISPOSITION['ANSWER'], COLOR_DISPOSITION['BUSY'], COLOR_DISPOSITION['CANCEL'], COLOR_DISPOSITION['CONGESTION'], COLOR_DISPOSITION['FAILED'], COLOR_DISPOSITION['NOANSWER'], ] extra_serie = { "tooltip": { "y_start": "", "y_end": " %" }, "color_list": color_list } hangup_analytic_chartdata = { 'x': xdata, 'y1': ydata, 'extra1': extra_serie } data = { 'form': form, 'campaign_phonebook_active_contact_count': pb_active_contact_count, 'reached_contact': reached_contact, 'total_duration_sum': total_duration_sum, 'total_billsec_sum': total_billsec_sum, 'total_call_count': total_call_count, 'total_answered': total_answered, 'total_not_answered': total_not_answered, 'total_busy': total_busy, 'total_cancel': total_cancel, 'total_congestion': total_congestion, 'total_failed': total_failed, 'answered_color': COLOR_DISPOSITION['ANSWER'], 'busy_color': COLOR_DISPOSITION['BUSY'], 'not_answered_color': COLOR_DISPOSITION['NOANSWER'], 'cancel_color': COLOR_DISPOSITION['CANCEL'], 'congestion_color': COLOR_DISPOSITION['CONGESTION'], 'failed_color': COLOR_DISPOSITION['FAILED'], 'CALL_DISPOSITION': CALL_DISPOSITION, 'hangup_analytic_chartdata': hangup_analytic_chartdata, 'hangup_analytic_charttype': hangup_analytic_charttype, 'hangup_chartcontainer': 'piechart_container', 'hangup_extra': { 'x_is_date': False, 'x_axis_format': '', 'tag_script_js': True, 'jquery_on_ready': True, }, 'final_chartdata': final_chartdata, 'final_charttype': final_charttype, 'final_chartcontainer': 'lineplusbarwithfocuschart_container', 'final_extra': { 'x_is_date': True, 'x_axis_format': '%d %b %Y', 'tag_script_js': True, 'jquery_on_ready': True, 'resize': True, 'focus_enable': True, } } if on_index == 'yes': return data return render_to_response('frontend/dashboard.html', data, context_instance=RequestContext(request))
def customer_dashboard(request, on_index=None): """Customer dashboard gives the following information * Total Campaigns contacts * Amount of contact reached today * Disposition of calls via pie chart * Call records & Duration of calls are shown on graph by days/hours **Attributes**: * ``template`` - frontend/dashboard.html * ``form`` - DashboardForm """ logging.debug('Start Dashboard') # All campaign for logged in User campaign_id_list = Campaign.objects.values_list('id', flat=True)\ .filter(user=request.user).order_by('id') # Contacts count which are active and belong to those phonebook(s) which is # associated with all campaign pb_active_contact_count = Contact.objects\ .filter(phonebook__campaign__in=campaign_id_list, status=CONTACT_STATUS.ACTIVE)\ .count() form = DashboardForm(request.user) logging.debug('Got Campaign list') total_record = dict() total_duration_sum = 0 total_call_count = 0 total_answered = 0 total_not_answered = 0 total_busy = 0 total_cancel = 0 total_congestion = 0 total_failed = 0 search_type = SEARCH_TYPE.D_Last_24_hours # default Last 24 hours selected_campaign = '' if campaign_id_list: selected_campaign = campaign_id_list[0] # default campaign id # selected_campaign should not be empty if selected_campaign: if request.method == 'POST': form = DashboardForm(request.user, request.POST) selected_campaign = request.POST['campaign'] search_type = request.POST['search_type'] end_date = datetime.utcnow().replace(tzinfo=utc) start_date = calculate_date(search_type) # date_length is used to do group by starting_date if int(search_type) >= SEARCH_TYPE.B_Last_7_days: # all options except 30 days date_length = 13 if int(search_type) == SEARCH_TYPE.C_Yesterday: # yesterday tday = datetime.utcnow().replace(tzinfo=utc) start_date = datetime(tday.year, tday.month, tday.day, 0, 0, 0, 0).replace(tzinfo=utc) - relativedelta(days=1) end_date = datetime(tday.year, tday.month, tday.day, 23, 59, 59, 999999).replace(tzinfo=utc) - relativedelta(days=1) if int(search_type) >= SEARCH_TYPE.E_Last_12_hours: date_length = 16 else: date_length = 10 # Last 30 days option select_data = { "starting_date": "SUBSTR(CAST(starting_date as CHAR(30)),1,%s)" % str(date_length) } # This calls list is used by pie chart calls = VoIPCall.objects\ .filter(callrequest__campaign=selected_campaign, duration__isnull=False, user=request.user, starting_date__range=(start_date, end_date))\ .extra(select=select_data)\ .values('starting_date', 'disposition')\ .annotate(Count('starting_date'))\ .order_by('starting_date') logging.debug('Aggregate VoIPCall') for i in calls: total_call_count += i['starting_date__count'] if (i['disposition'] == VOIPCALL_DISPOSITION.ANSWER or i['disposition'] == 'NORMAL_CLEARING'): total_answered += i['starting_date__count'] elif (i['disposition'] == VOIPCALL_DISPOSITION.BUSY or i['disposition'] == 'USER_BUSY'): total_busy += i['starting_date__count'] elif (i['disposition'] == VOIPCALL_DISPOSITION.NOANSWER or i['disposition'] == 'NO_ANSWER'): total_not_answered += i['starting_date__count'] elif (i['disposition'] == VOIPCALL_DISPOSITION.CANCEL or i['disposition'] == 'ORIGINATOR_CANCEL'): total_cancel += i['starting_date__count'] elif (i['disposition'] == VOIPCALL_DISPOSITION.CONGESTION or i['disposition'] == 'NORMAL_CIRCUIT_CONGESTION'): total_congestion += i['starting_date__count'] else: #VOIP CALL FAILED total_failed += i['starting_date__count'] # following calls list is without disposition & group by call date calls = VoIPCall.objects\ .filter(callrequest__campaign=selected_campaign, duration__isnull=False, user=request.user, starting_date__range=(start_date, end_date))\ .extra(select=select_data)\ .values('starting_date').annotate(Sum('duration'))\ .annotate(Avg('duration'))\ .annotate(Count('starting_date'))\ .order_by('starting_date') logging.debug('Aggregate VoIPCall (2)') mintime = start_date maxtime = end_date calls_dict = {} calls_dict_with_min = {} for data in calls: if int(search_type) >= SEARCH_TYPE.B_Last_7_days: ctime = datetime(int(data['starting_date'][0:4]), int(data['starting_date'][5:7]), int(data['starting_date'][8:10]), int(data['starting_date'][11:13]), 0, 0, 0).replace(tzinfo=utc) if int(search_type) >= SEARCH_TYPE.E_Last_12_hours: ctime = datetime(int(data['starting_date'][0:4]), int(data['starting_date'][5:7]), int(data['starting_date'][8:10]), int(data['starting_date'][11:13]), int(data['starting_date'][14:16]), 0, 0).replace(tzinfo=utc) else: ctime = datetime(int(data['starting_date'][0:4]), int(data['starting_date'][5:7]), int(data['starting_date'][8:10]), 0, 0, 0, 0).replace(tzinfo=utc) if ctime > maxtime: maxtime = ctime elif ctime < mintime: mintime = ctime # all options except 30 days if int(search_type) >= SEARCH_TYPE.B_Last_7_days: calls_dict[int(ctime.strftime("%Y%m%d%H"))] =\ { 'call_count': data['starting_date__count'], 'duration_sum': data['duration__sum'], 'duration_avg': float(data['duration__avg']), } calls_dict_with_min[int(ctime.strftime("%Y%m%d%H%M"))] =\ { 'call_count': data['starting_date__count'], 'duration_sum': data['duration__sum'], 'duration_avg': float(data['duration__avg']), } else: # Last 30 days option calls_dict[int(ctime.strftime("%Y%m%d"))] =\ { 'call_count': data['starting_date__count'], 'duration_sum': data['duration__sum'], 'duration_avg': float(data['duration__avg']), } logging.debug('After Call Loops') dateList = date_range(mintime, maxtime, q=search_type) for date in dateList: inttime = int(date.strftime("%Y%m%d")) # last 7 days | yesterday | last 24 hrs if int(search_type) == SEARCH_TYPE.B_Last_7_days \ or int(search_type) == SEARCH_TYPE.C_Yesterday \ or int(search_type) == SEARCH_TYPE.D_Last_24_hours: for option in range(0, 24): day_time = int(str(inttime) + str(option).zfill(2)) graph_day = datetime(int(date.strftime("%Y")), int(date.strftime("%m")), int(date.strftime("%d")), int(str(option).zfill(2))).replace(tzinfo=utc) dt = int(1000 * time.mktime(graph_day.timetuple())) total_record[dt] = { 'call_count': 0, 'duration_sum': 0, 'duration_avg': 0.0, } if day_time in calls_dict.keys(): total_record[dt]['call_count'] += calls_dict[day_time]['call_count'] total_record[dt]['duration_sum'] += calls_dict[day_time]['duration_sum'] total_record[dt]['duration_avg'] += float(calls_dict[day_time]['duration_avg']) # last 12 hrs | last 6 hrs | last 1 hrs elif (int(search_type) == SEARCH_TYPE.E_Last_12_hours or int(search_type) == SEARCH_TYPE.F_Last_6_hours or int(search_type) == SEARCH_TYPE.G_Last_hour): for hour in range(0, 24): for minute in range(0, 60): hr_time = int(str(inttime) + str(hour).zfill(2) + str(minute).zfill(2)) graph_day = datetime(int(date.strftime("%Y")), int(date.strftime("%m")), int(date.strftime("%d")), int(str(hour).zfill(2)), int(str(minute).zfill(2))).replace(tzinfo=utc) dt = int(1000 * time.mktime(graph_day.timetuple())) total_record[dt] = { 'call_count': 0, 'duration_sum': 0, 'duration_avg': 0.0, } if hr_time in calls_dict_with_min.keys(): total_record[dt]['call_count'] += calls_dict_with_min[hr_time]['call_count'] total_record[dt]['duration_sum'] += calls_dict_with_min[hr_time]['duration_sum'] total_record[dt]['duration_avg'] += float(calls_dict_with_min[hr_time]['duration_avg']) else: # Last 30 days option graph_day = datetime(int(date.strftime("%Y")), int(date.strftime("%m")), int(date.strftime("%d"))).replace(tzinfo=utc) dt = int(1000 * time.mktime(graph_day.timetuple())) total_record[dt] = { 'call_count': 0, 'duration_sum': 0, 'duration_avg': 0, } if inttime in calls_dict.keys(): total_record[dt]['call_count'] += calls_dict[inttime]['call_count'] total_record[dt]['duration_sum'] += calls_dict[inttime]['duration_sum'] total_record[dt]['duration_avg'] += float(calls_dict[inttime]['duration_avg']) logging.debug('After dateList Loops') # sorting on date col total_record = total_record.items() total_record = sorted(total_record, key=lambda k: k[0]) # lineplusbarwithfocuschart final_charttype = "linePlusBarWithFocusChart" xdata = [] ydata = [] ydata2 = [] for i in total_record: xdata.append(i[0]) ydata.append(i[1]['call_count']) ydata2.append(i[1]['duration_sum']) tooltip_date = "%d %b %y %H:%M %p" kwargs1 = {} kwargs1['bar'] = True extra_serie1 = {"tooltip": {"y_start": "", "y_end": " calls"}, "date_format": tooltip_date} extra_serie2 = {"tooltip": {"y_start": "", "y_end": " sec"}, "date_format": tooltip_date} final_chartdata = { 'x': xdata, 'name1': 'Calls', 'y1': ydata, 'extra1': extra_serie1, 'kwargs1': kwargs1, 'name2': 'Duration', 'y2': ydata2, 'extra2': extra_serie2, } # Contacts which are successfully called for running campaign reached_contact = 0 if campaign_id_list: tday = datetime.utcnow().replace(tzinfo=utc) start_date = datetime(tday.year, tday.month, tday.day, 0, 0, 0, 0).replace(tzinfo=utc) end_date = datetime(tday.year, tday.month, tday.day, 23, 59, 59, 999999).replace(tzinfo=utc) reached_contact = Subscriber.objects\ .filter(campaign_id__in=campaign_id_list, # status=5, updated_date__range=(start_date, end_date))\ .count() # PieChart hangup_analytic_charttype = "pieChart" xdata = [] ydata = [] hangup_analytic_chartdata = {'x': xdata, 'y1': ydata} if total_call_count != 0: for i in VOIPCALL_DISPOSITION: xdata.append(i[0]) # Y-axis order depend upon VOIPCALL_DISPOSITION # 'ANSWER', 'BUSY', 'CANCEL', 'CONGESTION', 'FAILED', 'NOANSWER' ydata = [percentage(total_answered, total_call_count), percentage(total_busy, total_call_count), percentage(total_cancel, total_call_count), percentage(total_congestion, total_call_count), percentage(total_failed, total_call_count), percentage(total_not_answered, total_call_count)] color_list = [ COLOR_DISPOSITION['ANSWER'], COLOR_DISPOSITION['BUSY'], COLOR_DISPOSITION['CANCEL'], COLOR_DISPOSITION['CONGESTION'], COLOR_DISPOSITION['FAILED'], COLOR_DISPOSITION['NOANSWER'], ] extra_serie = {"tooltip": {"y_start": "", "y_end": " %"}, "color_list": color_list} hangup_analytic_chartdata = {'x': xdata, 'y1': ydata, 'extra1': extra_serie} template = 'frontend/dashboard.html' data = { 'form': form, 'dialer_setting_msg': user_dialer_setting_msg(request.user), 'campaign_phonebook_active_contact_count': pb_active_contact_count, 'reached_contact': reached_contact, 'total_duration_sum': total_duration_sum, 'total_call_count': total_call_count, 'total_answered': total_answered, 'total_not_answered': total_not_answered, 'total_busy': total_busy, 'total_cancel': total_cancel, 'total_congestion': total_congestion, 'total_failed': total_failed, 'answered_color': COLOR_DISPOSITION['ANSWER'], 'busy_color': COLOR_DISPOSITION['BUSY'], 'not_answered_color': COLOR_DISPOSITION['NOANSWER'], 'cancel_color': COLOR_DISPOSITION['CANCEL'], 'congestion_color': COLOR_DISPOSITION['CONGESTION'], 'failed_color': COLOR_DISPOSITION['FAILED'], 'VOIPCALL_DISPOSITION': VOIPCALL_DISPOSITION, 'hangup_analytic_chartdata': hangup_analytic_chartdata, 'hangup_analytic_charttype': hangup_analytic_charttype, 'hangup_chartcontainer': 'piechart_container', 'hangup_extra': { 'x_is_date': False, 'x_axis_format': '', 'tag_script_js': True, 'jquery_on_ready': True, }, 'final_chartdata': final_chartdata, 'final_charttype': final_charttype, 'final_chartcontainer': 'lineplusbarwithfocuschart_container', 'final_extra': { 'x_is_date': True, 'x_axis_format': '%d %b %Y', 'tag_script_js': True, 'jquery_on_ready': True, 'resize': True, } } if on_index == 'yes': return data return render_to_response(template, data, context_instance=RequestContext(request))
def customer_dashboard(request, on_index=None): """Customer dashboard gives the following information * Total Campaigns contacts * Amount of contact reached today * Disposition of calls via pie chart * Call records & Duration of calls are shown on graph by days/hours **Attributes**: * ``template`` - frontend/dashboard.html * ``form`` - DashboardForm """ logging.debug("Start Dashboard") # All campaign for logged in User campaign_id_list = Campaign.objects.values_list("id", flat=True).filter(user=request.user).order_by("id") # Contacts count which are active and belong to those phonebook(s) which is # associated with all campaign pb_active_contact_count = Contact.objects.filter( phonebook__campaign__in=campaign_id_list, status=CONTACT_STATUS.ACTIVE ).count() form = DashboardForm(request.user, request.POST or None) logging.debug("Got Campaign list") total_record = dict() total_duration_sum = 0 total_call_count = 0 total_answered = 0 total_not_answered = 0 total_busy = 0 total_cancel = 0 total_congestion = 0 total_failed = 0 search_type = SEARCH_TYPE.D_Last_24_hours # default Last 24 hours selected_campaign = "" if campaign_id_list: selected_campaign = campaign_id_list[0] # default campaign id # selected_campaign should not be empty if selected_campaign: if form.is_valid(): selected_campaign = request.POST["campaign"] search_type = request.POST["search_type"] end_date = datetime.utcnow().replace(tzinfo=utc) start_date = calculate_date(search_type) # date_length is used to do group by starting_date if int(search_type) >= SEARCH_TYPE.B_Last_7_days: # all options except 30 days date_length = 13 if int(search_type) == SEARCH_TYPE.C_Yesterday: # yesterday tday = datetime.utcnow().replace(tzinfo=utc) start_date = datetime(tday.year, tday.month, tday.day, 0, 0, 0, 0).replace(tzinfo=utc) - relativedelta( days=1 ) end_date = datetime(tday.year, tday.month, tday.day, 23, 59, 59, 999999).replace( tzinfo=utc ) - relativedelta(days=1) if int(search_type) >= SEARCH_TYPE.E_Last_12_hours: date_length = 16 else: date_length = 10 # Last 30 days option select_data = {"starting_date": "SUBSTR(CAST(starting_date as CHAR(30)),1,%s)" % str(date_length)} # This calls list is used by pie chart calls = ( VoIPCall.objects.filter( callrequest__campaign=selected_campaign, duration__isnull=False, user=request.user, starting_date__range=(start_date, end_date), ) .extra(select=select_data) .values("starting_date", "disposition") .annotate(Count("starting_date")) .order_by("starting_date") ) logging.debug("Aggregate VoIPCall") for i in calls: total_call_count += i["starting_date__count"] if i["disposition"] == VOIPCALL_DISPOSITION.ANSWER or i["disposition"] == "NORMAL_CLEARING": total_answered += i["starting_date__count"] elif i["disposition"] == VOIPCALL_DISPOSITION.BUSY or i["disposition"] == "USER_BUSY": total_busy += i["starting_date__count"] elif i["disposition"] == VOIPCALL_DISPOSITION.NOANSWER or i["disposition"] == "NO_ANSWER": total_not_answered += i["starting_date__count"] elif i["disposition"] == VOIPCALL_DISPOSITION.CANCEL or i["disposition"] == "ORIGINATOR_CANCEL": total_cancel += i["starting_date__count"] elif i["disposition"] == VOIPCALL_DISPOSITION.CONGESTION or i["disposition"] == "NORMAL_CIRCUIT_CONGESTION": total_congestion += i["starting_date__count"] else: # VOIP CALL FAILED total_failed += i["starting_date__count"] # following calls list is without disposition & group by call date calls = ( VoIPCall.objects.filter( callrequest__campaign=selected_campaign, duration__isnull=False, user=request.user, starting_date__range=(start_date, end_date), ) .extra(select=select_data) .values("starting_date") .annotate(Sum("duration")) .annotate(Avg("duration")) .annotate(Count("starting_date")) .order_by("starting_date") ) logging.debug("Aggregate VoIPCall (2)") mintime = start_date maxtime = end_date calls_dict = {} calls_dict_with_min = {} for data in calls: if int(search_type) >= SEARCH_TYPE.B_Last_7_days: ctime = datetime( int(data["starting_date"][0:4]), int(data["starting_date"][5:7]), int(data["starting_date"][8:10]), int(data["starting_date"][11:13]), 0, 0, 0, ).replace(tzinfo=utc) if int(search_type) >= SEARCH_TYPE.E_Last_12_hours: ctime = datetime( int(data["starting_date"][0:4]), int(data["starting_date"][5:7]), int(data["starting_date"][8:10]), int(data["starting_date"][11:13]), int(data["starting_date"][14:16]), 0, 0, ).replace(tzinfo=utc) else: ctime = datetime( int(data["starting_date"][0:4]), int(data["starting_date"][5:7]), int(data["starting_date"][8:10]), 0, 0, 0, 0, ).replace(tzinfo=utc) if ctime > maxtime: maxtime = ctime elif ctime < mintime: mintime = ctime # all options except 30 days if int(search_type) >= SEARCH_TYPE.B_Last_7_days: calls_dict[int(ctime.strftime("%Y%m%d%H"))] = { "call_count": data["starting_date__count"], "duration_sum": data["duration__sum"], "duration_avg": float(data["duration__avg"]), } calls_dict_with_min[int(ctime.strftime("%Y%m%d%H%M"))] = { "call_count": data["starting_date__count"], "duration_sum": data["duration__sum"], "duration_avg": float(data["duration__avg"]), } else: # Last 30 days option calls_dict[int(ctime.strftime("%Y%m%d"))] = { "call_count": data["starting_date__count"], "duration_sum": data["duration__sum"], "duration_avg": float(data["duration__avg"]), } logging.debug("After Call Loops") dateList = date_range(mintime, maxtime, q=search_type) for date in dateList: inttime = int(date.strftime("%Y%m%d")) # last 7 days | yesterday | last 24 hrs if ( int(search_type) == SEARCH_TYPE.B_Last_7_days or int(search_type) == SEARCH_TYPE.C_Yesterday or int(search_type) == SEARCH_TYPE.D_Last_24_hours ): for option in range(0, 24): day_time = int(str(inttime) + str(option).zfill(2)) graph_day = datetime( int(date.strftime("%Y")), int(date.strftime("%m")), int(date.strftime("%d")), int(str(option).zfill(2)), ).replace(tzinfo=utc) dt = int(1000 * time.mktime(graph_day.timetuple())) total_record[dt] = {"call_count": 0, "duration_sum": 0, "duration_avg": 0.0} if day_time in calls_dict.keys(): total_record[dt]["call_count"] += calls_dict[day_time]["call_count"] total_record[dt]["duration_sum"] += calls_dict[day_time]["duration_sum"] total_record[dt]["duration_avg"] += float(calls_dict[day_time]["duration_avg"]) # last 12 hrs | last 6 hrs | last 1 hrs elif ( int(search_type) == SEARCH_TYPE.E_Last_12_hours or int(search_type) == SEARCH_TYPE.F_Last_6_hours or int(search_type) == SEARCH_TYPE.G_Last_hour ): for hour in range(0, 24): for minute in range(0, 60): hr_time = int(str(inttime) + str(hour).zfill(2) + str(minute).zfill(2)) graph_day = datetime( int(date.strftime("%Y")), int(date.strftime("%m")), int(date.strftime("%d")), int(str(hour).zfill(2)), int(str(minute).zfill(2)), ).replace(tzinfo=utc) dt = int(1000 * time.mktime(graph_day.timetuple())) total_record[dt] = {"call_count": 0, "duration_sum": 0, "duration_avg": 0.0} if hr_time in calls_dict_with_min.keys(): total_record[dt]["call_count"] += calls_dict_with_min[hr_time]["call_count"] total_record[dt]["duration_sum"] += calls_dict_with_min[hr_time]["duration_sum"] total_record[dt]["duration_avg"] += float(calls_dict_with_min[hr_time]["duration_avg"]) else: # Last 30 days option graph_day = datetime( int(date.strftime("%Y")), int(date.strftime("%m")), int(date.strftime("%d")) ).replace(tzinfo=utc) dt = int(1000 * time.mktime(graph_day.timetuple())) total_record[dt] = {"call_count": 0, "duration_sum": 0, "duration_avg": 0} if inttime in calls_dict.keys(): total_record[dt]["call_count"] += calls_dict[inttime]["call_count"] total_record[dt]["duration_sum"] += calls_dict[inttime]["duration_sum"] total_record[dt]["duration_avg"] += float(calls_dict[inttime]["duration_avg"]) logging.debug("After dateList Loops") # sorting on date col total_record = total_record.items() total_record = sorted(total_record, key=lambda k: k[0]) # lineplusbarwithfocuschart final_charttype = "linePlusBarWithFocusChart" xdata = [] ydata = [] ydata2 = [] for i in total_record: xdata.append(i[0]) ydata.append(i[1]["call_count"]) ydata2.append(i[1]["duration_sum"]) tooltip_date = "%d %b %y %H:%M %p" kwargs1 = {} kwargs1["bar"] = True extra_serie1 = {"tooltip": {"y_start": "", "y_end": " calls"}, "date_format": tooltip_date} extra_serie2 = {"tooltip": {"y_start": "", "y_end": " sec"}, "date_format": tooltip_date} final_chartdata = { "x": xdata, "name1": "Calls", "y1": ydata, "extra1": extra_serie1, "kwargs1": kwargs1, "name2": "Duration", "y2": ydata2, "extra2": extra_serie2, } # Contacts which are successfully called for running campaign reached_contact = 0 if campaign_id_list: tday = datetime.utcnow().replace(tzinfo=utc) start_date = datetime(tday.year, tday.month, tday.day, 0, 0, 0, 0).replace(tzinfo=utc) end_date = datetime(tday.year, tday.month, tday.day, 23, 59, 59, 999999).replace(tzinfo=utc) reached_contact = Subscriber.objects.filter( campaign_id__in=campaign_id_list, updated_date__range=(start_date, end_date) # status=5, ).count() # PieChart hangup_analytic_charttype = "pieChart" xdata = [] ydata = [] hangup_analytic_chartdata = {"x": xdata, "y1": ydata} if total_call_count != 0: for i in VOIPCALL_DISPOSITION: xdata.append(i[0]) # Y-axis order depend upon VOIPCALL_DISPOSITION # 'ANSWER', 'BUSY', 'CANCEL', 'CONGESTION', 'FAILED', 'NOANSWER' ydata = [ percentage(total_answered, total_call_count), percentage(total_busy, total_call_count), percentage(total_cancel, total_call_count), percentage(total_congestion, total_call_count), percentage(total_failed, total_call_count), percentage(total_not_answered, total_call_count), ] color_list = [ COLOR_DISPOSITION["ANSWER"], COLOR_DISPOSITION["BUSY"], COLOR_DISPOSITION["CANCEL"], COLOR_DISPOSITION["CONGESTION"], COLOR_DISPOSITION["FAILED"], COLOR_DISPOSITION["NOANSWER"], ] extra_serie = {"tooltip": {"y_start": "", "y_end": " %"}, "color_list": color_list} hangup_analytic_chartdata = {"x": xdata, "y1": ydata, "extra1": extra_serie} data = { "form": form, "campaign_phonebook_active_contact_count": pb_active_contact_count, "reached_contact": reached_contact, "total_duration_sum": total_duration_sum, "total_call_count": total_call_count, "total_answered": total_answered, "total_not_answered": total_not_answered, "total_busy": total_busy, "total_cancel": total_cancel, "total_congestion": total_congestion, "total_failed": total_failed, "answered_color": COLOR_DISPOSITION["ANSWER"], "busy_color": COLOR_DISPOSITION["BUSY"], "not_answered_color": COLOR_DISPOSITION["NOANSWER"], "cancel_color": COLOR_DISPOSITION["CANCEL"], "congestion_color": COLOR_DISPOSITION["CONGESTION"], "failed_color": COLOR_DISPOSITION["FAILED"], "VOIPCALL_DISPOSITION": VOIPCALL_DISPOSITION, "hangup_analytic_chartdata": hangup_analytic_chartdata, "hangup_analytic_charttype": hangup_analytic_charttype, "hangup_chartcontainer": "piechart_container", "hangup_extra": {"x_is_date": False, "x_axis_format": "", "tag_script_js": True, "jquery_on_ready": True}, "final_chartdata": final_chartdata, "final_charttype": final_charttype, "final_chartcontainer": "lineplusbarwithfocuschart_container", "final_extra": { "x_is_date": True, "x_axis_format": "%d %b %Y", "tag_script_js": True, "jquery_on_ready": True, "resize": True, }, } if on_index == "yes": return data return render_to_response("frontend/dashboard.html", data, context_instance=RequestContext(request))
def customer_dashboard(request, on_index=None): """Customer dashboard gives the following information * No of Campaigns for logged in user * Total phonebook contacts * Total Campaigns contacts * Amount of contact reached today * Disposition of calls via pie chart * Call records & Duration of calls are shown on graph by days/hours **Attributes**: * ``template`` - frontend/dashboard.html * ``form`` - DashboardForm """ logging.debug('Start Dashboard') # All campaign for logged in User campaign_id_list = Campaign.objects.values_list('id', flat=True)\ .filter(user=request.user).order_by('id') campaign_count = campaign_id_list.count() # Contacts count which are active and belong to those phonebook(s) which is # associated with all campaign pb_active_contact_count = Contact.objects\ .filter(phonebook__campaign__in=campaign_id_list, status=CONTACT_STATUS.ACTIVE)\ .count() total_of_phonebook_contacts =\ Contact.objects.filter(phonebook__user=request.user).count() form = DashboardForm(request.user) logging.debug('Got Campaign list') total_record = dict() total_duration_sum = 0 total_call_count = 0 total_answered = 0 total_not_answered = 0 total_busy = 0 total_cancel = 0 total_congestion = 0 total_failed = 0 search_type = SEARCH_TYPE.D_Last_24_hours # default Last 24 hours selected_campaign = '' if campaign_id_list: selected_campaign = campaign_id_list[0] # default campaign id # selected_campaign should not be empty if selected_campaign: if request.method == 'POST': form = DashboardForm(request.user, request.POST) selected_campaign = request.POST['campaign'] search_type = request.POST['search_type'] end_date = datetime.today() start_date = calculate_date(search_type) # date_length is used to do group by starting_date if int(search_type) >= SEARCH_TYPE.B_Last_7_days: # all options except 30 days date_length = 13 if int(search_type) == SEARCH_TYPE.C_Yesterday: # yesterday now = datetime.now() start_date = datetime(now.year, now.month, now.day, 0, 0, 0, 0) - relativedelta(days=1) end_date = datetime(now.year, now.month, now.day, 23, 59, 59, 999999) - relativedelta(days=1) if int(search_type) >= SEARCH_TYPE.E_Last_12_hours: date_length = 16 else: date_length = 10 # Last 30 days option select_data = { "starting_date": "SUBSTR(CAST(starting_date as CHAR(30)),1,%s)" % str(date_length) } # This calls list is used by pie chart calls = VoIPCall.objects\ .filter(callrequest__campaign=selected_campaign, duration__isnull=False, user=request.user, starting_date__range=(start_date, end_date))\ .extra(select=select_data)\ .values('starting_date', 'disposition')\ .annotate(Count('starting_date'))\ .order_by('starting_date') logging.debug('Aggregate VoIPCall') for i in calls: total_call_count += i['starting_date__count'] if (i['disposition'] == VOIPCALL_DISPOSITION.ANSWER or i['disposition'] == 'NORMAL_CLEARING'): total_answered += i['starting_date__count'] elif (i['disposition'] == VOIPCALL_DISPOSITION.BUSY or i['disposition'] == 'USER_BUSY'): total_busy += i['starting_date__count'] elif (i['disposition'] == VOIPCALL_DISPOSITION.NOANSWER or i['disposition'] == 'NO_ANSWER'): total_not_answered += i['starting_date__count'] elif (i['disposition'] == VOIPCALL_DISPOSITION.CANCEL or i['disposition'] == 'ORIGINATOR_CANCEL'): total_cancel += i['starting_date__count'] elif (i['disposition'] == VOIPCALL_DISPOSITION.CONGESTION or i['disposition'] == 'NORMAL_CIRCUIT_CONGESTION'): total_congestion += i['starting_date__count'] else: #VOIP CALL FAILED total_failed += i['starting_date__count'] # following calls list is without disposition & group by call date calls = VoIPCall.objects\ .filter(callrequest__campaign=selected_campaign, duration__isnull=False, user=request.user, starting_date__range=(start_date, end_date))\ .extra(select=select_data)\ .values('starting_date').annotate(Sum('duration'))\ .annotate(Avg('duration'))\ .annotate(Count('starting_date'))\ .order_by('starting_date') logging.debug('Aggregate VoIPCall (2)') mintime = start_date maxtime = end_date calls_dict = {} calls_dict_with_min = {} for data in calls: if int(search_type) >= SEARCH_TYPE.B_Last_7_days: ctime = datetime(int(data['starting_date'][0:4]), int(data['starting_date'][5:7]), int(data['starting_date'][8:10]), int(data['starting_date'][11:13]), 0, 0, 0) if int(search_type) >= SEARCH_TYPE.E_Last_12_hours: ctime = datetime(int(data['starting_date'][0:4]), int(data['starting_date'][5:7]), int(data['starting_date'][8:10]), int(data['starting_date'][11:13]), int(data['starting_date'][14:16]), 0, 0) else: ctime = datetime(int(data['starting_date'][0:4]), int(data['starting_date'][5:7]), int(data['starting_date'][8:10]), 0, 0, 0, 0) if ctime > maxtime: maxtime = ctime elif ctime < mintime: mintime = ctime # all options except 30 days if int(search_type) >= SEARCH_TYPE.B_Last_7_days: calls_dict[int(ctime.strftime("%Y%m%d%H"))] =\ { 'call_count': data['starting_date__count'], 'duration_sum': data['duration__sum'], 'duration_avg': float(data['duration__avg']), } calls_dict_with_min[int(ctime.strftime("%Y%m%d%H%M"))] =\ { 'call_count': data['starting_date__count'], 'duration_sum': data['duration__sum'], 'duration_avg': float(data['duration__avg']), } else: # Last 30 days option calls_dict[int(ctime.strftime("%Y%m%d"))] =\ { 'call_count': data['starting_date__count'], 'duration_sum': data['duration__sum'], 'duration_avg': float(data['duration__avg']), } logging.debug('After Call Loops') dateList = date_range(mintime, maxtime, q=search_type) for date in dateList: inttime = int(date.strftime("%Y%m%d")) # last 7 days | yesterday | last 24 hrs if int(search_type) == SEARCH_TYPE.B_Last_7_days \ or int(search_type) == SEARCH_TYPE.C_Yesterday \ or int(search_type) == SEARCH_TYPE.D_Last_24_hours: for option in range(0, 24): day_time = int(str(inttime) + str(option).zfill(2)) graph_day = datetime(int(date.strftime("%Y")), int(date.strftime("%m")), int(date.strftime("%d")), int(str(option).zfill(2))) dt = int(1000 * time.mktime(graph_day.timetuple())) total_record[dt] = { 'call_count': 0, 'duration_sum': 0, 'duration_avg': 0.0, } if day_time in calls_dict.keys(): total_record[dt]['call_count'] += calls_dict[day_time]['call_count'] total_record[dt]['duration_sum'] += calls_dict[day_time]['duration_sum'] total_record[dt]['duration_avg'] += float(calls_dict[day_time]['duration_avg']) # last 12 hrs | last 6 hrs | last 1 hrs elif (int(search_type) == SEARCH_TYPE.E_Last_12_hours or int(search_type) == SEARCH_TYPE.F_Last_6_hours or int(search_type) == SEARCH_TYPE.G_Last_hour): for hour in range(0, 24): for minute in range(0, 60): hr_time = int(str(inttime) + str(hour).zfill(2) + str(minute).zfill(2)) graph_day = datetime(int(date.strftime("%Y")), int(date.strftime("%m")), int(date.strftime("%d")), int(str(hour).zfill(2)), int(str(minute).zfill(2))) dt = int(1000 * time.mktime(graph_day.timetuple())) total_record[dt] = { 'call_count': 0, 'duration_sum': 0, 'duration_avg': 0.0, } if hr_time in calls_dict_with_min.keys(): total_record[dt]['call_count'] += calls_dict_with_min[hr_time]['call_count'] total_record[dt]['duration_sum'] += calls_dict_with_min[hr_time]['duration_sum'] total_record[dt]['duration_avg'] += float(calls_dict_with_min[hr_time]['duration_avg']) else: # Last 30 days option graph_day = datetime(int(date.strftime("%Y")), int(date.strftime("%m")), int(date.strftime("%d"))) dt = int(1000 * time.mktime(graph_day.timetuple())) total_record[dt] = { 'call_count': 0, 'duration_sum': 0, 'duration_avg': 0, } if inttime in calls_dict.keys(): total_record[dt]['call_count'] += calls_dict[inttime]['call_count'] total_record[dt]['duration_sum'] += calls_dict[inttime]['duration_sum'] total_record[dt]['duration_avg'] += float(calls_dict[inttime]['duration_avg']) logging.debug('After dateList Loops') # sorting on date col total_record = total_record.items() total_record = sorted(total_record, key=lambda k: k[0]) # Contacts which are successfully called for running campaign reached_contact = 0 if campaign_id_list: now = datetime.now() start_date = datetime(now.year, now.month, now.day, 0, 0, 0, 0) end_date = datetime(now.year, now.month, now.day, 23, 59, 59, 999999) reached_contact = Subscriber.objects\ .filter(campaign_id__in=campaign_id_list, # status=5, updated_date__range=(start_date, end_date))\ .count() template = 'frontend/dashboard.html' data = { 'module': current_view(request), 'form': form, 'dialer_setting_msg': user_dialer_setting_msg(request.user), 'campaign_count': campaign_count, 'total_of_phonebook_contacts': total_of_phonebook_contacts, 'campaign_phonebook_active_contact_count': pb_active_contact_count, 'reached_contact': reached_contact, 'total_record': total_record, 'total_duration_sum': total_duration_sum, 'total_call_count': total_call_count, 'total_answered': total_answered, 'total_not_answered': total_not_answered, 'total_busy': total_busy, #'total_others': total_others, 'total_cancel': total_cancel, 'total_congestion': total_congestion, 'total_failed': total_failed, 'answered_color': COLOR_DISPOSITION['ANSWER'], 'busy_color': COLOR_DISPOSITION['BUSY'], 'not_answered_color': COLOR_DISPOSITION['NOANSWER'], 'cancel_color': COLOR_DISPOSITION['CANCEL'], 'congestion_color': COLOR_DISPOSITION['CONGESTION'], 'failed_color': COLOR_DISPOSITION['FAILED'], 'SEARCH_TYPE': SEARCH_TYPE, 'VOIPCALL_DISPOSITION': VOIPCALL_DISPOSITION, } if on_index == 'yes': return data return render_to_response(template, data, context_instance=RequestContext(request))
def sms_dashboard(request, on_index=None): """SMS dashboard gives the following information * No of SMSCampaigns for logged in user * Total phonebook contacts * Total SMSCampaigns contacts * Amount of contact reached today * Disposition of sms via pie chart * SMS count shown on graph by days/hours **Attributes**: * ``template`` - mod_sms/sms_dashboard.html * ``form`` - SMSDashboardForm """ # All sms_campaign for logged in User sms_campaign_id_list = SMSCampaign.objects.values_list( 'id', flat=True).filter(user=request.user).order_by('id') # Contacts count which are active and belong to those phonebook(s) which is # associated with all sms campaign pb_active_contact_count = Contact.objects.filter( phonebook__smscampaign__in=sms_campaign_id_list, status=CONTACT_STATUS.ACTIVE).count() form = SMSDashboardForm(request.user, request.POST or None) total_record = dict() total_sms_count = 0 total_unsent = 0 total_sent = 0 total_delivered = 0 total_failed = 0 total_no_route = 0 total_unauthorized = 0 select_graph_for = 'sms count' # default search_type = SEARCH_TYPE.D_Last_24_hours # default Last 24 hours selected_sms_campaign = '' if sms_campaign_id_list: selected_sms_campaign = sms_campaign_id_list[ 0] # default sms campaign id # selected_sms_campaign should not be empty if selected_sms_campaign: if form.is_valid(): selected_sms_campaign = request.POST['smscampaign'] search_type = request.POST['search_type'] end_date = datetime.utcnow().replace(tzinfo=utc) start_date = calculate_date(search_type) # date_length is used to do group by starting_date if int(search_type ) >= SEARCH_TYPE.B_Last_7_days: # all options except 30 days date_length = 13 if int(search_type) == SEARCH_TYPE.C_Yesterday: # yesterday now = datetime.utcnow().replace(tzinfo=utc) start_date = datetime(now.year, now.month, now.day, 0, 0, 0, 0).replace(tzinfo=utc) \ - relativedelta(days=1) end_date = datetime(now.year, now.month, now.day, 23, 59, 59, 999999).replace(tzinfo=utc) \ - relativedelta(days=1) if int(search_type) >= SEARCH_TYPE.E_Last_12_hours: date_length = 16 else: date_length = 10 # Last 30 days option select_data = { "send_date": "SUBSTR(CAST(send_date as CHAR(30)),1," + str(date_length) + ")" } # This calls list is used by pie chart list_sms = SMSMessage.objects.filter( sender=request.user, sms_campaign_id=selected_sms_campaign, send_date__range=(start_date, end_date))\ .extra(select=select_data)\ .values('send_date', 'status')\ .annotate(Count('send_date'))\ .order_by('send_date') for i in list_sms: # convert unicode date string into date if i['status'] == 'Unsent': total_unsent += i['send_date__count'] elif i['status'] == 'Sent': total_sent += i['send_date__count'] elif i['status'] == 'Delivered': total_delivered += i['send_date__count'] elif i['status'] == 'Failed': total_failed += i['send_date__count'] elif i['status'] == 'No_Route': total_no_route += i['send_date__count'] else: total_unauthorized += i['send_date__count'] # Unauthorized total_sms_count += i['send_date__count'] list_sms = SMSMessage.objects.filter( sender=request.user, sms_campaign_id=selected_sms_campaign, send_date__range=(start_date, end_date))\ .extra(select=select_data).values('send_date')\ .annotate(Count('send_date')).order_by('send_date') mintime = start_date maxtime = end_date sms_dict = {} sms_dict_with_min = {} for data in list_sms: if int(search_type) >= SEARCH_TYPE.B_Last_7_days: ctime = datetime(int(data['send_date'][0:4]), int(data['send_date'][5:7]), int(data['send_date'][8:10]), int(data['send_date'][11:13]), 0, 0, 0).replace(tzinfo=utc) if int(search_type) >= SEARCH_TYPE.E_Last_12_hours: ctime = datetime(int(data['send_date'][0:4]), int(data['send_date'][5:7]), int(data['send_date'][8:10]), int(data['send_date'][11:13]), int(data['send_date'][14:16]), 0, 0).replace(tzinfo=utc) else: ctime = datetime(int(data['send_date'][0:4]), int(data['send_date'][5:7]), int(data['send_date'][8:10]), 0, 0, 0, 0).replace(tzinfo=utc) if ctime > maxtime: maxtime = ctime elif ctime < mintime: mintime = ctime # all options except 30 days if int(search_type) >= SEARCH_TYPE.B_Last_7_days: sms_dict[int(ctime.strftime("%Y%m%d%H"))] = { 'sms_count': data['send_date__count'] } sms_dict_with_min[int(ctime.strftime("%Y%m%d%H%M"))] = { 'sms_count': data['send_date__count'] } else: # Last 30 days option sms_dict[int(ctime.strftime("%Y%m%d"))] = { 'sms_count': data['send_date__count'] } dateList = date_range(mintime, maxtime, q=search_type) i = 0 total_record = {} for date in dateList: inttime = int(date.strftime("%Y%m%d")) # last 7 days | yesterday | last 24 hrs if (int(search_type) == SEARCH_TYPE.B_Last_7_days or int(search_type) == SEARCH_TYPE.C_Yesterday or int(search_type) == SEARCH_TYPE.D_Last_24_hours): for option in range(0, 24): day_time = int(str(inttime) + str(option).zfill(2)) graph_day = datetime( int(date.strftime("%Y")), int(date.strftime("%m")), int(date.strftime("%d")), int(str(option).zfill(2))).replace(tzinfo=utc) dt = int(1000 * time.mktime(graph_day.timetuple())) total_record[dt] = {'sms_count': 0} if day_time in sms_dict.keys(): total_record[dt]['sms_count'] += sms_dict[day_time][ 'sms_count'] # last 12 hrs | last 6 hrs | last 1 hrs elif (int(search_type) == SEARCH_TYPE.E_Last_12_hours or int(search_type) == SEARCH_TYPE.F_Last_6_hours or int(search_type) == SEARCH_TYPE.G_Last_hour): for hour in range(0, 24): for minute in range(0, 60): hr_time = int( str(inttime) + str(hour).zfill(2) + str(minute).zfill(2)) graph_day = datetime( int(date.strftime("%Y")), int(date.strftime("%m")), int(date.strftime("%d")), int(str(hour).zfill(2)), int(str(minute).zfill(2))).replace(tzinfo=utc) dt = int(1000 * time.mktime(graph_day.timetuple())) total_record[dt] = {'sms_count': 0} if hr_time in sms_dict_with_min.keys(): total_record[dt]['sms_count'] += sms_dict_with_min[ hr_time]['sms_count'] else: # Last 30 days option graph_day = datetime( int(date.strftime("%Y")), int(date.strftime("%m")), int(date.strftime("%d"))).replace(tzinfo=utc) dt = int(1000 * time.mktime(graph_day.timetuple())) total_record[dt] = {'sms_count': 0} if inttime in sms_dict.keys(): total_record[dt]['sms_count'] += sms_dict[inttime][ 'sms_count'] # sorting on date col total_record = total_record.items() total_record = sorted(total_record, key=lambda k: k[0]) # lineWithFocusChart final_charttype = "lineWithFocusChart" xdata = [] ydata = [] for i in total_record: xdata.append(i[0]) ydata.append(i[1]['sms_count']) tooltip_date = "%d %b %y %H:%M %p" extra_serie1 = { "tooltip": { "y_start": "", "y_end": " SMS" }, "date_format": tooltip_date } final_chartdata = { 'x': xdata, 'name1': 'SMS', 'y1': ydata, 'extra1': extra_serie1, } # Contacts which are successfully messaged for running sms campaign reached_contact = 0 if sms_campaign_id_list: now = datetime.utcnow().replace(tzinfo=utc) start_date = datetime(now.year, now.month, now.day, 0, 0, 0, 0).replace(tzinfo=utc) end_date = datetime(now.year, now.month, now.day, 23, 59, 59, 999999).replace(tzinfo=utc) sms_campaign_subscriber = SMSCampaignSubscriber.objects.filter( sms_campaign_id__in=sms_campaign_id_list, status=SMS_SUBSCRIBER_STATUS.COMPLETE, updated_date__range=(start_date, end_date)).count() reached_contact += sms_campaign_subscriber # PieChart sms_analytic_charttype = "pieChart" xdata = [] ydata = [] sms_analytic_chartdata = {'x': xdata, 'y1': ydata} if total_sms_count != 0: for i in SMS_MESSAGE_STATUS: xdata.append(i[0].upper()) # Y-axis order depend upon SMS_MESSAGE_STATUS # 'UNSENT', 'SENT', 'DELIVERED', 'FAILED', 'NO_ROUTE', 'UNAUTHORIZED' ydata = [ percentage(total_unsent, total_sms_count), percentage(total_sent, total_sms_count), percentage(total_delivered, total_sms_count), percentage(total_failed, total_sms_count), percentage(total_no_route, total_sms_count), percentage(total_unauthorized, total_sms_count), ] color_list = [ COLOR_SMS_DISPOSITION['UNSENT'], COLOR_SMS_DISPOSITION['SENT'], COLOR_SMS_DISPOSITION['DELIVERED'], COLOR_SMS_DISPOSITION['FAILED'], COLOR_SMS_DISPOSITION['NO_ROUTE'], COLOR_SMS_DISPOSITION['UNAUTHORIZED'], ] extra_serie = { "tooltip": { "y_start": "", "y_end": " %" }, "color_list": color_list } kwargs1 = {} kwargs1['resize'] = True sms_analytic_chartdata = { 'x': xdata, 'y1': ydata, 'extra1': extra_serie, 'kwargs1': kwargs1, } data = { 'form': form, 'SEARCH_TYPE': SEARCH_TYPE, 'pb_active_contact_count': pb_active_contact_count, 'reached_contact': reached_contact, 'total_record': total_record, 'select_graph_for': select_graph_for, 'total_sms_count': total_sms_count, 'total_unsent': total_unsent, 'total_sent': total_sent, 'total_delivered': total_delivered, 'total_failed': total_failed, 'total_no_route': total_no_route, 'total_unauthorized': total_unauthorized, 'unsent_color': COLOR_SMS_DISPOSITION['UNSENT'], 'sent_color': COLOR_SMS_DISPOSITION['SENT'], 'delivered_color': COLOR_SMS_DISPOSITION['DELIVERED'], 'failed_color': COLOR_SMS_DISPOSITION['FAILED'], 'no_route_color': COLOR_SMS_DISPOSITION['NO_ROUTE'], 'unauthorized_color': COLOR_SMS_DISPOSITION['UNAUTHORIZED'], 'final_chartcontainer': 'lineplusbarwithfocuschart_container', 'final_chartdata': final_chartdata, 'final_charttype': final_charttype, 'final_extra': { 'x_is_date': True, 'x_axis_format': '%d %b %Y', 'tag_script_js': True, 'jquery_on_ready': False, }, 'sms_analytic_chartcontainer': 'piechart_container', 'sms_analytic_charttype': sms_analytic_charttype, 'sms_analytic_chartdata': sms_analytic_chartdata, 'sms_analytic_extra': { 'x_is_date': False, 'x_axis_format': '', 'tag_script_js': True, 'jquery_on_ready': False, }, } if on_index == 'yes': return data return render_to_response('mod_sms/sms_dashboard.html', data, context_instance=RequestContext(request))