support batch deleting transactions

This commit is contained in:
MaysWind
2026-04-25 20:01:16 +08:00
parent de885c963d
commit e4e74304b6
28 changed files with 428 additions and 86 deletions
+1
View File
@@ -396,6 +396,7 @@ func startWebServer(c *core.CliContext) error {
apiV1Route.POST("/transactions/batch_update/category.json", bindApi(api.Transactions.TransactionBatchUpdateCategoriesHandler))
apiV1Route.POST("/transactions/move/all.json", bindApi(api.Transactions.TransactionMoveAllBetweenAccountsHandler))
apiV1Route.POST("/transactions/delete.json", bindApi(api.Transactions.TransactionDeleteHandler))
apiV1Route.POST("/transactions/batch_delete.json", bindApi(api.Transactions.TransactionBatchDeleteHandler))
if config.EnableDataImport {
apiV1Route.POST("/transactions/parse_custom_file.json", bindApi(api.Transactions.TransactionParseImportCustomFileDataHandler))
+74
View File
@@ -1551,6 +1551,80 @@ func (a *TransactionsApi) TransactionDeleteHandler(c *core.WebContext) (any, *er
return true, nil
}
// TransactionBatchDeleteHandler deletes existed transactions by request parameters for current user
func (a *TransactionsApi) TransactionBatchDeleteHandler(c *core.WebContext) (any, *errs.Error) {
var transactionBatchDeleteReq models.TransactionBatchDeleteRequest
err := c.ShouldBindJSON(&transactionBatchDeleteReq)
if err != nil {
log.Warnf(c, "[transactions.TransactionBatchDeleteHandler] parse request failed, because %s", err.Error())
return nil, errs.NewIncompleteOrIncorrectSubmissionError(err)
}
clientTimezone, err := c.GetClientTimezone()
if err != nil {
log.Warnf(c, "[transactions.TransactionBatchDeleteHandler] cannot get client timezone, because %s", err.Error())
return nil, errs.ErrClientTimezoneOffsetInvalid
}
transactionIds, err := utils.StringArrayToInt64Array(transactionBatchDeleteReq.Ids)
if err != nil {
log.Warnf(c, "[transactions.TransactionBatchDeleteHandler] parse transaction ids failed, because %s", err.Error())
return nil, errs.ErrTransactionIdInvalid
}
uid := c.GetCurrentUid()
user, err := a.users.GetUserById(c, uid)
if err != nil {
if !errs.IsCustomError(err) {
log.Errorf(c, "[transactions.TransactionBatchDeleteHandler] failed to get user, because %s", err.Error())
}
return nil, errs.ErrUserNotFound
}
if !a.users.IsPasswordEqualsUserPassword(transactionBatchDeleteReq.Password, user) {
return nil, errs.ErrUserPasswordWrong
}
transactions, err := a.transactions.GetTransactionsByTransactionIds(c, uid, transactionIds)
if err != nil {
log.Errorf(c, "[transactions.TransactionBatchDeleteHandler] failed to get transactions for user \"uid:%d\", because %s", uid, err.Error())
return nil, errs.Or(err, errs.ErrOperationFailed)
}
for i := 0; i < len(transactions); i++ {
transaction := transactions[i]
transactionEditable := user.CanEditTransactionByTransactionTime(transaction.TransactionTime, clientTimezone)
if !transactionEditable {
log.Warnf(c, "[transactions.TransactionBatchUpdateCategoriesHandler] transaction \"id:%d\" is not editable for user \"uid:%d\"", transaction.TransactionId, uid)
return nil, errs.ErrCannotModifyTransactionWithThisTransactionTime
}
}
deletedCount := 0
for i := 0; i < len(transactions); i++ {
transaction := transactions[i]
err = a.transactions.DeleteTransaction(c, uid, transaction.TransactionId)
if err != nil {
log.Errorf(c, "[transactions.TransactionBatchDeleteHandler] failed to delete transaction \"id:%d\" for user \"uid:%d\", because %s", transaction.TransactionId, uid, err.Error())
return nil, errs.Or(err, errs.ErrOperationFailed)
}
deletedCount++
}
log.Infof(c, "[transactions.TransactionBatchDeleteHandler] user \"uid:%d\" has deleted %d transactions", uid, deletedCount)
return true, nil
}
// TransactionParseImportCustomFileDataHandler returns the parsed file data by request parameters for current user
func (a *TransactionsApi) TransactionParseImportCustomFileDataHandler(c *core.WebContext) (any, *errs.Error) {
uid := c.GetCurrentUid()
+6
View File
@@ -342,6 +342,12 @@ type TransactionDeleteRequest struct {
Id int64 `json:"id,string" binding:"required,min=1"`
}
// TransactionBatchDeleteRequest represents all parameters of transaction batch deleting request
type TransactionBatchDeleteRequest struct {
Ids []string `json:"ids,string" binding:"required"`
Password string `json:"password" binding:"omitempty,min=6,max=128"`
}
// YearMonthRangeRequest represents all parameters of a request with year and month range
type YearMonthRangeRequest struct {
StartYearMonth string `form:"start_year_month"`
+1
View File
@@ -7,6 +7,7 @@ export const DEFAULT_API_TIMEOUT: number = 10000; // 10s
export const DEFAULT_UPLOAD_API_TIMEOUT: number = 30000; // 30s
export const DEFAULT_EXPORT_API_TIMEOUT: number = 180000; // 180s
export const DEFAULT_IMPORT_API_TIMEOUT: number = 1800000; // 1800s
export const DEFAULT_BATCH_UPDATE_TRANSACTIONS_API_TIMEOUT: number = 1800000; // 1800s
export const DEFAULT_CLEAR_ALL_TRANSACTIONS_API_TIMEOUT: number = 1800000; // 1800s
export const DEFAULT_LLM_API_TIMEOUT: number = 600000; // 600s
+10 -1
View File
@@ -24,6 +24,7 @@ import {
DEFAULT_UPLOAD_API_TIMEOUT,
DEFAULT_EXPORT_API_TIMEOUT,
DEFAULT_IMPORT_API_TIMEOUT,
DEFAULT_BATCH_UPDATE_TRANSACTIONS_API_TIMEOUT,
DEFAULT_CLEAR_ALL_TRANSACTIONS_API_TIMEOUT,
DEFAULT_LLM_API_TIMEOUT,
GOOGLE_MAP_JAVASCRIPT_URL,
@@ -67,6 +68,7 @@ import type {
TransactionBatchUpdateCategoryRequest,
TransactionMoveBetweenAccountsRequest,
TransactionDeleteRequest,
TransactionBatchDeleteRequest,
TransactionImportRequest,
TransactionListByMaxTimeRequest,
TransactionListInMonthByPageRequest,
@@ -613,7 +615,9 @@ export default {
return axios.post<ApiResponse<TransactionInfoResponse>>('v1/transactions/modify.json', req);
},
batchUpdateTransactionCategories: (req: TransactionBatchUpdateCategoryRequest): ApiResponsePromise<boolean> => {
return axios.post<ApiResponse<boolean>>('v1/transactions/batch_update/category.json', req);
return axios.post<ApiResponse<boolean>>('v1/transactions/batch_update/category.json', req, {
timeout: DEFAULT_BATCH_UPDATE_TRANSACTIONS_API_TIMEOUT
} as ApiRequestConfig);
},
moveAllTransactionsBetweenAccounts: (req: TransactionMoveBetweenAccountsRequest): ApiResponsePromise<boolean> => {
return axios.post<ApiResponse<boolean>>('v1/transactions/move/all.json', req);
@@ -621,6 +625,11 @@ export default {
deleteTransaction: (req: TransactionDeleteRequest): ApiResponsePromise<boolean> => {
return axios.post<ApiResponse<boolean>>('v1/transactions/delete.json', req);
},
batchDeleteTransaction: (req: TransactionBatchDeleteRequest): ApiResponsePromise<boolean> => {
return axios.post<ApiResponse<boolean>>('v1/transactions/batch_delete.json', req, {
timeout: DEFAULT_BATCH_UPDATE_TRANSACTIONS_API_TIMEOUT
} as ApiRequestConfig);
},
parseImportCustomFile: ({ fileType, fileEncoding, importFile }: { fileType: string, fileEncoding?: string, importFile: File }): ApiResponsePromise<string[][]> => {
return axios.postForm<ApiResponse<string[][]>>('v1/transactions/parse_custom_file.json', {
fileType: fileType,
+4
View File
@@ -134,11 +134,13 @@
"selectedCount": "{count} von {totalCount} ausgewählt",
"queryIndex": "Abfrage #{index}",
"youHaveUpdatedTransactions": "Sie haben {count} Transaktionen aktualisiert",
"youHaveDeletedTransactions": "You have deleted {count} transactions",
"confirmImportTransactions": "Sind Sie sicher, dass Sie {count} Transaktionen importieren möchten?",
"importingTransactions": "Importiere ({process}%)",
"importTransactionResult": "Sie haben {count} Transaktionen erfolgreich importiert.",
"moveTransactionsInAccountTip": "Diese Aktion kann NICHT rückgängig gemacht werden. Alle Transaktionen werden von {fromAccount} nach {toAccount} verschoben.",
"clearTransactionsInAccountTip": "Diese Aktion kann NICHT rückgängig gemacht werden. Ihre Transaktionsdaten in {account} werden gelöscht. Bitte geben Sie Ihr aktuelles Passwort zur Bestätigung ein.",
"deleteTransactionsTip": "You CANNOT undo this action. This will delete {count} transactions. Please enter your current password to confirm.",
"accountActivationAndResendValidationEmailTip": "Ein Aktivierungslink wurde an Ihre E-Mail-Adresse gesendet: {email}. Wenn Sie die E-Mail nicht erhalten haben, geben Sie bitte das Passwort erneut ein und klicken Sie auf die Schaltfläche unten, um die Bestätigungs-E-Mail erneut zu senden.",
"resendValidationEmailTip": "Wenn Sie die E-Mail nicht erhalten haben, geben Sie bitte das Passwort erneut ein und klicken Sie auf die Schaltfläche unten, um die Bestätigungs-E-Mail an: {email} erneut zu senden.",
"oauth2bindTip": "Sie melden sich beim Benutzer {userName} mit {providerName} an. Bitte geben Sie Ihr ezBookkeeping-Passwort zur Bestätigung ein."
@@ -1851,6 +1853,8 @@
"Update Categories for Income Transactions": "Update Categories for Income Transactions",
"Update Categories for Transfer Transactions": "Update Categories for Transfer Transactions",
"Unable to update categories for transactions": "Unable to update categories for transactions",
"Delete Transactions": "Delete Transactions",
"Unable to delete these transactions": "Unable to delete these transactions",
"Account List": "Kontoliste",
"This Week": "Diese Woche",
"This Month": "Dieser Monat",
+4
View File
@@ -134,11 +134,13 @@
"selectedCount": "Selected {count} of {totalCount}",
"queryIndex": "Query #{index}",
"youHaveUpdatedTransactions": "You have updated {count} transactions",
"youHaveDeletedTransactions": "You have deleted {count} transactions",
"confirmImportTransactions": "Are you sure you want to import {count} transactions?",
"importingTransactions": "Importing ({process}%)",
"importTransactionResult": "You have imported {count} transactions successfully.",
"moveTransactionsInAccountTip": "You CANNOT undo this action. This will move all transactions from {fromAccount} to {toAccount}.",
"clearTransactionsInAccountTip": "You CANNOT undo this action. This will clear your transactions data in {account}. Please enter your current password to confirm.",
"deleteTransactionsTip": "You CANNOT undo this action. This will delete {count} transactions. Please enter your current password to confirm.",
"accountActivationAndResendValidationEmailTip": "Account activation link has been sent to your email address: {email}, If you don't receive the mail, please fill password again and click the button below to resend the validation mail.",
"resendValidationEmailTip": "If you don't receive the mail, please fill password again and click the button below to resend the validation mail to: {email}",
"oauth2bindTip": "You're signing in to the {userName} user using {providerName}. Please enter your ezBookkeeping password to verify."
@@ -1851,6 +1853,8 @@
"Update Categories for Income Transactions": "Update Categories for Income Transactions",
"Update Categories for Transfer Transactions": "Update Categories for Transfer Transactions",
"Unable to update categories for transactions": "Unable to update categories for transactions",
"Delete Transactions": "Delete Transactions",
"Unable to delete these transactions": "Unable to delete these transactions",
"Account List": "Account List",
"This Week": "This Week",
"This Month": "This Month",
+4
View File
@@ -134,11 +134,13 @@
"selectedCount": "Seleccionado {count} de {totalCount}",
"queryIndex": "Query #{index}",
"youHaveUpdatedTransactions": "Has actualizado {count} transacciones",
"youHaveDeletedTransactions": "You have deleted {count} transactions",
"confirmImportTransactions": "¿Seguro que deseas importar {count} transacciones?",
"importingTransactions": "Importando ({process}%)",
"importTransactionResult": "Has importado {count} transacciones correctamente.",
"moveTransactionsInAccountTip": "NO PUEDES deshacer esta acción. Se moverán todas las transacciones de {fromAccount} a {toAccount}.",
"clearTransactionsInAccountTip": "NO PUEDES deshacer esta acción. Se eliminarán todas las transacciones de {account}. Por favor introduce tu contraseña para confirmar.",
"deleteTransactionsTip": "You CANNOT undo this action. This will delete {count} transactions. Please enter your current password to confirm.",
"accountActivationAndResendValidationEmailTip": "El enlace de activación de la cuenta se envió a tu dirección de correo electrónico: {email}. Si no recibes el correo, introduce nuevamente la contraseña y haz clic en el botón de abajo para reenviar el correo de validación.",
"resendValidationEmailTip": "Si no recibes el correo, introduce nuevamente la contraseña y haz clic en el botón de abajo para reenviar el correo de validación a: {email}",
"oauth2bindTip": "Estás iniciando sesión con el usuario {userName} usando {providerName}. Porfavor introduce tu contraseña de ezBookkeeping para verificar."
@@ -1851,6 +1853,8 @@
"Update Categories for Income Transactions": "Update Categories for Income Transactions",
"Update Categories for Transfer Transactions": "Update Categories for Transfer Transactions",
"Unable to update categories for transactions": "Unable to update categories for transactions",
"Delete Transactions": "Delete Transactions",
"Unable to delete these transactions": "Unable to delete these transactions",
"Account List": "Lista de Cuentas",
"This Week": "Esta Semana",
"This Month": "Este Mes",
+4
View File
@@ -134,11 +134,13 @@
"selectedCount": "Sélectionné {count} sur {totalCount}",
"queryIndex": "Query #{index}",
"youHaveUpdatedTransactions": "Vous avez mis à jour {count} transactions",
"youHaveDeletedTransactions": "You have deleted {count} transactions",
"confirmImportTransactions": "Êtes-vous sûr de vouloir importer {count} transactions ?",
"importingTransactions": "Importation ({process}%)",
"importTransactionResult": "Vous avez importé {count} transactions avec succès.",
"moveTransactionsInAccountTip": "You CANNOT undo this action. This will move all transactions from {fromAccount} to {toAccount}.",
"clearTransactionsInAccountTip": "You CANNOT undo this action. This will clear your transactions data in {account}. Please enter your current password to confirm.",
"deleteTransactionsTip": "You CANNOT undo this action. This will delete {count} transactions. Please enter your current password to confirm.",
"accountActivationAndResendValidationEmailTip": "Le lien d'activation du compte a été envoyé à votre adresse e-mail : {email}, Si vous ne recevez pas le mail, veuillez remplir à nouveau le mot de passe et cliquer sur le bouton ci-dessous pour renvoyer l'e-mail de validation.",
"resendValidationEmailTip": "Si vous ne recevez pas le mail, veuillez remplir à nouveau le mot de passe et cliquer sur le bouton ci-dessous pour renvoyer l'e-mail de validation à : {email}",
"oauth2bindTip": "You're signing in to the {userName} user using {providerName}. Please enter your ezBookkeeping password to verify."
@@ -1851,6 +1853,8 @@
"Update Categories for Income Transactions": "Update Categories for Income Transactions",
"Update Categories for Transfer Transactions": "Update Categories for Transfer Transactions",
"Unable to update categories for transactions": "Unable to update categories for transactions",
"Delete Transactions": "Delete Transactions",
"Unable to delete these transactions": "Unable to delete these transactions",
"Account List": "Liste des comptes",
"This Week": "Cette semaine",
"This Month": "Ce mois",
+4
View File
@@ -134,11 +134,13 @@
"selectedCount": "{count} selezionati su {totalCount}",
"queryIndex": "Query #{index}",
"youHaveUpdatedTransactions": "Hai aggiornato {count} transazioni",
"youHaveDeletedTransactions": "You have deleted {count} transactions",
"confirmImportTransactions": "Sei sicuro di voler importare {count} transazioni?",
"importingTransactions": "Importing ({process}%)",
"importTransactionResult": "Hai importato {count} transazioni.",
"moveTransactionsInAccountTip": "You CANNOT undo this action. This will move all transactions from {fromAccount} to {toAccount}.",
"clearTransactionsInAccountTip": "You CANNOT undo this action. This will clear your transactions data in {account}. Please enter your current password to confirm.",
"deleteTransactionsTip": "You CANNOT undo this action. This will delete {count} transactions. Please enter your current password to confirm.",
"accountActivationAndResendValidationEmailTip": "Abbiamo inviato un link per l'attivazione del tuo account all'indirizzo {email}. Se non hai ricevuto la mail, inserisci nuovamente la password e premi il bottone per ritentare l'invio.",
"resendValidationEmailTip": "Se non hai ricevuto la mail, inserisci nuovamente la password e premi il bottone per ritentare l'invio all'indirizzo: {email}",
"oauth2bindTip": "You're signing in to the {userName} user using {providerName}. Please enter your ezBookkeeping password to verify."
@@ -1851,6 +1853,8 @@
"Update Categories for Income Transactions": "Update Categories for Income Transactions",
"Update Categories for Transfer Transactions": "Update Categories for Transfer Transactions",
"Unable to update categories for transactions": "Unable to update categories for transactions",
"Delete Transactions": "Delete Transactions",
"Unable to delete these transactions": "Unable to delete these transactions",
"Account List": "Elenco account",
"This Week": "Questa settimana",
"This Month": "Questo mese",
+4
View File
@@ -134,11 +134,13 @@
"selectedCount": "{count} / {totalCount}を選択",
"queryIndex": "Query #{index}",
"youHaveUpdatedTransactions": "{count}件の取引を更新しました",
"youHaveDeletedTransactions": "You have deleted {count} transactions",
"confirmImportTransactions": "本当に{count}件の取引をインポートしますか?",
"importingTransactions": "Importing ({process}%)",
"importTransactionResult": "{count}件の取引を正常にインポートしました。",
"moveTransactionsInAccountTip": "You CANNOT undo this action. This will move all transactions from {fromAccount} to {toAccount}.",
"clearTransactionsInAccountTip": "You CANNOT undo this action. This will clear your transactions data in {account}. Please enter your current password to confirm.",
"deleteTransactionsTip": "You CANNOT undo this action. This will delete {count} transactions. Please enter your current password to confirm.",
"accountActivationAndResendValidationEmailTip": "アカウントの有効化リンクがメールアドレスに送信されました:{email}、メールが届かない場合はパスワードをもう一度入力して下のボタンをクリックして認証メールを再送信してください。",
"resendValidationEmailTip": "メールが届かない場合は、パスワードをもう一度入力の上、以下のボタンをクリックして検証メールを再送信してください: {email}",
"oauth2bindTip": "You're signing in to the {userName} user using {providerName}. Please enter your ezBookkeeping password to verify."
@@ -1851,6 +1853,8 @@
"Update Categories for Income Transactions": "Update Categories for Income Transactions",
"Update Categories for Transfer Transactions": "Update Categories for Transfer Transactions",
"Unable to update categories for transactions": "Unable to update categories for transactions",
"Delete Transactions": "Delete Transactions",
"Unable to delete these transactions": "Unable to delete these transactions",
"Account List": "口座リスト",
"This Week": "今週",
"This Month": "今月",
+4
View File
@@ -134,11 +134,13 @@
"selectedCount": "{totalCount}ರಲ್ಲಿ {count} ಆಯ್ಕೆ ಮಾಡಲಾಗಿದೆ",
"queryIndex": "Query #{index}",
"youHaveUpdatedTransactions": "ನೀವು {count} ವಹಿವಾಟುಗಳನ್ನು ನವೀಕರಿಸಿದ್ದೀರಿ",
"youHaveDeletedTransactions": "You have deleted {count} transactions",
"confirmImportTransactions": "ನೀವು {count} ವಹಿವಾಟುಗಳನ್ನು ಆಮದು ಮಾಡಲು ಖಚಿತವಾಗಿದ್ದೀರಾ?",
"importingTransactions": "ಆಮದು ಮಾಡಲಾಗುತ್ತಿದೆ ({process}%)",
"importTransactionResult": "ನೀವು ಯಶಸ್ವಿಯಾಗಿ {count} ವಹಿವಾಟುಗಳನ್ನು ಆಮದು ಮಾಡಿದ್ದೀರಿ.",
"moveTransactionsInAccountTip": "ಈ ಕ್ರಿಯೆಯನ್ನು ಹಿಂದಕ್ಕೆ ತರಲು ಸಾಧ್ಯವಿಲ್ಲ. ಇದು {fromAccount} ನ ಎಲ್ಲಾ ವಹಿವಾಟುಗಳನ್ನು {toAccount} ಗೆ ಸ್ಥಳಾಂತರಿಸುತ್ತದೆ.",
"clearTransactionsInAccountTip": "ಈ ಕ್ರಿಯೆಯನ್ನು ಹಿಂದಕ್ಕೆ ತರಲು ಸಾಧ್ಯವಿಲ್ಲ. ಇದು {account} ನಲ್ಲಿ ನಿಮ್ಮ ಎಲ್ಲಾ ವಹಿವಾಟುಗಳನ್ನು ಅಳಿಸುತ್ತದೆ. ದೃಢೀಕರಿಸಲು ದಯವಿಟ್ಟು ನಿಮ್ಮ ಪ್ರಸ್ತುತ ಪಾಸ್‌ವರ್ಡ್ ನಮೂದಿಸಿ.",
"deleteTransactionsTip": "You CANNOT undo this action. This will delete {count} transactions. Please enter your current password to confirm.",
"accountActivationAndResendValidationEmailTip": "ಖಾತೆ ಸಕ್ರಿಯಗೊಳಿಸುವ ಲಿಂಕ್ ಅನ್ನು ನಿಮ್ಮ ಈಮೇಲ್‌ಗೆ ಕಳುಹಿಸಲಾಗಿದೆ: {email}. ನೀವು ಇಮೇಲ್ ಪಡೆಯದಿದ್ದರೆ, ದಯವಿಟ್ಟು ಪಾಸ್‌ವರ್ಡ್ ಮರು ನಮೂದಿಸಿ ಮತ್ತು ಕೆಳಗಿನ ಬಟನ್ ಒತ್ತಿ ಸರೀಕರಿಸುವ ಇಮೇಲ್ ಮರು ಕಳುಹಿಸಿ.",
"resendValidationEmailTip": "ನೀವು ಇಮೇಲ್ ಪಡೆಯದಿದ್ದರೆ, ದಯವಿಟ್ಟು ಪಾಸ್‌ವರ್ಡ್ ಮರು ನಮೂದಿಸಿ ಮತ್ತು ಕೆಳಗಿನ ಬಟನ್ ಒತ್ತಿ ಮರು ಸರೀಕರಿಸುವ ಇಮೇಲ್ ಕಳುಹಿಸಲಾಗುವುದು: {email}",
"oauth2bindTip": "ನೀವು {providerName} ಬಳಸಿ {userName} ಬಳಕೆದಾರರಾಗಿ ಲಾಗಿನ್ ಆಗುತ್ತಿದ್ದೀರಿ. ದೃಢೀಕರಿಸಲು ದಯವಿಟ್ಟು ನಿಮ್ಮ ezBookkeeping ಪಾಸ್‌ವರ್ಡ್ ನಮೂದಿಸಿ."
@@ -1851,6 +1853,8 @@
"Update Categories for Income Transactions": "Update Categories for Income Transactions",
"Update Categories for Transfer Transactions": "Update Categories for Transfer Transactions",
"Unable to update categories for transactions": "Unable to update categories for transactions",
"Delete Transactions": "Delete Transactions",
"Unable to delete these transactions": "Unable to delete these transactions",
"Account List": "ಖಾತೆಗಳ ಪಟ್ಟಿ",
"This Week": "ಈ ವಾರ",
"This Month": "ಈ ತಿಂಗಳು",
+4
View File
@@ -134,11 +134,13 @@
"selectedCount": "{count}개 중 {totalCount}개 선택됨",
"queryIndex": "Query #{index}",
"youHaveUpdatedTransactions": "{count}개의 거래가 업데이트되었습니다.",
"youHaveDeletedTransactions": "You have deleted {count} transactions",
"confirmImportTransactions": "{count}개의 거래를 가져오시겠습니까?",
"importingTransactions": "가져오는 중 ({process}%)",
"importTransactionResult": "성공적으로 {count}개의 거래를 가져왔습니다.",
"moveTransactionsInAccountTip": "이 작업은 되돌릴 수 없습니다. {fromAccount}에서 {toAccount}로 모든 거래를 이동합니다.",
"clearTransactionsInAccountTip": "이 작업은 되돌릴 수 없습니다. {account}의 거래 데이터를 지웁니다. 계속하시려면 현재 비밀번호를 입력하세요.",
"deleteTransactionsTip": "You CANNOT undo this action. This will delete {count} transactions. Please enter your current password to confirm.",
"accountActivationAndResendValidationEmailTip": "계정 활성화 링크가 귀하의 이메일 주소({email})로 전송되었습니다. 메일을 받지 못하신 경우, 비밀번호를 다시 입력하고 아래 버튼을 클릭하여 확인 메일을 재전송하십시오.",
"resendValidationEmailTip": "메일을 받지 못하신 경우, 비밀번호를 다시 입력하고 아래 버튼을 클릭하여 확인 메일을 {email}로 재전송하십시오.",
"oauth2bindTip": "{providerName}를 사용하여 {userName} 사용자로 로그인하고 있습니다. 확인을 위해 ezBookkeeping 비밀번호를 입력하세요."
@@ -1851,6 +1853,8 @@
"Update Categories for Income Transactions": "Update Categories for Income Transactions",
"Update Categories for Transfer Transactions": "Update Categories for Transfer Transactions",
"Unable to update categories for transactions": "Unable to update categories for transactions",
"Delete Transactions": "Delete Transactions",
"Unable to delete these transactions": "Unable to delete these transactions",
"Account List": "계좌 목록",
"This Week": "이번 주",
"This Month": "이번 달",
+4
View File
@@ -134,11 +134,13 @@
"selectedCount": "{count} van {totalCount} geselecteerd",
"queryIndex": "Query #{index}",
"youHaveUpdatedTransactions": "Je hebt {count} transacties bijgewerkt",
"youHaveDeletedTransactions": "You have deleted {count} transactions",
"confirmImportTransactions": "Weet je zeker dat je {count} transacties wilt importeren?",
"importingTransactions": "Bezig met importeren ({process}%)",
"importTransactionResult": "Je hebt {count} transacties succesvol geïmporteerd.",
"moveTransactionsInAccountTip": "You CANNOT undo this action. This will move all transactions from {fromAccount} to {toAccount}.",
"clearTransactionsInAccountTip": "You CANNOT undo this action. This will clear your transactions data in {account}. Please enter your current password to confirm.",
"deleteTransactionsTip": "You CANNOT undo this action. This will delete {count} transactions. Please enter your current password to confirm.",
"accountActivationAndResendValidationEmailTip": "Een activatielink is verzonden naar je e-mailadres: {email}. Als je de e-mail niet ontvangt, vul dan je wachtwoord opnieuw in en klik op de knop hieronder om de validatiemail opnieuw te verzenden.",
"resendValidationEmailTip": "Als je de e-mail niet ontvangt, vul dan je wachtwoord opnieuw in en klik op de knop hieronder om de validatiemail opnieuw te verzenden naar: {email}",
"oauth2bindTip": "You're signing in to the {userName} user using {providerName}. Please enter your ezBookkeeping password to verify."
@@ -1851,6 +1853,8 @@
"Update Categories for Income Transactions": "Update Categories for Income Transactions",
"Update Categories for Transfer Transactions": "Update Categories for Transfer Transactions",
"Unable to update categories for transactions": "Unable to update categories for transactions",
"Delete Transactions": "Delete Transactions",
"Unable to delete these transactions": "Unable to delete these transactions",
"Account List": "Rekeningenlijst",
"This Week": "Deze week",
"This Month": "Deze maand",
+4
View File
@@ -134,11 +134,13 @@
"selectedCount": "{count} de {totalCount} selecionados",
"queryIndex": "Consulta #{index}",
"youHaveUpdatedTransactions": "Você atualizou {count} transações",
"youHaveDeletedTransactions": "You have deleted {count} transactions",
"confirmImportTransactions": "Tem certeza de que deseja importar {count} transações?",
"importingTransactions": "Importando ({process}%)",
"importTransactionResult": "Você importou {count} transações com sucesso.",
"moveTransactionsInAccountTip": "Você NÃO PODE desfazer esta ação. Isso moverá todas as transações de {fromAccount} para {toAccount}.",
"clearTransactionsInAccountTip": "Você NÃO PODE desfazer esta ação. Isso apagará todas as transações em {account}. Por favor, insira sua senha atual para confirmar.",
"deleteTransactionsTip": "You CANNOT undo this action. This will delete {count} transactions. Please enter your current password to confirm.",
"accountActivationAndResendValidationEmailTip": "O link de ativação da conta foi enviado para seu endereço de e-mail: {email}. Se você não receber o e-mail, por favor, insira a senha novamente e clique no botão abaixo para reenviar o e-mail de validação.",
"resendValidationEmailTip": "Se você não receber o e-mail, por favor, insira a senha novamente e clique no botão abaixo para reenviar o e-mail de validação para: {email}",
"oauth2bindTip": "Você está fazendo login como {userName} usando {providerName}. Por favor, insira sua senha do ezBookkeeping para verificar."
@@ -1851,6 +1853,8 @@
"Update Categories for Income Transactions": "Update Categories for Income Transactions",
"Update Categories for Transfer Transactions": "Update Categories for Transfer Transactions",
"Unable to update categories for transactions": "Unable to update categories for transactions",
"Delete Transactions": "Delete Transactions",
"Unable to delete these transactions": "Unable to delete these transactions",
"Account List": "Lista de Contas",
"This Week": "Esta Semana",
"This Month": "Este Mês",
+4
View File
@@ -134,11 +134,13 @@
"selectedCount": "Выбрано {count} из {totalCount}",
"queryIndex": "Запрос #{index}",
"youHaveUpdatedTransactions": "Вы обновили {count} транзакций",
"youHaveDeletedTransactions": "You have deleted {count} transactions",
"confirmImportTransactions": "Вы уверены, что хотите импортировать {count} транзакций?",
"importingTransactions": "Импортирование ({process}%)",
"importTransactionResult": "Вы успешно импортировали {count} транзакций.",
"moveTransactionsInAccountTip": "Вы НЕ сможете отменить это действие. Все транзакции будут перемещены с {fromAccount} на {toAccount}.",
"clearTransactionsInAccountTip": "Вы НЕ сможете отменить это действие. Все транзакции будут отчищеы с {account}. Пожалуйста введите пароль.",
"deleteTransactionsTip": "You CANNOT undo this action. This will delete {count} transactions. Please enter your current password to confirm.",
"accountActivationAndResendValidationEmailTip": "Ссылка для активации учетной записи была отправлена на ваш электронный адрес: {email}. Если вы не получили письмо, заполните пароль снова и нажмите кнопку ниже, чтобы отправить письмо повторно.",
"resendValidationEmailTip": "Если вы не получили письмо, заполните пароль снова и нажмите кнопку ниже, чтобы отправить письмо повторно на: {email}",
"oauth2bindTip": "Вы входите как пользователь {userName} используя {providerName}. Пожалуйста введите ваш ezBookkeeping пароль для подтверждения."
@@ -1851,6 +1853,8 @@
"Update Categories for Income Transactions": "Update Categories for Income Transactions",
"Update Categories for Transfer Transactions": "Update Categories for Transfer Transactions",
"Unable to update categories for transactions": "Unable to update categories for transactions",
"Delete Transactions": "Delete Transactions",
"Unable to delete these transactions": "Unable to delete these transactions",
"Account List": "Список счетов",
"This Week": "На этой неделе",
"This Month": "В этом месяце",
+4
View File
@@ -134,11 +134,13 @@
"selectedCount": "Izbranih {count} od {totalCount}",
"queryIndex": "Poizvedba #{index}",
"youHaveUpdatedTransactions": "Posodobili ste {count} transakcij",
"youHaveDeletedTransactions": "You have deleted {count} transactions",
"confirmImportTransactions": "Ali ste prepričani, da želite uvoziti {count} transakcij?",
"importingTransactions": "Uvažam ({process}%)",
"importTransactionResult": "Uspešno ste uvozili {count} transakcij.",
"moveTransactionsInAccountTip": "Tega dejanja NE MORETE razveljaviti. S tem boste vse transakcije premaknili iz računa {fromAccount} v račun {toAccount}.",
"clearTransactionsInAccountTip": "Tega dejanja NE MORETE razveljaviti. S tem boste izbrisali podatke o transakcijah v računu {account}. Za potrditev vnesite trenutno geslo.",
"deleteTransactionsTip": "You CANNOT undo this action. This will delete {count} transactions. Please enter your current password to confirm.",
"accountActivationAndResendValidationEmailTip": "Povezava za aktivacijo računa je bila poslana na vaš e-poštni naslov: {email}. Če e-pošte ne prejmete, ponovno vnesite geslo in kliknite spodnji gumb, da ponovno pošljete potrditveno e-pošto.",
"resendValidationEmailTip": "Če ne prejmete e-pošte, ponovno vnesite geslo in kliknite spodnji gumb, da ponovno pošljete potrditveno e-pošto na: {email}",
"oauth2bindTip": "Prijavljate se v uporabniški račun {userName} z uporabo računa {providerName}. Za potrditev vnesite svoje geslo za ezBookkeeping."
@@ -1851,6 +1853,8 @@
"Update Categories for Income Transactions": "Update Categories for Income Transactions",
"Update Categories for Transfer Transactions": "Update Categories for Transfer Transactions",
"Unable to update categories for transactions": "Unable to update categories for transactions",
"Delete Transactions": "Delete Transactions",
"Unable to delete these transactions": "Unable to delete these transactions",
"Account List": "Seznam računov",
"This Week": "Ta teden",
"This Month": "Ta mesec",
+4
View File
@@ -134,11 +134,13 @@
"selectedCount": "{totalCount} இல் {count} தேர்ந்தெடுக்கப்பட்டது",
"queryIndex": "வினவல் #{index}",
"youHaveUpdatedTransactions": "நீங்கள் {count} பரிவர்த்தனைகளை புதுப்பித்துள்ளீர்கள்",
"youHaveDeletedTransactions": "You have deleted {count} transactions",
"confirmImportTransactions": "நீங்கள் {count} பரிவர்த்தனைகளை இறக்குமதி செய்ய விரும்புகிறீர்களா?",
"importingTransactions": "இறக்குமதி செய்யப்படுகிறது ({process}%)",
"importTransactionResult": "நீங்கள் வெற்றிகரமாக {count} பரிவர்த்தனைகளை இறக்குமதி செய்துள்ளீர்கள்.",
"moveTransactionsInAccountTip": "இந்த செயலை மீட்டெடுக்க முடியாது. இது {fromAccount} இலிருந்து அனைத்து பரிவர்த்தனைகளையும் {toAccount} க்கு மாற்றும்.",
"clearTransactionsInAccountTip": "இந்த செயலை மீட்டெடுக்க முடியாது. இது {account} இல் உள்ள உங்கள் அனைத்து பரிவர்த்தனைகளையும் நீக்கும். உறுதிப்படுத்த உங்கள் தற்போதைய கடவுச்சொல்லை உள்ளிடவும்.",
"deleteTransactionsTip": "You CANNOT undo this action. This will delete {count} transactions. Please enter your current password to confirm.",
"accountActivationAndResendValidationEmailTip": "கணக்கு செயல்படுத்தும் இணைப்பு உங்கள் மின்னஞ்சலுக்கு அனுப்பப்பட்டது: {email}. நீங்கள் மின்னஞ்சலைப் பெறவில்லை என்றால், கடவுச்சொல்லை மீண்டும் உள்ளிட்டு கீழே உள்ள பொத்தானை அழுத்தி சரிபார்ப்பு மின்னஞ்சலை மீண்டும் அனுப்பவும்.",
"resendValidationEmailTip": "நீங்கள் மின்னஞ்சலைப் பெறவில்லை என்றால், கடவுச்சொல்லை மீண்டும் உள்ளிட்டு கீழே உள்ள பொத்தானை அழுத்தவும், சரிபார்ப்பு மின்னஞ்சல் அனுப்பப்படும்: {email}",
"oauth2bindTip": "நீங்கள் {providerName} பயன்படுத்தி {userName} பயனராக உள்நுழைகிறீர்கள். உறுதிப்படுத்த உங்கள் ezBookkeeping கடவுச்சொல்லை உள்ளிடவும்."
@@ -1851,6 +1853,8 @@
"Update Categories for Income Transactions": "Update Categories for Income Transactions",
"Update Categories for Transfer Transactions": "Update Categories for Transfer Transactions",
"Unable to update categories for transactions": "Unable to update categories for transactions",
"Delete Transactions": "Delete Transactions",
"Unable to delete these transactions": "Unable to delete these transactions",
"Account List": "கணக்குகளின் பட்டியல்",
"This Week": "இந்த வாரம்",
"This Month": "இந்த மாதம்",
+4
View File
@@ -134,11 +134,13 @@
"selectedCount": "เลือกแล้ว {count} จาก {totalCount}",
"queryIndex": "Query #{index}",
"youHaveUpdatedTransactions": "คุณได้อัปเดตธุรกรรม {count} รายการ",
"youHaveDeletedTransactions": "You have deleted {count} transactions",
"confirmImportTransactions": "คุณแน่ใจหรือไม่ว่าต้องการนำเข้าธุรกรรม {count} รายการ?",
"importingTransactions": "กำลังนำเข้า ({process}%)",
"importTransactionResult": "คุณได้นำเข้าธุรกรรม {count} รายการเรียบร้อยแล้ว",
"moveTransactionsInAccountTip": "You CANNOT undo this action. This will move all transactions from {fromAccount} to {toAccount}.",
"clearTransactionsInAccountTip": "คุณไม่สามารถยกเลิกการกระทำนี้ได้ การกระทำนี้จะลบข้อมูลธุรกรรมทั้งหมดใน {account} โปรดป้อนรหัสผ่านปัจจุบันเพื่อยืนยัน",
"deleteTransactionsTip": "You CANNOT undo this action. This will delete {count} transactions. Please enter your current password to confirm.",
"accountActivationAndResendValidationEmailTip": "ลิงก์สำหรับเปิดใช้งานบัญชีได้ถูกส่งไปยังอีเมลของคุณแล้ว: {email} หากคุณไม่ได้รับอีเมล โปรดกรอกรหัสผ่านอีกครั้งแล้วกดปุ่มด้านล่างเพื่อส่งอีเมลยืนยันอีกครั้ง",
"resendValidationEmailTip": "หากคุณไม่ได้รับอีเมล โปรดกรอกรหัสผ่านอีกครั้งแล้วกดปุ่มด้านล่างเพื่อส่งอีเมลยืนยันไปยัง: {email}",
"oauth2bindTip": "You're signing in to the {userName} user using {providerName}. Please enter your ezBookkeeping password to verify."
@@ -1851,6 +1853,8 @@
"Update Categories for Income Transactions": "Update Categories for Income Transactions",
"Update Categories for Transfer Transactions": "Update Categories for Transfer Transactions",
"Unable to update categories for transactions": "Unable to update categories for transactions",
"Delete Transactions": "Delete Transactions",
"Unable to delete these transactions": "Unable to delete these transactions",
"Account List": "รายการบัญชี",
"This Week": "สัปดาห์นี้",
"This Month": "เดือนนี้",
+4
View File
@@ -134,11 +134,13 @@
"selectedCount": "{totalCount} öğeden {count} tanesi seçildi",
"queryIndex": "Query #{index}",
"youHaveUpdatedTransactions": "{count} işlemi güncellediniz",
"youHaveDeletedTransactions": "You have deleted {count} transactions",
"confirmImportTransactions": "{count} işlemi içe aktarmak istediğinize emin misiniz?",
"importingTransactions": "İçe aktarılıyor (%{process})",
"importTransactionResult": "{count} işlem başarıyla içe aktarıldı.",
"moveTransactionsInAccountTip": "Bu işlem GERİ ALINAMAZ. Bu, {fromAccount} hesabındaki tüm işlemleri {toAccount} hesabına taşıyacaktır.",
"clearTransactionsInAccountTip": "Bu işlem GERİ ALINAMAZ. Bu, {account} hesabındaki işlem verilerinizi silecektir. Onaylamak için lütfen mevcut şifrenizi girin.",
"deleteTransactionsTip": "You CANNOT undo this action. This will delete {count} transactions. Please enter your current password to confirm.",
"accountActivationAndResendValidationEmailTip": "Hesap aktivasyon bağlantısı e-posta adresinize ({email}) gönderildi. Eğer e-postayı almadıysanız, lütfen şifrenizi tekrar girin ve doğrulama postasını yeniden göndermek için aşağıdaki butona tıklayın.",
"resendValidationEmailTip": "Eğer e-postayı almadıysanız, lütfen şifrenizi tekrar girin ve doğrulama postasını şu adrese yeniden göndermek için aşağıdaki butona tıklayın: {email}",
"oauth2bindTip": "{providerName} kullanarak {userName} hesabına giriş yapıyorsunuz. Doğrulamak için lütfen ezBookkeeping şifrenizi girin."
@@ -1851,6 +1853,8 @@
"Update Categories for Income Transactions": "Update Categories for Income Transactions",
"Update Categories for Transfer Transactions": "Update Categories for Transfer Transactions",
"Unable to update categories for transactions": "Unable to update categories for transactions",
"Delete Transactions": "Delete Transactions",
"Unable to delete these transactions": "Unable to delete these transactions",
"Account List": "Hesap Listesi",
"This Week": "Bu Hafta",
"This Month": "Bu Ay",
+4
View File
@@ -134,11 +134,13 @@
"selectedCount": "Вибрано {count} з {totalCount}",
"queryIndex": "Query #{index}",
"youHaveUpdatedTransactions": "Ви оновили {count} транзакцій",
"youHaveDeletedTransactions": "You have deleted {count} transactions",
"confirmImportTransactions": "Ви впевнені, що хочете імпортувати {count} транзакцій?",
"importingTransactions": "Importing ({process}%)",
"importTransactionResult": "Ви успішно імпортували {count} транзакцій.",
"moveTransactionsInAccountTip": "You CANNOT undo this action. This will move all transactions from {fromAccount} to {toAccount}.",
"clearTransactionsInAccountTip": "You CANNOT undo this action. This will clear your transactions data in {account}. Please enter your current password to confirm.",
"deleteTransactionsTip": "You CANNOT undo this action. This will delete {count} transactions. Please enter your current password to confirm.",
"accountActivationAndResendValidationEmailTip": "Посилання для активації облікового запису було надіслано на вашу електронну адресу: {email}. Якщо ви не отримали лист, введіть пароль ще раз і натисніть кнопку нижче, щоб надіслати лист повторно.",
"resendValidationEmailTip": "Якщо ви не отримали лист, введіть пароль ще раз і натисніть кнопку нижче, щоб надіслати лист повторно на адресу: {email}",
"oauth2bindTip": "You're signing in to the {userName} user using {providerName}. Please enter your ezBookkeeping password to verify."
@@ -1851,6 +1853,8 @@
"Update Categories for Income Transactions": "Update Categories for Income Transactions",
"Update Categories for Transfer Transactions": "Update Categories for Transfer Transactions",
"Unable to update categories for transactions": "Unable to update categories for transactions",
"Delete Transactions": "Delete Transactions",
"Unable to delete these transactions": "Unable to delete these transactions",
"Account List": "Список рахунків",
"This Week": "Цього тижня",
"This Month": "Цього місяця",
+4
View File
@@ -134,11 +134,13 @@
"selectedCount": "Đã chọn {count} trên {totalCount}",
"queryIndex": "Query #{index}",
"youHaveUpdatedTransactions": "Bạn đã cập nhật {count} giao dịch",
"youHaveDeletedTransactions": "You have deleted {count} transactions",
"confirmImportTransactions": "Bạn có chắc chắn muốn nhập {count} giao dịch không?",
"importingTransactions": "Importing ({process}%)",
"importTransactionResult": "Bạn đã nhập thành công {count} giao dịch.",
"moveTransactionsInAccountTip": "You CANNOT undo this action. This will move all transactions from {fromAccount} to {toAccount}.",
"clearTransactionsInAccountTip": "You CANNOT undo this action. This will clear your transactions data in {account}. Please enter your current password to confirm.",
"deleteTransactionsTip": "You CANNOT undo this action. This will delete {count} transactions. Please enter your current password to confirm.",
"accountActivationAndResendValidationEmailTip": "Liên kết kích hoạt tài khoản đã được gửi tới email của bạn: {email}. Nếu bạn không nhận được email, vui lòng nhập lại mật khẩu và nhấp nút bên dưới để gửi lại email xác nhận.",
"resendValidationEmailTip": "Nếu bạn không nhận được email, vui lòng nhập lại mật khẩu và nhấp nút bên dưới để gửi lại email xác nhận tới: {email}",
"oauth2bindTip": "You're signing in to the {userName} user using {providerName}. Please enter your ezBookkeeping password to verify."
@@ -1851,6 +1853,8 @@
"Update Categories for Income Transactions": "Update Categories for Income Transactions",
"Update Categories for Transfer Transactions": "Update Categories for Transfer Transactions",
"Unable to update categories for transactions": "Unable to update categories for transactions",
"Delete Transactions": "Delete Transactions",
"Unable to delete these transactions": "Unable to delete these transactions",
"Account List": "Danh sách tài khoản",
"This Week": "Tuần này",
"This Month": "Tháng này",
+4
View File
@@ -134,11 +134,13 @@
"selectedCount": "已选择 {count} / {totalCount}",
"queryIndex": "查询 #{index}",
"youHaveUpdatedTransactions": "您已经更新 {count} 个交易",
"youHaveDeletedTransactions": "您已经删除 {count} 个交易",
"confirmImportTransactions": "您确定要导入 {count} 个交易?",
"importingTransactions": "正在导入 ({process}%)",
"importTransactionResult": "您已经成功导入 {count} 个交易。",
"moveTransactionsInAccountTip": "您不能撤销该操作。该操作将会把 {fromAccount} 账户中所有的交易数据移动到 {toAccount}。",
"clearTransactionsInAccountTip": "您不能撤销该操作。该操作将会清除您在 {account} 账户中的交易数据。请输入您当前的密码以确认。",
"deleteTransactionsTip": "您不能撤销该操作。该操作将会删除 {count} 个交易数据。请输入您当前的密码以确认。",
"accountActivationAndResendValidationEmailTip": "账号激活链接已经发送到您的邮箱地址:{email},如果您没有收到邮件,请再次输入密码并点击下方的按钮重新发送验证邮件。",
"resendValidationEmailTip": "如果您没有收到邮件,请再次输入密码并点击下方的按钮重新发送验证邮件到:{email}",
"oauth2bindTip": "您正在使用 {providerName} 登录 \"{userName}\" 用户,请输入你的 ezBookkeeping 的密码进行验证。"
@@ -1851,6 +1853,8 @@
"Update Categories for Income Transactions": "更新收入交易的分类",
"Update Categories for Transfer Transactions": "更新转账交易的分类",
"Unable to update categories for transactions": "无法更新交易的分类",
"Delete Transactions": "删除交易",
"Unable to delete these transactions": "无法删除这些交易",
"Account List": "账户列表",
"This Week": "本周",
"This Month": "本月",
+4
View File
@@ -134,11 +134,13 @@
"selectedCount": "已選擇 {count} / {totalCount}",
"queryIndex": "查詢 #{index}",
"youHaveUpdatedTransactions": "您已經更新 {count} 個交易",
"youHaveDeletedTransactions": "您已經刪除 {count} 個交易",
"confirmImportTransactions": "您確定要匯入 {count} 個交易?",
"importingTransactions": "正在匯入 ({process}%)",
"importTransactionResult": "您已經成功匯入 {count} 個交易。",
"moveTransactionsInAccountTip": "您不能還原此操作。此操作將會把 {fromAccount} 帳戶中的所有交易資料移動到 {toAccount}。",
"clearTransactionsInAccountTip": "您不能還原此操作。此操作將會清除您在 {account} 帳戶中的交易資料。請輸入您目前的密碼以確認。",
"deleteTransactionsTip": "您不能還原此操作。此操作將會刪除 {count} 個交易資料。請輸入您目前的密碼以確認。",
"accountActivationAndResendValidationEmailTip": "帳號啟用連結已經傳送到您的信箱地址:{email},如果您沒有收到郵件,請再次輸入密碼並點擊下方的按鈕重新發送驗證郵件。",
"resendValidationEmailTip": "如果您沒有收到郵件,請再次輸入密碼並點擊下方的按鈕重新發送驗證郵件到:{email}",
"oauth2bindTip": "您正在使用 {providerName} 登入 \"{userName}\" 使用者,請輸入您的 ezBookkeeping 的密碼以進行驗證。"
@@ -1851,6 +1853,8 @@
"Update Categories for Income Transactions": "更新收入交易的分類",
"Update Categories for Transfer Transactions": "更新轉帳交易的分類",
"Unable to update categories for transactions": "無法更新交易的分類",
"Delete Transactions": "刪除交易",
"Unable to delete these transactions": "無法刪除這些交易",
"Account List": "帳戶清單",
"This Week": "本週",
"This Month": "本月",
+5
View File
@@ -572,6 +572,11 @@ export interface TransactionDeleteRequest {
readonly id: string;
}
export interface TransactionBatchDeleteRequest {
readonly ids: string[];
readonly password: string;
}
export interface TransactionImportRequest {
readonly transactions: TransactionCreateRequest[];
readonly clientSessionId: string;
+102 -80
View File
@@ -610,6 +610,32 @@ export const useTransactionsStore = defineStore('transactions', () => {
transactionReconciliationStatementStateInvalid.value = invalidState;
}
function updateStoreInvalidState(options: { transactionList?: boolean, reconciliationStatement?: boolean, accountList?: boolean, overview?: boolean, statistics?: boolean, explorer?: boolean }): void {
if (options.transactionList && !transactionListStateInvalid.value) {
updateTransactionListInvalidState(true);
}
if (options.reconciliationStatement && !transactionReconciliationStatementStateInvalid.value) {
updateTransactionReconciliationStatementInvalidState(true);
}
if (options.accountList && !accountsStore.accountListStateInvalid) {
accountsStore.updateAccountListInvalidState(true);
}
if (options.overview && !overviewStore.transactionOverviewStateInvalid) {
overviewStore.updateTransactionOverviewInvalidState(true);
}
if (options.statistics && !statisticsStore.transactionStatisticsStateInvalid) {
statisticsStore.updateTransactionStatisticsInvalidState(true);
}
if (options.explorer && !explorersStore.transactionExplorerStateInvalid) {
explorersStore.updateTransactionExplorerInvalidState(true);
}
}
function resetTransactions(): void {
transactionsFilter.value.dateType = DateRange.All.type;
transactionsFilter.value.maxTime = 0;
@@ -1078,25 +1104,13 @@ export const useTransactionsStore = defineStore('transactions', () => {
});
}
if (!transactionReconciliationStatementStateInvalid.value) {
updateTransactionReconciliationStatementInvalidState(true);
}
if (!accountsStore.accountListStateInvalid) {
accountsStore.updateAccountListInvalidState(true);
}
if (!overviewStore.transactionOverviewStateInvalid) {
overviewStore.updateTransactionOverviewInvalidState(true);
}
if (!statisticsStore.transactionStatisticsStateInvalid) {
statisticsStore.updateTransactionStatisticsInvalidState(true);
}
if (!explorersStore.transactionExplorerStateInvalid) {
explorersStore.updateTransactionExplorerInvalidState(true);
}
updateStoreInvalidState({
reconciliationStatement: true,
accountList: true,
overview: true,
statistics: true,
explorer: true
});
resolve(transaction);
}).catch(error => {
@@ -1127,25 +1141,13 @@ export const useTransactionsStore = defineStore('transactions', () => {
return;
}
if (!transactionListStateInvalid.value) {
updateTransactionListInvalidState(true);
}
if (!transactionReconciliationStatementStateInvalid.value) {
updateTransactionReconciliationStatementInvalidState(true);
}
if (!overviewStore.transactionOverviewStateInvalid) {
overviewStore.updateTransactionOverviewInvalidState(true);
}
if (!statisticsStore.transactionStatisticsStateInvalid) {
statisticsStore.updateTransactionStatisticsInvalidState(true);
}
if (!explorersStore.transactionExplorerStateInvalid) {
explorersStore.updateTransactionExplorerInvalidState(true);
}
updateStoreInvalidState({
transactionList: true,
reconciliationStatement: true,
overview: true,
statistics: true,
explorer: true
});
resolve(data.result);
}).catch(error => {
@@ -1172,29 +1174,14 @@ export const useTransactionsStore = defineStore('transactions', () => {
return;
}
if (!transactionListStateInvalid.value) {
updateTransactionListInvalidState(true);
}
if (!transactionReconciliationStatementStateInvalid.value) {
updateTransactionReconciliationStatementInvalidState(true);
}
if (!accountsStore.accountListStateInvalid) {
accountsStore.updateAccountListInvalidState(true);
}
if (!overviewStore.transactionOverviewStateInvalid) {
overviewStore.updateTransactionOverviewInvalidState(true);
}
if (!statisticsStore.transactionStatisticsStateInvalid) {
statisticsStore.updateTransactionStatisticsInvalidState(true);
}
if (!explorersStore.transactionExplorerStateInvalid) {
explorersStore.updateTransactionExplorerInvalidState(true);
}
updateStoreInvalidState({
transactionList: true,
reconciliationStatement: true,
accountList: true,
overview: true,
statistics: true,
explorer: true
});
resolve(data.result);
}).catch(error => {
@@ -1237,25 +1224,13 @@ export const useTransactionsStore = defineStore('transactions', () => {
});
}
if (!transactionReconciliationStatementStateInvalid.value) {
updateTransactionReconciliationStatementInvalidState(true);
}
if (!accountsStore.accountListStateInvalid) {
accountsStore.updateAccountListInvalidState(true);
}
if (!overviewStore.transactionOverviewStateInvalid) {
overviewStore.updateTransactionOverviewInvalidState(true);
}
if (!statisticsStore.transactionStatisticsStateInvalid) {
statisticsStore.updateTransactionStatisticsInvalidState(true);
}
if (!explorersStore.transactionExplorerStateInvalid) {
explorersStore.updateTransactionExplorerInvalidState(true);
}
updateStoreInvalidState({
reconciliationStatement: true,
accountList: true,
overview: true,
statistics: true,
explorer: true
});
resolve(data.result);
}).catch(error => {
@@ -1272,6 +1247,52 @@ export const useTransactionsStore = defineStore('transactions', () => {
});
}
function batchDeleteTransactions({ transactionIds, password }: { transactionIds: string[], password: string }): Promise<boolean> {
return new Promise((resolve, reject) => {
services.batchDeleteTransaction({
ids: transactionIds,
password: password
}).then(response => {
const data = response.data;
if (!data || !data.success || !data.result) {
reject({ message: 'Unable to delete these transactions' });
return;
}
updateStoreInvalidState({
transactionList: true,
reconciliationStatement: true,
accountList: true,
overview: true,
statistics: true,
explorer: true
});
resolve(data.result);
}).catch(error => {
logger.error('failed to delete transactions', error);
updateStoreInvalidState({
transactionList: true,
reconciliationStatement: true,
accountList: true,
overview: true,
statistics: true,
explorer: true
});
if (error.response && error.response.data && error.response.data.errorMessage) {
reject({ error: error.response.data });
} else if (!error.processed) {
reject({ message: 'Unable to delete these transactions' });
} else {
reject(error);
}
});
});
}
function recognizeReceiptImage({ imageFile, cancelableUuid }: { imageFile: File, cancelableUuid?: string }): Promise<RecognizedReceiptImageResponse> {
return new Promise((resolve, reject) => {
services.recognizeReceiptImage({ imageFile, cancelableUuid }).then(response => {
@@ -1520,6 +1541,7 @@ export const useTransactionsStore = defineStore('transactions', () => {
batchUpdateTransactionCategories,
moveAllTransactionsBetweenAccounts,
deleteTransaction,
batchDeleteTransactions,
recognizeReceiptImage,
cancelRecognizeReceiptImage,
parseImportCustomFile,
@@ -0,0 +1,103 @@
<template>
<v-dialog width="600" :persistent="true" v-model="showState">
<v-card class="pa-sm-1 pa-md-2">
<template #title>
<h4 class="text-h4 text-error text-wrap">{{ tt('Delete Transactions') }}</h4>
</template>
<v-card-text class="pb-2 text-error">{{ tt('format.misc.deleteTransactionsTip', { count: formatNumberToLocalizedNumerals(deleteIds?.length ?? 0) }) }}</v-card-text>
<v-card-text class="w-100 d-flex justify-center">
<div class="w-100">
<v-text-field
autocomplete="current-password"
type="password"
variant="underlined"
color="error"
:disabled="deleting"
:placeholder="tt('Current Password')"
v-model="currentPassword"
/>
</div>
</v-card-text>
<v-card-text>
<div class="w-100 d-flex justify-center flex-wrap mt-sm-1 mt-md-2 gap-4">
<v-btn color="error" :disabled="!currentPassword || deleting || deleteIds.length < 1" @click="confirm">
{{ tt('Confirm') }}
<v-progress-circular indeterminate size="22" class="ms-2" v-if="deleting"></v-progress-circular>
</v-btn>
<v-btn color="secondary" variant="tonal" :disabled="deleting" @click="cancel">{{ tt('Cancel') }}</v-btn>
</div>
</v-card-text>
</v-card>
</v-dialog>
<snack-bar ref="snackbar" />
</template>
<script setup lang="ts">
import SnackBar from '@/components/desktop/SnackBar.vue';
import { ref, useTemplateRef } from 'vue';
import { useI18n } from '@/locales/helpers.ts';
import { useTransactionsStore } from '@/stores/transaction.ts';
type SnackBarType = InstanceType<typeof SnackBar>;
const {
tt,
formatNumberToLocalizedNumerals
} = useI18n();
const transactionsStore = useTransactionsStore();
const snackbar = useTemplateRef<SnackBarType>('snackbar');
const showState = ref<boolean>(false);
const deleting = ref<boolean>(false);
const deleteIds = ref<string[]>([]);
const currentPassword = ref<string>('');
let resolveFunc: ((response: number) => void) | null = null;
let rejectFunc: ((reason?: unknown) => void) | null = null;
function open(options: { updateIds: string[] }): Promise<number> {
deleteIds.value = options.updateIds;
currentPassword.value = '';
deleting.value = false;
showState.value = true;
return new Promise((resolve, reject) => {
resolveFunc = resolve;
rejectFunc = reject;
});
}
function confirm(): void {
deleting.value = true;
transactionsStore.batchDeleteTransactions({
transactionIds: deleteIds.value,
password: currentPassword.value
}).then(() => {
deleting.value = false;
showState.value = false;
resolveFunc?.(deleteIds.value.length);
}).catch(error => {
deleting.value = false;
if (!error.processed) {
snackbar.value?.showError(error);
}
});
}
function cancel(): void {
rejectFunc?.();
showState.value = false;
}
defineExpose({
open
});
</script>
@@ -90,6 +90,12 @@
:title="tt('Update Categories for Transfer Transactions')"
:disabled="!isAllSelectedTransactionsTransfer"
@click="batchUpdateTransactionCategories(CategoryType.Transfer)"></v-list-item>
<v-divider class="my-2" />
<v-list-item :prepend-icon="mdiDeleteOutline"
:title="tt('Delete Transactions')"
:disabled="selectedTransactionCount < 1"
@click="batchDeleteTransactions">
</v-list-item>
</v-list>
</v-menu>
</div>
@@ -174,6 +180,7 @@
</v-data-table>
<batch-update-category-dialog ref="batchUpdateCategoryDialog" />
<batch-delete-dialog ref="batchDeleteDialog" />
<snack-bar ref="snackbar" />
</template>
@@ -181,12 +188,14 @@
import SnackBar from '@/components/desktop/SnackBar.vue';
import PaginationButtons from '@/components/desktop/PaginationButtons.vue';
import BatchUpdateCategoryDialog from '@/views/desktop/insights/dialogs/BatchUpdateCategoryDialog.vue';
import BatchDeleteDialog from '@/views/desktop/insights/dialogs/BatchDeleteDialog.vue';
import { ref, computed, useTemplateRef } from 'vue';
import { ref, computed, useTemplateRef, watch } from 'vue';
import { useI18n } from '@/locales/helpers.ts';
import { useExplorerDataTablePageBase } from '@/views/base/explorer/ExplorerDataTablePageBase.ts';
import { keys } from '@/core/base.ts';
import { CategoryType } from '@/core/category.ts';
import { TransactionType } from '@/core/transaction.ts';
import type { TransactionInsightDataItem } from '@/models/transaction.ts';
@@ -201,11 +210,13 @@ import {
mdiSelectAll,
mdiSelectInverse,
mdiMenuDown,
mdiTextBoxEditOutline
mdiTextBoxEditOutline,
mdiDeleteOutline
} from '@mdi/js';
type SnackBarType = InstanceType<typeof SnackBar>;
type BatchUpdateCategoryDialogType = InstanceType<typeof BatchUpdateCategoryDialog>;
type BatchDeleteDialogType = InstanceType<typeof BatchDeleteDialog>;
interface InsightsExplorerDataTableTabProps {
loading?: boolean;
@@ -221,6 +232,7 @@ const emit = defineEmits<{
const snackbar = useTemplateRef<SnackBarType>('snackbar');
const batchUpdateCategoryDialog = useTemplateRef<BatchUpdateCategoryDialogType>('batchUpdateCategoryDialog');
const batchDeleteDialog = useTemplateRef<BatchDeleteDialogType>('batchDeleteDialog');
const {
tt,
@@ -305,8 +317,8 @@ function selectInvert(): void {
function batchUpdateTransactionCategories(type: CategoryType): void {
batchUpdateCategoryDialog.value?.open({
type: type,
updateIds: getAllSelectedTransactionIds() }
).then(updatedCount => {
updateIds: getAllSelectedTransactionIds()
}).then(updatedCount => {
if (updatedCount > 0) {
snackbar.value?.showMessage('format.misc.youHaveUpdatedTransactions', {
count: formatNumberToLocalizedNumerals(updatedCount)
@@ -315,15 +327,48 @@ function batchUpdateTransactionCategories(type: CategoryType): void {
selectedTransactions.value = {};
emit('update:transactions');
}).catch(error => {
if (!error.processed) {
if (error) {
snackbar.value?.showError(error);
}
});
}
function batchDeleteTransactions(): void {
batchDeleteDialog.value?.open({
updateIds: getAllSelectedTransactionIds()
}).then(updatedCount => {
if (updatedCount > 0) {
snackbar.value?.showMessage('format.misc.youHaveDeletedTransactions', {
count: formatNumberToLocalizedNumerals(updatedCount)
});
}
selectedTransactions.value = {};
emit('update:transactions');
}).catch(error => {
if (error) {
snackbar.value?.showError(error);
}
emit('update:transactions');
});
}
function showTransaction(transaction: TransactionInsightDataItem): void {
emit('click:transaction', transaction);
}
watch(() => filteredTransactions.value, newValue => {
const allAvailableTransactionIds: Record<string, boolean> = {};
for (const transaction of newValue) {
allAvailableTransactionIds[transaction.id] = true;
}
for (const transactionId of keys(selectedTransactions.value)) {
if (!allAvailableTransactionIds[transactionId]) {
delete selectedTransactions.value[transactionId];
}
}
});
</script>
<style>