From 1054bad73a06b7399af2752f7aeda5607c07c2fe Mon Sep 17 00:00:00 2001 From: Gerdriaan Mulder Date: Tue, 11 Feb 2020 21:56:06 +0100 Subject: [PATCH] Add notion of 'Source' in a price. Note on processing multiple legs --- combine.go | 60 ++++++++++++++++++++++++++++++++++++------------- import_cdr.go | 2 +- import_price.go | 1 + 3 files changed, 46 insertions(+), 17 deletions(-) diff --git a/combine.go b/combine.go index 5d15725..1b79ef4 100644 --- a/combine.go +++ b/combine.go @@ -140,7 +140,7 @@ func CombineCallCDRs(cdrLines []Line, prices []Price) ([]Call, error) { } if !matched { - fmt.Printf("[debug] non-matched price for destination %q\n", l.Destination) + fmt.Printf("[debug] non-matched price for destination %q (from line: %+v)\n", l.Destination, l) nonMatchedDestinations[l.Destination] = struct{}{} } } @@ -175,8 +175,12 @@ func CombineCallCDRs(cdrLines []Line, prices []Price) ([]Call, error) { */ callCost := 0.0 callPrice := 0.0 - for _, leg := range v { + pricedLegs := make([]PricedLine, len(v)) + for i, leg := range v { legPrice := Price{} + pricedLeg := PricedLine{} + // TODO: observation: first check the number of legs, if we have multiple, assume it's a HS->PBX->Destination (outgoing) call. + // Source->PBX->Handset ends up as one leg if leg.CLI == leg.From { switch { case leg.Source == CALL_FROM_HANDSET_SOURCE && leg.Destination == CALL_FROM_HANDSET_DESTINATION: @@ -219,28 +223,52 @@ func CombineCallCDRs(cdrLines []Line, prices []Price) ([]Call, error) { leg.Id, leg.Time.Format(DateTimeFormat), leg.CLI, leg.From, leg.To, leg.Source, leg.Destination, leg.Reason, mapOk) } else { // RawCount is in seconds. Buy/SellUnit is in cents*100, per minute - callCost += float64(legPrice.BuyEach) + float64(leg.RawCount)*(float64(legPrice.BuyUnit)/60.0) - callPrice += float64(legPrice.SellEach) + float64(leg.RawCount)*(float64(legPrice.SellUnit)/60.0) - fmt.Printf("(%12s->%12s) leg %d, callCost: %.4f, callPrice: %.4f (dst: %q)\n", leg.CLI, leg.To, leg.Leg, callCost, callPrice, legPrice.OurRef) + thisLegCost := float64(legPrice.BuyEach) + float64(leg.RawCount)*(float64(legPrice.BuyUnit)/60.0) + thisLegPrice := float64(legPrice.SellEach) + float64(leg.RawCount)*(float64(legPrice.SellUnit)/60.0) + + pricedLeg.Line = leg + pricedLeg.Cost = int(math.Round(thisLegCost)) + pricedLeg.Price = int(math.Round(thisLegPrice)) + pricedLegs[i] = pricedLeg + + callCost += thisLegCost + callPrice += thisLegPrice + fmt.Printf("(%12s( %12s)->%12s) leg %d, callCost: %.4f, callPrice: %.4f (dst: %q)\n", leg.CLI, leg.From, leg.To, leg.Leg, callCost, callPrice, legPrice.OurRef) } // Source -> HS (non-roaming) (i.e. incoming calls) does not exist in the CSV //fmt.Printf("(%12s->%12s) leg %d, price: %+v\n", leg.CLI, leg.To, leg.Leg, legPrice) } + callDuration, _ := time.ParseDuration(fmt.Sprintf("%ds", v[0].RawCount)) + var callFrom, callTo string + + ret[i] = Call{ + Duration: callDuration, + Time: v[0].Time, + Cost: int(math.Round(callCost)), + Price: int(math.Round(callPrice)), + Legs: pricedLegs, + } if len(v) == 1 { - callDuration, _ := time.ParseDuration(fmt.Sprintf("%ds", v[0].RawCount)) // CLI == From, then this leg's CLI is our "From" field, and this leg's "To" likewise - ret[i] = Call{ - From: v[0].CLI, - To: v[0].To, - Duration: callDuration, - Time: v[0].Time, - Cost: int(math.Round(callCost)), - Price: int(math.Round(callPrice)), - } + callFrom = v[0].CLI + callTo = v[0].To } else { - + // We capture the "To" from the leg that has no source, we capture the "From" from the leg that has both source and destination + for _, leg := range v { + if leg.Source == "" && leg.Destination != "" { + callTo = leg.To + } else if leg.Source != "" && leg.Destination != "" { + callFrom = leg.From + } else { + // We should not reach this + return nil, fmt.Errorf("failed to combine these legs into one call: %+v", v) + } + } } - fmt.Printf("==> %+v\n", ret[i]) + ret[i].From = callFrom + ret[i].To = callTo + + fmt.Printf(" ==> %+v\n\n", ret[i]) //ret[i].Legs = make([]PricedLine, len(v)) //for j, leg := range v { //ret[i].Legs[j] = leg diff --git a/import_cdr.go b/import_cdr.go index 974fa7f..601b55a 100644 --- a/import_cdr.go +++ b/import_cdr.go @@ -117,7 +117,7 @@ func ImportCSV(fn string) ([]Line, error) { ret[i] = Line{ Id: line[ImportCid], - Time: tryDate, + Time: tryDate, // This field is recorded in UTC CLI: line[ImportCLI], From: line[ImportFrom], To: line[ImportTo], diff --git a/import_price.go b/import_price.go index ceb3415..c1e0911 100644 --- a/import_price.go +++ b/import_price.go @@ -22,6 +22,7 @@ type Price struct { BuyUnit int SellEach int SellUnit int + Source string // optional Destination string OurRef string }