return resp
}
- data, err := types.NewTransaction(t.logger, transaction)
+ resp.Data, err = types.NewTransaction(t.ctx, t.db, transaction)
if err != nil {
resp.Msg = err.Error()
t.logger.Error(resp.Msg)
return resp
}
- if err := data.SetAttributes(t.ctx, t.db); err != nil {
- resp.Msg = fmt.Sprintf("Failed to set attributes for transaction %d: %s", transaction.ID, err.Error())
+ resp.Success = true
+
+ return resp
+
+}
+
+func (t *transactionService) GetTransactionsTag(id int64) types.TransactionsResponse {
+ var resp types.TransactionsResponse
+ var q []qm.QueryMod
+
+ q = []qm.QueryMod{
+ qm.Where("tag.id=?", id),
+ qm.InnerJoin("tag on tag.id = tag_transactions.tag_id"),
+ qm.InnerJoin("tag_transactions on tag_transactions.transactions_id = transactions.id"),
+ qm.InnerJoin("splits on splits.transactions_id = transactions.id"),
+ qm.InnerJoin("account on account.id = splits.account_id"),
+ qm.Load("Splits"),
+ qm.Load("Splits.Account"),
+ qm.Load("TagTransactions"),
+ }
+ transactions, err := model.Transactions(q...).All(t.ctx, t.db)
+ if err != nil {
+ resp.Msg = err.Error()
t.logger.Error(resp.Msg)
return resp
}
- if err := data.SetSplits(t.ctx, t.db); err != nil {
+ resp.Data = []types.Transaction{}
+ for _, i := range transactions {
+ transaction, err := types.NewTransaction(t.ctx, t.db, i)
+ if err != nil {
+ resp.Msg = err.Error()
+ t.logger.Error(resp.Msg)
+ return resp
+ }
+
+ if transaction.Deleted == true {
+ continue
+ }
+
+ resp.Data = append(resp.Data, transaction)
+ }
+
+ resp.Success = true
+ return resp
+}
+
+func (t *transactionService) GetTransactionsAccount(id int64) types.TransactionsResponse {
+ var resp types.TransactionsResponse
+ var q []qm.QueryMod
+
+ q = []qm.QueryMod{
+ qm.Where("account.id=?", id),
+ qm.InnerJoin("splits on splits.transactions_id = transactions.id"),
+ qm.InnerJoin("account on account.id = splits.account_id"),
+ qm.Load("Splits"),
+ qm.Load("Splits.Account"),
+ }
+ transactions, err := model.Transactions(q...).All(t.ctx, t.db)
+ if err != nil {
resp.Msg = err.Error()
t.logger.Error(resp.Msg)
return resp
}
- resp.Success = true
- resp.Data = data
+ resp.Data = []types.Transaction{}
+ for _, i := range transactions {
+ transaction, err := types.NewTransaction(t.ctx, t.db, i)
+ if err != nil {
+ resp.Msg = err.Error()
+ t.logger.Error(resp.Msg)
+ return resp
+ }
- return resp
+ if transaction.Deleted == true {
+ continue
+ }
+
+ resp.Data = append(resp.Data, transaction)
+ }
+ resp.Success = true
+ return resp
}
-func (t *transactionService) GetTransactions() types.JSResp {
+func (t *transactionService) GetTransactions() types.TransactionsResponse {
+ var resp types.TransactionsResponse
var err error
- var resp types.JSResp
var q []qm.QueryMod
q = []qm.QueryMod{
return resp
}
- data := []types.Transaction{}
+ resp.Data = []types.Transaction{}
for _, i := range transactions {
- transaction, err := types.NewTransaction(t.logger, i)
+ transaction, err := types.NewTransaction(t.ctx, t.db, i)
if err != nil {
resp.Msg = err.Error()
t.logger.Error(resp.Msg)
return resp
}
- if err := transaction.SetSplits(t.ctx, t.db); err != nil {
- resp.Msg = fmt.Sprintf("Failed to get splits for transaction %d: %s", i.ID, err.Error())
- t.logger.Error(resp.Msg)
- return resp
- }
-
- if err := transaction.SetAttributes(t.ctx, t.db); err != nil {
- resp.Msg = fmt.Sprintf("Failed to set attributes for transaction %d: %s", i.ID, err.Error())
- t.logger.Error(resp.Msg)
- return resp
- }
-
if transaction.Deleted == true {
continue
}
- transaction.SetAmount()
- transaction.SetDisplay()
-
- data = append(data, transaction)
+ resp.Data = append(resp.Data, transaction)
}
resp.Success = true
- resp.Data = data
return resp
}
"fmt"
"math/big"
"pennyapp/backend/internal/dberror"
- "pennyapp/backend/logwrap"
"pennyapp/backend/model"
"time"
Data Transaction `json:"data"`
}
+type TransactionsResponse struct {
+ Success bool `json:"success"`
+ Msg string `json:"msg"`
+ Data []Transaction `json:"data"`
+}
+
// NewTransactionResponse returns a default TransactionResponse. All attributes
// of TransactionResponse must be set or else the struct wont be returned
// correctly to the frontend.
}
type Transaction struct {
- ID int64 `json:"id"`
- Memo string `json:"memo"`
- Date string `json:"date"`
+ ID int64 `json:"id"`
+ Memo string `json:"memo"`
+ Date string `json:"date"`
+ Splits []Split `json:"splits"`
+ Amount string `json:"amount"`
+ Deleted bool `json:"deleted"`
+ Display TransactionDisplay `json:"display"`
Currency `json:"currency"`
- Splits []Split `json:"splits"`
- Amount string `json:"amount"`
- Deleted bool `json:"deleted"`
-
- modelTransaction *model.Transaction
- logger *logwrap.LogWrap
-
- // Display attributes are potentially shown in UI and not used in any other logic.
- Display TransactionDisplay `json:"display"`
}
type TransactionDisplay struct {
ID int64 `json:"id"`
}
-func NewTransaction(logger *logwrap.LogWrap, t *model.Transaction) (Transaction, error) {
+func NewTransaction(ctx context.Context, db *sql.DB, t *model.Transaction) (Transaction, error) {
+ var err error
+
transaction := Transaction{
- ID: t.ID,
- Memo: t.Memo,
- modelTransaction: t,
- logger: logger,
+ ID: t.ID,
+ Memo: t.Memo,
}
date, err := time.Parse(DefaultDBTimeLayout, t.Date)
}
transaction.Date = date.Format("2006-01-02")
+ if err = transaction.setSplits(ctx, db, t); err != nil {
+ return transaction, err
+ }
+
+ if err = transaction.setDeleted(ctx, db, t); err != nil {
+ return transaction, err
+ }
+
+ transaction.setAmount()
+ transaction.setDisplay()
+
return transaction, nil
}
-func (t *Transaction) SetSplits(ctx context.Context, db *sql.DB) error {
- splits, err := t.modelTransaction.Splits(qm.Select("splits.id, splits.transactions_id, splits.account_id, splits.value_num, splits.value_denom")).All(ctx, db)
+func (t *Transaction) setSplits(ctx context.Context, db *sql.DB, transaction *model.Transaction) error {
+ splits, err := transaction.Splits(qm.Select("splits.id, splits.transactions_id, splits.account_id, splits.value_num, splits.value_denom")).All(ctx, db)
if err != nil {
- t.logger.Error(err.Error())
return err
}
for _, ii := range splits {
account, err := model.FindAccount(ctx, db, ii.AccountID)
if err != nil {
- t.logger.Error(err.Error())
return err
}
accountType, err := model.FindAccountType(ctx, db, account.AccountTypeID)
if err != nil {
- t.logger.Error(err.Error())
return err
}
if accountType.ParentID != 0 {
pat, err := model.FindAccountType(ctx, db, accountType.ParentID)
if err != nil {
- t.logger.Error(err.Error())
return err
}
parentAccountType = &ParentAccountType{
return nil
}
-func (t *Transaction) SetDisplay() {
+func (t *Transaction) setDisplay() {
display := TransactionDisplay{
Account: TransactionDisplayAccount{},
}
return
}
-func (t *Transaction) SetAmount() {
+func (t *Transaction) setAmount() {
if len(t.Splits) < 1 {
t.Amount = "0"
return
}
}
-func (t *Transaction) SetAttributes(ctx context.Context, db *sql.DB) error {
- if err := t.setDeleted(ctx, db); err != nil {
- return err
- }
- return nil
-}
-
-func (t *Transaction) setDeleted(ctx context.Context, db *sql.DB) error {
- transactionAttribute, err := model.TransactionsAttributes(qm.Where("transactions_id=? AND name=?", t.modelTransaction.ID, "deleted")).One(ctx, db)
+func (t *Transaction) setDeleted(ctx context.Context, db *sql.DB, transaction *model.Transaction) error {
+ transactionAttribute, err := model.TransactionsAttributes(qm.Where("transactions_id=? AND name=?", transaction.ID, "deleted")).One(ctx, db)
switch {
case dberror.IsNoRowsFound(err):
case err != nil:
component: () => import('../views/GetTransactions.vue')
},
{
+ path: '/get-transactions/account/:accountid',
+ name: 'get-transactions-account',
+ component: () => import('../views/GetTransactions.vue'),
+ props: true
+ },
+ {
+ path: '/get-transactions/tag/:tagid',
+ name: 'get-transactions-tag',
+ component: () => import('../views/GetTransactions.vue'),
+ props: true
+ },
+ {
path: '/get-transaction/:id',
name: 'get-transaction',
component: () => import('../views/GetTransaction.vue'),
<label class="small mb-1">
Amount
</label>
- <input class="form-control" readonly type="text" v-model="account.amount">
+ <div>
+ <router-link :to="{ name: 'get-transactions-account', params: { accountid: account.id }}">{{ account.amount }}</router-link>
+ </div>
</div>
<div class="mb-1">
<label class="small mb-1">
<label class="small mb-1">
Amount
</label>
- <input class="form-control" readonly type="text" v-model="tag.amount">
+ <div>
+ <router-link :to="{ name: 'get-transactions-tag', params: { tagid: tag.id }}">{{ tag.amount }}</router-link>
+ </div>
</div>
<div v-for="(regex, idx) in tag.regexes" class="row gx-3 mb-3">
<div class="col-md-6">
<script>
import { ref } from 'vue';
-import { GetTransactions } from 'wailsjs/go/services/transactionService.js'
+import { GetTransactions, GetTransactionsAccount, GetTransactionsTag } from 'wailsjs/go/services/transactionService.js'
import { useRouter } from 'vue-router';
export default {
+ props: [
+ 'accountid',
+ 'tagid',
+ ],
setup() {
const router = useRouter();
return {
methods: {
async getTransactions() {
let transactions = [];
- const { success, msg, data } = await GetTransactions()
- if (!success) {
- $message.error(msg)
- return
+
+ let success = false
+ let msg = ""
+ let data = {}
+
+ if (typeof this.accountid !== 'undefined') {
+ const getTransactionsAccountResp = await GetTransactionsAccount(Number(this.accountid))
+ success = getTransactionsAccountResp.success
+ msg = getTransactionsAccountResp.msg
+ data = getTransactionsAccountResp.data
+ if (!success) {
+ $message.error(msg)
+ return
+ }
+ } else if (typeof this.tagid !== 'undefined') {
+ const getTransactionsTagResp = await GetTransactionsTag(Number(this.tagid))
+ success = getTransactionsTagResp.success
+ msg = getTransactionsTagResp.msg
+ data = getTransactionsTagResp.data
+ if (!success) {
+ $message.error(msg)
+ return
+ }
+
+ } else {
+ const getTransactionsResp = await GetTransactions()
+ success = getTransactionsResp.success
+ msg = getTransactionsResp.msg
+ data = getTransactionsResp.data
+ if (!success) {
+ $message.error(msg)
+ return
+ }
}
+
for (const transaction of data) {
let t = {
id: transaction.id,
id: number;
memo: string;
date: string;
- id: number;
- name: string;
splits: Split[];
amount: string;
deleted: boolean;
display: TransactionDisplay;
+ id: number;
+ name: string;
static createFrom(source: any = {}) {
return new Transaction(source);
this.id = source["id"];
this.memo = source["memo"];
this.date = source["date"];
- this.id = source["id"];
- this.name = source["name"];
this.splits = this.convertValues(source["splits"], Split);
this.amount = source["amount"];
this.deleted = source["deleted"];
this.display = this.convertValues(source["display"], TransactionDisplay);
+ this.id = source["id"];
+ this.name = source["name"];
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
return a;
}
}
+ export class TransactionsResponse {
+ success: boolean;
+ msg: string;
+ data: Transaction[];
+
+ static createFrom(source: any = {}) {
+ return new TransactionsResponse(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.success = source["success"];
+ this.msg = source["msg"];
+ this.data = this.convertValues(source["data"], Transaction);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
}
export function GetTransaction(arg1:number):Promise<types.TransactionResponse>;
-export function GetTransactions():Promise<types.JSResp>;
+export function GetTransactions():Promise<types.TransactionsResponse>;
+
+export function GetTransactionsAccount(arg1:number):Promise<types.TransactionsResponse>;
+
+export function GetTransactionsTag(arg1:number):Promise<types.TransactionsResponse>;
export function ImportTransactions(arg1:string):Promise<types.JSResp>;
return window['go']['services']['transactionService']['GetTransactions']();
}
+export function GetTransactionsAccount(arg1) {
+ return window['go']['services']['transactionService']['GetTransactionsAccount'](arg1);
+}
+
+export function GetTransactionsTag(arg1) {
+ return window['go']['services']['transactionService']['GetTransactionsTag'](arg1);
+}
+
export function ImportTransactions(arg1) {
return window['go']['services']['transactionService']['ImportTransactions'](arg1);
}