You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

151 lines
3.5 KiB

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
Source string // optional
Destination string
OurRef 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 {
var destination string
if line[PriceImportRegion] == "Europe" || line[PriceImportRegion] == "North America" || line[PriceImportRegion] == "Africa" {
destination = line[PriceImportDestination] + " - " + priceType + " - "
if priceType == "Fixed" {
destination = destination + "Proper"
} else {
destination = destination + priceType
}
} else {
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
}