Added some status Printlns.
Added parametric header skipping in processTrialBalance in csv.go. Began earnest work on a sustainable verizon pipeline.master
parent
791ca84414
commit
6fd8e8bd39
@ -0,0 +1,125 @@
|
||||
package telecom
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/csv"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
/*
|
||||
First step is building the reports on verizon's website. Below are the columns (and hopefully categories) that you need
|
||||
to completely recreate the report.
|
||||
|
||||
|
||||
Wireless number [mandatory]
|
||||
"User name" [Contact Information]
|
||||
Date [Voice Usage]
|
||||
Minutes [voice usage]
|
||||
Number [voice usage]
|
||||
|
||||
|
||||
The report comes as a comma/LF formatted CSV. It has 13 lines of useless header data and 1 line of useless total data
|
||||
that must be trimmed off to shove everything through a struct factory.
|
||||
|
||||
*/
|
||||
|
||||
type (
|
||||
VerizonCSV struct {
|
||||
trimmed bool
|
||||
rawData *[]byte
|
||||
TabularData *bytes.Buffer
|
||||
}
|
||||
|
||||
VerizonCallLine struct {
|
||||
WirelessNumber string
|
||||
UserName string
|
||||
CallDate string
|
||||
CallMinutes int
|
||||
OtherNumber string
|
||||
UsageCategory string
|
||||
}
|
||||
)
|
||||
|
||||
func RowToVerizonCallLine(row []string) *VerizonCallLine {
|
||||
minutes, err := strconv.Atoi(row[3])
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
line := VerizonCallLine{row[0], row[1], row[2], minutes, row[4], row[5]}
|
||||
return &line
|
||||
}
|
||||
|
||||
func NewVerizonCSV(pathlike string) *VerizonCSV {
|
||||
csv := VerizonCSV{trimmed: false}
|
||||
file, err := os.OpenFile(pathlike, os.O_RDONLY, 777)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
payload, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
csv.rawData = &payload
|
||||
(&csv).trimHeadersAndFooters()
|
||||
|
||||
return &csv
|
||||
}
|
||||
|
||||
func (v *VerizonCSV) trimHeadersAndFooters() {
|
||||
if v.trimmed {
|
||||
return
|
||||
}
|
||||
data := *v.rawData
|
||||
lineCount := 0
|
||||
headerIdx := -1
|
||||
footerIdx := -1
|
||||
for i, c := range data {
|
||||
if c == '\n' {
|
||||
lineCount += 1
|
||||
if lineCount == 13 {
|
||||
headerIdx = i + 1
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
for i := len(data) - 1; i >= 0; i-- {
|
||||
c := data[i]
|
||||
if c == 'n' {
|
||||
footerIdx = i + 1
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
tabData := bytes.NewBuffer(data[headerIdx:footerIdx])
|
||||
v.TabularData = tabData
|
||||
v.trimmed = true
|
||||
}
|
||||
|
||||
func ProcessVerizonCsvToObjects[K any](v *VerizonCSV, mappingFunction func([]string) *K, filterFunction func([]string) bool) *[]*K {
|
||||
ret := make([]*K, 0, 1000)
|
||||
doc := csv.NewReader(v.TabularData)
|
||||
|
||||
var filter func([]string) bool
|
||||
if filterFunction == nil {
|
||||
filter = func([]string) bool { return true }
|
||||
} else {
|
||||
filter = filterFunction
|
||||
}
|
||||
|
||||
//this is going to read the entire thing line by line until it hits a parser error or the io.EOF error at the end of the buffer.
|
||||
//we did it like this because verizon reports love to append jagged rows every so often, which makes the parser freak out.
|
||||
//all the stuff we care about is in the top of the document so far, so this works for now. -dtookey 6/7/2022
|
||||
for record, err := doc.Read(); err == nil; record, err = doc.Read() {
|
||||
if filter(record) {
|
||||
obj := mappingFunction(record)
|
||||
ret = append(ret, obj)
|
||||
}
|
||||
}
|
||||
|
||||
return &ret
|
||||
}
|
||||
Loading…
Reference in New Issue