fixstmt

Tool to rename bank statements to yyyy-mm-dd format
git clone https://git.bracken.jp/fixstmt.git
Log | Files | Refs | LICENSE

convert.go (3290B)


      1 package convert
      2 
      3 import (
      4 	"fmt"
      5 	"path/filepath"
      6 	"regexp"
      7 	"strings"
      8 )
      9 
     10 type Converter interface {
     11 	Type() string
     12 	CanConvert(fname string) bool
     13 	Convert(fname string) (string, error)
     14 }
     15 
     16 // RbcDirectInvesting is a Converter for RBC Direct Investing statements.
     17 type RbcDirectInvesting struct{}
     18 
     19 // AppleCard is a Converter for Apple Card (MasterCard) statements.
     20 type AppleCard struct{}
     21 
     22 // ShinseiBank is a Converter for Shinsei Bank statements.
     23 type ShinseiBank struct{}
     24 
     25 func ConverterForFile(fname string) (Converter, error) {
     26 	converters := []Converter{
     27 		&AppleCard{},
     28 		&RbcDirectInvesting{},
     29 		&ShinseiBank{},
     30 	}
     31 	for _, c := range converters {
     32 		if c.CanConvert(fname) {
     33 			return c, nil
     34 		}
     35 	}
     36 	return nil, fmt.Errorf("Unknown statement type: %s", fname)
     37 }
     38 
     39 func (c *RbcDirectInvesting) Type() string {
     40 	return "RBC Direct Investing"
     41 }
     42 
     43 func (c *RbcDirectInvesting) CanConvert(fname string) bool {
     44 	r := regexp.MustCompile(`^\d+-\d{4}[A-Za-z]{3}\d\d-\d{4}[A-Za-z]{3}\d\d\.pdf$`)
     45 	return r.MatchString(fname)
     46 }
     47 
     48 // Format: ACCTNO-2020Jan15-2020Feb14.pdf
     49 func (c *RbcDirectInvesting) Convert(fname string) (string, error) {
     50 	date := strings.Split(fname, "-")[2][0:9]
     51 	y := date[0:4]
     52 	m, err := getMonthNumber(strings.ToLower(date[4:7]))
     53 	if err != nil {
     54 		return "", err
     55 	}
     56 	d := date[7:9]
     57 	newFname := fmt.Sprintf("%s-%s-%s.pdf", y, m, d)
     58 	return newFname, nil
     59 }
     60 
     61 func (c *AppleCard) Type() string {
     62 	return "Apple Card"
     63 }
     64 
     65 func (c *AppleCard) CanConvert(fname string) bool {
     66 	return strings.HasPrefix(strings.ToLower(fname), "apple card statement ")
     67 }
     68 
     69 // Format: Apple Card Statement - January 2020.pdf
     70 func (c *AppleCard) Convert(fname string) (string, error) {
     71 	ext := filepath.Ext(fname)
     72 	basename := fname[0 : len(fname)-len(ext)]
     73 	date := strings.Split(basename, " ")[4:6]
     74 	y := date[1]
     75 	m, err := getMonthNumber(strings.ToLower(date[0]))
     76 	if err != nil {
     77 		return "", err
     78 	}
     79 	newFname := fmt.Sprintf("%s-%s.pdf", y, m)
     80 	return newFname, nil
     81 }
     82 
     83 func (c *ShinseiBank) Type() string {
     84 	return "Shinsei Bank"
     85 }
     86 
     87 func (c *ShinseiBank) CanConvert(fname string) bool {
     88 	// TODO: this will break in the year 3000.
     89 	// Even more terrifying if we're still using PDFs.
     90 	r := regexp.MustCompile(`^2\d{15}\.pdf$`)
     91 	return r.MatchString(strings.ToLower(fname))
     92 }
     93 
     94 // Format: YYYYmmBBBAAAAAAA.pdf where BBB is the branch number and AAAAAAA is
     95 // the 7-digit account number.
     96 func (c *ShinseiBank) Convert(fname string) (string, error) {
     97 	y := fname[0:4]
     98 	m := fname[4:6]
     99 	newFname := fmt.Sprintf("%s-%s.pdf", y, m)
    100 	return newFname, nil
    101 }
    102 
    103 func getMonthNumber(m string) (string, error) {
    104 	switch {
    105 	case m == "jan" || m == "january":
    106 		return "01", nil
    107 	case m == "feb" || m == "february":
    108 		return "02", nil
    109 	case m == "mar" || m == "march":
    110 		return "03", nil
    111 	case m == "apr" || m == "april":
    112 		return "04", nil
    113 	case m == "may":
    114 		return "05", nil
    115 	case m == "jun" || m == "june":
    116 		return "06", nil
    117 	case m == "jul" || m == "july":
    118 		return "07", nil
    119 	case m == "aug" || m == "august":
    120 		return "08", nil
    121 	case m == "sep" || m == "september":
    122 		return "09", nil
    123 	case m == "oct" || m == "october":
    124 		return "10", nil
    125 	case m == "nov" || m == "november":
    126 		return "11", nil
    127 	case m == "dec" || m == "december":
    128 		return "12", nil
    129 	}
    130 	return "", fmt.Errorf("Bad month name: %s", m)
    131 }