gofio

http server for overview for accounts from FIO bank
git clone git://gtms.dev/gofio
Log | Files | Refs

template.go (2408B)


      1 package main
      2 
      3 import (
      4 	"bytes"
      5 	"fio/fio"
      6 	"fmt"
      7 	"os"
      8 	"sort"
      9 
     10 	"github.com/leekchan/accounting"
     11 )
     12 
     13 func loadTemplates(list []string) (templates map[string][]byte) {
     14 	templates = make(map[string][]byte, len(list))
     15 	for _, filename := range list {
     16 		file, err := os.ReadFile("./web/" + filename + ".template.html")
     17 		checkErr(err, "Template '"+filename+"' failed to load")
     18 		templates[filename] = file
     19 	}
     20 	return
     21 }
     22 
     23 func formatAccId(root *fio.Root) string {
     24 	return fmt.Sprintf("%s / %s", root.AccountStatement.Info.AccountId, root.AccountStatement.Info.BankId)
     25 }
     26 
     27 func formatList(root *fio.Root, config config) string {
     28 	ac := accounting.Accounting{Precision: 2, Thousand: " ", Format: "%v %s"}
     29 	headers := make(map[int]string)
     30 	var rows bytes.Buffer
     31 	for _, v := range root.AccountStatement.TransactionList.Transactions {
     32 		columns := []*fio.Column{
     33 			v.Date,
     34 			v.Money,
     35 			v.BeneficiaryAccount,
     36 			v.BeneficiaryMessage,
     37 			v.BeneficiaryComment,
     38 			v.Type,
     39 		}
     40 
     41 		var row bytes.Buffer
     42 		var skipRow bool
     43 		for i, c := range columns {
     44 			if c == nil {
     45 				row.WriteString("<td></td>")
     46 				// skip header
     47 				if _, in := headers[i]; !in {
     48 					headers[i] = ""
     49 				}
     50 				continue
     51 			}
     52 
     53 			// header
     54 			if n, in := headers[i]; !in || in && n == "" {
     55 				headers[i] = c.Name
     56 			}
     57 
     58 			// Row
     59 			switch c.Id {
     60 			case 1:
     61 				moneyClass := "positive"
     62 				if c.Value.(float64) < 0 {
     63 					if config.onlyIncome {
     64 						skipRow = true
     65 					}
     66 					moneyClass = "negative"
     67 				}
     68 				ac.Symbol = v.Currency.Value.(string)
     69 				row.WriteString(fmt.Sprintf("<td class='%s %s'>%v</td>", "money", moneyClass, ac.FormatMoney(c.Value)))
     70 			case 2:
     71 				row.WriteString(fmt.Sprintf("<td><span>%v</span> / <span>%v</span></td>", c.Value, v.BankCode.Value))
     72 			default:
     73 				row.WriteString(fmt.Sprintf("<td>%v</td>", c.Value))
     74 			}
     75 		}
     76 
     77 		if !skipRow {
     78 			rows.WriteString("<tr>")
     79 			rows.WriteString(row.String())
     80 			rows.WriteString("</tr>")
     81 		}
     82 	}
     83 
     84 	var head bytes.Buffer
     85 	indexes := make([]int, 0, len(headers))
     86 	for i := range headers {
     87 		indexes = append(indexes, i)
     88 	}
     89 	sort.Ints(indexes)
     90 	for _, i := range indexes {
     91 		name := headers[i]
     92 		head.WriteString(fmt.Sprintf("<th>%s</th>", name))
     93 	}
     94 
     95 	return fmt.Sprintf(`
     96   <thead>
     97   %s
     98   </thead>
     99   <tbody>
    100   %s
    101   </tbody>
    102     `, head.String(), rows.String())
    103 }
    104 
    105 func contains(s []int, e int) bool {
    106 	for _, a := range s {
    107 		if a == e {
    108 			return true
    109 		}
    110 	}
    111 	return false
    112 }