Files
excelConverter/pkg/loader/loader.go
Andreas Schröpfer 148502d151 rating as float
2021-03-03 19:59:11 +01:00

234 lines
6.0 KiB
Go

package loader
import (
"fmt"
"io"
"math"
"strconv"
"strings"
"git.ecogood.org/andreas.schroepfer/excelConverter/pkg/ecalc"
"git.ecogood.org/andreas.schroepfer/excelConverter/pkg/set"
"github.com/360EntSecGroup-Skylar/excelize/v2"
)
// XLSX reads the data out of the reader. If conf is nil
// the default configuration is used.
func XLSX(r io.Reader, conf *Conf) (*ecalc.Ecalc, error) {
eBalance := &ecalc.Ecalc{}
var errs []error
if conf == nil {
conf = DefaultConf()
}
eBalance.Version = conf.Version
eBalance.Type = conf.Type
xFile, err := excelize.OpenReader(r)
if err != nil {
return nil, fmt.Errorf("XLSX.OpenReader: %w", err)
}
for _, v := range conf.Values {
cellValue, err := xFile.GetCellValue(
xFile.GetSheetName(v.Sheet),
v.Cell,
)
if err != nil {
errs = append(errs, err)
}
switch v.Struct {
case "CompanyFacts":
set.Field(&eBalance.CompanyFacts, v.Field, cellValue)
}
}
for _, a := range conf.Areas {
switch a.Struct {
case "SupplyFraction":
for r := a.StartRow; r <= a.EndRow; r++ {
sf := ecalc.SupplyFraction{}
for _, c := range a.Cols {
axis := fmt.Sprintf("%s%d", c.Col, r)
cellValue, err := xFile.GetCellValue(
xFile.GetSheetName(a.Sheet),
axis)
if err != nil {
errs = append(errs, err)
}
if cellValue == c.Default {
continue
} else if c.Split != "" {
cellValue = strings.Split(cellValue, c.Split)[0]
}
err = set.Field(&sf, c.Field, cellValue)
if err != nil {
errs = append(errs,
fmt.Errorf("XLSXL.SupplyFraction: Sheet %d, Cell %s: %w",
a.Sheet, axis, err))
}
}
if (sf == ecalc.SupplyFraction{}) {
// do not add a empty struct
continue
}
eBalance.CompanyFacts.SupplyFractions =
append(
eBalance.CompanyFacts.SupplyFractions,
sf)
}
case "EmployeesFraction":
for r := a.StartRow; r <= a.EndRow; r++ {
ef := ecalc.EmployeesFraction{}
for _, c := range a.Cols {
axis := fmt.Sprintf("%s%d", c.Col, r)
cellValue, err := xFile.GetCellValue(
xFile.GetSheetName(a.Sheet),
axis)
if err != nil {
errs = append(errs, err)
}
if cellValue == c.Default {
continue
} else if c.Split != "" {
cellValue = strings.Split(cellValue, c.Split)[0]
}
err = set.Field(&ef, c.Field, cellValue)
if err != nil {
errs = append(errs,
fmt.Errorf("XLSXL.EmployeesFraction: Sheet %d, Cell %s: %w",
a.Sheet, axis, err))
}
}
if (ef == ecalc.EmployeesFraction{}) {
// do not add a empty struct
continue
}
eBalance.CompanyFacts.EmployeesFractions =
append(
eBalance.CompanyFacts.EmployeesFractions,
ef)
}
case "IndustrySector":
for r := a.StartRow; r <= a.EndRow; r++ {
is := ecalc.IndustrySector{}
for _, c := range a.Cols {
axis := fmt.Sprintf("%s%d", c.Col, r)
cellValue, err := xFile.GetCellValue(
xFile.GetSheetName(a.Sheet),
axis)
if err != nil {
errs = append(errs, err)
}
if cellValue == c.Default {
continue
} else if c.Split != "" {
cellValue = strings.Split(cellValue, c.Split)[0]
}
err = set.Field(&is, c.Field, cellValue)
if err != nil {
errs = append(errs,
fmt.Errorf("XLSXL.IndustrySector: Sheet %d, Cell %s: %w",
a.Sheet, axis, err))
}
}
if (is == ecalc.IndustrySector{}) {
// do not add a empty struct
continue
}
eBalance.CompanyFacts.IndustrySectors =
append(
eBalance.CompanyFacts.IndustrySectors,
is)
}
}
}
var topic ecalc.Topic
for r := conf.Rating.StartRow; r <= conf.Rating.EndRow; r++ {
shortName, err := xFile.GetCellValue(
xFile.GetSheetName(conf.Rating.Sheet),
fmt.Sprintf("%s%d", conf.Rating.ShortNameCol, r),
)
if err != nil {
errs = append(errs, err)
}
if len(shortName) < 2 {
continue
} else if len(shortName) == 2 {
if topic.ShortName != "" {
eBalance.CompanyFacts.Rating.Topics = append(eBalance.CompanyFacts.Rating.Topics, topic)
}
topic = ecalc.Topic{
ShortName: shortName,
}
for _, c := range conf.Rating.Cols {
cellValue, err := xFile.GetCellValue(
xFile.GetSheetName(conf.Rating.Sheet),
fmt.Sprintf("%s%d", c.Col, r),
)
if err != nil {
errs = append(errs, err)
}
set.Field(&topic, c.Field, cellValue)
}
} else {
aspect := ecalc.Aspect{
ShortName: shortName,
}
for _, c := range conf.Rating.Cols {
cellValue, err := xFile.GetCellValue(
xFile.GetSheetName(conf.Rating.Sheet),
fmt.Sprintf("%s%d", c.Col, r),
)
if err != nil {
errs = append(errs, err)
}
if cellValue == "" {
continue
}
err = set.Field(&aspect, c.Field, cellValue)
if err != nil {
fmt.Println(shortName, c.Field, cellValue)
fmt.Println(err)
}
}
topic.Aspects = append(topic.Aspects, aspect)
}
}
eBalance.CompanyFacts.Rating.Topics = append(eBalance.CompanyFacts.Rating.Topics, topic)
for _, stakeh := range conf.Matrix.Stakeholders {
for _, val := range conf.Matrix.Values {
mTopic := ecalc.MatrixTopic{
ShortName: fmt.Sprintf("%s%s", stakeh.ShortName, val.ShortName),
}
readCell := func(col, field string) {
axis := fmt.Sprintf("%s%d", col, stakeh.Row)
cellValue, err := xFile.GetCellValue(
xFile.GetSheetName(conf.Matrix.Sheet),
axis,
)
if err != nil {
errs = append(errs, err)
}
f, err := strconv.ParseFloat(cellValue, 64)
switch field {
case "Points":
f = math.Round(f)
mTopic.Points = int(f)
case "MaxPoints":
f = math.Round(f)
mTopic.MaxPoints = int(f)
case "PercentageReached":
mTopic.PercentageReached = int(f * 100)
}
// fmt.Println(axis, field, f, cellValue)
}
readCell(val.PointsCol, "Points")
readCell(val.MaxPointsCol, "MaxPoints")
readCell(val.PercentageReachedCol, "PercentageReached")
eBalance.Matrix.Topics = append(eBalance.Matrix.Topics, mTopic)
}
}
// TODO: error handling of errs
return eBalance, nil
}