aboutsummaryrefslogblamecommitdiffstats
path: root/cmd/dbasik-api/return.go
blob: 294c960c2ea4412eaffb774f95e7e03507bd188a (plain) (tree)

































































































































                                                                                                       
package main

import (
	"fmt"
	"github.com/tealeg/xlsx/v3"
	"path/filepath"
)

type ReturnLine struct {
	Sheet   string
	CellRef string
	Value   string
}

type Return struct {
	Name        string
	ReturnLines []ReturnLine
}

// NewReturnLine creates a new ReturnLine object
func NewReturnLine(sheet, cellRef, value string) (*ReturnLine, error) {
	if err := validateInputs(sheet, cellRef, value); err != nil {
		return nil, err
	}

	if !validateSpreadsheetCell(cellRef) {
		return nil, fmt.Errorf("cellRef must be A1 format")
	}

	return &ReturnLine{
		Sheet:   sheet,
		CellRef: cellRef,
		Value:   value,
	}, nil
}

func validateInputs(sheet, cellRef, value string) error {
	if sheet == "" {
		return fmt.Errorf("sheet parameter is required")
	}
	if cellRef == "" {
		return fmt.Errorf("cellRef parameter is required")
	}
	if value == "" {
		return fmt.Errorf("value parameter is required")
	}
	return nil
}

func NewReturn(name string, dm *Datamap, returnLines []ReturnLine) (*Return, error) {
	if len(returnLines) == 0 {
		return nil, fmt.Errorf("ReturnLines must contain at least one ReturnLine")
	}

	return &Return{
		Name:        name,
		ReturnLines: returnLines,
	}, nil
}

//func cellVisitor(c *xlsx.Cell) error {
//	value, err := c.FormattedValue()
//	if err != nil {
//		fmt.Println(err.Error())
//	} else {
//		fmt.Printf("Sheet: %s, Cell value: %s\n", c.Row.Sheet.Name, value)
//	}
//	return err
//}

//func rowVisitor(r *xlsx.Row) error {
//	return r.ForEachCell(cellVisitor, xlsx.SkipEmptyCells)
//}

func ParseXLSX(filePath string, dm *Datamap) (*Return, error) {
	// Use tealeg/xlsx to parse the Excel file
	wb, err := xlsx.OpenFile(filePath)
	if err != nil {
		return nil, err
	}

	// Get the set of sheets from the Datamap
	sheets := GetSheetsFromDM(*dm)

	// Loop through all DatamapLines
	returnLines := []ReturnLine{}
	for _, dml := range dm.DMLs {
		// Check if the sheet for this DatamapLine is in the set of sheets
		if !contains(sheets, dml.Sheet) {
			continue
		}

		sh, ok := wb.Sheet[dml.Sheet]
		if !ok {
			return nil, fmt.Errorf("sheet %s not found in Excel file", dml.Sheet)
		}

		col, row, err := xlsx.GetCoordsFromCellIDString(dml.CellRef)
		if err != nil {
			return nil, err
		}
		cell, err := sh.Cell(row, col)
		if err != nil {
			return nil, err
		}
		returnLines = append(returnLines, ReturnLine{
			Sheet:   dml.Sheet,
			CellRef: dml.CellRef,
			Value:   cell.Value, // or cell.FormattedValue() if you need formatted values
		})
	}

	// Here we create a new Return object with the name of the Excel file and the ReturnLines slice
	// that we just populated
	rtn, err := NewReturn(filepath.Base(filePath), dm, returnLines)
	if err != nil {
		return nil, err
	}
	return rtn, nil
}

// contains checks if a slice contains a given string
func contains(slice []string, str string) bool {
	for _, s := range slice {
		if s == str {
			return true
		}
	}
	return false
}