package cdr import ( "encoding/csv" "fmt" "os" "regexp" ) type PriceType int const ( PriceUnknown PriceType = iota PriceCall PriceText PriceData ) type Price struct { Type PriceType BuyEach int BuyUnit int SellEach int SellUnit int Destination string } const FieldsPerPricingLine = 14 // PriceImportIndex keeps track of what column corresponds to what data type PriceImportIndex int const ( PriceImportRegion PriceImportIndex = iota PriceImportDestination PriceImportPpcBuy PriceImportPpmBuyFixed PriceImportPpmBuyMobile PriceImportPpcSell PriceImportPpmSellFixed PriceImportPpmSellMobile PriceImportPpcMargin PriceImportPpmMarginFixed PriceImportPpmMarginMobile PriceImportPpcSellVAT PriceImportPpmSellFixedVAT PriceImportPpmSellMobileVAT ) var ( PricingRegexp = regexp.MustCompile(`(\d+\.\d+)`) ) // ImportPricesFile expects a CSV with the following fields: // - Regio (string) // - Destination (string) // - ppc_buy // - ppm_buy_fixed // - ppm_buy_mobile // - ppc_sell // - ppm_sell_fixed // - ppm_sell_mobile // - ppc_margin // - ppm_margin_fixed // - ppm_margin_mobile // - ppc_sell_vat // - ppm_sell_fixed_vat // - ppm_sell_mobile_vat func ImportPricesFile(fn string) ([]Price, error) { f, err := os.Open(fn) if err != nil { return nil, fmt.Errorf("opening file %q failed: %v", fn, err) } csvReader := csv.NewReader(f) csvReader.FieldsPerRecord = FieldsPerPricingLine csvReader.Comma = ';' all, err := csvReader.ReadAll() if err != nil { return nil, fmt.Errorf("reading csv %q failed: %v", fn, err) } var ret []Price priceTypes := []string{ "Fixed", "Mobile", } for _, line := range all { if line[PriceImportRegion] == "Regio" || line[PriceImportDestination] == "" { // Header line or no destination continue } for _, priceType := range priceTypes { destination := line[PriceImportRegion] + " - " + line[PriceImportDestination] + " - " + priceType priceKind := PriceCall // TODO: import Text and Data through the same CSV var buyUnit, sellUnit int buyEach := convertImportedPrice(line[PriceImportPpcBuy]) sellEach := convertImportedPrice(line[PriceImportPpcSell]) switch priceType { case "Fixed": buyUnit = convertImportedPrice(line[PriceImportPpmBuyFixed]) sellUnit = convertImportedPrice(line[PriceImportPpmSellFixed]) case "Mobile": buyUnit = convertImportedPrice(line[PriceImportPpmBuyMobile]) sellUnit = convertImportedPrice(line[PriceImportPpmSellMobile]) default: return nil, fmt.Errorf("unsupported priceType %q", priceType) } // Extract the prices ret = append(ret, Price{ Type: priceKind, Destination: destination, BuyEach: buyEach, BuyUnit: buyUnit, SellEach: sellEach, SellUnit: sellUnit, }) } } return ret, nil } func convertImportedPrice(s string) int { if s == "" { return 0 } p := PricingRegexp.FindString(s) conv, err := decimalStrToInt(p, ".") if err != nil { panic("cannot convert ImportedPrice: " + err.Error()) } return conv }