show process when importing a lot of transactions

This commit is contained in:
MaysWind
2025-05-01 01:00:11 +08:00
parent 20b65fd885
commit b7973772b3
20 changed files with 210 additions and 19 deletions
+1
View File
@@ -319,6 +319,7 @@ func startWebServer(c *core.CliContext) error {
apiV1Route.POST("/transactions/parse_dsv_file.json", bindApi(api.Transactions.TransactionParseImportDsvFileDataHandler)) apiV1Route.POST("/transactions/parse_dsv_file.json", bindApi(api.Transactions.TransactionParseImportDsvFileDataHandler))
apiV1Route.POST("/transactions/parse_import.json", bindApi(api.Transactions.TransactionParseImportFileHandler)) apiV1Route.POST("/transactions/parse_import.json", bindApi(api.Transactions.TransactionParseImportFileHandler))
apiV1Route.POST("/transactions/import.json", bindApi(api.Transactions.TransactionImportHandler)) apiV1Route.POST("/transactions/import.json", bindApi(api.Transactions.TransactionImportHandler))
apiV1Route.GET("/transactions/import/process.json", bindApi(api.Transactions.TransactionImportProcessHandler))
} }
// Transaction Pictures // Transaction Pictures
+69 -6
View File
@@ -2,6 +2,7 @@ package api
import ( import (
"encoding/json" "encoding/json"
"fmt"
"io" "io"
"sort" "sort"
"strings" "strings"
@@ -1344,11 +1345,21 @@ func (a *TransactionsApi) TransactionImportHandler(c *core.WebContext) (any, *er
found, remark := a.GetSubmissionRemark(duplicatechecker.DUPLICATE_CHECKER_TYPE_IMPORT_TRANSACTIONS, uid, transactionImportReq.ClientSessionId) found, remark := a.GetSubmissionRemark(duplicatechecker.DUPLICATE_CHECKER_TYPE_IMPORT_TRANSACTIONS, uid, transactionImportReq.ClientSessionId)
if found { if found {
log.Infof(c, "[transactions.TransactionImportHandler] another \"%s\" transactions has been imported for user \"uid:%d\"", remark, uid) items := strings.Split(remark, ":")
count, err := utils.StringToInt(remark)
if err == nil { if len(items) >= 2 {
return count, nil if items[0] == "finished" {
log.Infof(c, "[transactions.TransactionImportHandler] another \"%s\" transactions has been imported for user \"uid:%d\"", items[1], uid)
count, err := utils.StringToInt(items[1])
if err == nil {
return count, nil
}
} else if items[0] == "processing" {
return nil, errs.ErrRepeatedRequest
}
} else {
log.Warnf(c, "[transactions.TransactionImportHandler] another transaction import task may be executing, but remark \"%s\" is invalid", remark)
} }
} }
} }
@@ -1422,7 +1433,9 @@ func (a *TransactionsApi) TransactionImportHandler(c *core.WebContext) (any, *er
newTransactions[i] = transaction newTransactions[i] = transaction
} }
err = a.transactions.BatchCreateTransactions(c, user.Uid, newTransactions, newTransactionTagIdsMap) err = a.transactions.BatchCreateTransactions(c, user.Uid, newTransactions, newTransactionTagIdsMap, func(currentProcess float64) {
a.SetSubmissionRemarkIfEnable(duplicatechecker.DUPLICATE_CHECKER_TYPE_IMPORT_TRANSACTIONS, uid, transactionImportReq.ClientSessionId, fmt.Sprintf("processing:%.2f", currentProcess))
})
count := len(newTransactions) count := len(newTransactions)
if err != nil { if err != nil {
@@ -1432,11 +1445,61 @@ func (a *TransactionsApi) TransactionImportHandler(c *core.WebContext) (any, *er
log.Infof(c, "[transactions.TransactionImportHandler] user \"uid:%d\" has imported %d transactions successfully", uid, count) log.Infof(c, "[transactions.TransactionImportHandler] user \"uid:%d\" has imported %d transactions successfully", uid, count)
a.SetSubmissionRemarkIfEnable(duplicatechecker.DUPLICATE_CHECKER_TYPE_IMPORT_TRANSACTIONS, uid, transactionImportReq.ClientSessionId, utils.IntToString(count)) a.SetSubmissionRemarkIfEnable(duplicatechecker.DUPLICATE_CHECKER_TYPE_IMPORT_TRANSACTIONS, uid, transactionImportReq.ClientSessionId, fmt.Sprintf("finished:%d", count))
return count, nil return count, nil
} }
// TransactionImportProcessHandler returns the process of specified transaction import task by request parameters for current user
func (a *TransactionsApi) TransactionImportProcessHandler(c *core.WebContext) (any, *errs.Error) {
var transactionImportProcessReq models.TransactionImportProcessRequest
err := c.ShouldBindQuery(&transactionImportProcessReq)
if err != nil {
log.Warnf(c, "[transactions.TransactionImportProcessHandler] parse request failed, because %s", err.Error())
return nil, errs.NewIncompleteOrIncorrectSubmissionError(err)
}
uid := c.GetCurrentUid()
if !a.CurrentConfig().EnableDuplicateSubmissionsCheck {
return nil, nil
}
found, remark := a.GetSubmissionRemark(duplicatechecker.DUPLICATE_CHECKER_TYPE_IMPORT_TRANSACTIONS, uid, transactionImportProcessReq.ClientSessionId)
if !found {
return nil, nil
}
items := strings.Split(remark, ":")
if len(items) < 2 {
return nil, nil
}
if items[0] == "finished" {
return 100, nil
} else if items[0] != "processing" {
return nil, nil
}
process, err := utils.StringToFloat64(items[1])
if err != nil {
log.Warnf(c, "[transactions.TransactionImportProcessHandler] parse process failed, because %s", err.Error())
return nil, nil
}
if process < 0 {
return nil, nil
} else if process >= 100 {
process = 100
}
return process, nil
}
func (a *TransactionsApi) filterTransactions(c *core.WebContext, uid int64, transactions []*models.Transaction, accountMap map[int64]*models.Account) []*models.Transaction { func (a *TransactionsApi) filterTransactions(c *core.WebContext, uid int64, transactions []*models.Transaction, accountMap map[int64]*models.Account) []*models.Transaction {
finalTransactions := make([]*models.Transaction, 0, len(transactions)) finalTransactions := make([]*models.Transaction, 0, len(transactions))
+1 -1
View File
@@ -810,7 +810,7 @@ func (l *UserDataCli) ImportTransaction(c *core.CliContext, username string, fil
return errs.ErrOperationFailed return errs.ErrOperationFailed
} }
err = l.transactions.BatchCreateTransactions(c, user.Uid, newTransactions, newTransactionTagIdsMap) err = l.transactions.BatchCreateTransactions(c, user.Uid, newTransactions, newTransactionTagIdsMap, nil)
if err != nil { if err != nil {
log.CliErrorf(c, "[user_data.ImportTransaction] failed to create transaction, because %s", err.Error()) log.CliErrorf(c, "[user_data.ImportTransaction] failed to create transaction, because %s", err.Error())
+4
View File
@@ -0,0 +1,4 @@
package core
// TaskProcessUpdateHandler represents the task process update handler
type TaskProcessUpdateHandler func(currentProcess float64)
+1
View File
@@ -26,6 +26,7 @@ var (
ErrUploadedFileEmpty = NewNormalError(NormalSubcategoryGlobal, 16, http.StatusBadRequest, "uploaded file is empty") ErrUploadedFileEmpty = NewNormalError(NormalSubcategoryGlobal, 16, http.StatusBadRequest, "uploaded file is empty")
ErrExceedMaxUploadFileSize = NewNormalError(NormalSubcategoryGlobal, 17, http.StatusBadRequest, "uploaded file size exceeds the maximum allowed size") ErrExceedMaxUploadFileSize = NewNormalError(NormalSubcategoryGlobal, 17, http.StatusBadRequest, "uploaded file size exceeds the maximum allowed size")
ErrFailureCountLimitReached = NewNormalError(NormalSubcategoryGlobal, 18, http.StatusBadRequest, "failure count exceeded maximum limit") ErrFailureCountLimitReached = NewNormalError(NormalSubcategoryGlobal, 18, http.StatusBadRequest, "failure count exceeded maximum limit")
ErrRepeatedRequest = NewNormalError(NormalSubcategoryGlobal, 19, http.StatusBadRequest, "repeated request")
) )
// GetParameterInvalidMessage returns specific error message for invalid parameter error // GetParameterInvalidMessage returns specific error message for invalid parameter error
+5
View File
@@ -149,6 +149,11 @@ type TransactionImportRequest struct {
ClientSessionId string `json:"clientSessionId"` ClientSessionId string `json:"clientSessionId"`
} }
// TransactionImportProcessRequest represents all parameters of transaction import process request
type TransactionImportProcessRequest struct {
ClientSessionId string `form:"client_session_id"`
}
// TransactionCountRequest represents transaction count request // TransactionCountRequest represents transaction count request
type TransactionCountRequest struct { type TransactionCountRequest struct {
Type TransactionDbType `form:"type" binding:"min=0,max=4"` Type TransactionDbType `form:"type" binding:"min=0,max=4"`
+11 -1
View File
@@ -2,6 +2,7 @@ package services
import ( import (
"fmt" "fmt"
"math"
"strings" "strings"
"time" "time"
@@ -260,8 +261,11 @@ func (s *TransactionService) CreateTransaction(c core.Context, transaction *mode
} }
// BatchCreateTransactions saves new transactions to database // BatchCreateTransactions saves new transactions to database
func (s *TransactionService) BatchCreateTransactions(c core.Context, uid int64, transactions []*models.Transaction, allTagIds map[int][]int64) error { func (s *TransactionService) BatchCreateTransactions(c core.Context, uid int64, transactions []*models.Transaction, allTagIds map[int][]int64, processHandler core.TaskProcessUpdateHandler) error {
now := time.Now().Unix() now := time.Now().Unix()
currentProcess := float64(0)
processUpdateStep := int(math.Max(100.0, float64(len(transactions)/100.0)))
needTransactionUuidCount := uint16(0) needTransactionUuidCount := uint16(0)
needTagIndexUuidCount := uint16(0) needTagIndexUuidCount := uint16(0)
@@ -366,6 +370,12 @@ func (s *TransactionService) BatchCreateTransactions(c core.Context, uid int64,
transactionTagIds := allTransactionTagIds[transaction.TransactionId] transactionTagIds := allTransactionTagIds[transaction.TransactionId]
err := s.doCreateTransaction(c, userDataDb, sess, transaction, transactionTagIndexes, transactionTagIds, nil, nil) err := s.doCreateTransaction(c, userDataDb, sess, transaction, transactionTagIndexes, transactionTagIds, nil, nil)
currentProcess = float64(i) / float64(len(transactions)) * 100
if processHandler != nil && i%processUpdateStep == 0 {
processHandler(currentProcess)
}
if err != nil { if err != nil {
transactionUnixTime := utils.GetUnixTimeFromTransactionTime(transaction.TransactionTime) transactionUnixTime := utils.GetUnixTimeFromTransactionTime(transaction.TransactionTime)
transactionTimeZone := time.FixedZone("Transaction Timezone", int(transaction.TimezoneUtcOffset)*60) transactionTimeZone := time.FixedZone("Transaction Timezone", int(transaction.TimezoneUtcOffset)*60)
+5
View File
@@ -483,6 +483,11 @@ export default {
timeout: DEFAULT_IMPORT_API_TIMEOUT timeout: DEFAULT_IMPORT_API_TIMEOUT
} as ApiRequestConfig); } as ApiRequestConfig);
}, },
getImportTransactionsProcess: (clientSessionId: string): ApiResponsePromise<number | null> => {
return axios.get<ApiResponse<number | null>>('v1/transactions/import/process.json?client_session_id=' + clientSessionId, {
ignoreError: true
} as ApiRequestConfig);
},
uploadTransactionPicture: ({ pictureFile, clientSessionId }: { pictureFile: File, clientSessionId?: string }): ApiResponsePromise<TransactionPictureInfoBasicResponse> => { uploadTransactionPicture: ({ pictureFile, clientSessionId }: { pictureFile: File, clientSessionId?: string }): ApiResponsePromise<TransactionPictureInfoBasicResponse> => {
return axios.postForm<ApiResponse<TransactionPictureInfoBasicResponse>>('v1/transaction/pictures/upload.json', { return axios.postForm<ApiResponse<TransactionPictureInfoBasicResponse>>('v1/transaction/pictures/upload.json', {
picture: pictureFile, picture: pictureFile,
+4 -1
View File
@@ -102,6 +102,7 @@
"selectedCount": "{count} von {totalCount} ausgewählt", "selectedCount": "{count} von {totalCount} ausgewählt",
"youHaveUpdatedTransactions": "Sie haben {count} Transaktionen aktualisiert", "youHaveUpdatedTransactions": "Sie haben {count} Transaktionen aktualisiert",
"confirmImportTransactions": "Sind Sie sicher, dass Sie {count} Transaktionen importieren möchten?", "confirmImportTransactions": "Sind Sie sicher, dass Sie {count} Transaktionen importieren möchten?",
"importingTransactions": "Importing ({process}%)",
"importTransactionResult": "Sie haben {count} Transaktionen erfolgreich importiert.", "importTransactionResult": "Sie haben {count} Transaktionen erfolgreich importiert.",
"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.", "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." "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."
@@ -1179,7 +1180,8 @@
"no files uploaded": "Keine Dateien hochgeladen", "no files uploaded": "Keine Dateien hochgeladen",
"uploaded file is empty": "Hochgeladene Datei ist leer", "uploaded file is empty": "Hochgeladene Datei ist leer",
"uploaded file size exceeds the maximum allowed size": "Hochgeladene Datei überschreitet die maximal zulässige Größe", "uploaded file size exceeds the maximum allowed size": "Hochgeladene Datei überschreitet die maximal zulässige Größe",
"failure count exceeded maximum limit": "Failure count exceeded maximum limit, please try again after some time" "failure count exceeded maximum limit": "Failure count exceeded maximum limit, please try again after some time",
"repeated request": "Repeated Request"
}, },
"parameter": { "parameter": {
"id": "ID", "id": "ID",
@@ -1689,6 +1691,7 @@
"Transaction amount format is not set": "Transaction amount format is not set", "Transaction amount format is not set": "Transaction amount format is not set",
"Cannot import invalid transactions": "Ungültige Transaktionen können nicht importiert werden", "Cannot import invalid transactions": "Ungültige Transaktionen können nicht importiert werden",
"Unable to parse import file": "Importdatei kann nicht geparst werden", "Unable to parse import file": "Importdatei kann nicht geparst werden",
"Unable to import transactions": "Unable to import transactions",
"Batch Replace Selected Expense Categories": "Ausgewählte Ausgabenkategorien im Batch ersetzen", "Batch Replace Selected Expense Categories": "Ausgewählte Ausgabenkategorien im Batch ersetzen",
"Batch Replace Selected Income Categories": "Ausgewählte Einnahmenkategorien im Batch ersetzen", "Batch Replace Selected Income Categories": "Ausgewählte Einnahmenkategorien im Batch ersetzen",
"Batch Replace Selected Transfer Categories": "Ausgewählte Überweisungskategorien im Batch ersetzen", "Batch Replace Selected Transfer Categories": "Ausgewählte Überweisungskategorien im Batch ersetzen",
+4 -1
View File
@@ -102,6 +102,7 @@
"selectedCount": "Selected {count} of {totalCount}", "selectedCount": "Selected {count} of {totalCount}",
"youHaveUpdatedTransactions": "You have updated {count} transactions", "youHaveUpdatedTransactions": "You have updated {count} transactions",
"confirmImportTransactions": "Are you sure you want to import {count} transactions?", "confirmImportTransactions": "Are you sure you want to import {count} transactions?",
"importingTransactions": "Importing ({process}%)",
"importTransactionResult": "You have imported {count} transactions successfully.", "importTransactionResult": "You have imported {count} transactions successfully.",
"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.", "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}" "resendValidationEmailTip": "If you don't receive the mail, please fill password again and click the button below to resend the validation mail to: {email}"
@@ -1179,7 +1180,8 @@
"no files uploaded": "No files uploaded", "no files uploaded": "No files uploaded",
"uploaded file is empty": "Uploaded file is empty", "uploaded file is empty": "Uploaded file is empty",
"uploaded file size exceeds the maximum allowed size": "Uploaded file size exceeds the maximum allowed size", "uploaded file size exceeds the maximum allowed size": "Uploaded file size exceeds the maximum allowed size",
"failure count exceeded maximum limit": "Failure count exceeded maximum limit, please try again after some time" "failure count exceeded maximum limit": "Failure count exceeded maximum limit, please try again after some time",
"repeated request": "Repeated Request"
}, },
"parameter": { "parameter": {
"id": "ID", "id": "ID",
@@ -1689,6 +1691,7 @@
"Transaction amount format is not set": "Transaction amount format is not set", "Transaction amount format is not set": "Transaction amount format is not set",
"Cannot import invalid transactions": "Cannot import invalid transactions", "Cannot import invalid transactions": "Cannot import invalid transactions",
"Unable to parse import file": "Unable to parse import file", "Unable to parse import file": "Unable to parse import file",
"Unable to import transactions": "Unable to import transactions",
"Batch Replace Selected Expense Categories": "Batch Replace Selected Expense Categories", "Batch Replace Selected Expense Categories": "Batch Replace Selected Expense Categories",
"Batch Replace Selected Income Categories": "Batch Replace Selected Income Categories", "Batch Replace Selected Income Categories": "Batch Replace Selected Income Categories",
"Batch Replace Selected Transfer Categories": "Batch Replace Selected Transfer Categories", "Batch Replace Selected Transfer Categories": "Batch Replace Selected Transfer Categories",
+4 -1
View File
@@ -101,6 +101,7 @@
"selectedCount": "Seleccionado {count} de {totalCount}", "selectedCount": "Seleccionado {count} de {totalCount}",
"youHaveUpdatedTransactions": "Has actualizado {count} transacciones", "youHaveUpdatedTransactions": "Has actualizado {count} transacciones",
"confirmImportTransactions": "¿Está seguro de que desea importar {count} transacciones?", "confirmImportTransactions": "¿Está seguro de que desea importar {count} transacciones?",
"importingTransactions": "Importing ({process}%)",
"importTransactionResult": "Ha importado {count} transacciones correctamente.", "importTransactionResult": "Ha importado {count} transacciones correctamente.",
"accountActivationAndResendValidationEmailTip": "El enlace de activación de la cuenta se envió a su dirección de correo electrónico: {email}. Si no recibe el correo, ingrese la contraseña nuevamente y haga clic en el botón a continuación para reenviar el correo de validación.", "accountActivationAndResendValidationEmailTip": "El enlace de activación de la cuenta se envió a su dirección de correo electrónico: {email}. Si no recibe el correo, ingrese la contraseña nuevamente y haga clic en el botón a continuación para reenviar el correo de validación.",
"resendValidationEmailTip": "Si no recibe el correo, complete nuevamente la contraseña y haga clic en el botón a continuación para reenviar el correo de validación a: {email}" "resendValidationEmailTip": "Si no recibe el correo, complete nuevamente la contraseña y haga clic en el botón a continuación para reenviar el correo de validación a: {email}"
@@ -1178,7 +1179,8 @@
"no files uploaded": "No se subieron archivos", "no files uploaded": "No se subieron archivos",
"uploaded file is empty": "El archivo subido está vacío", "uploaded file is empty": "El archivo subido está vacío",
"uploaded file size exceeds the maximum allowed size": "El tamaño del archivo cargado excede el tamaño máximo permitido", "uploaded file size exceeds the maximum allowed size": "El tamaño del archivo cargado excede el tamaño máximo permitido",
"failure count exceeded maximum limit": "Failure count exceeded maximum limit, please try again after some time" "failure count exceeded maximum limit": "Failure count exceeded maximum limit, please try again after some time",
"repeated request": "Repeated Request"
}, },
"parameter": { "parameter": {
"id": "IDENTIFICACIÓN", "id": "IDENTIFICACIÓN",
@@ -1688,6 +1690,7 @@
"Transaction amount format is not set": "Transaction amount format is not set", "Transaction amount format is not set": "Transaction amount format is not set",
"Cannot import invalid transactions": "No se pueden importar transacciones no válidas", "Cannot import invalid transactions": "No se pueden importar transacciones no válidas",
"Unable to parse import file": "No se puede analizar el archivo de importación", "Unable to parse import file": "No se puede analizar el archivo de importación",
"Unable to import transactions": "Unable to import transactions",
"Batch Replace Selected Expense Categories": "Reemplazar por lotes categorías de gastos seleccionadas", "Batch Replace Selected Expense Categories": "Reemplazar por lotes categorías de gastos seleccionadas",
"Batch Replace Selected Income Categories": "Reemplazo por lotes de categorías de ingresos seleccionadas", "Batch Replace Selected Income Categories": "Reemplazo por lotes de categorías de ingresos seleccionadas",
"Batch Replace Selected Transfer Categories": "Reemplazar por lotes las categorías de transferencia seleccionadas", "Batch Replace Selected Transfer Categories": "Reemplazar por lotes las categorías de transferencia seleccionadas",
+4 -1
View File
@@ -102,6 +102,7 @@
"selectedCount": "{count} selezionati su {totalCount}", "selectedCount": "{count} selezionati su {totalCount}",
"youHaveUpdatedTransactions": "Hai aggiornato {count} transazioni", "youHaveUpdatedTransactions": "Hai aggiornato {count} transazioni",
"confirmImportTransactions": "Sei sicuro di voler importare {count} transazioni?", "confirmImportTransactions": "Sei sicuro di voler importare {count} transazioni?",
"importingTransactions": "Importing ({process}%)",
"importTransactionResult": "Hai importato {count} transazioni.", "importTransactionResult": "Hai importato {count} transazioni.",
"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.", "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}" "resendValidationEmailTip": "Se non hai ricevuto la mail, inserisci nuovamente la password e premi il bottone per ritentare l'invio all'indirizzo: {email}"
@@ -1179,7 +1180,8 @@
"no files uploaded": "Nessun file caricato", "no files uploaded": "Nessun file caricato",
"uploaded file is empty": "Il file caricato è vuoto", "uploaded file is empty": "Il file caricato è vuoto",
"uploaded file size exceeds the maximum allowed size": "La dimensione del file caricato supera la dimensione massima consentita", "uploaded file size exceeds the maximum allowed size": "La dimensione del file caricato supera la dimensione massima consentita",
"failure count exceeded maximum limit": "Il conteggio dei fallimenti ha superato il limite massimo, riprova più tardi" "failure count exceeded maximum limit": "Il conteggio dei fallimenti ha superato il limite massimo, riprova più tardi",
"repeated request": "Repeated Request"
}, },
"parameter": { "parameter": {
"id": "ID", "id": "ID",
@@ -1689,6 +1691,7 @@
"Transaction amount format is not set": "Formato importo transazione non impostato", "Transaction amount format is not set": "Formato importo transazione non impostato",
"Cannot import invalid transactions": "Impossibile importare transazioni non valide", "Cannot import invalid transactions": "Impossibile importare transazioni non valide",
"Unable to parse import file": "Impossibile analizzare il file di importazione", "Unable to parse import file": "Impossibile analizzare il file di importazione",
"Unable to import transactions": "Unable to import transactions",
"Batch Replace Selected Expense Categories": "Sostituisci in blocco categorie di spesa selezionate", "Batch Replace Selected Expense Categories": "Sostituisci in blocco categorie di spesa selezionate",
"Batch Replace Selected Income Categories": "Sostituisci in blocco categorie di entrata selezionate", "Batch Replace Selected Income Categories": "Sostituisci in blocco categorie di entrata selezionate",
"Batch Replace Selected Transfer Categories": "Sostituisci in blocco categorie di trasferimento selezionate", "Batch Replace Selected Transfer Categories": "Sostituisci in blocco categorie di trasferimento selezionate",
+4 -1
View File
@@ -102,6 +102,7 @@
"selectedCount": "{count} / {totalCount}を選択", "selectedCount": "{count} / {totalCount}を選択",
"youHaveUpdatedTransactions": "{count}件の取引を更新しました", "youHaveUpdatedTransactions": "{count}件の取引を更新しました",
"confirmImportTransactions": "本当に{count}件の取引をインポートしますか?", "confirmImportTransactions": "本当に{count}件の取引をインポートしますか?",
"importingTransactions": "Importing ({process}%)",
"importTransactionResult": "{count}件の取引を正常にインポートしました。", "importTransactionResult": "{count}件の取引を正常にインポートしました。",
"accountActivationAndResendValidationEmailTip": "アカウントの有効化リンクがメールアドレスに送信されました:{email}、メールが届かない場合はパスワードをもう一度入力して下のボタンをクリックして認証メールを再送信してください。", "accountActivationAndResendValidationEmailTip": "アカウントの有効化リンクがメールアドレスに送信されました:{email}、メールが届かない場合はパスワードをもう一度入力して下のボタンをクリックして認証メールを再送信してください。",
"resendValidationEmailTip": "メールが届かない場合は、パスワードをもう一度入力の上、以下のボタンをクリックして検証メールを再送信してください: {email}" "resendValidationEmailTip": "メールが届かない場合は、パスワードをもう一度入力の上、以下のボタンをクリックして検証メールを再送信してください: {email}"
@@ -1179,7 +1180,8 @@
"no files uploaded": "アップロードされたファイルはありません", "no files uploaded": "アップロードされたファイルはありません",
"uploaded file is empty": "アップロードされたファイルは空です", "uploaded file is empty": "アップロードされたファイルは空です",
"uploaded file size exceeds the maximum allowed size": "アップロードされたファイルが最大許容サイズを超えています", "uploaded file size exceeds the maximum allowed size": "アップロードされたファイルが最大許容サイズを超えています",
"failure count exceeded maximum limit": "Failure count exceeded maximum limit, please try again after some time" "failure count exceeded maximum limit": "Failure count exceeded maximum limit, please try again after some time",
"repeated request": "Repeated Request"
}, },
"parameter": { "parameter": {
"id": "ID", "id": "ID",
@@ -1689,6 +1691,7 @@
"Transaction amount format is not set": "Transaction amount format is not set", "Transaction amount format is not set": "Transaction amount format is not set",
"Cannot import invalid transactions": "無効な取引をインポートできません", "Cannot import invalid transactions": "無効な取引をインポートできません",
"Unable to parse import file": "インポートファイルを解析できません", "Unable to parse import file": "インポートファイルを解析できません",
"Unable to import transactions": "Unable to import transactions",
"Batch Replace Selected Expense Categories": "バッチは選択した支出カテゴリを置き換えます", "Batch Replace Selected Expense Categories": "バッチは選択した支出カテゴリを置き換えます",
"Batch Replace Selected Income Categories": "バッチは選択した収入カテゴリを置き換えます", "Batch Replace Selected Income Categories": "バッチは選択した収入カテゴリを置き換えます",
"Batch Replace Selected Transfer Categories": "バッチは選択した振替カテゴリを置き換えます", "Batch Replace Selected Transfer Categories": "バッチは選択した振替カテゴリを置き換えます",
+4 -1
View File
@@ -102,6 +102,7 @@
"selectedCount": "Выбрано {count} из {totalCount}", "selectedCount": "Выбрано {count} из {totalCount}",
"youHaveUpdatedTransactions": "Вы обновили {count} транзакций", "youHaveUpdatedTransactions": "Вы обновили {count} транзакций",
"confirmImportTransactions": "Вы уверены, что хотите импортировать {count} транзакций?", "confirmImportTransactions": "Вы уверены, что хотите импортировать {count} транзакций?",
"importingTransactions": "Importing ({process}%)",
"importTransactionResult": "Вы успешно импортировали {count} транзакций.", "importTransactionResult": "Вы успешно импортировали {count} транзакций.",
"accountActivationAndResendValidationEmailTip": "Ссылка для активации учетной записи была отправлена на ваш электронный адрес: {email}. Если вы не получили письмо, заполните пароль снова и нажмите кнопку ниже, чтобы отправить письмо повторно.", "accountActivationAndResendValidationEmailTip": "Ссылка для активации учетной записи была отправлена на ваш электронный адрес: {email}. Если вы не получили письмо, заполните пароль снова и нажмите кнопку ниже, чтобы отправить письмо повторно.",
"resendValidationEmailTip": "Если вы не получили письмо, заполните пароль снова и нажмите кнопку ниже, чтобы отправить письмо повторно на: {email}" "resendValidationEmailTip": "Если вы не получили письмо, заполните пароль снова и нажмите кнопку ниже, чтобы отправить письмо повторно на: {email}"
@@ -1179,7 +1180,8 @@
"no files uploaded": "Файлы не загружены", "no files uploaded": "Файлы не загружены",
"uploaded file is empty": "Загруженный файл пуст", "uploaded file is empty": "Загруженный файл пуст",
"uploaded file size exceeds the maximum allowed size": "Размер загруженного файла превышает максимально допустимый размер", "uploaded file size exceeds the maximum allowed size": "Размер загруженного файла превышает максимально допустимый размер",
"failure count exceeded maximum limit": "Failure count exceeded maximum limit, please try again after some time" "failure count exceeded maximum limit": "Failure count exceeded maximum limit, please try again after some time",
"repeated request": "Repeated Request"
}, },
"parameter": { "parameter": {
"id": "ID", "id": "ID",
@@ -1689,6 +1691,7 @@
"Transaction amount format is not set": "Transaction amount format is not set", "Transaction amount format is not set": "Transaction amount format is not set",
"Cannot import invalid transactions": "Невозможно импортировать недействительные транзакции", "Cannot import invalid transactions": "Невозможно импортировать недействительные транзакции",
"Unable to parse import file": "Не удалось обработать файл импорта", "Unable to parse import file": "Не удалось обработать файл импорта",
"Unable to import transactions": "Unable to import transactions",
"Batch Replace Selected Expense Categories": "Пакетная замена выбранных категорий расходов", "Batch Replace Selected Expense Categories": "Пакетная замена выбранных категорий расходов",
"Batch Replace Selected Income Categories": "Пакетная замена выбранных категорий доходов", "Batch Replace Selected Income Categories": "Пакетная замена выбранных категорий доходов",
"Batch Replace Selected Transfer Categories": "Пакетная замена выбранных категорий переводов", "Batch Replace Selected Transfer Categories": "Пакетная замена выбранных категорий переводов",
+4 -1
View File
@@ -102,6 +102,7 @@
"selectedCount": "Вибрано {count} з {totalCount}", "selectedCount": "Вибрано {count} з {totalCount}",
"youHaveUpdatedTransactions": "Ви оновили {count} транзакцій", "youHaveUpdatedTransactions": "Ви оновили {count} транзакцій",
"confirmImportTransactions": "Ви впевнені, що хочете імпортувати {count} транзакцій?", "confirmImportTransactions": "Ви впевнені, що хочете імпортувати {count} транзакцій?",
"importingTransactions": "Importing ({process}%)",
"importTransactionResult": "Ви успішно імпортували {count} транзакцій.", "importTransactionResult": "Ви успішно імпортували {count} транзакцій.",
"accountActivationAndResendValidationEmailTip": "Посилання для активації облікового запису було надіслано на вашу електронну адресу: {email}. Якщо ви не отримали лист, введіть пароль ще раз і натисніть кнопку нижче, щоб надіслати лист повторно.", "accountActivationAndResendValidationEmailTip": "Посилання для активації облікового запису було надіслано на вашу електронну адресу: {email}. Якщо ви не отримали лист, введіть пароль ще раз і натисніть кнопку нижче, щоб надіслати лист повторно.",
"resendValidationEmailTip": "Якщо ви не отримали лист, введіть пароль ще раз і натисніть кнопку нижче, щоб надіслати лист повторно на адресу: {email}" "resendValidationEmailTip": "Якщо ви не отримали лист, введіть пароль ще раз і натисніть кнопку нижче, щоб надіслати лист повторно на адресу: {email}"
@@ -1179,7 +1180,8 @@
"no files uploaded": "Файли не завантажено", "no files uploaded": "Файли не завантажено",
"uploaded file is empty": "Завантажений файл порожній", "uploaded file is empty": "Завантажений файл порожній",
"uploaded file size exceeds the maximum allowed size": "Розмір завантаженого файлу перевищує максимально допустимий", "uploaded file size exceeds the maximum allowed size": "Розмір завантаженого файлу перевищує максимально допустимий",
"failure count exceeded maximum limit": "Кількість невдали спроб перевищила допустимий ліміт, спробуйте пізніше" "failure count exceeded maximum limit": "Кількість невдали спроб перевищила допустимий ліміт, спробуйте пізніше",
"repeated request": "Repeated Request"
}, },
"parameter": { "parameter": {
"id": "ID", "id": "ID",
@@ -1689,6 +1691,7 @@
"Transaction amount format is not set": "Не вказано формат суми транзакцій", "Transaction amount format is not set": "Не вказано формат суми транзакцій",
"Cannot import invalid transactions": "Неможливо імпортувати недійсні транзакції", "Cannot import invalid transactions": "Неможливо імпортувати недійсні транзакції",
"Unable to parse import file": "Не вдалося обробити файл імпорту", "Unable to parse import file": "Не вдалося обробити файл імпорту",
"Unable to import transactions": "Unable to import transactions",
"Batch Replace Selected Expense Categories": "Пакетна заміна вибраних категорій витрат", "Batch Replace Selected Expense Categories": "Пакетна заміна вибраних категорій витрат",
"Batch Replace Selected Income Categories": "Пакетна заміна вибраних категорій доходів", "Batch Replace Selected Income Categories": "Пакетна заміна вибраних категорій доходів",
"Batch Replace Selected Transfer Categories": "Пакетна заміна вибраних категорій переказів", "Batch Replace Selected Transfer Categories": "Пакетна заміна вибраних категорій переказів",
+4 -1
View File
@@ -102,6 +102,7 @@
"selectedCount": "Đã chọn {count} trên {totalCount}", "selectedCount": "Đã chọn {count} trên {totalCount}",
"youHaveUpdatedTransactions": "Bạn đã cập nhật {count} giao dịch", "youHaveUpdatedTransactions": "Bạn đã cập nhật {count} giao dịch",
"confirmImportTransactions": "Bạn có chắc chắn muốn nhập {count} giao dịch không?", "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.", "importTransactionResult": "Bạn đã nhập thành công {count} giao dịch.",
"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.", "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}" "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}"
@@ -1179,7 +1180,8 @@
"no files uploaded": "Không có tệp nào được tải lên", "no files uploaded": "Không có tệp nào được tải lên",
"uploaded file is empty": "Tệp đã tải lên trống", "uploaded file is empty": "Tệp đã tải lên trống",
"uploaded file size exceeds the maximum allowed size": "Kích thước tệp đã tải lên vượt quá kích thước tối đa cho phép", "uploaded file size exceeds the maximum allowed size": "Kích thước tệp đã tải lên vượt quá kích thước tối đa cho phép",
"failure count exceeded maximum limit": "Failure count exceeded maximum limit, please try again after some time" "failure count exceeded maximum limit": "Failure count exceeded maximum limit, please try again after some time",
"repeated request": "Repeated Request"
}, },
"parameter": { "parameter": {
"id": "ID", "id": "ID",
@@ -1689,6 +1691,7 @@
"Transaction amount format is not set": "Transaction amount format is not set", "Transaction amount format is not set": "Transaction amount format is not set",
"Cannot import invalid transactions": "Không thể nhập giao dịch không hợp lệ", "Cannot import invalid transactions": "Không thể nhập giao dịch không hợp lệ",
"Unable to parse import file": "Không thể phân tích tệp nhập", "Unable to parse import file": "Không thể phân tích tệp nhập",
"Unable to import transactions": "Unable to import transactions",
"Batch Replace Selected Expense Categories": "Thay thế hàng loạt các danh mục chi phí đã chọn", "Batch Replace Selected Expense Categories": "Thay thế hàng loạt các danh mục chi phí đã chọn",
"Batch Replace Selected Income Categories": "Thay thế hàng loạt các danh mục thu nhập đã chọn", "Batch Replace Selected Income Categories": "Thay thế hàng loạt các danh mục thu nhập đã chọn",
"Batch Replace Selected Transfer Categories": "Thay thế hàng loạt các danh mục chuyển khoản đã chọn", "Batch Replace Selected Transfer Categories": "Thay thế hàng loạt các danh mục chuyển khoản đã chọn",
+4 -1
View File
@@ -102,6 +102,7 @@
"selectedCount": "已选择 {count} / {totalCount}", "selectedCount": "已选择 {count} / {totalCount}",
"youHaveUpdatedTransactions": "您已经更新 {count} 个交易", "youHaveUpdatedTransactions": "您已经更新 {count} 个交易",
"confirmImportTransactions": "您确定要导入 {count} 个交易?", "confirmImportTransactions": "您确定要导入 {count} 个交易?",
"importingTransactions": "正在导入 ({process}%)",
"importTransactionResult": "您已经成功导入 {count} 个交易。", "importTransactionResult": "您已经成功导入 {count} 个交易。",
"accountActivationAndResendValidationEmailTip": "账号激活链接已经发送到您的邮箱地址:{email},如果您没有收到邮件,请再次输入密码并点击下方的按钮重新发送验证邮件。", "accountActivationAndResendValidationEmailTip": "账号激活链接已经发送到您的邮箱地址:{email},如果您没有收到邮件,请再次输入密码并点击下方的按钮重新发送验证邮件。",
"resendValidationEmailTip": "如果您没有收到邮件,请再次输入密码并点击下方的按钮重新发送验证邮件到:{email}" "resendValidationEmailTip": "如果您没有收到邮件,请再次输入密码并点击下方的按钮重新发送验证邮件到:{email}"
@@ -1179,7 +1180,8 @@
"no files uploaded": "没有上传文件", "no files uploaded": "没有上传文件",
"uploaded file is empty": "上传的文件为空", "uploaded file is empty": "上传的文件为空",
"uploaded file size exceeds the maximum allowed size": "上传的文件大小超出了允许的最大大小", "uploaded file size exceeds the maximum allowed size": "上传的文件大小超出了允许的最大大小",
"failure count exceeded maximum limit": "失败次数超出最大限制,请稍后重试" "failure count exceeded maximum limit": "失败次数超出最大限制,请稍后重试",
"repeated request": "重复的请求"
}, },
"parameter": { "parameter": {
"id": "ID", "id": "ID",
@@ -1689,6 +1691,7 @@
"Transaction amount format is not set": "交易金额格式没有设置", "Transaction amount format is not set": "交易金额格式没有设置",
"Cannot import invalid transactions": "不能导入无效的交易", "Cannot import invalid transactions": "不能导入无效的交易",
"Unable to parse import file": "无法解析导入的文件", "Unable to parse import file": "无法解析导入的文件",
"Unable to import transactions": "无法导入交易",
"Batch Replace Selected Expense Categories": "批量替换选中的支出分类", "Batch Replace Selected Expense Categories": "批量替换选中的支出分类",
"Batch Replace Selected Income Categories": "批量替换选中的收入分类", "Batch Replace Selected Income Categories": "批量替换选中的收入分类",
"Batch Replace Selected Transfer Categories": "批量替换选中的转账分类", "Batch Replace Selected Transfer Categories": "批量替换选中的转账分类",
+4 -1
View File
@@ -102,6 +102,7 @@
"selectedCount": "已選擇 {count} / {totalCount}", "selectedCount": "已選擇 {count} / {totalCount}",
"youHaveUpdatedTransactions": "您已經更新 {count} 個交易", "youHaveUpdatedTransactions": "您已經更新 {count} 個交易",
"confirmImportTransactions": "您確定要匯入 {count} 個交易?", "confirmImportTransactions": "您確定要匯入 {count} 個交易?",
"importingTransactions": "正在匯入 ({process}%)",
"importTransactionResult": "您已經成功匯入 {count} 個交易。", "importTransactionResult": "您已經成功匯入 {count} 個交易。",
"accountActivationAndResendValidationEmailTip": "帳號啟用連結已經傳送到您的信箱地址:{email},如果您沒有收到郵件,請再次輸入密碼並點擊下方的按鈕重新發送驗證郵件。", "accountActivationAndResendValidationEmailTip": "帳號啟用連結已經傳送到您的信箱地址:{email},如果您沒有收到郵件,請再次輸入密碼並點擊下方的按鈕重新發送驗證郵件。",
"resendValidationEmailTip": "如果您沒有收到郵件,請再次輸入密碼並點擊下方的按鈕重新發送驗證郵件到:{email}" "resendValidationEmailTip": "如果您沒有收到郵件,請再次輸入密碼並點擊下方的按鈕重新發送驗證郵件到:{email}"
@@ -1179,7 +1180,8 @@
"no files uploaded": "沒有上傳檔案", "no files uploaded": "沒有上傳檔案",
"uploaded file is empty": "上傳的檔案為空", "uploaded file is empty": "上傳的檔案為空",
"uploaded file size exceeds the maximum allowed size": "上傳的檔案大小超出了允許的最大大小", "uploaded file size exceeds the maximum allowed size": "上傳的檔案大小超出了允許的最大大小",
"failure count exceeded maximum limit": "失敗次數超出最大限制,請稍後重試" "failure count exceeded maximum limit": "失敗次數超出最大限制,請稍後重試",
"repeated request": "重複的請求"
}, },
"parameter": { "parameter": {
"id": "ID", "id": "ID",
@@ -1689,6 +1691,7 @@
"Transaction amount format is not set": "交易金額格式沒有設定", "Transaction amount format is not set": "交易金額格式沒有設定",
"Cannot import invalid transactions": "無法匯入無效的交易", "Cannot import invalid transactions": "無法匯入無效的交易",
"Unable to parse import file": "無法解析匯入的檔案", "Unable to parse import file": "無法解析匯入的檔案",
"Unable to import transactions": "無法匯入交易",
"Batch Replace Selected Expense Categories": "批次替換選中的支出分類", "Batch Replace Selected Expense Categories": "批次替換選中的支出分類",
"Batch Replace Selected Income Categories": "批次替換選中的收入分類", "Batch Replace Selected Income Categories": "批次替換選中的收入分類",
"Batch Replace Selected Transfer Categories": "批次替換選中的轉帳分類", "Batch Replace Selected Transfer Categories": "批次替換選中的轉帳分類",
+26
View File
@@ -1143,6 +1143,31 @@ export const useTransactionsStore = defineStore('transactions', () => {
}); });
} }
function getImportTransactionsProcess({ clientSessionId }: { clientSessionId: string }): Promise<number | null> {
return new Promise((resolve, reject) => {
services.getImportTransactionsProcess(clientSessionId).then(response => {
const data = response.data;
if (!data || !data.success || !data.result) {
reject({ message: 'Unable to get transactions import process' });
return;
}
resolve(data.result);
}).catch(error => {
logger.error('Unable to get transactions import process', error);
if (error.response && error.response.data && error.response.data.errorMessage) {
reject({ error: error.response.data });
} else if (!error.processed) {
reject({ message: 'Unable to get transactions import process' });
} else {
reject(error);
}
});
});
}
function uploadTransactionPicture({ pictureFile, clientSessionId }: { pictureFile: File, clientSessionId?: string }): Promise<TransactionPictureInfoBasicResponse> { function uploadTransactionPicture({ pictureFile, clientSessionId }: { pictureFile: File, clientSessionId?: string }): Promise<TransactionPictureInfoBasicResponse> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
services.uploadTransactionPicture({ pictureFile, clientSessionId }).then(response => { services.uploadTransactionPicture({ pictureFile, clientSessionId }).then(response => {
@@ -1243,6 +1268,7 @@ export const useTransactionsStore = defineStore('transactions', () => {
parseImportDsvFile, parseImportDsvFile,
parseImportTransaction, parseImportTransaction,
importTransactions, importTransactions,
getImportTransactionsProcess,
uploadTransactionPicture, uploadTransactionPicture,
removeUnusedTransactionPicture, removeUnusedTransactionPicture,
getTransactionPictureUrl, getTransactionPictureUrl,
@@ -786,7 +786,7 @@
<v-btn color="teal" :disabled="submitting || !!editingTransaction || selectedImportTransactionCount < 1 || selectedInvalidTransactionCount > 0" <v-btn color="teal" :disabled="submitting || !!editingTransaction || selectedImportTransactionCount < 1 || selectedInvalidTransactionCount > 0"
:append-icon="!submitting ? mdiArrowRight : undefined" @click="submit" :append-icon="!submitting ? mdiArrowRight : undefined" @click="submit"
v-if="currentStep === 'checkData'"> v-if="currentStep === 'checkData'">
{{ tt('Import') }} {{ (submitting && importProcess > 0 ? tt('format.misc.importingTransactions', { process: importProcess.toFixed(2) }) : tt('Import')) }}
<v-progress-circular indeterminate size="22" class="ml-2" v-if="submitting"></v-progress-circular> <v-progress-circular indeterminate size="22" class="ml-2" v-if="submitting"></v-progress-circular>
</v-btn> </v-btn>
<v-btn color="secondary" variant="tonal" <v-btn color="secondary" variant="tonal"
@@ -969,6 +969,7 @@ const fileInput = useTemplateRef<HTMLInputElement>('fileInput');
const showState = ref<boolean>(false); const showState = ref<boolean>(false);
const clientSessionId = ref<string>(''); const clientSessionId = ref<string>('');
const currentStep = ref<ImportTransactionDialogStep>('uploadFile'); const currentStep = ref<ImportTransactionDialogStep>('uploadFile');
const importProcess = ref<number>(0);
const fileType = ref<string>('ezbookkeeping'); const fileType = ref<string>('ezbookkeeping');
const fileSubType = ref<string>('ezbookkeeping_csv'); const fileSubType = ref<string>('ezbookkeeping_csv');
const fileEncoding = ref<string>('utf-8'); const fileEncoding = ref<string>('utf-8');
@@ -1927,6 +1928,7 @@ function open(): Promise<void> {
fileSubType.value = 'ezbookkeeping_csv'; fileSubType.value = 'ezbookkeeping_csv';
fileEncoding.value = 'utf-8'; fileEncoding.value = 'utf-8';
currentStep.value = 'uploadFile'; currentStep.value = 'uploadFile';
importProcess.value = 0;
importFile.value = null; importFile.value = null;
importData.value = ''; importData.value = '';
parsedFileData.value = undefined; parsedFileData.value = undefined;
@@ -2221,10 +2223,48 @@ function submit(): void {
editingTags.value = []; editingTags.value = [];
submitting.value = true; submitting.value = true;
let showProcessTimer : number | undefined = undefined;
if (transactions.length > 100) {
setTimeout(() => {
if (!submitting.value) {
logger.warn('transaction import is not submitting');
return;
}
// @ts-expect-error the return value of setInterval is number, but lint shows it as NodeJS.Timer
showProcessTimer = setInterval(() => {
if (submitting.value) {
transactionsStore.getImportTransactionsProcess({
clientSessionId: clientSessionId.value
}).then(response => {
if (isNumber(response) && 0 <= response && response < 100) {
importProcess.value = response;
} else {
importProcess.value = 0;
clearInterval(showProcessTimer);
showProcessTimer = undefined;
}
}).catch(() => {
importProcess.value = 0;
clearInterval(showProcessTimer);
showProcessTimer = undefined;
});
}
}, 2000);
}, 2000);
}
transactionsStore.importTransactions({ transactionsStore.importTransactions({
transactions: transactions, transactions: transactions,
clientSessionId: clientSessionId.value clientSessionId: clientSessionId.value
}).then(response => { }).then(response => {
if (showProcessTimer) {
importProcess.value = 0;
clearInterval(showProcessTimer);
showProcessTimer = undefined;
}
importedCount.value = response; importedCount.value = response;
currentStep.value = 'finalResult'; currentStep.value = 'finalResult';
@@ -2235,6 +2275,12 @@ function submit(): void {
submitting.value = false; submitting.value = false;
}).catch(error => { }).catch(error => {
if (showProcessTimer) {
importProcess.value = 0;
clearInterval(showProcessTimer);
showProcessTimer = undefined;
}
submitting.value = false; submitting.value = false;
if (!error.processed) { if (!error.processed) {