test start
cicd / ci (push) Successful in 1m28s
Details
cicd / ci (push) Successful in 1m28s
Details
parent
682dc9880e
commit
3e001b8ddd
|
|
@ -26,7 +26,53 @@ func NewFiles(p string, q ...string) (Files, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (files Files) Amend(old, now Delta) error {
|
func (files Files) Amend(old, now Delta) error {
|
||||||
return io.EOF
|
xactions, err := files.transactions()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var transaction transaction
|
||||||
|
for _, xaction := range xactions {
|
||||||
|
if xaction.name != old.transaction {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
transaction = xaction
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
inverted := transaction.deltas()
|
||||||
|
for i := range inverted {
|
||||||
|
inverted[i].Value *= -1
|
||||||
|
}
|
||||||
|
|
||||||
|
if now.isSet {
|
||||||
|
return fmt.Errorf("cannot ammend: immutable isSet is set")
|
||||||
|
}
|
||||||
|
transaction.date = now.Date
|
||||||
|
transaction.description = now.Description
|
||||||
|
if transaction.payee == old.Name {
|
||||||
|
if len(transaction.recipients) != 1 {
|
||||||
|
return fmt.Errorf("cannot amend: modifying original payee, but many recipients cant share new value")
|
||||||
|
}
|
||||||
|
old.Value *= -1
|
||||||
|
old.Name = transaction.recipients[0].name
|
||||||
|
}
|
||||||
|
idx := -1
|
||||||
|
for i, recipient := range transaction.recipients {
|
||||||
|
if recipient.name == old.Name && recipient.value == old.Value {
|
||||||
|
idx = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if idx == -1 {
|
||||||
|
return fmt.Errorf("cannot amend: no recipient with name %s found to set new value", old.Name)
|
||||||
|
}
|
||||||
|
transaction.recipients[idx].name = now.Name
|
||||||
|
transaction.recipients[idx].value = now.Value
|
||||||
|
transaction.recipients[idx].currency = string(now.Currency)
|
||||||
|
amendedDeltas := transaction.deltas().Like(func(d Delta) bool {
|
||||||
|
return d.Name != transaction.payee
|
||||||
|
})
|
||||||
|
|
||||||
|
return files.Add(transaction.payee, append(inverted, amendedDeltas...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (files Files) TempGetLastNLines(n int) ([]string, error) {
|
func (files Files) TempGetLastNLines(n int) ([]string, error) {
|
||||||
|
|
@ -134,7 +180,16 @@ func (files Files) paths() []string {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func (files Files) Add(payee string, delta Delta) error {
|
func (files Files) Add(payee string, deltas ...Delta) error {
|
||||||
|
for _, delta := range deltas {
|
||||||
|
if err := files.add(payee, delta); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (files Files) add(payee string, delta Delta) error {
|
||||||
currencyValue := fmt.Sprintf("%s%.2f", delta.Currency, delta.Value)
|
currencyValue := fmt.Sprintf("%s%.2f", delta.Currency, delta.Value)
|
||||||
if delta.Currency != USD {
|
if delta.Currency != USD {
|
||||||
currencyValue = fmt.Sprintf("%.2f %s", delta.Value, delta.Currency)
|
currencyValue = fmt.Sprintf("%.2f %s", delta.Value, delta.Currency)
|
||||||
|
|
@ -214,39 +269,7 @@ func (files Files) Deltas(like ...Like) (Deltas, error) {
|
||||||
|
|
||||||
result := make(Deltas, 0, len(transactions)*2)
|
result := make(Deltas, 0, len(transactions)*2)
|
||||||
for _, transaction := range transactions {
|
for _, transaction := range transactions {
|
||||||
sums := map[string]float64{}
|
result = append(result, transaction.deltas()...)
|
||||||
for _, recipient := range transaction.recipients {
|
|
||||||
sums[recipient.currency] += recipient.value
|
|
||||||
delta := newDelta(
|
|
||||||
transaction.name,
|
|
||||||
transaction.date,
|
|
||||||
transaction.description,
|
|
||||||
recipient.name,
|
|
||||||
recipient.value,
|
|
||||||
recipient.currency,
|
|
||||||
recipient.isSet,
|
|
||||||
)
|
|
||||||
result = append(result, delta)
|
|
||||||
}
|
|
||||||
for currency, value := range sums {
|
|
||||||
if value == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if transaction.payee == "" {
|
|
||||||
//return nil, fmt.Errorf("didnt find net zero and no dumping ground payee set: %+v", transaction)
|
|
||||||
} else {
|
|
||||||
delta := newDelta(
|
|
||||||
transaction.name,
|
|
||||||
transaction.date,
|
|
||||||
transaction.description,
|
|
||||||
transaction.payee,
|
|
||||||
-1.0*value,
|
|
||||||
currency,
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
result = append(result, delta)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
balances := make(Balances)
|
balances := make(Balances)
|
||||||
|
|
|
||||||
|
|
@ -11,12 +11,61 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestFileAmend(t *testing.T) {
|
func TestFileAmend(t *testing.T) {
|
||||||
// given real xaction
|
cases := map[string]struct {
|
||||||
// find it
|
from string
|
||||||
// invert it
|
old Delta
|
||||||
// modify original delta to requested
|
now Delta
|
||||||
// modify counterpart
|
want string
|
||||||
// inbox.txt has xaction inverted and xaction'
|
}{
|
||||||
|
//"was set payee": {
|
||||||
|
//"payee": {
|
||||||
|
//"recipient": {
|
||||||
|
//"multi recipient": {
|
||||||
|
"was set": {
|
||||||
|
from: `
|
||||||
|
2006-01-02 description
|
||||||
|
recipient $3.45
|
||||||
|
payee
|
||||||
|
`,
|
||||||
|
old: Delta{
|
||||||
|
Date: "2006-01-02",
|
||||||
|
Name: "recipient",
|
||||||
|
Value: 3.45,
|
||||||
|
Currency: "$",
|
||||||
|
Description: "description",
|
||||||
|
},
|
||||||
|
now: Delta{
|
||||||
|
Date: "2106-11-12",
|
||||||
|
Name: "recipient",
|
||||||
|
Value: 3.45,
|
||||||
|
Currency: "$",
|
||||||
|
Description: "description",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, d := range cases {
|
||||||
|
c := d
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
p := path.Join(t.TempDir(), "dat")
|
||||||
|
if err := os.WriteFile(p, bytes.TrimSpace([]byte(c.from)), os.ModePerm); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
files, err := NewFiles(p)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := files.Amend(c.old, c.now); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
} else if b, err := os.ReadFile(path.Join(path.Dir(p), "inbox.dat")); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
} else if b := bytes.TrimSpace(b); string(b) != c.want {
|
||||||
|
t.Fatalf("expected \n\t%s\nbut got\n\t%s", c.want, b)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFileAdd(t *testing.T) {
|
func TestFileAdd(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,42 @@ type transactionRecipient struct {
|
||||||
isSet bool
|
isSet bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t transaction) deltas() Deltas {
|
||||||
|
result := []Delta{}
|
||||||
|
sums := map[string]float64{}
|
||||||
|
for _, recipient := range t.recipients {
|
||||||
|
sums[recipient.currency] += recipient.value
|
||||||
|
result = append(result, newDelta(
|
||||||
|
t.name,
|
||||||
|
t.date,
|
||||||
|
t.description,
|
||||||
|
recipient.name,
|
||||||
|
recipient.value,
|
||||||
|
recipient.currency,
|
||||||
|
recipient.isSet,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
for currency, value := range sums {
|
||||||
|
if value == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if t.payee == "" {
|
||||||
|
//return nil, fmt.Errorf("didnt find net zero and no dumping ground payee set: %+v", transaction)
|
||||||
|
} else {
|
||||||
|
result = append(result, newDelta(
|
||||||
|
t.name,
|
||||||
|
t.date,
|
||||||
|
t.description,
|
||||||
|
t.payee,
|
||||||
|
-1.0*value,
|
||||||
|
currency,
|
||||||
|
false,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
func (t transactionRecipient) empty() bool {
|
func (t transactionRecipient) empty() bool {
|
||||||
return t == (transactionRecipient{})
|
return t == (transactionRecipient{})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue