Add transaction detail view
This commit is contained in:
parent
d0ad0dcb3a
commit
81b3bf334a
@ -66,6 +66,7 @@ func (h *Handler) Serve() {
|
|||||||
withBudget.GET("/budget/:budgetid/settings", h.settings)
|
withBudget.GET("/budget/:budgetid/settings", h.settings)
|
||||||
withBudget.GET("/budget/:budgetid/settings/clear", h.clearBudget)
|
withBudget.GET("/budget/:budgetid/settings/clear", h.clearBudget)
|
||||||
withBudget.GET("/budget/:budgetid/settings/clean-negative", h.cleanNegativeBudget)
|
withBudget.GET("/budget/:budgetid/settings/clean-negative", h.cleanNegativeBudget)
|
||||||
|
withBudget.GET("/budget/:budgetid/transaction/:transactionid", h.transaction)
|
||||||
|
|
||||||
api := router.Group("/api/v1")
|
api := router.Group("/api/v1")
|
||||||
|
|
||||||
|
54
http/transaction-edit.go
Normal file
54
http/transaction-edit.go
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package http
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"git.javil.eu/jacob1123/budgeteer/postgres"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TransactionData struct {
|
||||||
|
AlwaysNeededData
|
||||||
|
Transaction *postgres.Transaction
|
||||||
|
Account *postgres.Account
|
||||||
|
Categories []postgres.GetCategoriesRow
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Handler) transaction(c *gin.Context) {
|
||||||
|
data := c.MustGet("data").(AlwaysNeededData)
|
||||||
|
|
||||||
|
transactionID := c.Param("transactionid")
|
||||||
|
transactionUUID, err := uuid.Parse(transactionID)
|
||||||
|
if err != nil {
|
||||||
|
c.Redirect(http.StatusTemporaryRedirect, "/login")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
transaction, err := h.Service.GetTransaction(c.Request.Context(), transactionUUID)
|
||||||
|
if err != nil {
|
||||||
|
c.AbortWithError(http.StatusNotFound, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
account, err := h.Service.GetAccount(c.Request.Context(), transaction.AccountID)
|
||||||
|
if err != nil {
|
||||||
|
c.AbortWithError(http.StatusNotFound, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
categories, err := h.Service.GetCategories(c.Request.Context(), data.Budget.ID)
|
||||||
|
if err != nil {
|
||||||
|
c.AbortWithError(http.StatusNotFound, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
d := TransactionData{
|
||||||
|
data,
|
||||||
|
&transaction,
|
||||||
|
&account,
|
||||||
|
categories,
|
||||||
|
}
|
||||||
|
|
||||||
|
c.HTML(http.StatusOK, "transaction.html", d)
|
||||||
|
}
|
@ -1,3 +1,7 @@
|
|||||||
|
-- name: GetTransaction :one
|
||||||
|
SELECT * FROM transactions
|
||||||
|
WHERE id = $1;
|
||||||
|
|
||||||
-- name: CreateTransaction :one
|
-- name: CreateTransaction :one
|
||||||
INSERT INTO transactions
|
INSERT INTO transactions
|
||||||
(date, memo, amount, account_id, payee_id, category_id)
|
(date, memo, amount, account_id, payee_id, category_id)
|
||||||
|
@ -63,6 +63,26 @@ func (q *Queries) DeleteAllTransactions(ctx context.Context, budgetID uuid.UUID)
|
|||||||
return result.RowsAffected()
|
return result.RowsAffected()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getTransaction = `-- name: GetTransaction :one
|
||||||
|
SELECT id, date, memo, amount, account_id, category_id, payee_id FROM transactions
|
||||||
|
WHERE id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) GetTransaction(ctx context.Context, id uuid.UUID) (Transaction, error) {
|
||||||
|
row := q.db.QueryRowContext(ctx, getTransaction, id)
|
||||||
|
var i Transaction
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.Date,
|
||||||
|
&i.Memo,
|
||||||
|
&i.Amount,
|
||||||
|
&i.AccountID,
|
||||||
|
&i.CategoryID,
|
||||||
|
&i.PayeeID,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
const getTransactionsByMonthAndCategory = `-- name: GetTransactionsByMonthAndCategory :many
|
const getTransactionsByMonthAndCategory = `-- name: GetTransactionsByMonthAndCategory :many
|
||||||
SELECT date, category_id, budget_id, amount
|
SELECT date, category_id, budget_id, amount
|
||||||
FROM transactions_by_month
|
FROM transactions_by_month
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
{{end}}
|
{{end}}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="transaction/{{.ID}}">{{.Memo}}</a>
|
<a href="/budget/{{$.Budget.ID}}/transaction/{{.ID}}">{{.Memo}}</a>
|
||||||
</td>
|
</td>
|
||||||
{{template "amount-cell" .Amount}}
|
{{template "amount-cell" .Amount}}
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{define "new"}}
|
{{define "new"}}
|
||||||
{{template "transaction-new"}}
|
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{define "main"}}
|
{{define "main"}}
|
||||||
|
65
web/transaction.html
Normal file
65
web/transaction.html
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
{{template "base" .}}
|
||||||
|
|
||||||
|
{{define "title"}}{{.Account.Name}}{{end}}
|
||||||
|
|
||||||
|
{{define "new"}}
|
||||||
|
{{template "transaction-new" .}}
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{define "main"}}
|
||||||
|
<div class="budget-item">
|
||||||
|
<a href="#newtransactionmodal" data-bs-toggle="modal" data-bs-target="#newtransactionmodal">New Transaction</a>
|
||||||
|
<span class="time"></span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<script>
|
||||||
|
$(document).ready(function () {
|
||||||
|
$('#errorcreatingtransaction').hide();
|
||||||
|
$('#newtransactionform').ajaxForm({
|
||||||
|
error: function() {
|
||||||
|
$('#errorcreatingtransaction').show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">Edit Transaction</h5>
|
||||||
|
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<form id="newtransactionform" action="/api/v1/transaction/new" method="POST">
|
||||||
|
<div class="modal-body">
|
||||||
|
<input type="hidden" name="account_id" value="{{.Account.ID}}" />
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="category_id">Category</label>
|
||||||
|
<select name="category_id" class="form-control">
|
||||||
|
<option value="" {{if not $.Transaction.CategoryID.Valid}}selected{{end}}>-- none --</option>
|
||||||
|
{{range .Categories}}
|
||||||
|
<option
|
||||||
|
value="{{.ID}}"
|
||||||
|
{{if and $.Transaction.CategoryID.Valid (eq .ID $.Transaction.CategoryID.UUID)}}selected{{end}}
|
||||||
|
>{{.Group}} : {{.Name}}</option>
|
||||||
|
{{end}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="date">Date</label>
|
||||||
|
<input type="date" name="date" class="form-control" value="{{.Transaction.Date.Format "2006-01-02"}}" />
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="memo">Memo</label>
|
||||||
|
<input type="text" name="memo" class="form-control" value="{{.Transaction.Memo}}" />
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="amount">Amount</label>
|
||||||
|
<input type="number" name="amount" class="form-control" placeholder="0.00" value="{{printf "%.2f" .Transaction.Amount.GetFloat64}}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||||
|
<input type="submit" class="btn btn-primary" value="Create" class="form-control" />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
Loading…
x
Reference in New Issue
Block a user