Advertisement
Guest User

Untitled

a guest
Aug 17th, 2018
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.21 KB | None | 0 0
  1.  
  2. // create max datetime for given day
  3. function max_date(d) {
  4. return new Date(d.setHours(23,59,59));
  5. }
  6.  
  7. // create min datetime for given day
  8. function min_date(d) {
  9. return new Date(d.setHours(0,0,0));
  10. }
  11.  
  12.  
  13. // add to given object proper type2 field
  14. function add_type2(one) {
  15. if (one.type == 'no_picked') {
  16. one.type2 = 'no_picked';
  17. } else {
  18. if (one.status == 'confirmed' || one.status == 'shift') {
  19. one.type2 = 'answered';
  20. } else {
  21. one.type2 = 'not_answered';
  22. }
  23. }
  24. return one;
  25. }
  26.  
  27. // return list of records from mongodb
  28. function return_records(day,consultant) {
  29. var t1 = min_date(day);
  30. var t2 = max_date(day);
  31. var pom = new Date(1970,1,1,0,0,0,0);
  32. // pipeline for call_history collection
  33. var pipeline_1 = [
  34. {'$match': { // choose all calls for chosen consultant in chosen time period
  35. 'consultant': 'ObjectId('+consultant+')',
  36. 'started_at': {
  37. '$gte': 'Date('+t1.toMongo()+')',
  38. '$lte': 'Date('+t2.toMongo()+')'}
  39. }
  40. },
  41. {'$project': { // create m_seconds field which is duration field changed into milliseconds
  42. 'status': 1,
  43. 'started_at': 1,
  44. 'm_seconds': {'$multiply': ['$duration', 1000]}}
  45. },
  46. {'$project': { // create end field and auxiliary pom_date field
  47. 'pom_date': 'Date('+pom.toMongo()+')',
  48. 'started_at': 1,
  49. 'end': {
  50. '$add': ['$started_at','$m_seconds']
  51. },
  52. 'status': 1}
  53. },
  54. {'$project': { // creates ts_ fields which holds timestamp
  55. 'status': 1,
  56. 'started_at': 1,
  57. 'end': 1,
  58. 'ts_started_at': {
  59. '$subtract': ['$started_at','$pom_date']
  60. },
  61. 'ts_end': {
  62. '$subtract': ['$end','$pom_date']}
  63. }
  64. },
  65. {'$sort': {'ts_started_at': 1}}, // sort
  66. {'$addFields': {'type': 'call'}} // add type field
  67. ];
  68. var records_1 = VM.mongo.aggregate('call_history',pipeline_1);
  69. var pipeline_2 = [ // pipeline for call_queue_pick_log collection
  70. {'$match': {
  71. 'created_at': { // choose no_picked attemps in chosen time by chosen consultant
  72. '$gte': 'Date('+t1.toMongo()+')',
  73. '$lte': 'Date('+t2.toMongo()+')'
  74. },
  75. 'user': 'ObjectId('+consultant+')',
  76. 'contact_picked': false,
  77. 'created_at': {'$exists': true}} // just in case
  78. },
  79. {'$project': { // create pom_date secondary field
  80. 'pom_date': 'Date('+pom.toMongo()+')',
  81. 'created_at': 1}
  82. },
  83. {'$project': { // create ts_started_at field which is created_at changed into timestamp
  84. 'created_at': 1,
  85. 'ts_started_at': {
  86. '$subtract': ['$created_at','$pom_date']}
  87. }
  88. },
  89. {'$sort': {'ts_started_at': 1}}, // sort
  90. {'$addFields': { // add the rest of required fields
  91. 'type': 'no_picked',
  92. 'started_at': '$created_at',
  93. 'end': '$created_at',
  94. 'ts_end': '$ts_started_at'}
  95. }
  96. ];
  97. var records_2 = VM.mongo.aggregate('call_queue_pick_log',pipeline_2);
  98. if (records_2.length == 0) { // if list with no_picked attemps is empty
  99. return records_1; // return list with calls only
  100. } else { // else join lists and sort them
  101. var records = new Array();
  102. var index = 0;
  103. var len_limit = records_2.length;
  104. for (x=0; x<records_1.length; x++) {
  105. while (records_2[index].ts_started_at < records_1[x].ts_started_at && index < len_limit) {
  106. records.push(add_type2(records_2[index])); // before put into target list add type2 property
  107. index ++;
  108. }
  109. records.push(add_type2(records_1[x])); // before put into target list add type2 property
  110. }
  111. return records; // return joined list
  112. }
  113. }
  114.  
  115. // return the difference between two values in milliseconds expressed in seconds
  116. function dif_sec(a,b) {
  117. return (b - a) / 1000;
  118. }
  119.  
  120.  
  121. // run the test
  122. function main_2b(day, consultant, limit_a, limit_b, limit_c, limit_d) {
  123. var work_time = 0;
  124. var empty_time = 0;
  125. var rest_time = 0;
  126. var T = new Array(); // [start, period_type]
  127. var Long_periods = new Array(); // [work_time, empty_time, rest_time, T]
  128. var records = return_records(day,consultant);
  129. if (records.length == 0) {
  130. return 0;
  131. }
  132. var period_start = null;
  133. var period_type = null; // 1 - work_time; 2 - empty_time; 3 - rest_time
  134. var prev_stop = null;
  135. var prev_type2 = null;
  136.  
  137.  
  138. // checking first record
  139. period_start = [records[0].started_at,records[0].ts_started_at];
  140. if (records[0].type == 'call') {
  141. period_type = 'call';
  142. T.push([period_start[0],1]);
  143. } else if (records[0].type = 'no_picked') {
  144. period_type = 'no_picked';
  145. T.push([period_start[0],2]);
  146. }
  147. prev_stop = records[0].ts_end;
  148. prev_type2 = records[0].type2;
  149.  
  150. // checking all other records
  151. for (x = 1; x<records.length; x++) {
  152. var diff = dif_sec(prev_stop,records[x].ts_started_at);
  153. if (diff >= limit_b) { // if this is the end of period
  154. if (period_type == 'call') {
  155. work_time += dif_sec(period_start[1],prev_stop);
  156. } else {
  157. empty_time += dif_sec(period_start[1],prev_stop);
  158. }
  159. T.push([prev_stop, 0]);
  160. Long_periods.push(T);
  161. T = new Array();
  162. period_start = [records[x].started_at,records[x].ts_started_at];
  163. if (records[x].type == 'call') {
  164. T.push([records[x].started_at,1]);
  165. period_type = 'call';
  166. } else {
  167. T.push([records[x].started_at,2]);
  168. period_type = 'no_picked';
  169. }
  170. // else if the break is too long
  171. } else if ((prev_type2 == 'not_answered' && diff >= limit_a) || (prev_type2 == 'answered' && diff >= limit_d) || (prev_type2 == 'no_picked' && diff >= limit_c)) {
  172. if (period_type == 'call') {
  173. work_time += dif_sec(period_start[1],prev_stop);
  174. } else {
  175. empty_time += dif_sec(period_start[1],prev_stop);
  176. }
  177. T.push([prev_stop,3]);
  178. rest_time += dif_sec(prev_stop,records[x].ts_started_at);
  179. period_start = [records[x].started_at,records[x].ts_started_at];
  180. if (records[x].type == 'call') {
  181. T.push([records[x].started_at,1]);
  182. period_type = 'call';
  183. } else {
  184. T.push([records[x].started_at,2]);
  185. period_type = 'no_picked';
  186. }
  187.  
  188. } else { // if break is not too long
  189. if (records[x].type != period_type) {
  190. if (records[x].type == 'call') {
  191. empty_time += dif_sec(period_start[1],records[x].ts_started_at);
  192. T.push([records[x].started_at,1]);
  193. period_start = [records[x].started_at,records[x].ts_started_at];
  194. period_type = 'call';
  195. } else {
  196. work_time += dif_sec(period_start[1],records[x].ts_started_at);
  197. T.push([records[x].started_at,2]);
  198. period_start = [records[x].started_at,records[x].ts_started_at];
  199. period_type = 'no_picked';
  200. }
  201. }
  202. }
  203. prev_stop = records[x].ts_end;
  204. prev_type2 = records[2].type2;
  205. }
  206. T.push([prev_stop, 0]);
  207. Long_periods.push(T);
  208. return [Long_periods, work_time, empty_time, rest_time];
  209. }
  210.  
  211.  
  212. function main_2() {
  213. var limit_a = 4 * 60; // the limit after contact that was neither confirmed nor shifted
  214. var limit_b = 5 * 60 * 60; // the limit of continuity of one period
  215. var limit_c = 2 * 60; // the limit after failed attempt to get a contact from the queue
  216. var limit_d = 10 * 60; // the limit after confirmed / shift contact
  217. var day = new Date(2018,6,10,0,0,0,0); // selected day
  218. var consultant = "5aa10ace68a2366db728b936"; // selected consultant
  219. // run test
  220. var response = main_2b(day, consultant, limit_a, limit_b, limit_c, limit_d);
  221. var List = response[0]; // list in format: [period,period...]
  222. // when period = [[start,type],[start,type]]
  223. // types: working time: 1, empty time: 2, rest time: 3, end of period: 0
  224. var work_time = response[1]; // amount of seconds when consultant was working
  225. var empty_time = response[2]; // amount of seconds when the queue was empty
  226. var rest_time = response[3]; // amount of seconds when consultant was not working
  227. /*
  228. VM.log('\n\n');
  229. VM.log('work_time: '+ work_time);
  230. VM.log('empty_time: '+ empty_time);
  231. VM.log('rest_time: '+ rest_time);
  232. VM.log('List:\n\n');
  233. for (x = 0; x<List.length; x++) {
  234. VM.log(List[x]);
  235. VM.log('\n');
  236. }
  237. */
  238. }
  239.  
  240.  
  241. main_2();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement