You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

144 lines
3.5 KiB
Go

package finance
import (
"database/sql"
"fmt"
"log"
"mercury/src/db"
"os"
"path"
"strconv"
"strings"
)
var (
ArInputHeaders = []string{"Acct Name", "Current", "30", "60", "90", ">90"}
arReportInputLineMappingFunction = func(s *sql.Stmt, item *arReportInputLine) {
_, err := s.Exec(
item.AccountName,
item.Current,
item.Thirty,
item.Sixty,
item.Ninety,
item.OverNinety,
item.TotalForPeriod,
item.ReportNameInfo.DateString,
item.ReportNameInfo.Region)
if err != nil {
log.Printf("%#v\n", s)
log.Panic(err)
}
}
)
type (
arReportInputLine struct {
AccountName string
Current float64
Thirty float64
Sixty float64
Ninety float64
OverNinety float64
TotalForPeriod float64
ReportNameInfo *arReportNameInfo
}
arReportNameInfo struct {
DateString string
Region string
}
)
func (ar arReportInputLine) ToQueryBlock() string {
companyName := strings.ReplaceAll(ar.AccountName, "'", "\\'")
return fmt.Sprintf("('%s',%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,'%s','%s')", companyName, ar.Current, ar.Thirty, ar.Sixty, ar.Ninety, ar.OverNinety, ar.TotalForPeriod, ar.ReportNameInfo.DateString, ar.ReportNameInfo.Region)
}
func GenerateArAgingReport(pathlike string) {
connector := &db.ConnectorGeneric{}
res := make([]*arReportInputLine, 0, 5000)
listing, err := os.ReadDir(pathlike)
if err != nil {
log.Panic(err)
}
for _, listing := range listing {
subPath := path.Join(pathlike, listing.Name())
parts := processArReport(subPath)
for _, part := range *parts {
res = append(res, part)
}
}
tableWipe := db.NewRunner("create-mercury-arReports-table.sql", db.MercuryDatabaseName)
connector.ExecuteSqlScript(tableWipe)
log.Println("Updating database")
db.BlockUpdate[arReportInputLine](connector, db.MercuryDatabaseName, "update-mercury-arReport.sql", &res)
log.Println("Updates finished.")
}
func processArReport(pathlike string) *[]*arReportInputLine {
log.Printf("Processing AR Report for: %s\n", pathlike)
res := make([]*arReportInputLine, 0, 500)
contents := readCsv(pathlike)
for _, row := range *contents {
if row[0] == "" || row[0] == "TOTAL" {
continue
}
reportNameInfo := parseReportNameToInfo(pathlike)
inputLine := rawRowToArReportInputLine(row, reportNameInfo)
res = append(res, inputLine)
}
return &res
}
func parseReportNameToInfo(pathlike string) *arReportNameInfo {
base := path.Base(pathlike)
parts := strings.Split(base, "_")
date := reformatSolidDateString(parts[0])
region := parts[2]
return &arReportNameInfo{date, region}
}
func reformatSolidDateString(dateString string) string {
year := dateString[:4]
month := dateString[4:6]
day := dateString[6:8]
return fmt.Sprintf("%s-%s-%s", year, month, day)
}
func rawRowToArReportInputLine(row []string, fileNameInfo *arReportNameInfo) *arReportInputLine {
res := arReportInputLine{}
res.AccountName = row[0]
current, err := strconv.ParseFloat(row[1], 64)
if err != nil {
log.Panicln(err)
}
thirty, err := strconv.ParseFloat(row[2], 64)
if err != nil {
log.Panicln(err)
}
sixty, err := strconv.ParseFloat(row[3], 64)
if err != nil {
log.Panicln(err)
}
ninety, err := strconv.ParseFloat(row[4], 64)
if err != nil {
log.Panicln(err)
}
overninety, err := strconv.ParseFloat(row[5], 64)
if err != nil {
log.Panicln(err)
}
res.Current = current
res.Thirty = thirty
res.Sixty = sixty
res.Ninety = ninety
res.OverNinety = overninety
res.TotalForPeriod = current + thirty + sixty + ninety + overninety
res.ReportNameInfo = fileNameInfo
return &res
}