Class: Phone::CallLogEventToRecordMatcher
- Inherits:
-
BaseService
- Object
- BaseService
- Phone::CallLogEventToRecordMatcher
- Defined in:
- app/services/phone/call_log_event_to_record_matcher.rb
Defined Under Namespace
Classes: Result
Instance Method Summary collapse
- #find_call_record(cle) ⇒ Object
- #load_call_log_events(options) ⇒ Object
- #parse_display_string(display) ⇒ Object
- #process(options = {}) ⇒ Object
- #reset_call_record_link(call_log_events = nil) ⇒ Object
Instance Method Details
#find_call_record(cle) ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'app/services/phone/call_log_event_to_record_matcher.rb', line 27 def find_call_record(cle) begin # Extract parts of the call log event caller_id,duration_raw = parse_display_string(cle.display) # Caller ID parse caller_id = CallRecord.parse_phone_number(caller_id) || caller_id require 'chronic_duration' duration_in_seconds = (ChronicDuration.parse(duration_raw) rescue nil) || 0 # If duration is not parseable it is probably zero if caller_id.blank? || duration_in_seconds.nil? || duration_in_seconds == 0 logger.warn "Call Log Event #{cle} has no duration or caller id, aborting" return nil end # Now try to match start_time = cle.call_log.start_time end_time = start_time + (cle.call_log.total_duration || 60) talk_time_min = (duration_in_seconds * 0.95).round logger.info "Looking for a call record between #{start_time} and #{end_time} talking to #{caller_id} for #{duration_raw}" call_records = CallRecord.where( "origin_number = :caller_id OR destination_number = :caller_id", caller_id: caller_id). where( created_at: start_time..end_time ). where( "duration_secs IS NULL OR duration_secs >= ?", talk_time_min). where.not("exists(select 1 from call_log_events where call_log_events.call_record_id = call_records.id)"). order(Arel.sql("@ extract(epoch from('#{start_time.to_fs(:db)}'::timestamp - call_records.created_at)), @ #{duration_in_seconds} - COALESCE(duration_secs,0)")) call_record = call_records.first logger.info call_record ? "Found #{call_record}" : "Did not find a call record for #{cle}" rescue StandardError => exc logger.error "Exception while processing call log event #{cle}, #{exc.to_s}" return nil end call_record end |
#load_call_log_events(options) ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'app/services/phone/call_log_event_to_record_matcher.rb', line 59 def load_call_log_events() if [:call_log_events].present? call_log_events = [:call_log_events] elsif [:call_log_event_ids].present? call_log_events = CallLogEvent.where(id: [:call_log_event_ids]) elsif [:call_log_ids].present? call_log_events = CallLogEvent.where(call_log_id: [:call_log_ids]) else call_log_events = CallLogEvent.where(call_record_id: nil) end # Filter only leg type TALKING call_log_events = call_log_events.where(leg_type: 'TALKING').order(:start_time).reverse_order # Include call_logs call_log_events = call_log_events.includes(:call_log) # Filter by start time call_log_events = call_log_events.where(CallLogEvent[:start_time].gteq([:start_time])) if [:start_time] # Filter by limit call_log_events = call_log_events.limit([:limit]) if [:limit].present? logger.info "Loaded #{call_log_events.size} call log event(s) to process" call_log_events end |
#parse_display_string(display) ⇒ Object
86 87 88 |
# File 'app/services/phone/call_log_event_to_record_matcher.rb', line 86 def parse_display_string(display) display.scan(/\ATalked\sto.*\<(\d{3,})\>\sfor\s(.*)\z/).flatten end |
#process(options = {}) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'app/services/phone/call_log_event_to_record_matcher.rb', line 7 def process(={}) # Get all call logs call_log_events = load_call_log_events() records_processed,records_matched,records_unmatched = 0,0,0 total_events = call_log_events.size call_log_events.find_each do |cle| records_processed += 1 logger.info "CallLogEventToRecordMatcher #{(records_processed*100/total_events).round}% [#{records_processed}/#{total_events}] - Processing #{cle}" if cr = find_call_record(cle) records_matched += 1 cle.update_column(:call_record_id, cr.id) else records_unmatched += 1 end end return Result.new(records_processed: records_processed, records_matched: records_matched, records_unmatched: records_unmatched) end |
#reset_call_record_link(call_log_events = nil) ⇒ Object
82 83 84 |
# File 'app/services/phone/call_log_event_to_record_matcher.rb', line 82 def reset_call_record_link(call_log_events=nil) (call_log_events || CallRecord.all).update_all(call_record_id: nil) end |