Commit db3c81d76337f9a49a88265f2da2b42594cc2712

  • avatar
  • arvind
  • Tue Mar 11 21:07:37 IST 2014
Readability counts.
Breaking lines longer than 80.
Minutes of a call should be counted after the user has answered the call
not since the call has been started. This value is stored in the billsec
column of cdr table.
Answered calls should be counted when there is a disposition of
answered, likewise for unanswered calls.
Count number of calls which went unaccounted for, as in failed/busy/no
answer with dcontext as default.
  • query.py 82 ---------------------+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  • report.py 8 ---+++++
  • Diff rendering mode:
  • inline
  • side by side

query.py

21 self.t.lt.posted.between(date, dateRange)).count()21 self.t.lt.posted.between(date, dateRange)).count()
2222
2323
24 def totalMinutes(self, channel, date, dateRange):
25 query = self.t.lt.query.with_entities(func.sum(self.t.lt.duration).label('sum')).filter(self.t.lt.dcontext == "callback", self.t.lt.channel.like(channel+'%'), self.t.lt.calldate.between(date, dateRange))
24 def totalMinutes(self, date, dateRange, channel=None):
25 query = self.t.lt.query.with_entities(
26 func.sum(self.t.lt.billsec).label('sum')).filter(
27 self.t.lt.dcontext == "callback",
28 self.t.lt.disposition == "ANSWERED",
29 self.t.lt.calldate.between(date, dateRange))
30
31 if channel is not None:
32 query = query.filter(self.t.lt.channel.like(channel+'%'))
33
26 sum = 034 sum = 0
27 for res in query:35 for res in query:
28 if res.sum is not None:36 if res.sum is not None:
3939
4040
41 def average(self, date, dateRange):41 def average(self, date, dateRange):
42 query = self.t.lt.query.with_entities(func.avg(self.t.lt.duration).label('average')).filter(self.t.lt.dcontext == "callback", self.t.lt.calldate.between(date, dateRange))
42 query = self.t.lt.query.with_entities(
43 func.avg(self.t.lt.billsec).label('average')).filter(
44 self.t.lt.dcontext == "callback",
45 self.t.lt.disposition == "ANSWERED",
46 self.t.lt.calldate.between(date, dateRange))
47
43 average = 048 average = 0
44 for res in query:49 for res in query:
45 if res.average is not None:50 if res.average is not None:
46 average = res.average/6051 average = res.average/60
47 return round(average, 4)52 return round(average, 4)
4853
49 def sum(self, date, dateRange):
50 query = self.t.lt.query.with_entities(func.sum(self.t.lt.duration).label('sum')).filter(self.t.lt.dcontext == "callback", self.t.lt.calldate.between(date, dateRange))
51 sum = 0
52 for res in query:
53 if res.sum is not None:
54 sum = res.sum/60
55 return round(sum, 4)
54 # def sum(self, date, dateRange):
55 # query = self.t.lt.query.with_entities(
56 # func.sum(self.t.lt.billsec).label('sum')).filter(
57 # self.t.lt.dcontext == "callback",
58 # self.t.lt.disposition == "ANSWERED",
59 # self.t.lt.calldate.between(date, dateRange))
60 # sum = 0
61 # for res in query:
62 # if res.sum is not None:
63 # sum = res.sum/60
64 # return round(sum, 4)
5665
5766
58 def missedCalls(self, date, dateRange, modem=None):67 def missedCalls(self, date, dateRange, modem=None):
59 if modem is None:68 if modem is None:
60 return self.t.lt.query.filter(((self.t.lt.dcontext == 'mobilink') |69 return self.t.lt.query.filter(((self.t.lt.dcontext == 'mobilink') |
61 (self.t.lt.dcontext == 'mobilinktata')) &
62 (self.t.lt.calldate.between(date, dateRange))).count()
70 (self.t.lt.dcontext ==
71 'mobilinktata')) &
72 (self.t.lt.calldate.between(date,
73 dateRange))).count()
63 else:74 else:
64 return self.t.lt.query.filter(self.t.lt.dcontext == modem, self.t.lt.calldate.between(date, dateRange)).count()
75 return self.t.lt.query.filter(self.t.lt.dcontext == modem,
76 self.t.lt.calldate.between(date,
77 dateRange)).count()
6578
6679
80 def unAccountedCalls(self, date, dateRange):
81 return self.t.lt.query.filter(self.t.lt.dcontext == 'default',
82 self.t.lt.calldate.between(date,
83 dateRange)).count()
84
85
67 def answeredCalls(self, date, dateRange):86 def answeredCalls(self, date, dateRange):
68 return self.t.lt.query.filter(self.t.lt.dcontext == 'callback',87 return self.t.lt.query.filter(self.t.lt.dcontext == 'callback',
69 self.t.lt.calldate.between(date, dateRange)).count()
88 self.t.lt.disposition == 'ANSWERED',
89 self.t.lt.calldate.between(date,
90 dateRange)).count()
7091
7192
72 def filter_calls_by_duration(self, date, dateRange, duration):
73 return self.t.lt.query.filter(self.t.lt.dcontext == 'callback', self.t.lt.duration < duration, self.t.lt.calldate.between(date, dateRange)).count()
93 def filter_calls_by_duration(self, date, dateRange, billsec):
94 return self.t.lt.query.filter(
95 self.t.lt.dcontext == 'callback', self.t.lt.billsec < billsec,
96 self.t.lt.calldate.between(date, dateRange)).count()
7497
7598
76 def call_distribution(self, date, dateRange, dcontext):99 def call_distribution(self, date, dateRange, dcontext):
77 startTimeStamp = datetime.datetime.strptime(date, '%Y-%m-%d %H:%M:%S')100 startTimeStamp = datetime.datetime.strptime(date, '%Y-%m-%d %H:%M:%S')
78 endTimeStamp = datetime.datetime.strptime(dateRange, '%Y-%m-%d %H:%M:%S')101 endTimeStamp = datetime.datetime.strptime(dateRange, '%Y-%m-%d %H:%M:%S')
79 result = self.t.lt.query.filter(self.t.lt.dcontext == dcontext, self.t.lt.calldate.between(date, dateRange))
102 result = self.t.lt.query.filter(
103 self.t.lt.dcontext == dcontext, self.t.lt.calldate.between(date, dateRange))
80 slots = {}104 slots = {}
81 while(startTimeStamp - endTimeStamp <= datetime.timedelta(0)):105 while(startTimeStamp - endTimeStamp <= datetime.timedelta(0)):
82 date1 = startTimeStamp106 date1 = startTimeStamp
83 date2 = startTimeStamp + datetime.timedelta(seconds=3600)107 date2 = startTimeStamp + datetime.timedelta(seconds=3600)
84 startTimeStamp = date2108 startTimeStamp = date2
85 if slots.has_key('{0}-{1}'.format(date1.strftime('%H'), date2.strftime('%H'))):109 if slots.has_key('{0}-{1}'.format(date1.strftime('%H'), date2.strftime('%H'))):
86 slots['{0}-{1}'.format(date1.strftime('%H'), date2.strftime('%H'))] += result.filter(self.t.lt.calldate.between(date1, date2)).count()
110 slots['{0}-{1}'.format(date1.strftime('%H'),
111 date2.strftime('%H'))] += result.filter(
112 self.t.lt.calldate.between(date1, date2)).count()
87 else:113 else:
88 slots['{0}-{1}'.format(date1.strftime('%H'), date2.strftime('%H'))] = result.filter(self.t.lt.calldate.between(date1, date2)).count()
114 slots['{0}-{1}'.format(date1.strftime('%H'),
115 date2.strftime('%H'))] = result.filter(
116 self.t.lt.calldate.between(date1, date2)).count()
89117
90 maxLoad = max(slots, key = lambda x: slots.get(x) )118 maxLoad = max(slots, key = lambda x: slots.get(x) )
91 minLoad = []119 minLoad = []
124124
125125
126 def calls_unanswered(self, date, dateRange):126 def calls_unanswered(self, date, dateRange):
127 return self.t.lt.query.filter(self.t.lt.dcontext=='default', self.t.lt.calldate.between(date,dateRange)).count()
127 return self.t.lt.query.filter(self.t.lt.disposition == 'NO ANSWER',
128 self.t.lt.dcontext == 'callback',
129 self.t.lt.calldate.between(date,dateRange)).count()
128130
129131
130 def max_duration_UC(self, date, dateRange):132 def max_duration_UC(self, date, dateRange):
131 query = self.t.lt.query.with_entities(func.max(self.t.lt.duration).label('duration')).filter(self.t.lt.dcontext=='default', self.t.lt.calldate.between(date,dateRange))
133 query = self.t.lt.query.with_entities(
134 func.max(self.t.lt.duration).label('duration')).filter(
135 self.t.lt.dcontext=='default', self.t.lt.calldate.between(date,dateRange))
132 duration = 0136 duration = 0
133 for result in query:137 for result in query:
134 if result.duration is not None:138 if result.duration is not None:

report.py

25postings = query.Query('lb_postings')25postings = query.Query('lb_postings')
26callDetails = query.Query('cdr')26callDetails = query.Query('cdr')
27average_call_length = callDetails.average(startDate, endDate)27average_call_length = callDetails.average(startDate, endDate)
28audio_minutes = callDetails.sum(startDate, endDate)
28audio_minutes = callDetails.totalMinutes(startDate, endDate)
29mobilink_load = callDetails.call_distribution(startDate, endDate, 'mobilink')29mobilink_load = callDetails.call_distribution(startDate, endDate, 'mobilink')
30mobilink_tata_load = callDetails.call_distribution(startDate, endDate, 'mobilinktata')30mobilink_tata_load = callDetails.call_distribution(startDate, endDate, 'mobilinktata')
3131
37 """37 """
38 minutes = {}38 minutes = {}
39 for ip in conf.ip_addr:39 for ip in conf.ip_addr:
40 minutes[ip] = callDetails.totalMinutes(ip, startDate, endDate)
40 minutes[ip] = callDetails.totalMinutes(startDate, endDate, ip)
41 return minutes41 return minutes
4242
43def individual_load():43def individual_load():
98 callDetails.calls_unanswered(startDate, endDate),98 callDetails.calls_unanswered(startDate, endDate),
9999
100 "Maximum_duration_of_unanswered_call":100 "Maximum_duration_of_unanswered_call":
101 callDetails.max_duration_UC(startDate, endDate)
101 callDetails.max_duration_UC(startDate, endDate),
102
103 "Number of calls failed permanently": callDetails.unAccountedCalls(startDate, endDate)
102 })104 })
103105
104def genReport():106def genReport():