AR aging reports can be scanned from a file and updated on the datastudio server. However, this is a highly-manual process. we need to work on automation next.
parent
f7b56120ea
commit
d36464aa8a
@ -0,0 +1,5 @@
|
|||||||
|
package drive
|
||||||
|
|
||||||
|
func Test() {
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,134 @@
|
|||||||
|
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 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
db.BulkUpdate[arReportInputLine](connector, "mercury", "update-mercury-arReport.sql", &res, arReportInputLineMappingFunction)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func processArReport(pathlike string) *[]*arReportInputLine {
|
||||||
|
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
|
||||||
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
DROP TABLE IF EXISTS mercury.ar_aging_report;
|
||||||
|
|
||||||
|
CREATE TABLE mercury.ar_aging_report
|
||||||
|
(
|
||||||
|
AccountName VARCHAR(150),
|
||||||
|
Current REAL,
|
||||||
|
Thirty REAL,
|
||||||
|
Sixty REAL,
|
||||||
|
Ninety REAL,
|
||||||
|
OverNinety REAL,
|
||||||
|
Total_for_Period REAL,
|
||||||
|
DateExported Date,
|
||||||
|
Region VARCHAR(25)
|
||||||
|
);
|
||||||
@ -0,0 +1 @@
|
|||||||
|
select * from picture_patterns;
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
INSERT INTO mercury.ar_aging_report (AccountName, Current, Thirty, Sixty, Ninety, OverNinety, Total_for_Period, DateExported, Region)
|
||||||
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"mercury/src/finance"
|
||||||
|
"mercury/src/mercury"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ic := mercury.NewInterconnect()
|
||||||
|
ic.ResetTables()
|
||||||
|
finance.GenerateArAgingReport("/home/dtookey/work/clarity-reporting/qb/ar/")
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue