support hiding/unhiding/deleting sub-account in account list page
This commit is contained in:
@@ -301,6 +301,7 @@ func startWebServer(c *core.CliContext) error {
|
|||||||
apiV1Route.POST("/accounts/hide.json", bindApi(api.Accounts.AccountHideHandler))
|
apiV1Route.POST("/accounts/hide.json", bindApi(api.Accounts.AccountHideHandler))
|
||||||
apiV1Route.POST("/accounts/move.json", bindApi(api.Accounts.AccountMoveHandler))
|
apiV1Route.POST("/accounts/move.json", bindApi(api.Accounts.AccountMoveHandler))
|
||||||
apiV1Route.POST("/accounts/delete.json", bindApi(api.Accounts.AccountDeleteHandler))
|
apiV1Route.POST("/accounts/delete.json", bindApi(api.Accounts.AccountDeleteHandler))
|
||||||
|
apiV1Route.POST("/accounts/sub_account/delete.json", bindApi(api.Accounts.SubAccountDeleteHandler))
|
||||||
|
|
||||||
// Transactions
|
// Transactions
|
||||||
apiV1Route.GET("/transactions/count.json", bindApi(api.Transactions.TransactionCountHandler))
|
apiV1Route.GET("/transactions/count.json", bindApi(api.Transactions.TransactionCountHandler))
|
||||||
|
|||||||
@@ -508,6 +508,28 @@ func (a *AccountsApi) AccountDeleteHandler(c *core.WebContext) (any, *errs.Error
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SubAccountDeleteHandler deletes an existed sub-account by request parameters for current user
|
||||||
|
func (a *AccountsApi) SubAccountDeleteHandler(c *core.WebContext) (any, *errs.Error) {
|
||||||
|
var accountDeleteReq models.AccountDeleteRequest
|
||||||
|
err := c.ShouldBindJSON(&accountDeleteReq)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf(c, "[accounts.SubAccountDeleteHandler] parse request failed, because %s", err.Error())
|
||||||
|
return nil, errs.NewIncompleteOrIncorrectSubmissionError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
uid := c.GetCurrentUid()
|
||||||
|
err = a.accounts.DeleteSubAccount(c, uid, accountDeleteReq.Id)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf(c, "[accounts.SubAccountDeleteHandler] failed to delete sub-account \"id:%d\" for user \"uid:%d\", because %s", accountDeleteReq.Id, uid, err.Error())
|
||||||
|
return nil, errs.Or(err, errs.ErrOperationFailed)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Infof(c, "[accounts.SubAccountDeleteHandler] user \"uid:%d\" has deleted sub-account \"id:%d\"", uid, accountDeleteReq.Id)
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (a *AccountsApi) createNewAccountModel(uid int64, accountCreateReq *models.AccountCreateRequest, isSubAccount bool, order int32) *models.Account {
|
func (a *AccountsApi) createNewAccountModel(uid int64, accountCreateReq *models.AccountCreateRequest, isSubAccount bool, order int32) *models.Account {
|
||||||
accountExtend := &models.AccountExtend{}
|
accountExtend := &models.AccountExtend{}
|
||||||
|
|
||||||
|
|||||||
@@ -22,4 +22,6 @@ var (
|
|||||||
ErrAccountBalanceTimeNotSet = NewNormalError(NormalSubcategoryAccount, 15, http.StatusBadRequest, "account balance time is not set")
|
ErrAccountBalanceTimeNotSet = NewNormalError(NormalSubcategoryAccount, 15, http.StatusBadRequest, "account balance time is not set")
|
||||||
ErrCannotSetStatementDateForNonCreditCard = NewNormalError(NormalSubcategoryAccount, 16, http.StatusBadRequest, "cannot set statement date for non credit card account")
|
ErrCannotSetStatementDateForNonCreditCard = NewNormalError(NormalSubcategoryAccount, 16, http.StatusBadRequest, "cannot set statement date for non credit card account")
|
||||||
ErrCannotSetStatementDateForSubAccount = NewNormalError(NormalSubcategoryAccount, 17, http.StatusBadRequest, "cannot set statement date for sub account")
|
ErrCannotSetStatementDateForSubAccount = NewNormalError(NormalSubcategoryAccount, 17, http.StatusBadRequest, "cannot set statement date for sub account")
|
||||||
|
ErrSubAccountNotFound = NewNormalError(NormalSubcategoryAccount, 18, http.StatusBadRequest, "sub-account not found")
|
||||||
|
ErrSubAccountInUseCannotBeDeleted = NewNormalError(NormalSubcategoryAccount, 19, http.StatusBadRequest, "sub-account is in use and cannot be deleted")
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -429,7 +429,7 @@ func (s *AccountService) DeleteAccount(c core.Context, uid int64, accountId int6
|
|||||||
|
|
||||||
return s.UserDataDB(uid).DoTransaction(c, func(sess *xorm.Session) error {
|
return s.UserDataDB(uid).DoTransaction(c, func(sess *xorm.Session) error {
|
||||||
var accountAndSubAccounts []*models.Account
|
var accountAndSubAccounts []*models.Account
|
||||||
err := sess.Where("uid=? AND deleted=? AND (account_id=? OR parent_account_id=?)", uid, false, accountId, accountId).Find(&accountAndSubAccounts)
|
err := sess.Where("uid=? AND deleted=? AND ((account_id=? AND parent_account_id=?) OR parent_account_id=?)", uid, false, accountId, models.LevelOneAccountParentId, accountId).Find(&accountAndSubAccounts)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -499,6 +499,86 @@ func (s *AccountService) DeleteAccount(c core.Context, uid int64, accountId int6
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteSubAccount deletes an existed sub-account from database
|
||||||
|
func (s *AccountService) DeleteSubAccount(c core.Context, uid int64, accountId int64) error {
|
||||||
|
if uid <= 0 {
|
||||||
|
return errs.ErrUserIdInvalid
|
||||||
|
}
|
||||||
|
|
||||||
|
now := time.Now().Unix()
|
||||||
|
|
||||||
|
updateModel := &models.Account{
|
||||||
|
Balance: 0,
|
||||||
|
Deleted: true,
|
||||||
|
DeletedUnixTime: now,
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.UserDataDB(uid).DoTransaction(c, func(sess *xorm.Session) error {
|
||||||
|
account := &models.Account{}
|
||||||
|
has, err := sess.Cols("account_id", "uid", "deleted", "parent_account_id").Where("uid=? AND deleted=? AND account_id=? AND parent_account_id<>?", uid, false, accountId, models.LevelOneAccountParentId).Limit(1).Get(account)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if !has {
|
||||||
|
return errs.ErrSubAccountNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
subAccountsCount, err := sess.Where("uid=? AND deleted=? AND parent_account_id=?", uid, false, account.ParentAccountId).Count(&models.Account{})
|
||||||
|
|
||||||
|
if subAccountsCount <= 1 {
|
||||||
|
return errs.ErrAccountHaveNoSubAccount
|
||||||
|
}
|
||||||
|
|
||||||
|
var relatedTransactionsByAccount []*models.Transaction
|
||||||
|
err = sess.Cols("transaction_id", "uid", "deleted", "account_id", "type").Where("uid=? AND deleted=? AND account_id=?", uid, false, accountId).Limit(2).Find(&relatedTransactionsByAccount)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if len(relatedTransactionsByAccount) > 1 {
|
||||||
|
return errs.ErrSubAccountInUseCannotBeDeleted
|
||||||
|
} else if len(relatedTransactionsByAccount) > 0 {
|
||||||
|
for i := 0; i < len(relatedTransactionsByAccount); i++ {
|
||||||
|
transaction := relatedTransactionsByAccount[i]
|
||||||
|
|
||||||
|
if transaction.Type != models.TRANSACTION_DB_TYPE_MODIFY_BALANCE {
|
||||||
|
return errs.ErrSubAccountInUseCannotBeDeleted
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deletedRows, err := sess.Cols("balance", "deleted", "deleted_unix_time").Where("uid=? AND deleted=? AND account_id=?", uid, false, accountId).Update(updateModel)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if deletedRows < 1 {
|
||||||
|
return errs.ErrSubAccountNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(relatedTransactionsByAccount) > 0 {
|
||||||
|
updateTransaction := &models.Transaction{
|
||||||
|
Deleted: true,
|
||||||
|
DeletedUnixTime: now,
|
||||||
|
}
|
||||||
|
|
||||||
|
transactionIds := make([]int64, len(relatedTransactionsByAccount))
|
||||||
|
|
||||||
|
for i := 0; i < len(relatedTransactionsByAccount); i++ {
|
||||||
|
transactionIds[i] = relatedTransactionsByAccount[i].TransactionId
|
||||||
|
}
|
||||||
|
|
||||||
|
deletedTransactionRows, err := sess.Cols("deleted", "deleted_unix_time").Where("uid=? AND deleted=?", uid, false).In("transaction_id", transactionIds).Update(updateTransaction)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if deletedTransactionRows < int64(len(transactionIds)) {
|
||||||
|
return errs.ErrDatabaseOperationFailed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// GetAccountMapByList returns an account map by a list
|
// GetAccountMapByList returns an account map by a list
|
||||||
func (s *AccountService) GetAccountMapByList(accounts []*models.Account) map[int64]*models.Account {
|
func (s *AccountService) GetAccountMapByList(accounts []*models.Account) map[int64]*models.Account {
|
||||||
accountMap := make(map[int64]*models.Account)
|
accountMap := make(map[int64]*models.Account)
|
||||||
|
|||||||
@@ -360,6 +360,9 @@ export default {
|
|||||||
deleteAccount: (req: AccountDeleteRequest): ApiResponsePromise<boolean> => {
|
deleteAccount: (req: AccountDeleteRequest): ApiResponsePromise<boolean> => {
|
||||||
return axios.post<ApiResponse<boolean>>('v1/accounts/delete.json', req);
|
return axios.post<ApiResponse<boolean>>('v1/accounts/delete.json', req);
|
||||||
},
|
},
|
||||||
|
deleteSubAccount: (req: AccountDeleteRequest): ApiResponsePromise<boolean> => {
|
||||||
|
return axios.post<ApiResponse<boolean>>('v1/accounts/sub_account/delete.json', req);
|
||||||
|
},
|
||||||
getTransactions: (req: TransactionListByMaxTimeRequest): ApiResponsePromise<TransactionInfoPageWrapperResponse> => {
|
getTransactions: (req: TransactionListByMaxTimeRequest): ApiResponsePromise<TransactionInfoPageWrapperResponse> => {
|
||||||
const amountFilter = encodeURIComponent(req.amountFilter);
|
const amountFilter = encodeURIComponent(req.amountFilter);
|
||||||
const keyword = encodeURIComponent(req.keyword);
|
const keyword = encodeURIComponent(req.keyword);
|
||||||
|
|||||||
@@ -1067,6 +1067,8 @@
|
|||||||
"account balance time is not set": "Kontosaldo-Zeit ist nicht festgelegt",
|
"account balance time is not set": "Kontosaldo-Zeit ist nicht festgelegt",
|
||||||
"cannot set statement date for non credit card account": "Abrechnungsdatum kann für kein Kreditkartenkonto festgelegt werden",
|
"cannot set statement date for non credit card account": "Abrechnungsdatum kann für kein Kreditkartenkonto festgelegt werden",
|
||||||
"cannot set statement date for sub account": "Abrechnungsdatum kann für Teilkonto nicht festgelegt werden",
|
"cannot set statement date for sub account": "Abrechnungsdatum kann für Teilkonto nicht festgelegt werden",
|
||||||
|
"sub-account not found": "Sub-account is not found",
|
||||||
|
"sub-account is in use and cannot be deleted": "Sub-account is in use and it cannot be deleted",
|
||||||
"transaction id is invalid": "Transaktions-ID ist ungültig",
|
"transaction id is invalid": "Transaktions-ID ist ungültig",
|
||||||
"transaction not found": "Transaktion nicht gefunden",
|
"transaction not found": "Transaktion nicht gefunden",
|
||||||
"transaction type is invalid": "Transaktionstyp ist ungültig",
|
"transaction type is invalid": "Transaktionstyp ist ungültig",
|
||||||
@@ -1576,7 +1578,9 @@
|
|||||||
"Unable to unhide this account": "Dieses Konto kann nicht eingeblendet werden",
|
"Unable to unhide this account": "Dieses Konto kann nicht eingeblendet werden",
|
||||||
"Unable to move account": "Konto kann nicht verschoben werden",
|
"Unable to move account": "Konto kann nicht verschoben werden",
|
||||||
"Are you sure you want to delete this account?": "Sind Sie sicher, dass Sie dieses Konto löschen möchten?",
|
"Are you sure you want to delete this account?": "Sind Sie sicher, dass Sie dieses Konto löschen möchten?",
|
||||||
|
"Are you sure you want to delete this sub-account?": "Are you sure you want to delete this sub-account?",
|
||||||
"Unable to delete this account": "Konto kann nicht gelöscht werden",
|
"Unable to delete this account": "Konto kann nicht gelöscht werden",
|
||||||
|
"Unable to delete this sub-account": "Unable to delete this sub-account",
|
||||||
"Transaction": "Transaktion",
|
"Transaction": "Transaktion",
|
||||||
"Transactions": "Transaktionen",
|
"Transactions": "Transaktionen",
|
||||||
"Transaction Pictures": "Transaktionsbilder",
|
"Transaction Pictures": "Transaktionsbilder",
|
||||||
|
|||||||
@@ -1067,6 +1067,8 @@
|
|||||||
"account balance time is not set": "Account balance time is not set",
|
"account balance time is not set": "Account balance time is not set",
|
||||||
"cannot set statement date for non credit card account": "Cannot set statement date for non credit card account",
|
"cannot set statement date for non credit card account": "Cannot set statement date for non credit card account",
|
||||||
"cannot set statement date for sub account": "Cannot set statement date for sub-account",
|
"cannot set statement date for sub account": "Cannot set statement date for sub-account",
|
||||||
|
"sub-account not found": "Sub-account is not found",
|
||||||
|
"sub-account is in use and cannot be deleted": "Sub-account is in use and it cannot be deleted",
|
||||||
"transaction id is invalid": "Transaction ID is invalid",
|
"transaction id is invalid": "Transaction ID is invalid",
|
||||||
"transaction not found": "Transaction is not found",
|
"transaction not found": "Transaction is not found",
|
||||||
"transaction type is invalid": "Transaction type is invalid",
|
"transaction type is invalid": "Transaction type is invalid",
|
||||||
@@ -1576,7 +1578,9 @@
|
|||||||
"Unable to unhide this account": "Unable to unhide this account",
|
"Unable to unhide this account": "Unable to unhide this account",
|
||||||
"Unable to move account": "Unable to move account",
|
"Unable to move account": "Unable to move account",
|
||||||
"Are you sure you want to delete this account?": "Are you sure you want to delete this account?",
|
"Are you sure you want to delete this account?": "Are you sure you want to delete this account?",
|
||||||
|
"Are you sure you want to delete this sub-account?": "Are you sure you want to delete this sub-account?",
|
||||||
"Unable to delete this account": "Unable to delete this account",
|
"Unable to delete this account": "Unable to delete this account",
|
||||||
|
"Unable to delete this sub-account": "Unable to delete this sub-account",
|
||||||
"Transaction": "Transaction",
|
"Transaction": "Transaction",
|
||||||
"Transactions": "Transactions",
|
"Transactions": "Transactions",
|
||||||
"Transaction Pictures": "Transaction Pictures",
|
"Transaction Pictures": "Transaction Pictures",
|
||||||
|
|||||||
@@ -1067,6 +1067,8 @@
|
|||||||
"account balance time is not set": "La hora del saldo de la cuenta no está establecida",
|
"account balance time is not set": "La hora del saldo de la cuenta no está establecida",
|
||||||
"cannot set statement date for non credit card account": "No se puede establecer la fecha del extracto para una cuenta que no sea de tarjeta de crédito",
|
"cannot set statement date for non credit card account": "No se puede establecer la fecha del extracto para una cuenta que no sea de tarjeta de crédito",
|
||||||
"cannot set statement date for sub account": "No se puede establecer la fecha del estado de cuenta para la subcuenta",
|
"cannot set statement date for sub account": "No se puede establecer la fecha del estado de cuenta para la subcuenta",
|
||||||
|
"sub-account not found": "Sub-account is not found",
|
||||||
|
"sub-account is in use and cannot be deleted": "Sub-account is in use and it cannot be deleted",
|
||||||
"transaction id is invalid": "El ID de transacción no es válido",
|
"transaction id is invalid": "El ID de transacción no es válido",
|
||||||
"transaction not found": "La transacción no se encuentra",
|
"transaction not found": "La transacción no se encuentra",
|
||||||
"transaction type is invalid": "El tipo de transacción no es válido",
|
"transaction type is invalid": "El tipo de transacción no es válido",
|
||||||
@@ -1576,7 +1578,9 @@
|
|||||||
"Unable to unhide this account": "No se puede mostrar esta cuenta",
|
"Unable to unhide this account": "No se puede mostrar esta cuenta",
|
||||||
"Unable to move account": "No se puede mover la cuenta",
|
"Unable to move account": "No se puede mover la cuenta",
|
||||||
"Are you sure you want to delete this account?": "¿Está seguro de que desea eliminar esta cuenta?",
|
"Are you sure you want to delete this account?": "¿Está seguro de que desea eliminar esta cuenta?",
|
||||||
|
"Are you sure you want to delete this sub-account?": "Are you sure you want to delete this sub-account?",
|
||||||
"Unable to delete this account": "No se puede eliminar esta cuenta",
|
"Unable to delete this account": "No se puede eliminar esta cuenta",
|
||||||
|
"Unable to delete this sub-account": "Unable to delete this sub-account",
|
||||||
"Transaction": "Transacción",
|
"Transaction": "Transacción",
|
||||||
"Transactions": "Transacciones",
|
"Transactions": "Transacciones",
|
||||||
"Transaction Pictures": "Imágenes de transacciones",
|
"Transaction Pictures": "Imágenes de transacciones",
|
||||||
|
|||||||
@@ -1067,6 +1067,8 @@
|
|||||||
"account balance time is not set": "口座残高の時間が設定されていません",
|
"account balance time is not set": "口座残高の時間が設定されていません",
|
||||||
"cannot set statement date for non credit card account": "クレジットカード以外の口座の明細書の日付を設定できません",
|
"cannot set statement date for non credit card account": "クレジットカード以外の口座の明細書の日付を設定できません",
|
||||||
"cannot set statement date for sub account": "子口座の明細日を設定できません",
|
"cannot set statement date for sub account": "子口座の明細日を設定できません",
|
||||||
|
"sub-account not found": "Sub-account is not found",
|
||||||
|
"sub-account is in use and cannot be deleted": "Sub-account is in use and it cannot be deleted",
|
||||||
"transaction id is invalid": "取引IDは無効です",
|
"transaction id is invalid": "取引IDは無効です",
|
||||||
"transaction not found": "取引が見つかりません",
|
"transaction not found": "取引が見つかりません",
|
||||||
"transaction type is invalid": "取引タイプは無効です",
|
"transaction type is invalid": "取引タイプは無効です",
|
||||||
@@ -1576,7 +1578,9 @@
|
|||||||
"Unable to unhide this account": "この口座は非表示を解除できません",
|
"Unable to unhide this account": "この口座は非表示を解除できません",
|
||||||
"Unable to move account": "口座を移動できません",
|
"Unable to move account": "口座を移動できません",
|
||||||
"Are you sure you want to delete this account?": "この口座を削除しますか?",
|
"Are you sure you want to delete this account?": "この口座を削除しますか?",
|
||||||
|
"Are you sure you want to delete this sub-account?": "Are you sure you want to delete this sub-account?",
|
||||||
"Unable to delete this account": "この口座を削除できません",
|
"Unable to delete this account": "この口座を削除できません",
|
||||||
|
"Unable to delete this sub-account": "Unable to delete this sub-account",
|
||||||
"Transaction": "取引",
|
"Transaction": "取引",
|
||||||
"Transactions": "取引",
|
"Transactions": "取引",
|
||||||
"Transaction Pictures": "取引の写真",
|
"Transaction Pictures": "取引の写真",
|
||||||
|
|||||||
@@ -1067,6 +1067,8 @@
|
|||||||
"account balance time is not set": "Время баланса счета не установлено",
|
"account balance time is not set": "Время баланса счета не установлено",
|
||||||
"cannot set statement date for non credit card account": "Нельзя установить дату выписки для счета, не являющегося кредитной картой",
|
"cannot set statement date for non credit card account": "Нельзя установить дату выписки для счета, не являющегося кредитной картой",
|
||||||
"cannot set statement date for sub account": "Нельзя установить дату выписки для субсчета",
|
"cannot set statement date for sub account": "Нельзя установить дату выписки для субсчета",
|
||||||
|
"sub-account not found": "Sub-account is not found",
|
||||||
|
"sub-account is in use and cannot be deleted": "Sub-account is in use and it cannot be deleted",
|
||||||
"transaction id is invalid": "ID транзакции недействителен",
|
"transaction id is invalid": "ID транзакции недействителен",
|
||||||
"transaction not found": "Транзакция не найдена",
|
"transaction not found": "Транзакция не найдена",
|
||||||
"transaction type is invalid": "Тип транзакции недействителен",
|
"transaction type is invalid": "Тип транзакции недействителен",
|
||||||
@@ -1576,7 +1578,9 @@
|
|||||||
"Unable to unhide this account": "Не удалось отобразить этот счет",
|
"Unable to unhide this account": "Не удалось отобразить этот счет",
|
||||||
"Unable to move account": "Не удалось переместить счет",
|
"Unable to move account": "Не удалось переместить счет",
|
||||||
"Are you sure you want to delete this account?": "Вы уверены, что хотите удалить этот счет?",
|
"Are you sure you want to delete this account?": "Вы уверены, что хотите удалить этот счет?",
|
||||||
|
"Are you sure you want to delete this sub-account?": "Are you sure you want to delete this sub-account?",
|
||||||
"Unable to delete this account": "Не удалось удалить этот счет",
|
"Unable to delete this account": "Не удалось удалить этот счет",
|
||||||
|
"Unable to delete this sub-account": "Unable to delete this sub-account",
|
||||||
"Transaction": "Транзакция",
|
"Transaction": "Транзакция",
|
||||||
"Transactions": "Транзакции",
|
"Transactions": "Транзакции",
|
||||||
"Transaction Pictures": "Изображения транзакций",
|
"Transaction Pictures": "Изображения транзакций",
|
||||||
|
|||||||
@@ -1067,6 +1067,8 @@
|
|||||||
"account balance time is not set": "Thời gian số dư tài khoản chưa được đặt",
|
"account balance time is not set": "Thời gian số dư tài khoản chưa được đặt",
|
||||||
"cannot set statement date for non credit card account": "Cannot set statement date for non credit card account",
|
"cannot set statement date for non credit card account": "Cannot set statement date for non credit card account",
|
||||||
"cannot set statement date for sub account": "Cannot set statement date for sub-account",
|
"cannot set statement date for sub account": "Cannot set statement date for sub-account",
|
||||||
|
"sub-account not found": "Sub-account is not found",
|
||||||
|
"sub-account is in use and cannot be deleted": "Sub-account is in use and it cannot be deleted",
|
||||||
"transaction id is invalid": "ID giao dịch không hợp lệ",
|
"transaction id is invalid": "ID giao dịch không hợp lệ",
|
||||||
"transaction not found": "Không tìm thấy giao dịch",
|
"transaction not found": "Không tìm thấy giao dịch",
|
||||||
"transaction type is invalid": "Loại giao dịch không hợp lệ",
|
"transaction type is invalid": "Loại giao dịch không hợp lệ",
|
||||||
@@ -1576,7 +1578,9 @@
|
|||||||
"Unable to unhide this account": "Không thể hiển thị tài khoản này",
|
"Unable to unhide this account": "Không thể hiển thị tài khoản này",
|
||||||
"Unable to move account": "Không thể di chuyển tài khoản",
|
"Unable to move account": "Không thể di chuyển tài khoản",
|
||||||
"Are you sure you want to delete this account?": "Bạn có chắc chắn muốn xóa tài khoản này không?",
|
"Are you sure you want to delete this account?": "Bạn có chắc chắn muốn xóa tài khoản này không?",
|
||||||
|
"Are you sure you want to delete this sub-account?": "Are you sure you want to delete this sub-account?",
|
||||||
"Unable to delete this account": "Không thể xóa tài khoản này",
|
"Unable to delete this account": "Không thể xóa tài khoản này",
|
||||||
|
"Unable to delete this sub-account": "Unable to delete this sub-account",
|
||||||
"Transaction": "Giao dịch",
|
"Transaction": "Giao dịch",
|
||||||
"Transactions": "Giao dịch",
|
"Transactions": "Giao dịch",
|
||||||
"Transaction Pictures": "Ảnh giao dịch",
|
"Transaction Pictures": "Ảnh giao dịch",
|
||||||
|
|||||||
@@ -1067,6 +1067,8 @@
|
|||||||
"account balance time is not set": "账户余额时间没有设置",
|
"account balance time is not set": "账户余额时间没有设置",
|
||||||
"cannot set statement date for non credit card account": "非信用卡账户不能设置账单日期",
|
"cannot set statement date for non credit card account": "非信用卡账户不能设置账单日期",
|
||||||
"cannot set statement date for sub account": "子账户不能设置账单日期",
|
"cannot set statement date for sub account": "子账户不能设置账单日期",
|
||||||
|
"sub-account not found": "子账户不存在",
|
||||||
|
"sub-account is in use and cannot be deleted": "子账户正在被使用,无法删除",
|
||||||
"transaction id is invalid": "交易ID无效",
|
"transaction id is invalid": "交易ID无效",
|
||||||
"transaction not found": "交易不存在",
|
"transaction not found": "交易不存在",
|
||||||
"transaction type is invalid": "交易类型无效",
|
"transaction type is invalid": "交易类型无效",
|
||||||
@@ -1576,7 +1578,9 @@
|
|||||||
"Unable to unhide this account": "无法取消隐藏账户",
|
"Unable to unhide this account": "无法取消隐藏账户",
|
||||||
"Unable to move account": "无法移动账户",
|
"Unable to move account": "无法移动账户",
|
||||||
"Are you sure you want to delete this account?": "您确定要删除该账户?",
|
"Are you sure you want to delete this account?": "您确定要删除该账户?",
|
||||||
|
"Are you sure you want to delete this sub-account?": "您确定要删除该子账户?",
|
||||||
"Unable to delete this account": "无法删除该账户",
|
"Unable to delete this account": "无法删除该账户",
|
||||||
|
"Unable to delete this sub-account": "无法删除该子账户",
|
||||||
"Transaction": "交易",
|
"Transaction": "交易",
|
||||||
"Transactions": "交易",
|
"Transactions": "交易",
|
||||||
"Transaction Pictures": "交易图片",
|
"Transaction Pictures": "交易图片",
|
||||||
|
|||||||
@@ -240,6 +240,30 @@ export class Account implements AccountInfoResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public isAccountOrSubAccountHidden(subAccountId: string): boolean {
|
||||||
|
if (this.type === AccountType.SingleAccount.type) {
|
||||||
|
return this.hidden;
|
||||||
|
} else if (this.type === AccountType.MultiSubAccounts.type && !subAccountId) {
|
||||||
|
return this.hidden;
|
||||||
|
} else if (this.type === AccountType.MultiSubAccounts.type && subAccountId) {
|
||||||
|
if (!this.subAccounts || !this.subAccounts.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < this.subAccounts.length; i++) {
|
||||||
|
const subAccount = this.subAccounts[i];
|
||||||
|
|
||||||
|
if (subAccountId && subAccountId === subAccount.id) {
|
||||||
|
return subAccount.hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public getAccountOrSubAccountComment(subAccountId: string): string | null {
|
public getAccountOrSubAccountComment(subAccountId: string): string | null {
|
||||||
if (this.type === AccountType.SingleAccount.type) {
|
if (this.type === AccountType.SingleAccount.type) {
|
||||||
return this.comment;
|
return this.comment;
|
||||||
@@ -264,6 +288,46 @@ export class Account implements AccountInfoResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getAccountOrSubAccount(subAccountId: string): Account | null {
|
||||||
|
if (this.type === AccountType.SingleAccount.type) {
|
||||||
|
return this;
|
||||||
|
} else if (this.type === AccountType.MultiSubAccounts.type && !subAccountId) {
|
||||||
|
return this;
|
||||||
|
} else if (this.type === AccountType.MultiSubAccounts.type && subAccountId) {
|
||||||
|
if (!this.subAccounts || !this.subAccounts.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < this.subAccounts.length; i++) {
|
||||||
|
const subAccount = this.subAccounts[i];
|
||||||
|
|
||||||
|
if (subAccountId && subAccountId === subAccount.id) {
|
||||||
|
return subAccount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public getSubAccount(subAccountId: string): Account | null {
|
||||||
|
if (!this.subAccounts || !this.subAccounts.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < this.subAccounts.length; i++) {
|
||||||
|
const subAccount = this.subAccounts[i];
|
||||||
|
|
||||||
|
if (subAccountId && subAccountId === subAccount.id) {
|
||||||
|
return subAccount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public getSubAccountCurrencies(showHidden: boolean, subAccountId: string): string[] {
|
public getSubAccountCurrencies(showHidden: boolean, subAccountId: string): string[] {
|
||||||
if (!this.subAccounts || !this.subAccounts.length) {
|
if (!this.subAccounts || !this.subAccounts.length) {
|
||||||
return [];
|
return [];
|
||||||
|
|||||||
+77
-1
@@ -295,6 +295,46 @@ export const useAccountsStore = defineStore('accounts', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function removeSubAccountFromAccountList(subAccount: Account): void {
|
||||||
|
for (let i = 0; i < allAccounts.value.length; i++) {
|
||||||
|
if (allAccounts.value[i].type !== AccountType.MultiSubAccounts.type || !allAccounts.value[i].subAccounts) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const subAccounts = allAccounts.value[i].subAccounts as Account[];
|
||||||
|
|
||||||
|
for (let j = 0; j < subAccounts.length; j++) {
|
||||||
|
if (subAccounts[j].id === subAccount.id) {
|
||||||
|
subAccounts.splice(j, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allAccountsMap.value[subAccount.id]) {
|
||||||
|
delete allAccountsMap.value[subAccount.id];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allCategorizedAccountsMap.value[subAccount.category]) {
|
||||||
|
const accountList = allCategorizedAccountsMap.value[subAccount.category].accounts;
|
||||||
|
|
||||||
|
for (let i = 0; i < accountList.length; i++) {
|
||||||
|
if (accountList[i].type !== AccountType.MultiSubAccounts.type || !accountList[i].subAccounts) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const subAccounts = accountList[i].subAccounts as Account[];
|
||||||
|
|
||||||
|
for (let j = 0; j < subAccounts.length; j++) {
|
||||||
|
if (subAccounts[j].id === subAccount.id) {
|
||||||
|
subAccounts.splice(j, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function updateAccountListInvalidState(invalidState: boolean): void {
|
function updateAccountListInvalidState(invalidState: boolean): void {
|
||||||
accountListStateInvalid.value = invalidState;
|
accountListStateInvalid.value = invalidState;
|
||||||
}
|
}
|
||||||
@@ -997,6 +1037,41 @@ export const useAccountsStore = defineStore('accounts', () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function deleteSubAccount({ subAccount, beforeResolve }: { subAccount: Account, beforeResolve?: BeforeResolveFunction }): Promise<boolean> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
services.deleteSubAccount({
|
||||||
|
id: subAccount.id
|
||||||
|
}).then(response => {
|
||||||
|
const data = response.data;
|
||||||
|
|
||||||
|
if (!data || !data.success || !data.result) {
|
||||||
|
reject({ message: 'Unable to delete this sub-account' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (beforeResolve) {
|
||||||
|
beforeResolve(() => {
|
||||||
|
removeSubAccountFromAccountList(subAccount);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
removeSubAccountFromAccountList(subAccount);
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(data.result);
|
||||||
|
}).catch(error => {
|
||||||
|
logger.error('failed to delete sub-account', error);
|
||||||
|
|
||||||
|
if (error.response && error.response.data && error.response.data.errorMessage) {
|
||||||
|
reject({ error: error.response.data });
|
||||||
|
} else if (!error.processed) {
|
||||||
|
reject({ message: 'Unable to delete this sub-account' });
|
||||||
|
} else {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// states
|
// states
|
||||||
allAccounts,
|
allAccounts,
|
||||||
@@ -1029,6 +1104,7 @@ export const useAccountsStore = defineStore('accounts', () => {
|
|||||||
changeAccountDisplayOrder,
|
changeAccountDisplayOrder,
|
||||||
updateAccountDisplayOrders,
|
updateAccountDisplayOrders,
|
||||||
hideAccount,
|
hideAccount,
|
||||||
deleteAccount
|
deleteAccount,
|
||||||
|
deleteSubAccount
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -196,24 +196,24 @@
|
|||||||
|
|
||||||
<v-divider/>
|
<v-divider/>
|
||||||
|
|
||||||
<v-card-text v-if="accountComment(element)">
|
<v-card-text v-if="element.getAccountOrSubAccountComment(activeSubAccount[element.id])">
|
||||||
{{ accountComment(element) }}
|
{{ element.getAccountOrSubAccountComment(activeSubAccount[element.id]) }}
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
|
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<div class="d-flex account-toolbar align-center">
|
<div class="d-flex account-toolbar align-center">
|
||||||
<v-btn class="px-2" density="comfortable" color="default" variant="text"
|
<v-btn class="px-2" density="comfortable" color="default" variant="text"
|
||||||
:disabled="loading" :prepend-icon="mdiListBoxOutline"
|
:disabled="loading" :prepend-icon="mdiListBoxOutline"
|
||||||
:to="`/transaction/list?accountIds=${accountOrSubAccountId(element)}`">
|
:to="`/transaction/list?accountIds=${element.getAccountOrSubAccountId(activeSubAccount[element.id])}`">
|
||||||
{{ tt('Transaction List') }}
|
{{ tt('Transaction List') }}
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-btn class="px-2 ml-1" density="comfortable" color="default" variant="text"
|
<v-btn class="px-2 ml-1" density="comfortable" color="default" variant="text"
|
||||||
:class="{ 'd-none': loading, 'hover-display': !loading }"
|
:class="{ 'd-none': loading, 'hover-display': !loading }"
|
||||||
:disabled="loading"
|
:disabled="loading"
|
||||||
:prepend-icon="element.hidden ? mdiEyeOutline : mdiEyeOffOutline"
|
:prepend-icon="element.isAccountOrSubAccountHidden(activeSubAccount[element.id]) ? mdiEyeOutline : mdiEyeOffOutline"
|
||||||
v-if="!activeSubAccount[element.id]"
|
v-if="!activeSubAccount[element.id] || element.getSubAccount(activeSubAccount[element.id])"
|
||||||
@click="hide(element, !element.hidden)">
|
@click="hide(element, element.getAccountOrSubAccount(activeSubAccount[element.id]), !element.isAccountOrSubAccountHidden(activeSubAccount[element.id]))">
|
||||||
{{ element.hidden ? tt('Show') : tt('Hide') }}
|
{{ element.isAccountOrSubAccountHidden(activeSubAccount[element.id]) ? tt('Show') : tt('Hide') }}
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-btn class="px-2 ml-1" density="comfortable" color="default" variant="text"
|
<v-btn class="px-2 ml-1" density="comfortable" color="default" variant="text"
|
||||||
:class="{ 'd-none': loading, 'hover-display': !loading }"
|
:class="{ 'd-none': loading, 'hover-display': !loading }"
|
||||||
@@ -225,7 +225,7 @@
|
|||||||
<v-btn class="px-2 ml-1" density="comfortable" color="default" variant="text"
|
<v-btn class="px-2 ml-1" density="comfortable" color="default" variant="text"
|
||||||
:class="{ 'd-none': loading, 'hover-display': !loading }"
|
:class="{ 'd-none': loading, 'hover-display': !loading }"
|
||||||
:disabled="loading" :prepend-icon="mdiDeleteOutline"
|
:disabled="loading" :prepend-icon="mdiDeleteOutline"
|
||||||
v-if="!activeSubAccount[element.id]"
|
v-if="!activeSubAccount[element.id] || element.getSubAccount(activeSubAccount[element.id])"
|
||||||
@click="remove(element)">
|
@click="remove(element)">
|
||||||
{{ tt('Delete') }}
|
{{ tt('Delete') }}
|
||||||
</v-btn>
|
</v-btn>
|
||||||
@@ -383,14 +383,6 @@ function hasAccount(accountCategory: AccountCategory): boolean {
|
|||||||
return accountsStore.hasAccount(accountCategory, !showHidden.value);
|
return accountsStore.hasAccount(accountCategory, !showHidden.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
function accountOrSubAccountId(account: Account): string | null {
|
|
||||||
return account.getAccountOrSubAccountId(activeSubAccount.value[account.id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function accountComment(account: Account): string | null {
|
|
||||||
return account.getAccountOrSubAccountComment(activeSubAccount.value[account.id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function accountCurrency(account: Account): string | null {
|
function accountCurrency(account: Account): string | null {
|
||||||
if (account.type === AccountType.SingleAccount.type) {
|
if (account.type === AccountType.SingleAccount.type) {
|
||||||
return getCurrencyName(account.currency);
|
return getCurrencyName(account.currency);
|
||||||
@@ -458,13 +450,17 @@ function edit(account: Account): void {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function hide(account: Account, hidden: boolean): void {
|
function hide(account: Account, targetAccount: Account, hidden: boolean): void {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
|
|
||||||
accountsStore.hideAccount({
|
accountsStore.hideAccount({
|
||||||
account: account,
|
account: targetAccount,
|
||||||
hidden: hidden
|
hidden: hidden
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
|
if (hidden && !showHidden.value && activeSubAccount.value[account.id]) {
|
||||||
|
activeSubAccount.value[account.id] = '';
|
||||||
|
}
|
||||||
|
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
@@ -476,21 +472,46 @@ function hide(account: Account, hidden: boolean): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function remove(account: Account): void {
|
function remove(account: Account): void {
|
||||||
confirmDialog.value?.open('Are you sure you want to delete this account?').then(() => {
|
if (activeSubAccount.value[account.id]) {
|
||||||
loading.value = true;
|
const subAccount: Account | null = account.getSubAccount(activeSubAccount.value[account.id]);
|
||||||
|
|
||||||
accountsStore.deleteAccount({
|
if (!subAccount) {
|
||||||
account: account
|
snackbar.value?.showMessage('Unable to delete this sub-account');
|
||||||
}).then(() => {
|
return;
|
||||||
loading.value = false;
|
}
|
||||||
}).catch(error => {
|
|
||||||
loading.value = false;
|
|
||||||
|
|
||||||
if (!error.processed) {
|
confirmDialog.value?.open('Are you sure you want to delete this sub-account?').then(() => {
|
||||||
snackbar.value?.showError(error);
|
loading.value = true;
|
||||||
}
|
|
||||||
|
accountsStore.deleteSubAccount({
|
||||||
|
subAccount: subAccount
|
||||||
|
}).then(() => {
|
||||||
|
loading.value = false;
|
||||||
|
}).catch(error => {
|
||||||
|
loading.value = false;
|
||||||
|
|
||||||
|
if (!error.processed) {
|
||||||
|
snackbar.value?.showError(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
} else {
|
||||||
|
confirmDialog.value?.open('Are you sure you want to delete this account?').then(() => {
|
||||||
|
loading.value = true;
|
||||||
|
|
||||||
|
accountsStore.deleteAccount({
|
||||||
|
account: account
|
||||||
|
}).then(() => {
|
||||||
|
loading.value = false;
|
||||||
|
}).catch(error => {
|
||||||
|
loading.value = false;
|
||||||
|
|
||||||
|
if (!error.processed) {
|
||||||
|
snackbar.value?.showError(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveSortResult(): void {
|
function saveSortResult(): void {
|
||||||
|
|||||||
Reference in New Issue
Block a user