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
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
|
|
}
|
|
|