Add description to money transfers
Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
parent
a3523c0a16
commit
5d41188876
4 changed files with 39 additions and 16 deletions
|
@ -228,7 +228,7 @@
|
||||||
aria-labelledby="transferMoneyModalLabel"
|
aria-labelledby="transferMoneyModalLabel"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
>
|
>
|
||||||
<div class="modal-dialog modal-sm">
|
<div class="modal-dialog">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h1
|
<h1
|
||||||
|
@ -306,6 +306,19 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label
|
||||||
|
for="transferMoneyModalDescription"
|
||||||
|
class="form-label"
|
||||||
|
>Description</label>
|
||||||
|
<input
|
||||||
|
id="transferMoneyModalDescription"
|
||||||
|
v-model.number="modals.createTransfer.description"
|
||||||
|
type="text"
|
||||||
|
class="form-control"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label
|
<label
|
||||||
for="transferMoneyModalAmount"
|
for="transferMoneyModalAmount"
|
||||||
|
@ -453,6 +466,7 @@ export default {
|
||||||
createTransfer: {
|
createTransfer: {
|
||||||
amount: 0,
|
amount: 0,
|
||||||
category: '',
|
category: '',
|
||||||
|
description: '',
|
||||||
from: '',
|
from: '',
|
||||||
to: '',
|
to: '',
|
||||||
},
|
},
|
||||||
|
@ -550,6 +564,9 @@ export default {
|
||||||
if (this.modals.createTransfer.category) {
|
if (this.modals.createTransfer.category) {
|
||||||
params.set('category', this.modals.createTransfer.category)
|
params.set('category', this.modals.createTransfer.category)
|
||||||
}
|
}
|
||||||
|
if (this.modals.createTransfer.description) {
|
||||||
|
params.set('description', this.modals.createTransfer.description)
|
||||||
|
}
|
||||||
|
|
||||||
return fetch(`/api/accounts/${this.modals.createTransfer.from}/transfer/${this.modals.createTransfer.to}?${params.toString()}`, {
|
return fetch(`/api/accounts/${this.modals.createTransfer.from}/transfer/${this.modals.createTransfer.to}?${params.toString()}`, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
|
|
|
@ -54,7 +54,7 @@ func (a apiServer) handleCreateAccount(w http.ResponseWriter, r *http.Request) {
|
||||||
})
|
})
|
||||||
|
|
||||||
case database.AccountTypeCategory:
|
case database.AccountTypeCategory:
|
||||||
err = a.dbc.TransferMoney(database.UnallocatedMoney, acc.ID, payload.StartingBalance)
|
err = a.dbc.TransferMoney(database.UnallocatedMoney, acc.ID, payload.StartingBalance, "")
|
||||||
|
|
||||||
case database.AccountTypeTracking:
|
case database.AccountTypeTracking:
|
||||||
_, err = a.dbc.CreateTransaction(database.Transaction{
|
_, err = a.dbc.CreateTransaction(database.Transaction{
|
||||||
|
@ -184,12 +184,12 @@ func (a apiServer) handleTransferMoney(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if category == uuid.Nil {
|
if category == uuid.Nil {
|
||||||
if err = a.dbc.TransferMoney(from, to, amount); err != nil {
|
if err = a.dbc.TransferMoney(from, to, amount, r.URL.Query().Get("description")); err != nil {
|
||||||
a.errorResponse(w, err, "transferring money", http.StatusInternalServerError)
|
a.errorResponse(w, err, "transferring money", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if err = a.dbc.TransferMoneyWithCategory(from, to, amount, category); err != nil {
|
if err = a.dbc.TransferMoneyWithCategory(from, to, amount, r.URL.Query().Get("description"), category); err != nil {
|
||||||
a.errorResponse(w, err, "transferring money", http.StatusInternalServerError)
|
a.errorResponse(w, err, "transferring money", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -287,7 +287,7 @@ func (c *Client) MarkAccountReconciled(acc uuid.UUID) (err error) {
|
||||||
// TransferMoney creates new Transactions for the given account
|
// TransferMoney creates new Transactions for the given account
|
||||||
// transfer. The account type of the from and to account must match
|
// transfer. The account type of the from and to account must match
|
||||||
// for this to work.
|
// for this to work.
|
||||||
func (c *Client) TransferMoney(from, to uuid.UUID, amount float64) (err error) {
|
func (c *Client) TransferMoney(from, to uuid.UUID, amount float64, description string) (err error) {
|
||||||
var fromAcc, toAcc Account
|
var fromAcc, toAcc Account
|
||||||
|
|
||||||
if fromAcc, err = c.GetAccount(from); err != nil {
|
if fromAcc, err = c.GetAccount(from); err != nil {
|
||||||
|
@ -311,7 +311,8 @@ func (c *Client) TransferMoney(from, to uuid.UUID, amount float64) (err error) {
|
||||||
txs = []*Transaction{
|
txs = []*Transaction{
|
||||||
{
|
{
|
||||||
Time: time.Now().UTC(),
|
Time: time.Now().UTC(),
|
||||||
Description: fmt.Sprintf("Transfer: %s → %s", fromAcc.Name, toAcc.Name),
|
Payee: fmt.Sprintf("Transfer: %s → %s", fromAcc.Name, toAcc.Name),
|
||||||
|
Description: description,
|
||||||
Amount: -amount,
|
Amount: -amount,
|
||||||
Account: uuid.NullUUID{UUID: from, Valid: true},
|
Account: uuid.NullUUID{UUID: from, Valid: true},
|
||||||
Category: uuid.NullUUID{},
|
Category: uuid.NullUUID{},
|
||||||
|
@ -320,7 +321,8 @@ func (c *Client) TransferMoney(from, to uuid.UUID, amount float64) (err error) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Time: time.Now().UTC(),
|
Time: time.Now().UTC(),
|
||||||
Description: fmt.Sprintf("Transfer: %s → %s", fromAcc.Name, toAcc.Name),
|
Payee: fmt.Sprintf("Transfer: %s → %s", fromAcc.Name, toAcc.Name),
|
||||||
|
Description: description,
|
||||||
Amount: amount,
|
Amount: amount,
|
||||||
Account: uuid.NullUUID{UUID: to, Valid: true},
|
Account: uuid.NullUUID{UUID: to, Valid: true},
|
||||||
Category: uuid.NullUUID{},
|
Category: uuid.NullUUID{},
|
||||||
|
@ -334,7 +336,8 @@ func (c *Client) TransferMoney(from, to uuid.UUID, amount float64) (err error) {
|
||||||
txs = []*Transaction{
|
txs = []*Transaction{
|
||||||
{
|
{
|
||||||
Time: time.Now().UTC(),
|
Time: time.Now().UTC(),
|
||||||
Description: fmt.Sprintf("Transfer: %s → %s", fromAcc.Name, toAcc.Name),
|
Payee: fmt.Sprintf("Transfer: %s → %s", fromAcc.Name, toAcc.Name),
|
||||||
|
Description: description,
|
||||||
Amount: -amount,
|
Amount: -amount,
|
||||||
Account: uuid.NullUUID{},
|
Account: uuid.NullUUID{},
|
||||||
Category: uuid.NullUUID{UUID: from, Valid: true},
|
Category: uuid.NullUUID{UUID: from, Valid: true},
|
||||||
|
@ -343,7 +346,8 @@ func (c *Client) TransferMoney(from, to uuid.UUID, amount float64) (err error) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Time: time.Now().UTC(),
|
Time: time.Now().UTC(),
|
||||||
Description: fmt.Sprintf("Transfer: %s → %s", fromAcc.Name, toAcc.Name),
|
Payee: fmt.Sprintf("Transfer: %s → %s", fromAcc.Name, toAcc.Name),
|
||||||
|
Description: description,
|
||||||
Amount: amount,
|
Amount: amount,
|
||||||
Account: uuid.NullUUID{},
|
Account: uuid.NullUUID{},
|
||||||
Category: uuid.NullUUID{UUID: to, Valid: true},
|
Category: uuid.NullUUID{UUID: to, Valid: true},
|
||||||
|
@ -370,7 +374,7 @@ func (c *Client) TransferMoney(from, to uuid.UUID, amount float64) (err error) {
|
||||||
|
|
||||||
// TransferMoneyWithCategory creates new Transactions for the given
|
// TransferMoneyWithCategory creates new Transactions for the given
|
||||||
// account transfer. This is not possible for category type accounts.
|
// account transfer. This is not possible for category type accounts.
|
||||||
func (c *Client) TransferMoneyWithCategory(from, to uuid.UUID, amount float64, category uuid.UUID) (err error) {
|
func (c *Client) TransferMoneyWithCategory(from, to uuid.UUID, amount float64, description string, category uuid.UUID) (err error) {
|
||||||
var fromAcc, toAcc Account
|
var fromAcc, toAcc Account
|
||||||
|
|
||||||
if fromAcc, err = c.GetAccount(from); err != nil {
|
if fromAcc, err = c.GetAccount(from); err != nil {
|
||||||
|
@ -390,7 +394,8 @@ func (c *Client) TransferMoneyWithCategory(from, to uuid.UUID, amount float64, c
|
||||||
if err = c.retryTx(func(tx *gorm.DB) (err error) {
|
if err = c.retryTx(func(tx *gorm.DB) (err error) {
|
||||||
fromTx := Transaction{
|
fromTx := Transaction{
|
||||||
Time: time.Now().UTC(),
|
Time: time.Now().UTC(),
|
||||||
Description: fmt.Sprintf("Transfer: %s → %s", fromAcc.Name, toAcc.Name),
|
Payee: fmt.Sprintf("Transfer: %s → %s", fromAcc.Name, toAcc.Name),
|
||||||
|
Description: description,
|
||||||
Amount: -amount,
|
Amount: -amount,
|
||||||
Account: uuid.NullUUID{UUID: from, Valid: true},
|
Account: uuid.NullUUID{UUID: from, Valid: true},
|
||||||
Category: uuid.NullUUID{},
|
Category: uuid.NullUUID{},
|
||||||
|
@ -404,7 +409,8 @@ func (c *Client) TransferMoneyWithCategory(from, to uuid.UUID, amount float64, c
|
||||||
|
|
||||||
toTx := Transaction{
|
toTx := Transaction{
|
||||||
Time: time.Now().UTC(),
|
Time: time.Now().UTC(),
|
||||||
Description: fmt.Sprintf("Transfer: %s → %s", fromAcc.Name, toAcc.Name),
|
Payee: fmt.Sprintf("Transfer: %s → %s", fromAcc.Name, toAcc.Name),
|
||||||
|
Description: description,
|
||||||
Amount: amount,
|
Amount: amount,
|
||||||
Account: uuid.NullUUID{UUID: to, Valid: true},
|
Account: uuid.NullUUID{UUID: to, Valid: true},
|
||||||
Category: uuid.NullUUID{},
|
Category: uuid.NullUUID{},
|
||||||
|
|
|
@ -94,7 +94,7 @@ func TestPairKeyRemoval(t *testing.T) {
|
||||||
testCheckAcctBal(t, bals, tb2.ID, 0)
|
testCheckAcctBal(t, bals, tb2.ID, 0)
|
||||||
|
|
||||||
// Transfer some money
|
// Transfer some money
|
||||||
require.NoError(t, dbc.TransferMoney(tb1.ID, tb2.ID, 500))
|
require.NoError(t, dbc.TransferMoney(tb1.ID, tb2.ID, 500, ""))
|
||||||
bals, err = dbc.ListAccountBalances(false)
|
bals, err = dbc.ListAccountBalances(false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
testCheckAcctBal(t, bals, tb1.ID, -500)
|
testCheckAcctBal(t, bals, tb1.ID, -500)
|
||||||
|
@ -163,7 +163,7 @@ func TestTransactions(t *testing.T) {
|
||||||
testCheckAcctBal(t, bals, UnallocatedMoney, 1000)
|
testCheckAcctBal(t, bals, UnallocatedMoney, 1000)
|
||||||
|
|
||||||
// Lets redistribute the money
|
// Lets redistribute the money
|
||||||
require.NoError(t, dbc.TransferMoney(UnallocatedMoney, tc.ID, 500))
|
require.NoError(t, dbc.TransferMoney(UnallocatedMoney, tc.ID, 500, ""))
|
||||||
bals, err = dbc.ListAccountBalances(false)
|
bals, err = dbc.ListAccountBalances(false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
testCheckAcctBal(t, bals, tb1.ID, 1000)
|
testCheckAcctBal(t, bals, tb1.ID, 1000)
|
||||||
|
@ -173,7 +173,7 @@ func TestTransactions(t *testing.T) {
|
||||||
testCheckAcctBal(t, bals, UnallocatedMoney, 500)
|
testCheckAcctBal(t, bals, UnallocatedMoney, 500)
|
||||||
|
|
||||||
// Now transfer some money to another budget account
|
// Now transfer some money to another budget account
|
||||||
require.NoError(t, dbc.TransferMoney(tb1.ID, tb2.ID, 100))
|
require.NoError(t, dbc.TransferMoney(tb1.ID, tb2.ID, 100, ""))
|
||||||
bals, err = dbc.ListAccountBalances(false)
|
bals, err = dbc.ListAccountBalances(false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
testCheckAcctBal(t, bals, tb1.ID, 900)
|
testCheckAcctBal(t, bals, tb1.ID, 900)
|
||||||
|
@ -183,7 +183,7 @@ func TestTransactions(t *testing.T) {
|
||||||
testCheckAcctBal(t, bals, UnallocatedMoney, 500)
|
testCheckAcctBal(t, bals, UnallocatedMoney, 500)
|
||||||
|
|
||||||
// And some to a tracking account (needs category)
|
// And some to a tracking account (needs category)
|
||||||
require.NoError(t, dbc.TransferMoneyWithCategory(tb1.ID, tt.ID, 100, tc.ID))
|
require.NoError(t, dbc.TransferMoneyWithCategory(tb1.ID, tt.ID, 100, "", tc.ID))
|
||||||
bals, err = dbc.ListAccountBalances(false)
|
bals, err = dbc.ListAccountBalances(false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
testCheckAcctBal(t, bals, tb1.ID, 800)
|
testCheckAcctBal(t, bals, tb1.ID, 800)
|
||||||
|
|
Loading…
Reference in a new issue