Files
any2anexoj/internal/table_writer.go
Natercio Moniz 5060fca7be
All checks were successful
Generate check / check-changes (push) Successful in 3s
Generate check / check-generate (push) Has been skipped
round to decimals and improve presentation
2025-11-25 15:14:49 +00:00

116 lines
3.2 KiB
Go

package internal
import (
"context"
"fmt"
"io"
"github.com/biter777/countries"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/jedib0t/go-pretty/v6/text"
"github.com/shopspring/decimal"
)
// TableWriter writes a simple, human readable, table row to the provided io.Writer for each
// ReportItem received.
type TableWriter struct {
table table.Writer
output io.Writer
totalEarned decimal.Decimal
totalSpent decimal.Decimal
totalFees decimal.Decimal
totalTaxes decimal.Decimal
}
func NewTableWriter(w io.Writer) *TableWriter {
t := table.NewWriter()
t.SetOutputMirror(w)
t.SetAutoIndex(true)
t.SetStyle(table.StyleLight)
t.SetColumnConfigs([]table.ColumnConfig{
colCountry(1),
colOther(2),
colOther(3),
colOther(4),
colOther(5),
colEuros(6),
colOther(7),
colOther(8),
colOther(9),
colEuros(10),
colEuros(11),
colEuros(12),
colCountry(13),
})
t.AppendHeader(table.Row{"", "", "Realisation", "Realisation", "Realisation", "Realisation", "Acquisition", "Acquisition", "Acquisition", "Acquisition", "", "", ""}, table.RowConfig{AutoMerge: true})
t.AppendHeader(table.Row{"Source Country", "Code", "Year", "Month", "Day", "Value", "Year", "Month", "Day", "Value", "Expenses", "Paid Taxes", "Counter Country"})
return &TableWriter{
table: t,
output: w,
}
}
func (tw *TableWriter) Write(_ context.Context, ri ReportItem) error {
tw.totalEarned = tw.totalEarned.Add(ri.SellValue.Round(2))
tw.totalSpent = tw.totalSpent.Add(ri.BuyValue.Round(2))
tw.totalFees = tw.totalFees.Add(ri.Fees.Round(2))
tw.totalTaxes = tw.totalTaxes.Add(ri.Taxes.Round(2))
tw.table.AppendRow(table.Row{
ri.AssetCountry, ri.Nature,
ri.SellTimestamp.Year(), int(ri.SellTimestamp.Month()), ri.SellTimestamp.Day(), ri.SellValue.StringFixed(2),
ri.BuyTimestamp.Year(), int(ri.BuyTimestamp.Month()), ri.BuyTimestamp.Day(), ri.BuyValue.StringFixed(2),
ri.Fees.StringFixed(2), ri.Taxes.StringFixed(2), ri.BrokerCountry,
})
return nil
}
func (tw *TableWriter) Render() {
tw.table.AppendFooter(table.Row{"SUM", "SUM", "SUM", "SUM", "SUM", tw.totalEarned.StringFixed(2), "", "", "", tw.totalSpent.StringFixed(2), tw.totalFees.StringFixed(2), tw.totalTaxes.StringFixed(2)}, table.RowConfig{AutoMerge: true, AutoMergeAlign: text.AlignRight})
tw.table.Render()
}
func colEuros(n int) table.ColumnConfig {
return table.ColumnConfig{
Number: n,
Align: text.AlignRight,
AlignFooter: text.AlignRight,
AlignHeader: text.AlignRight,
WidthMin: 12,
Transformer: func(val any) string {
return fmt.Sprintf("%v €", val)
},
TransformerFooter: func(val any) string {
return fmt.Sprintf("%v €", val)
},
}
}
func colOther(n int) table.ColumnConfig {
return table.ColumnConfig{
Number: n,
Align: text.AlignLeft,
AlignFooter: text.AlignLeft,
AlignHeader: text.AlignLeft,
}
}
func colCountry(n int) table.ColumnConfig {
return table.ColumnConfig{
Number: n,
Align: text.AlignLeft,
AlignFooter: text.AlignLeft,
AlignHeader: text.AlignLeft,
WidthMax: 24,
WidthMaxEnforcer: text.Trim,
Transformer: func(val any) string {
countryCode := val.(int64)
return fmt.Sprintf("%v - %s", val, countries.ByNumeric(int(countryCode)).Info().Name)
},
}
}