From 02a4784e586af24233f0e2721fe31821e1fee51a Mon Sep 17 00:00:00 2001 From: "saito.k" Date: Fri, 15 Mar 2024 00:15:01 +0000 Subject: [PATCH 1/7] =?UTF-8?q?Merged=20PR=20836:=20=E7=BF=BB=E8=A8=B3?= =?UTF-8?q?=E6=83=85=E5=A0=B1=E3=81=AE=E5=8F=8D=E6=98=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task3908: 翻訳情報の反映](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3908) - 翻訳情報の反映 - 修正したのは、licenseNotAssignedErrorのピリオドの後にスペースを入れた部分です。 ## レビューポイント - 特になし ## UIの変更 - Before/Afterのスクショなど - スクショ置き場 ## クエリの変更 - なし ## 動作確認状況 - ローカルで確認、develop環境で確認など - リテラルの修正だけのためほか機能への影響はなし ## 補足 - 相談、参考資料などがあれば --- dictation_client/src/translation/de.json | 22 +++++++++++++++++++--- dictation_client/src/translation/en.json | 22 +++++++++++++++++++--- dictation_client/src/translation/es.json | 22 +++++++++++++++++++--- dictation_client/src/translation/fr.json | 22 +++++++++++++++++++--- 4 files changed, 76 insertions(+), 12 deletions(-) diff --git a/dictation_client/src/translation/de.json b/dictation_client/src/translation/de.json index 9a7af9d..b749dd4 100644 --- a/dictation_client/src/translation/de.json +++ b/dictation_client/src/translation/de.json @@ -252,8 +252,9 @@ "backupFailedError": "Der Prozess „Dateisicherung“ ist fehlgeschlagen. Bitte versuchen Sie es später noch einmal. Wenn der Fehler weiterhin besteht, wenden Sie sich an Ihren Systemadministrator.", "cancelFailedError": "Die Diktate konnten nicht gelöscht werden. Bitte aktualisieren Sie Ihren Bildschirm und versuchen Sie es erneut.", "deleteFailedError": "(de)タスクの削除に失敗しました。画面を更新し、再度ご確認ください。", - "licenseNotAssignedError": "Die Transkription ist nicht möglich, da keine gültige Lizenz zugewiesen ist.Bitten Sie Ihren Administrator, eine gültige Lizenz zuzuweisen.", - "licenseExpiredError": "Die Transkription ist nicht möglich, da Ihre Lizenz abgelaufen ist. Bitte bitten Sie Ihren Administrator, Ihnen eine gültige Lizenz zuzuweisen." + "licenseNotAssignedError": "Die Transkription ist nicht möglich, da keine gültige Lizenz zugewiesen ist. Bitten Sie Ihren Administrator, eine gültige Lizenz zuzuweisen.", + "licenseExpiredError": "Die Transkription ist nicht möglich, da Ihre Lizenz abgelaufen ist. Bitte bitten Sie Ihren Administrator, Ihnen eine gültige Lizenz zuzuweisen.", + "fileAlreadyDeletedError": "(de)既に削除された音声ファイルが含まれています。画面を更新し、再度ご確認ください" }, "label": { "title": "Diktate", @@ -368,7 +369,8 @@ "shortage": "Lizenzmangel", "issueRequesting": "Lizenzen auf Bestellung", "viewDetails": "Details anzeigen", - "accounts": "konten" + "accounts": "konten", + "changeOwnerButton": "(de)Change Owner" } }, "orderHistoriesPage": { @@ -619,5 +621,19 @@ "saveButton": "(de)Save Settings", "daysValidationError": "(de)Daysには1~999の数字を入力してください。" } + }, + "changeOwnerPopup": { + "message": { + "accountNotFoundError": "(de)変更先のアカウントIDは存在しません。", + "hierarchyMismatchError": "(de)パートナーアカウントの変更に失敗しました。\n子アカウントの1階層上のアカウントを切り替え先に指定してください。", + "regionMismatchError": "(de)パートナーアカウントの変更に失敗しました。\n子アカウントと同じリージョンのアカウントを切り替え先に指定してください。", + "countryMismatchError": "(de)パートナーアカウントの変更に失敗しました。\n子アカウントと同じ国のアカウントを切り替え先に指定してください。" + }, + "label": { + "invalidInputError": "(de)変更先アカウントIDには1~9999999の数字を入力してください。", + "title": "(de)Change Owner", + "upperLayerId": "(de)Upper Layer ID", + "lowerLayerId": "(de)Lower Layer ID" + } } } \ No newline at end of file diff --git a/dictation_client/src/translation/en.json b/dictation_client/src/translation/en.json index 7b91390..310dab6 100644 --- a/dictation_client/src/translation/en.json +++ b/dictation_client/src/translation/en.json @@ -252,8 +252,9 @@ "backupFailedError": "The \"File Backup\" process has failed. Please try again later. If the error continues, contact your system administrator.", "cancelFailedError": "Failed to delete the dictations. Please refresh your screen and try again.", "deleteFailedError": "タスクの削除に失敗しました。画面を更新し、再度ご確認ください。", - "licenseNotAssignedError": "Transcription is not possible because a valid license is not assigned.Please ask your administrator to assign a valid license.", - "licenseExpiredError": "Transcription is not possible because your license is expired. Please ask your administrator to assign a valid license." + "licenseNotAssignedError": "Transcription is not possible because a valid license is not assigned. Please ask your administrator to assign a valid license.", + "licenseExpiredError": "Transcription is not possible because your license is expired. Please ask your administrator to assign a valid license.", + "fileAlreadyDeletedError": "既に削除された音声ファイルが含まれています。画面を更新し、再度ご確認ください" }, "label": { "title": "Dictations", @@ -368,7 +369,8 @@ "shortage": "License Shortage", "issueRequesting": "Licenses on Order", "viewDetails": "View Details", - "accounts": "accounts" + "accounts": "accounts", + "changeOwnerButton": "Change Owner" } }, "orderHistoriesPage": { @@ -619,5 +621,19 @@ "saveButton": "Save Settings", "daysValidationError": "Daysには1~999の数字を入力してください。" } + }, + "changeOwnerPopup": { + "message": { + "accountNotFoundError": "変更先のアカウントIDは存在しません。", + "hierarchyMismatchError": "パートナーアカウントの変更に失敗しました。\n子アカウントの1階層上のアカウントを切り替え先に指定してください。", + "regionMismatchError": "パートナーアカウントの変更に失敗しました。\n子アカウントと同じリージョンのアカウントを切り替え先に指定してください。", + "countryMismatchError": "パートナーアカウントの変更に失敗しました。\n子アカウントと同じ国のアカウントを切り替え先に指定してください。" + }, + "label": { + "invalidInputError": "変更先アカウントIDには1~9999999の数字を入力してください。", + "title": "Change Owner", + "upperLayerId": "Upper Layer ID", + "lowerLayerId": "Lower Layer ID" + } } } \ No newline at end of file diff --git a/dictation_client/src/translation/es.json b/dictation_client/src/translation/es.json index 4dd9b29..1ac861b 100644 --- a/dictation_client/src/translation/es.json +++ b/dictation_client/src/translation/es.json @@ -252,8 +252,9 @@ "backupFailedError": "El proceso de \"Copia de seguridad de archivos\" ha fallado. Por favor, inténtelo de nuevo más tarde. Si el error continúa, comuníquese con el administrador del sistema.", "cancelFailedError": "No se pudieron eliminar los dictados. Actualice su pantalla e inténtelo nuevamente.", "deleteFailedError": "(es)タスクの削除に失敗しました。画面を更新し、再度ご確認ください。", - "licenseNotAssignedError": "La transcripción no es posible porque no se ha asignado una licencia válida.Solicite a su administrador que le asigne una licencia válida.", - "licenseExpiredError": "La transcripción no es posible porque su licencia ha caducado. Solicite a su administrador que le asigne una licencia válida." + "licenseNotAssignedError": "La transcripción no es posible porque no se ha asignado una licencia válida. Solicite a su administrador que le asigne una licencia válida.", + "licenseExpiredError": "La transcripción no es posible porque su licencia ha caducado. Solicite a su administrador que le asigne una licencia válida.", + "fileAlreadyDeletedError": "(es)既に削除された音声ファイルが含まれています。画面を更新し、再度ご確認ください" }, "label": { "title": "Dictado", @@ -368,7 +369,8 @@ "shortage": "Escasez de licencias", "issueRequesting": "Licencias en Pedido", "viewDetails": "Ver detalles", - "accounts": "cuentas" + "accounts": "cuentas", + "changeOwnerButton": "(es)Change Owner" } }, "orderHistoriesPage": { @@ -619,5 +621,19 @@ "saveButton": "(es)Save Settings", "daysValidationError": "(es)Daysには1~999の数字を入力してください。" } + }, + "changeOwnerPopup": { + "message": { + "accountNotFoundError": "(es)変更先のアカウントIDは存在しません。", + "hierarchyMismatchError": "(es)パートナーアカウントの変更に失敗しました。\n子アカウントの1階層上のアカウントを切り替え先に指定してください。", + "regionMismatchError": "(es)パートナーアカウントの変更に失敗しました。\n子アカウントと同じリージョンのアカウントを切り替え先に指定してください。", + "countryMismatchError": "(es)パートナーアカウントの変更に失敗しました。\n子アカウントと同じ国のアカウントを切り替え先に指定してください。" + }, + "label": { + "invalidInputError": "(es)変更先アカウントIDには1~9999999の数字を入力してください。", + "title": "(es)Change Owner", + "upperLayerId": "(es)Upper Layer ID", + "lowerLayerId": "(es)Lower Layer ID" + } } } \ No newline at end of file diff --git a/dictation_client/src/translation/fr.json b/dictation_client/src/translation/fr.json index af62dc2..fcd78f1 100644 --- a/dictation_client/src/translation/fr.json +++ b/dictation_client/src/translation/fr.json @@ -252,8 +252,9 @@ "backupFailedError": "Le processus de « Sauvegarde de fichier » a échoué. Veuillez réessayer plus tard. Si l'erreur persiste, contactez votre administrateur système.", "cancelFailedError": "Échec de la suppression des dictées. Veuillez actualiser votre écran et réessayer.", "deleteFailedError": "(fr)タスクの削除に失敗しました。画面を更新し、再度ご確認ください。", - "licenseNotAssignedError": "La transcription n'est pas possible car aucune licence valide n'a été attribuée.Veuillez demander à votre administrateur d'attribuer une licence valide.", - "licenseExpiredError": "La transcription n'est pas possible car votre licence est expirée. Veuillez demander à votre administrateur de vous attribuer une licence valide." + "licenseNotAssignedError": "La transcription n'est pas possible car aucune licence valide n'a été attribuée. Veuillez demander à votre administrateur d'attribuer une licence valide.", + "licenseExpiredError": "La transcription n'est pas possible car votre licence est expirée. Veuillez demander à votre administrateur de vous attribuer une licence valide.", + "fileAlreadyDeletedError": "(fr)既に削除された音声ファイルが含まれています。画面を更新し、再度ご確認ください" }, "label": { "title": "Dictées", @@ -368,7 +369,8 @@ "shortage": "Pénurie de licences", "issueRequesting": "Licences en commande", "viewDetails": "Voir les détails", - "accounts": "comptes" + "accounts": "comptes", + "changeOwnerButton": "(fr)Change Owner" } }, "orderHistoriesPage": { @@ -619,5 +621,19 @@ "saveButton": "(fr)Save Settings", "daysValidationError": "(fr)Daysには1~999の数字を入力してください。" } + }, + "changeOwnerPopup": { + "message": { + "accountNotFoundError": "(fr)変更先のアカウントIDは存在しません。", + "hierarchyMismatchError": "(fr)パートナーアカウントの変更に失敗しました。\n子アカウントの1階層上のアカウントを切り替え先に指定してください。", + "regionMismatchError": "(fr)パートナーアカウントの変更に失敗しました。\n子アカウントと同じリージョンのアカウントを切り替え先に指定してください。", + "countryMismatchError": "(fr)パートナーアカウントの変更に失敗しました。\n子アカウントと同じ国のアカウントを切り替え先に指定してください。" + }, + "label": { + "invalidInputError": "(fr)変更先アカウントIDには1~9999999の数字を入力してください。", + "title": "(fr)Change Owner", + "upperLayerId": "(fr)Upper Layer ID", + "lowerLayerId": "(fr)Lower Layer ID" + } } } \ No newline at end of file From 1451d6f58458c5d47f33692adbb575430225024a Mon Sep 17 00:00:00 2001 From: "makabe.t" Date: Fri, 15 Mar 2024 01:02:33 +0000 Subject: [PATCH 2/7] =?UTF-8?q?Merged=20PR=20835:=20=E6=9C=AC=E7=95=AA?= =?UTF-8?q?=E7=92=B0=E5=A2=83=E3=81=AB=E5=AF=BE=E3=81=99=E3=82=8B=E7=A7=BB?= =?UTF-8?q?=E8=A1=8C=E3=83=87=E3=83=BC=E3=82=BF=E3=81=AE=E6=8A=95=E5=85=A5?= =?UTF-8?q?=E5=BE=8C=E3=81=AE=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task3580: 本番環境に対する移行データの投入後の修正](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3580) - 検証ツールの日時比較について、一度Date型に変換してから比較するように修正しました。 - 時刻フォーマットで秒が入っていなくても比較できるようにするため ## レビューポイント - 日時の変換は適切でしょうか? ## UIの変更 - なし ## クエリの変更 - なし ## 動作確認状況 - 本番踏み台で確認 - 行った修正がデグレを発生させていないことを確認できるか - ツールの変更のみなので影響なし ## 補足 - 相談、参考資料などがあれば --- .../verification/verification.service.ts | 36 ++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/data_migration_tools/server/src/features/verification/verification.service.ts b/data_migration_tools/server/src/features/verification/verification.service.ts index 10733f5..97194b6 100644 --- a/data_migration_tools/server/src/features/verification/verification.service.ts +++ b/data_migration_tools/server/src/features/verification/verification.service.ts @@ -382,18 +382,26 @@ function compareCardLicenses( } */ - const formattedActivated = getFormattedDate( - filterdCardLicenses[0].activated_at, - `yyyy/MM/dd hh:mm:ss` + const formattedFileActivated = getFormattedDate( + cardlicensesInputFile.activated_at + ? new Date(cardlicensesInputFile.activated_at) + : null, + `yyyy/MM/dd hh:mm:ss`, + true ); - if (cardlicensesInputFile.activated_at !== formattedActivated) { + const formattedDbActivated = getFormattedDate( + filterdCardLicenses[0].activated_at, + `yyyy/MM/dd hh:mm:ss`, + true + ); + if (formattedFileActivated !== formattedDbActivated) { const VerificationResultDetailsOne: VerificationResultDetails = { input: "cardLicenses", inputRow: row, diffTargetTable: "cardLicenses", columnName: "activated_at", - fileData: cardlicensesInputFile.activated_at, - databaseData: formattedActivated, + fileData: formattedFileActivated, + databaseData: formattedDbActivated, reason: "内容不一致", }; VerificationResultDetails.push(VerificationResultDetailsOne); @@ -574,7 +582,13 @@ function compareLicenses( // expiry_dateについて、時はゼロパディングした値で比較する(×01~09 ○1~9) if ( !licensesFromDatabase[i] || - licensesFromFile[i].expired_date !== + getFormattedDate( + licensesFromFile[i].expired_date + ? new Date(licensesFromFile[i].expired_date) + : null, + `yyyy/MM/dd hh:mm:ss`, + true + ) !== getFormattedDate( licensesFromDatabase[i].expiry_date, `yyyy/MM/dd hh:mm:ss`, @@ -586,7 +600,13 @@ function compareLicenses( inputRow: licensesFromFile[i].row, diffTargetTable: "licenses", columnName: "expired_date", - fileData: licensesFromFile[i].expired_date, + fileData: getFormattedDate( + licensesFromFile[i].expired_date + ? new Date(licensesFromFile[i].expired_date) + : null, + `yyyy/MM/dd hh:mm:ss`, + true + ), databaseData: licensesFromDatabase[i] ? getFormattedDate( licensesFromDatabase[i].expiry_date, From 13e0793219c2715e79e0a74964bbc3d84ef4f590 Mon Sep 17 00:00:00 2001 From: "saito.k" Date: Fri, 15 Mar 2024 08:21:24 +0000 Subject: [PATCH 3/7] =?UTF-8?q?Merged=20PR=20847:=20=E3=83=AA=E3=83=86?= =?UTF-8?q?=E3=83=A9=E3=83=AB=E3=81=AE=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task3927: リテラルの修正](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3927) - 翻訳反映 - Auto Renew → Auto Assign に変更 - Transcriptionist List→ Transcription List に変更 ## レビューポイント - 特になし ## UIの変更 - Before/Afterのスクショなど - スクショ置き場 ## 動作確認状況 - ローカルで確認、develop環境で確認など - 行った修正がデグレを発生させていないことを確認できるか - 具体的にどのような確認をしたか - リテラルの反映のみのためほか機能に影響なし ## 補足 - 相談、参考資料などがあれば --- dictation_client/src/translation/de.json | 12 ++++++------ dictation_client/src/translation/en.json | 12 ++++++------ dictation_client/src/translation/es.json | 12 ++++++------ dictation_client/src/translation/fr.json | 12 ++++++------ 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/dictation_client/src/translation/de.json b/dictation_client/src/translation/de.json index b749dd4..84cceb9 100644 --- a/dictation_client/src/translation/de.json +++ b/dictation_client/src/translation/de.json @@ -154,7 +154,7 @@ "status": "Status", "expiration": "Verfallsdatum", "remaining": "Verbleibender Zeitraum", - "autoRenew": "Automatische Erneuerung", + "autoRenew": "Automatisch zuweisen", "licenseAlert": "Lizenzalarm", "notification": "Benachrichtigung", "users": "Benutzer", @@ -436,7 +436,7 @@ "templateOptional": "Vorlage (Optional)", "editRule": "Regel bearbeiten", "selected": "Ausgewählter transkriptionist", - "pool": "Liste der Transkriptionisten", + "pool": "Transkriptionsliste", "selectAuthor": "Autoren-ID auswählen", "selectWorktypeId": "Aufgabentypkennung auswählen", "selectTemplate": "Vorlage auswählen" @@ -456,7 +456,7 @@ "addTypistGroup": "Transkriptionist Gruppe hinzufügen", "transcriptionist": "Transkriptionist", "selected": "Ausgewählter transkriptionist", - "pool": "Liste der Transkriptionisten", + "pool": "Transkriptionsliste", "add": "Hinzufügen", "remove": "Entfernen", "editTypistGroup": "Transkriptionistengruppe bearbeiten" @@ -625,9 +625,9 @@ "changeOwnerPopup": { "message": { "accountNotFoundError": "(de)変更先のアカウントIDは存在しません。", - "hierarchyMismatchError": "(de)パートナーアカウントの変更に失敗しました。\n子アカウントの1階層上のアカウントを切り替え先に指定してください。", - "regionMismatchError": "(de)パートナーアカウントの変更に失敗しました。\n子アカウントと同じリージョンのアカウントを切り替え先に指定してください。", - "countryMismatchError": "(de)パートナーアカウントの変更に失敗しました。\n子アカウントと同じ国のアカウントを切り替え先に指定してください。" + "hierarchyMismatchError": "(de)パートナーアカウントの変更に失敗しました。\nLower layerの1階層上のアカウントを切り替え先に指定してください。", + "regionMismatchError": "(de)パートナーアカウントの変更に失敗しました。\nLower layerと同じリージョンのアカウントを切り替え先に指定してください。", + "countryMismatchError": "(de)パートナーアカウントの変更に失敗しました。\nLower layerと同じ国のアカウントを切り替え先に指定してください。" }, "label": { "invalidInputError": "(de)変更先アカウントIDには1~9999999の数字を入力してください。", diff --git a/dictation_client/src/translation/en.json b/dictation_client/src/translation/en.json index 310dab6..4130f22 100644 --- a/dictation_client/src/translation/en.json +++ b/dictation_client/src/translation/en.json @@ -154,7 +154,7 @@ "status": "Status", "expiration": "Expiration Date", "remaining": "Remaining Period", - "autoRenew": "Auto Renew", + "autoRenew": "Auto Assign", "licenseAlert": "License Alert", "notification": "Notification", "users": "Users", @@ -436,7 +436,7 @@ "templateOptional": "Template (Optional)", "editRule": "Edit Rule", "selected": "Selected Transcriptionist", - "pool": "Transcriptionist List", + "pool": "Transcription List", "selectAuthor": "Select Author ID", "selectWorktypeId": "Select Worktype ID", "selectTemplate": "Select Template" @@ -456,7 +456,7 @@ "addTypistGroup": "Add Transcriptionist Group", "transcriptionist": "Transcriptionist", "selected": "Selected Transcriptionist", - "pool": "Transcriptionist List", + "pool": "Transcription List", "add": "Add", "remove": "Remove", "editTypistGroup": "Edit Transcriptionist Group" @@ -625,9 +625,9 @@ "changeOwnerPopup": { "message": { "accountNotFoundError": "変更先のアカウントIDは存在しません。", - "hierarchyMismatchError": "パートナーアカウントの変更に失敗しました。\n子アカウントの1階層上のアカウントを切り替え先に指定してください。", - "regionMismatchError": "パートナーアカウントの変更に失敗しました。\n子アカウントと同じリージョンのアカウントを切り替え先に指定してください。", - "countryMismatchError": "パートナーアカウントの変更に失敗しました。\n子アカウントと同じ国のアカウントを切り替え先に指定してください。" + "hierarchyMismatchError": "パートナーアカウントの変更に失敗しました。\nLower layerの1階層上のアカウントを切り替え先に指定してください。", + "regionMismatchError": "パートナーアカウントの変更に失敗しました。\nLower layerと同じリージョンのアカウントを切り替え先に指定してください。", + "countryMismatchError": "パートナーアカウントの変更に失敗しました。\nLower layerと同じ国のアカウントを切り替え先に指定してください。" }, "label": { "invalidInputError": "変更先アカウントIDには1~9999999の数字を入力してください。", diff --git a/dictation_client/src/translation/es.json b/dictation_client/src/translation/es.json index 1ac861b..e398fb0 100644 --- a/dictation_client/src/translation/es.json +++ b/dictation_client/src/translation/es.json @@ -154,7 +154,7 @@ "status": "Estado", "expiration": "Fecha de caducidad", "remaining": "Período restante", - "autoRenew": "Renovación Automática", + "autoRenew": "Asignación automática", "licenseAlert": "Alerta de licencia", "notification": "Notificación", "users": "Usuarios", @@ -436,7 +436,7 @@ "templateOptional": "Plantilla (Opcional)", "editRule": "Editar regla", "selected": "Transcriptor seleccionado", - "pool": "Lista de transcriptores", + "pool": "Lista de transcriptor", "selectAuthor": "Seleccionar ID de autor", "selectWorktypeId": "Seleccionar ID de tipo de trabajo", "selectTemplate": "Seleccionar Plantilla" @@ -456,7 +456,7 @@ "addTypistGroup": "Agregar grupo transcriptor", "transcriptionist": "Transcriptor", "selected": "Transcriptor seleccionado", - "pool": "Lista de transcriptores", + "pool": "Lista de transcriptor", "add": "Añadir", "remove": "Eliminar", "editTypistGroup": "Editar grupo transcriptor" @@ -625,9 +625,9 @@ "changeOwnerPopup": { "message": { "accountNotFoundError": "(es)変更先のアカウントIDは存在しません。", - "hierarchyMismatchError": "(es)パートナーアカウントの変更に失敗しました。\n子アカウントの1階層上のアカウントを切り替え先に指定してください。", - "regionMismatchError": "(es)パートナーアカウントの変更に失敗しました。\n子アカウントと同じリージョンのアカウントを切り替え先に指定してください。", - "countryMismatchError": "(es)パートナーアカウントの変更に失敗しました。\n子アカウントと同じ国のアカウントを切り替え先に指定してください。" + "hierarchyMismatchError": "(es)パートナーアカウントの変更に失敗しました。\nLower layerの1階層上のアカウントを切り替え先に指定してください。", + "regionMismatchError": "(es)パートナーアカウントの変更に失敗しました。\nLower layerと同じリージョンのアカウントを切り替え先に指定してください。", + "countryMismatchError": "(es)パートナーアカウントの変更に失敗しました。\nLower layerと同じ国のアカウントを切り替え先に指定してください。" }, "label": { "invalidInputError": "(es)変更先アカウントIDには1~9999999の数字を入力してください。", diff --git a/dictation_client/src/translation/fr.json b/dictation_client/src/translation/fr.json index fcd78f1..98105f3 100644 --- a/dictation_client/src/translation/fr.json +++ b/dictation_client/src/translation/fr.json @@ -154,7 +154,7 @@ "status": "État", "expiration": "Date d'expiration", "remaining": "Période restante", - "autoRenew": "Renouvellement automatique", + "autoRenew": "Assignation automatique", "licenseAlert": "Alerte de licence", "notification": "Notification", "users": "Utilisateurs", @@ -436,7 +436,7 @@ "templateOptional": "Masque (Facultatif)", "editRule": "Modifier la règle", "selected": "Transcriptionniste sélectionné", - "pool": "Liste des transcripteurs", + "pool": "Liste de transcriptionniste", "selectAuthor": "Sélectionner le Identifiant Auteur", "selectWorktypeId": "Sélectionner le Identifiant du Type de travail", "selectTemplate": "Sélectionner le Masque" @@ -456,7 +456,7 @@ "addTypistGroup": "Ajouter un groupe de transcripteurs", "transcriptionist": "Transcriptionniste", "selected": "Transcriptionniste sélectionné", - "pool": "Liste des transcripteurs", + "pool": "Liste de transcriptionniste", "add": "Ajouter", "remove": "Supprimer", "editTypistGroup": "Modifier le groupe de transcripteurs" @@ -625,9 +625,9 @@ "changeOwnerPopup": { "message": { "accountNotFoundError": "(fr)変更先のアカウントIDは存在しません。", - "hierarchyMismatchError": "(fr)パートナーアカウントの変更に失敗しました。\n子アカウントの1階層上のアカウントを切り替え先に指定してください。", - "regionMismatchError": "(fr)パートナーアカウントの変更に失敗しました。\n子アカウントと同じリージョンのアカウントを切り替え先に指定してください。", - "countryMismatchError": "(fr)パートナーアカウントの変更に失敗しました。\n子アカウントと同じ国のアカウントを切り替え先に指定してください。" + "hierarchyMismatchError": "(fr)パートナーアカウントの変更に失敗しました。\nLower layerの1階層上のアカウントを切り替え先に指定してください。", + "regionMismatchError": "(fr)パートナーアカウントの変更に失敗しました。\nLower layerと同じリージョンのアカウントを切り替え先に指定してください。", + "countryMismatchError": "(fr)パートナーアカウントの変更に失敗しました。\nLower layerと同じ国のアカウントを切り替え先に指定してください。" }, "label": { "invalidInputError": "(fr)変更先アカウントIDには1~9999999の数字を入力してください。", From 1f0cf501669af4c6eb3217503def081f4e4ec40f Mon Sep 17 00:00:00 2001 From: Kentaro Fukunaga Date: Mon, 25 Mar 2024 07:54:43 +0000 Subject: [PATCH 4/7] =?UTF-8?q?Merged=20PR=20856:=20Client=E3=83=93?= =?UTF-8?q?=E3=83=AB=E3=83=89=E6=99=82=E3=81=AB=E5=9F=8B=E3=82=81=E8=BE=BC?= =?UTF-8?q?=E3=82=93=E3=81=A7=E3=81=84=E3=82=8B=E3=82=AD=E3=83=BC=E3=82=84?= =?UTF-8?q?URL=E3=81=AE=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task3963: Clientビルド時に埋め込んでいるキーやURLの更新](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3963) - クライアント本番用のACB2C関連の環境変数を作り直したACB2Cの値に差し替えました。 ## レビューポイント - 共有 ## UIの変更 - なし ## クエリの変更 - なし ## 動作確認状況 - 未実施 - デプロイ後に確認 ## 補足 - 相談、参考資料などがあれば --- dictation_client/.env.production | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dictation_client/.env.production b/dictation_client/.env.production index 7169682..2e31d7e 100644 --- a/dictation_client/.env.production +++ b/dictation_client/.env.production @@ -1,5 +1,5 @@ VITE_STAGE=production -VITE_B2C_CLIENTID=b0ec473b-6b2b-4f12-adc6-39a24ebe6a3f -VITE_B2C_AUTHORITY=https://adb2codmsprod.b2clogin.com/adb2codmsprod.onmicrosoft.com/b2c_1_signin_prod -VITE_B2C_KNOWNAUTHORITIES=adb2codmsprod.b2clogin.com +VITE_B2C_CLIENTID=ea6e2535-c914-4889-8659-7ca1ec2e420d +VITE_B2C_AUTHORITY=https://adb2codmsproduction.b2clogin.com/adb2codmsproduction.onmicrosoft.com/b2c_1_signin_production +VITE_B2C_KNOWNAUTHORITIES=adb2codmsproduction.b2clogin.com VITE_DESK_TOP_APP_SCHEME=odms-desktopapp \ No newline at end of file From 5147f853ae0f8fde7ffce02cc38385c77e6890b7 Mon Sep 17 00:00:00 2001 From: "saito.k" Date: Wed, 3 Apr 2024 05:35:30 +0000 Subject: [PATCH 5/7] =?UTF-8?q?Merged=20PR=20861:=20API=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task4038: API修正](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/4038) - タスク作成時のジョブナンバーの採番ルールを修正 - 常に最新タスクのジョブナンバー+1を採番する - テストケース追加 - 非同期処理の呼び出しでawaitが抜けている箇所を修正 ## レビューポイント - 修正内容の認識は合っているか - テストケースに不足はないか - 修正箇所がほかの機能に影響していないか - taskRepositoryのcreateはupload-finished以外では使用されていない ## クエリの変更 - Repositoryを変更し、クエリが変更された場合は変更内容を確認する - Before/Afterのクエリ - https://ndstokyo.sharepoint.com/:f:/r/sites/Piranha/Shared%20Documents/General/OMDS/%E3%82%AF%E3%82%A8%E3%83%AA/Task4038?csf=1&web=1&e=WTIk2l - L107辺りが変更箇所 ## 動作確認状況 - ローカルで確認 - 行った修正がデグレを発生させていないことを確認できるか - 具体的にどのような確認をしたか - 修正したcreateがほかで使用していないことを確認 - テストケースを追加し確認 - 既存のテスト含め成功することを確認 ## 補足 - 相談、参考資料などがあれば --- dictation_server/src/app.module.ts | 4 +- .../src/features/files/files.service.spec.ts | 624 +++++++++++++++++- .../src/features/files/test/utility.ts | 18 +- .../src/features/licenses/licenses.service.ts | 2 +- .../src/features/tasks/tasks.service.ts | 2 +- .../tasks/tasks.repository.service.ts | 5 +- 6 files changed, 634 insertions(+), 21 deletions(-) diff --git a/dictation_server/src/app.module.ts b/dictation_server/src/app.module.ts index 4022501..1672c4e 100644 --- a/dictation_server/src/app.module.ts +++ b/dictation_server/src/app.module.ts @@ -165,9 +165,7 @@ import { CheckHeaderMiddleware } from './common/check-header.middleware'; }) export class AppModule { configure(consumer: MiddlewareConsumer) { - consumer - .apply(LoggerMiddleware) - .forRoutes(''); + consumer.apply(LoggerMiddleware).forRoutes(''); // stage=localの場合はmiddlewareを適用しない // ローカル環境ではサーバーから静的ファイルも返すため、APIリクエスト以外のリクエストにもmiddlewareが適用されてしまう if (process.env.STAGE !== 'local') { diff --git a/dictation_server/src/features/files/files.service.spec.ts b/dictation_server/src/features/files/files.service.spec.ts index deff777..e0a1ccd 100644 --- a/dictation_server/src/features/files/files.service.spec.ts +++ b/dictation_server/src/features/files/files.service.spec.ts @@ -8,6 +8,7 @@ import { createUserGroupAndMember, getTaskFromJobNumber, makeTestingModuleWithBlobAndNotification, + updateTaskStatusAndIsJobNumberEnabled, } from './test/utility'; import { FilesService } from './files.service'; import { makeContext } from '../../common/log'; @@ -319,7 +320,7 @@ describe('タスク作成から自動ルーティング(DB使用)', () => { ); if (!module) fail(); const service = module.get(FilesService); - const NotificationHubService = module.get( + const notificationHubService = module.get( NotificationhubService, ); const result = await service.uploadFinished( @@ -340,9 +341,9 @@ describe('タスク作成から自動ルーティング(DB使用)', () => { optionItemList, false, ); - expect(result).toEqual({ jobNumber: '00000001' }); + expect(result.jobNumber).toEqual('00000001'); // 通知処理が想定通りの引数で呼ばれているか確認 - expect(NotificationHubService.notify).toHaveBeenCalledWith( + expect(notificationHubService.notify).toHaveBeenCalledWith( makeContext('trackingId', 'requestId'), [`user_${typistUserId}`], { @@ -420,7 +421,7 @@ describe('タスク作成から自動ルーティング(DB使用)', () => { ); if (!module) fail(); const service = module.get(FilesService); - const NotificationHubService = module.get( + const notificationHubService = module.get( NotificationhubService, ); const result = await service.uploadFinished( @@ -441,9 +442,9 @@ describe('タスク作成から自動ルーティング(DB使用)', () => { optionItemList, false, ); - expect(result).toEqual({ jobNumber: '00000002' }); + expect(result.jobNumber).toEqual('00000002'); // 通知処理が想定通りの引数で呼ばれているか確認 - expect(NotificationHubService.notify).toHaveBeenCalledWith( + expect(notificationHubService.notify).toHaveBeenCalledWith( makeContext('trackingId', 'requestId'), [`user_${typistUserId}`], { @@ -543,7 +544,7 @@ describe('タスク作成から自動ルーティング(DB使用)', () => { ); if (!module) fail(); const service = module.get(FilesService); - const NotificationHubService = module.get( + const notificationHubService = module.get( NotificationhubService, ); const result = await service.uploadFinished( @@ -564,9 +565,9 @@ describe('タスク作成から自動ルーティング(DB使用)', () => { optionItemList, false, ); - expect(result).toEqual({ jobNumber: '00000001' }); + expect(result.jobNumber).toEqual('00000001'); // 通知処理が想定通りの引数で呼ばれているか確認 - expect(NotificationHubService.notify).toHaveBeenCalledWith( + expect(notificationHubService.notify).toHaveBeenCalledWith( makeContext('trackingId', 'requestId'), [`user_${typistUserId}`], { @@ -665,7 +666,7 @@ describe('タスク作成から自動ルーティング(DB使用)', () => { ); if (!module) fail(); const service = module.get(FilesService); - const NotificationHubService = module.get( + const notificationHubService = module.get( NotificationhubService, ); const result = await service.uploadFinished( @@ -686,9 +687,9 @@ describe('タスク作成から自動ルーティング(DB使用)', () => { optionItemList, false, ); - expect(result).toEqual({ jobNumber: '00000001' }); + expect(result.jobNumber).toEqual('00000001'); // 通知処理が想定通りの引数で呼ばれているか確認 - expect(NotificationHubService.notify).toHaveBeenCalledWith( + expect(notificationHubService.notify).toHaveBeenCalledWith( makeContext('trackingId', 'requestId'), [`user_${typistUserId}`], { @@ -755,7 +756,7 @@ describe('タスク作成から自動ルーティング(DB使用)', () => { optionItemList, false, ); - expect(result).toEqual({ jobNumber: '00000001' }); + expect(result.jobNumber).toEqual('00000001'); // タスクを取得 const resultTask = await getTaskFromJobNumber(source, result.jobNumber); // タスクのチェックアウト権限を取得 @@ -957,6 +958,603 @@ describe('タスク作成から自動ルーティング(DB使用)', () => { ), ); }); + + it('タスク作成時に採番されるジョブナンバーが常に最新タスクのジョブナンバー + 1となる(最新タスクのジョブナンバーが有効でない場合)', async () => { + if (!source) fail(); + const { id: accountId } = await makeTestSimpleAccount(source); + const { + external_id: authorExternalId, + id: authorUserId, + author_id: authorAuthorId, + } = await makeTestUser(source, { + account_id: accountId, + external_id: 'author-user-external-id', + role: 'author', + author_id: 'AUTHOR_ID', + }); + const { id: typistUserId } = await makeTestUser(source, { + account_id: accountId, + external_id: 'typist-user-external-id', + role: 'typist', + author_id: undefined, + }); + // ワークタイプを作成 + const { id: worktypeId, custom_worktype_id } = await createWorktype( + source, + accountId, + 'worktypeId', + ); + // テンプレートファイルを作成 + const { id: templateFileId } = await createTemplateFile( + source, + accountId, + 'templateFile', + 'http://blob/url/templateFile.zip', + ); + // ワークフローを作成 + const { id: workflowId } = await createWorkflow( + source, + accountId, + authorUserId, + worktypeId, + templateFileId, + ); + // ワークフロータイピストを作成 + await createWorkflowTypist(source, workflowId, typistUserId); + const blobParam = makeBlobstorageServiceMockValue(); + const notificationParam = makeDefaultNotificationhubServiceMockValue(); + + // タスクを10件作成, ジョブナンバーは00000001から00000010まで + for (let i = 1; i <= 10; i++) { + await createTask( + source, + accountId, + `http://blob/url/file_${i}.zip`, + `file_${i}.zip`, + '01', + typistUserId, + authorAuthorId ?? '', + i.toString().padStart(8, '0'), + ); + } + + // 最新のジョブナンバーでタスクを取得 + const latestTask = await getTaskFromJobNumber(source, '00000010'); + + // 最新のタスクのステータスとis_job_number_enabledを更新 + await updateTaskStatusAndIsJobNumberEnabled( + source, + latestTask?.id ?? 0, + 'Backup', + false, + ); + + const module = await makeTestingModuleWithBlobAndNotification( + source, + blobParam, + notificationParam, + ); + if (!module) fail(); + const service = module.get(FilesService); + const notificationHubService = module.get( + NotificationhubService, + ); + const result = await service.uploadFinished( + makeContext('trackingId', 'requestId'), + authorExternalId, + 'http://blob/url/file.zip', + authorAuthorId ?? '', + 'file.zip', + '11:22:33', + '2023-05-26T11:22:33.444', + '2023-05-26T11:22:33.444', + '2023-05-26T11:22:33.444', + 256, + '01', + 'DS2', + 'comment', + custom_worktype_id, + optionItemList, + false, + ); + expect(result.jobNumber).toEqual('00000011'); + // 通知処理が想定通りの引数で呼ばれているか確認 + expect(notificationHubService.notify).toHaveBeenCalledWith( + makeContext('trackingId', 'requestId'), + [`user_${typistUserId}`], + { + authorId: 'AUTHOR_ID', + filename: 'file', + priority: 'High', + uploadedAt: '2023-05-26T11:22:33.444', + }, + ); + // 作成したタスクを取得 + const resultTask = await getTaskFromJobNumber(source, result.jobNumber); + // タスクのチェックアウト権限を取得 + const resultCheckoutPermission = await getCheckoutPermissions( + source, + resultTask?.id ?? 0, + ); + // タスクのテンプレートファイルIDを確認 + expect(resultTask?.template_file_id).toEqual(templateFileId); + // タスクのチェックアウト権限が想定通り(ワークフローで設定されている)のユーザーIDで作成されているか確認 + expect(resultCheckoutPermission.length).toEqual(1); + expect(resultCheckoutPermission[0].user_id).toEqual(typistUserId); + }); + + it('タスク作成時に採番されるジョブナンバーが常に最新タスクのジョブナンバー + 1となる(最新タスクのジョブナンバー有効である場合)', async () => { + if (!source) fail(); + const { id: accountId } = await makeTestSimpleAccount(source); + const { + external_id: authorExternalId, + id: authorUserId, + author_id: authorAuthorId, + } = await makeTestUser(source, { + account_id: accountId, + external_id: 'author-user-external-id', + role: 'author', + author_id: 'AUTHOR_ID', + }); + const { id: typistUserId } = await makeTestUser(source, { + account_id: accountId, + external_id: 'typist-user-external-id', + role: 'typist', + author_id: undefined, + }); + // ワークタイプを作成 + const { id: worktypeId, custom_worktype_id } = await createWorktype( + source, + accountId, + 'worktypeId', + ); + // テンプレートファイルを作成 + const { id: templateFileId } = await createTemplateFile( + source, + accountId, + 'templateFile', + 'http://blob/url/templateFile.zip', + ); + // ワークフローを作成 + const { id: workflowId } = await createWorkflow( + source, + accountId, + authorUserId, + worktypeId, + templateFileId, + ); + // ワークフロータイピストを作成 + await createWorkflowTypist(source, workflowId, typistUserId); + const blobParam = makeBlobstorageServiceMockValue(); + const notificationParam = makeDefaultNotificationhubServiceMockValue(); + + // タスクを10件作成, ジョブナンバーは00000001から00000010まで + for (let i = 1; i <= 10; i++) { + await createTask( + source, + accountId, + `http://blob/url/file_${i}.zip`, + `file_${i}.zip`, + '01', + typistUserId, + authorAuthorId ?? '', + i.toString().padStart(8, '0'), + ); + } + + const module = await makeTestingModuleWithBlobAndNotification( + source, + blobParam, + notificationParam, + ); + if (!module) fail(); + const service = module.get(FilesService); + const notificationHubService = module.get( + NotificationhubService, + ); + const result = await service.uploadFinished( + makeContext('trackingId', 'requestId'), + authorExternalId, + 'http://blob/url/file.zip', + authorAuthorId ?? '', + 'file.zip', + '11:22:33', + '2023-05-26T11:22:33.444', + '2023-05-26T11:22:33.444', + '2023-05-26T11:22:33.444', + 256, + '01', + 'DS2', + 'comment', + custom_worktype_id, + optionItemList, + false, + ); + expect(result.jobNumber).toEqual('00000011'); + // 通知処理が想定通りの引数で呼ばれているか確認 + expect(notificationHubService.notify).toHaveBeenCalledWith( + makeContext('trackingId', 'requestId'), + [`user_${typistUserId}`], + { + authorId: 'AUTHOR_ID', + filename: 'file', + priority: 'High', + uploadedAt: '2023-05-26T11:22:33.444', + }, + ); + // 作成したタスクを取得 + const resultTask = await getTaskFromJobNumber(source, result.jobNumber); + // タスクのチェックアウト権限を取得 + const resultCheckoutPermission = await getCheckoutPermissions( + source, + resultTask?.id ?? 0, + ); + // タスクのテンプレートファイルIDを確認 + expect(resultTask?.template_file_id).toEqual(templateFileId); + // タスクのチェックアウト権限が想定通り(ワークフローで設定されている)のユーザーIDで作成されているか確認 + expect(resultCheckoutPermission.length).toEqual(1); + expect(resultCheckoutPermission[0].user_id).toEqual(typistUserId); + }); + + it('タスク作成時に採番されるジョブナンバーが常に最新タスクのジョブナンバー + 1となる(途中のタスクのジョブナンバーが有効でない場合)', async () => { + if (!source) fail(); + const { id: accountId } = await makeTestSimpleAccount(source); + const { + external_id: authorExternalId, + id: authorUserId, + author_id: authorAuthorId, + } = await makeTestUser(source, { + account_id: accountId, + external_id: 'author-user-external-id', + role: 'author', + author_id: 'AUTHOR_ID', + }); + const { id: typistUserId } = await makeTestUser(source, { + account_id: accountId, + external_id: 'typist-user-external-id', + role: 'typist', + author_id: undefined, + }); + // ワークタイプを作成 + const { id: worktypeId, custom_worktype_id } = await createWorktype( + source, + accountId, + 'worktypeId', + ); + // テンプレートファイルを作成 + const { id: templateFileId } = await createTemplateFile( + source, + accountId, + 'templateFile', + 'http://blob/url/templateFile.zip', + ); + // ワークフローを作成 + const { id: workflowId } = await createWorkflow( + source, + accountId, + authorUserId, + worktypeId, + templateFileId, + ); + // ワークフロータイピストを作成 + await createWorkflowTypist(source, workflowId, typistUserId); + const blobParam = makeBlobstorageServiceMockValue(); + const notificationParam = makeDefaultNotificationhubServiceMockValue(); + + // タスクを10件作成, ジョブナンバーは00000001から00000010まで + for (let i = 1; i <= 10; i++) { + await createTask( + source, + accountId, + `http://blob/url/file_${i}.zip`, + `file_${i}.zip`, + '01', + typistUserId, + authorAuthorId ?? '', + i.toString().padStart(8, '0'), + ); + } + + // ジョブナンバー00000005のタスクを取得 + const middleTask = await getTaskFromJobNumber(source, '00000005'); + + // ジョブナンバー00000005のタスクのステータスとis_job_number_enabledを更新 + await updateTaskStatusAndIsJobNumberEnabled( + source, + middleTask?.id ?? 0, + 'Backup', + false, + ); + + const module = await makeTestingModuleWithBlobAndNotification( + source, + blobParam, + notificationParam, + ); + if (!module) fail(); + const service = module.get(FilesService); + const notificationHubService = module.get( + NotificationhubService, + ); + const result = await service.uploadFinished( + makeContext('trackingId', 'requestId'), + authorExternalId, + 'http://blob/url/file.zip', + authorAuthorId ?? '', + 'file.zip', + '11:22:33', + '2023-05-26T11:22:33.444', + '2023-05-26T11:22:33.444', + '2023-05-26T11:22:33.444', + 256, + '01', + 'DS2', + 'comment', + custom_worktype_id, + optionItemList, + false, + ); + expect(result.jobNumber).toEqual('00000011'); + // 通知処理が想定通りの引数で呼ばれているか確認 + expect(notificationHubService.notify).toHaveBeenCalledWith( + makeContext('trackingId', 'requestId'), + [`user_${typistUserId}`], + { + authorId: 'AUTHOR_ID', + filename: 'file', + priority: 'High', + uploadedAt: '2023-05-26T11:22:33.444', + }, + ); + // 作成したタスクを取得 + const resultTask = await getTaskFromJobNumber(source, result.jobNumber); + // タスクのチェックアウト権限を取得 + const resultCheckoutPermission = await getCheckoutPermissions( + source, + resultTask?.id ?? 0, + ); + // タスクのテンプレートファイルIDを確認 + expect(resultTask?.template_file_id).toEqual(templateFileId); + // タスクのチェックアウト権限が想定通り(ワークフローで設定されている)のユーザーIDで作成されているか確認 + expect(resultCheckoutPermission.length).toEqual(1); + expect(resultCheckoutPermission[0].user_id).toEqual(typistUserId); + }); + + it('タスク作成時に採番されるジョブナンバーが常に最新タスクのジョブナンバー + 1となる(最新タスクのジョブナンバーが99999999で有効でない場合)', async () => { + if (!source) fail(); + const { id: accountId } = await makeTestSimpleAccount(source); + const { + external_id: authorExternalId, + id: authorUserId, + author_id: authorAuthorId, + } = await makeTestUser(source, { + account_id: accountId, + external_id: 'author-user-external-id', + role: 'author', + author_id: 'AUTHOR_ID', + }); + const { id: typistUserId } = await makeTestUser(source, { + account_id: accountId, + external_id: 'typist-user-external-id', + role: 'typist', + author_id: undefined, + }); + // ワークタイプを作成 + const { id: worktypeId, custom_worktype_id } = await createWorktype( + source, + accountId, + 'worktypeId', + ); + // テンプレートファイルを作成 + const { id: templateFileId } = await createTemplateFile( + source, + accountId, + 'templateFile', + 'http://blob/url/templateFile.zip', + ); + // ワークフローを作成 + const { id: workflowId } = await createWorkflow( + source, + accountId, + authorUserId, + worktypeId, + templateFileId, + ); + // ワークフロータイピストを作成 + await createWorkflowTypist(source, workflowId, typistUserId); + const blobParam = makeBlobstorageServiceMockValue(); + const notificationParam = makeDefaultNotificationhubServiceMockValue(); + + // タスクを10件作成, ジョブナンバーは99999989から99999999まで + for (let i = 99999989; i <= 99999999; i++) { + await createTask( + source, + accountId, + `http://blob/url/file_${i}.zip`, + `file_${i}.zip`, + '01', + typistUserId, + authorAuthorId ?? '', + i.toString().padStart(8, '0'), + ); + } + + // 最新ジョブナンバーのタスクを取得 + const latestTask = await getTaskFromJobNumber(source, '99999999'); + + // 最新のタスクのステータスとis_job_number_enabledを更新 + await updateTaskStatusAndIsJobNumberEnabled( + source, + latestTask?.id ?? 0, + 'Backup', + false, + ); + + const module = await makeTestingModuleWithBlobAndNotification( + source, + blobParam, + notificationParam, + ); + if (!module) fail(); + const service = module.get(FilesService); + const notificationHubService = module.get( + NotificationhubService, + ); + const result = await service.uploadFinished( + makeContext('trackingId', 'requestId'), + authorExternalId, + 'http://blob/url/file.zip', + authorAuthorId ?? '', + 'file.zip', + '11:22:33', + '2023-05-26T11:22:33.444', + '2023-05-26T11:22:33.444', + '2023-05-26T11:22:33.444', + 256, + '01', + 'DS2', + 'comment', + custom_worktype_id, + optionItemList, + false, + ); + expect(result.jobNumber).toEqual('00000001'); + // 通知処理が想定通りの引数で呼ばれているか確認 + expect(notificationHubService.notify).toHaveBeenCalledWith( + makeContext('trackingId', 'requestId'), + [`user_${typistUserId}`], + { + authorId: 'AUTHOR_ID', + filename: 'file', + priority: 'High', + uploadedAt: '2023-05-26T11:22:33.444', + }, + ); + // 作成したタスクを取得 + const resultTask = await getTaskFromJobNumber(source, result.jobNumber); + // タスクのチェックアウト権限を取得 + const resultCheckoutPermission = await getCheckoutPermissions( + source, + resultTask?.id ?? 0, + ); + // タスクのテンプレートファイルIDを確認 + expect(resultTask?.template_file_id).toEqual(templateFileId); + // タスクのチェックアウト権限が想定通り(ワークフローで設定されている)のユーザーIDで作成されているか確認 + expect(resultCheckoutPermission.length).toEqual(1); + expect(resultCheckoutPermission[0].user_id).toEqual(typistUserId); + }); + + it('タスク作成時に採番されるジョブナンバーが常に最新タスクのジョブナンバー + 1となる(最新タスクのジョブナンバーが99999999で有効な場合)', async () => { + if (!source) fail(); + const { id: accountId } = await makeTestSimpleAccount(source); + const { + external_id: authorExternalId, + id: authorUserId, + author_id: authorAuthorId, + } = await makeTestUser(source, { + account_id: accountId, + external_id: 'author-user-external-id', + role: 'author', + author_id: 'AUTHOR_ID', + }); + const { id: typistUserId } = await makeTestUser(source, { + account_id: accountId, + external_id: 'typist-user-external-id', + role: 'typist', + author_id: undefined, + }); + // ワークタイプを作成 + const { id: worktypeId, custom_worktype_id } = await createWorktype( + source, + accountId, + 'worktypeId', + ); + // テンプレートファイルを作成 + const { id: templateFileId } = await createTemplateFile( + source, + accountId, + 'templateFile', + 'http://blob/url/templateFile.zip', + ); + // ワークフローを作成 + const { id: workflowId } = await createWorkflow( + source, + accountId, + authorUserId, + worktypeId, + templateFileId, + ); + // ワークフロータイピストを作成 + await createWorkflowTypist(source, workflowId, typistUserId); + const blobParam = makeBlobstorageServiceMockValue(); + const notificationParam = makeDefaultNotificationhubServiceMockValue(); + + // タスクを10件作成, ジョブナンバーは99999989から99999999まで + for (let i = 99999989; i <= 99999999; i++) { + await createTask( + source, + accountId, + `http://blob/url/file_${i}.zip`, + `file_${i}.zip`, + '01', + typistUserId, + authorAuthorId ?? '', + i.toString().padStart(8, '0'), + ); + } + const module = await makeTestingModuleWithBlobAndNotification( + source, + blobParam, + notificationParam, + ); + if (!module) fail(); + const service = module.get(FilesService); + const notificationHubService = module.get( + NotificationhubService, + ); + const result = await service.uploadFinished( + makeContext('trackingId', 'requestId'), + authorExternalId, + 'http://blob/url/file.zip', + authorAuthorId ?? '', + 'file.zip', + '11:22:33', + '2023-05-26T11:22:33.444', + '2023-05-26T11:22:33.444', + '2023-05-26T11:22:33.444', + 256, + '01', + 'DS2', + 'comment', + custom_worktype_id, + optionItemList, + false, + ); + expect(result.jobNumber).toEqual('00000001'); + // 通知処理が想定通りの引数で呼ばれているか確認 + expect(notificationHubService.notify).toHaveBeenCalledWith( + makeContext('trackingId', 'requestId'), + [`user_${typistUserId}`], + { + authorId: 'AUTHOR_ID', + filename: 'file', + priority: 'High', + uploadedAt: '2023-05-26T11:22:33.444', + }, + ); + // 作成したタスクを取得 + const resultTask = await getTaskFromJobNumber(source, result.jobNumber); + // タスクのチェックアウト権限を取得 + const resultCheckoutPermission = await getCheckoutPermissions( + source, + resultTask?.id ?? 0, + ); + // タスクのテンプレートファイルIDを確認 + expect(resultTask?.template_file_id).toEqual(templateFileId); + // タスクのチェックアウト権限が想定通り(ワークフローで設定されている)のユーザーIDで作成されているか確認 + expect(resultCheckoutPermission.length).toEqual(1); + expect(resultCheckoutPermission[0].user_id).toEqual(typistUserId); + }); }); describe('音声ファイルダウンロードURL取得', () => { diff --git a/dictation_server/src/features/files/test/utility.ts b/dictation_server/src/features/files/test/utility.ts index 1fe086b..25f9397 100644 --- a/dictation_server/src/features/files/test/utility.ts +++ b/dictation_server/src/features/files/test/utility.ts @@ -53,6 +53,7 @@ export const createTask = async ( status: string, typist_user_id?: number | undefined, author_id?: string | undefined, + job_number?: string | undefined, ): Promise<{ audioFileId: number }> => { const { identifiers: audioFileIdentifiers } = await datasource .getRepository(AudioFile) @@ -87,7 +88,7 @@ export const createTask = async ( const templateFile = templateFileIdentifiers.pop() as TemplateFile; await datasource.getRepository(Task).insert({ - job_number: '00000001', + job_number: job_number ?? '00000001', account_id: account_id, is_job_number_enabled: true, audio_file_id: audioFile.id, @@ -114,6 +115,21 @@ export const getTaskFromJobNumber = async ( return task; }; +// 指定したタスクのステータスとis_job_number_enabledを更新する +export const updateTaskStatusAndIsJobNumberEnabled = async ( + datasource: DataSource, + taskId: number, + status: string, + isJobNumberEnabled: boolean, +): Promise => { + await datasource + .getRepository(Task) + .update( + { id: taskId }, + { status: status, is_job_number_enabled: isJobNumberEnabled }, + ); +}; + // ユーザーグループとユーザーグループメンバーを作成する export const createUserGroupAndMember = async ( datasource: DataSource, diff --git a/dictation_server/src/features/licenses/licenses.service.ts b/dictation_server/src/features/licenses/licenses.service.ts index 3f64729..f06eeab 100644 --- a/dictation_server/src/features/licenses/licenses.service.ts +++ b/dictation_server/src/features/licenses/licenses.service.ts @@ -117,7 +117,7 @@ export class LicensesService { parentAccountId, ); - this.sendgridService.sendMailWithU105( + await this.sendgridService.sendMailWithU105( context, customer.adminEmails, customer.companyName, diff --git a/dictation_server/src/features/tasks/tasks.service.ts b/dictation_server/src/features/tasks/tasks.service.ts index 8ddf007..2e19af4 100644 --- a/dictation_server/src/features/tasks/tasks.service.ts +++ b/dictation_server/src/features/tasks/tasks.service.ts @@ -489,7 +489,7 @@ export class TasksService { getUserNameAndMailAddress(primaryAdmin); // メール送信 - this.sendgridService.sendMailWithU117( + await this.sendgridService.sendMailWithU117( context, authorNotification ? authorEmail : null, typistEmail, diff --git a/dictation_server/src/repositories/tasks/tasks.repository.service.ts b/dictation_server/src/repositories/tasks/tasks.repository.service.ts index a95a8ab..66202f2 100644 --- a/dictation_server/src/repositories/tasks/tasks.repository.service.ts +++ b/dictation_server/src/repositories/tasks/tasks.repository.service.ts @@ -899,9 +899,10 @@ export class TasksRepositoryService { const taskRepo = entityManager.getRepository(Task); - // アカウント内でJOBナンバーが有効なタスクのうち最新のものを取得 + // バグ 3954: [4/8リリース]タスクをすべてBackupした後、タスクを作成するとジョブナンバーが1から採番される(暫定対応) + // アカウント内で最新タスクのタスクを取得し、そのJOBナンバーをインクリメントして新しいタスクのJOBナンバーを設定する const lastTask = await taskRepo.findOne({ - where: { account_id: account_id, is_job_number_enabled: true }, + where: { account_id: account_id }, order: { created_at: 'DESC', job_number: 'DESC' }, comment: `${context.getTrackingId()}_${new Date().toUTCString()}`, lock: { mode: 'pessimistic_write' }, From f975ecf551b8dadd873bba371f1efee707ad413a Mon Sep 17 00:00:00 2001 From: "saito.k" Date: Tue, 16 Apr 2024 05:08:04 +0000 Subject: [PATCH 6/7] =?UTF-8?q?Merged=20PR=20869:=20Functions=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task4085: Functions修正](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/4085) - メール送信対象のアカウント取得条件を修正 - プライマリー管理者の規約同意用のカラムがNULLであった場合は、そのアカウントにはメール送信しない。 - Entityの`@Column`で設定する型が実際のパラメータの型と異なっていたため修正 - 文字列のところをDateTimeとしていた ## レビューポイント - 修正内容の認識あっているか - テストケースは足りているか ## クエリの変更 - Repositoryを変更し、クエリが変更された場合は変更内容を確認する - Before/Afterのクエリ - https://ndstokyo.sharepoint.com/:f:/r/sites/Piranha/Shared%20Documents/General/OMDS/%E3%82%AF%E3%82%A8%E3%83%AA/4085?csf=1&web=1&e=WRec5O - 35行目に変更あり(規約系のカラムがNULLではないという条件を追加) ## 動作確認状況 - ローカルで確認 - 行った修正がデグレを発生させていないことを確認できるか - 既存のテスト結果に影響なし ## 補足 - 相談、参考資料などがあれば --- .../src/entity/account.entity.ts | 4 +- .../src/entity/license.entity.ts | 8 +-- dictation_function/src/entity/user.entity.ts | 7 ++- .../src/functions/licenseAlert.ts | 7 +++ dictation_function/src/test/common/utility.ts | 14 ++++- .../src/test/licenseAlert.spec.ts | 58 ++++++++++++++++++- 6 files changed, 86 insertions(+), 12 deletions(-) diff --git a/dictation_function/src/entity/account.entity.ts b/dictation_function/src/entity/account.entity.ts index 3a1c9af..15988a6 100644 --- a/dictation_function/src/entity/account.entity.ts +++ b/dictation_function/src/entity/account.entity.ts @@ -49,7 +49,7 @@ export class Account { @Column({ nullable: true, type: "datetime" }) deleted_at: Date | null; - @Column({ nullable: true, type: "datetime" }) + @Column({ nullable: true, type: "varchar" }) created_by: string | null; @CreateDateColumn({ @@ -58,7 +58,7 @@ export class Account { }) // defaultはSQLite用設定値.本番用は別途migrationで設定 created_at: Date; - @Column({ nullable: true, type: "datetime" }) + @Column({ nullable: true, type: "varchar"}) updated_by: string | null; @UpdateDateColumn({ diff --git a/dictation_function/src/entity/license.entity.ts b/dictation_function/src/entity/license.entity.ts index 56f2f00..ca38f5a 100644 --- a/dictation_function/src/entity/license.entity.ts +++ b/dictation_function/src/entity/license.entity.ts @@ -40,7 +40,7 @@ export class License { @Column({ nullable: true, type: "bigint", transformer: bigintTransformer }) delete_order_id: number | null; - @Column({ nullable: true, type: "datetime" }) + @Column({ nullable: true, type: "varchar" }) created_by: string | null; @CreateDateColumn({ @@ -49,7 +49,7 @@ export class License { }) created_at: Date; - @Column({ nullable: true, type: "datetime" }) + @Column({ nullable: true, type: "varchar" }) updated_by: string | null; @UpdateDateColumn({ @@ -89,7 +89,7 @@ export class LicenseAllocationHistory { @Column({ nullable: true, type: "datetime" }) deleted_at: Date | null; - @Column({ nullable: true, type: "datetime" }) + @Column({ nullable: true, type: "varchar" }) created_by: string | null; @CreateDateColumn({ @@ -98,7 +98,7 @@ export class LicenseAllocationHistory { }) created_at: Date; - @Column({ nullable: true, type: "datetime" }) + @Column({ nullable: true, type: "varchar" }) updated_by: string | null; @UpdateDateColumn({ diff --git a/dictation_function/src/entity/user.entity.ts b/dictation_function/src/entity/user.entity.ts index 10032d4..d8c78f9 100644 --- a/dictation_function/src/entity/user.entity.ts +++ b/dictation_function/src/entity/user.entity.ts @@ -31,6 +31,9 @@ export class User { @Column({ nullable: true, type: "varchar" }) accepted_eula_version: string | null; + @Column({ nullable: true, type: "varchar" }) + accepted_privacy_notice_version: string | null; + @Column({ nullable: true, type: "varchar" }) accepted_dpa_version: string | null; @@ -55,7 +58,7 @@ export class User { @Column({ nullable: true, type: "datetime" }) deleted_at: Date | null; - @Column({ nullable: true, type: "datetime" }) + @Column({ nullable: true, type: "varchar" }) created_by: string | null; @CreateDateColumn({ @@ -64,7 +67,7 @@ export class User { }) // defaultはSQLite用設定値.本番用は別途migrationで設定 created_at: Date; - @Column({ nullable: true, type: "datetime" }) + @Column({ nullable: true, type: "varchar" }) updated_by: string | null; @UpdateDateColumn({ diff --git a/dictation_function/src/functions/licenseAlert.ts b/dictation_function/src/functions/licenseAlert.ts index ad4119f..b3735fc 100644 --- a/dictation_function/src/functions/licenseAlert.ts +++ b/dictation_function/src/functions/licenseAlert.ts @@ -167,9 +167,16 @@ async function getAlertMailTargetAccount( // 第五のアカウントを取得 const accountRepository = datasource.getRepository(Account); + // 管理者ユーザーが規約に同意しているアカウントのみを取得 + // プロダクト バックログ項目 4073: [保守]システムに一度もログインしていないユーザーにはライセンスアラートメールを送信しないようにしたい の対応 const accounts = await accountRepository.find({ where: { tier: TIERS.TIER5, + primaryAdminUser: { + accepted_dpa_version: Not(IsNull()), + accepted_eula_version: Not(IsNull()), + accepted_privacy_notice_version: Not(IsNull()), + }, }, relations: { primaryAdminUser: true, diff --git a/dictation_function/src/test/common/utility.ts b/dictation_function/src/test/common/utility.ts index f675ed7..3db9a67 100644 --- a/dictation_function/src/test/common/utility.ts +++ b/dictation_function/src/test/common/utility.ts @@ -96,7 +96,7 @@ export const makeTestAccount = async ( locked: d?.locked ?? false, company_name: d?.company_name ?? "test inc.", verified: d?.verified ?? true, - deleted_at: d?.deleted_at ?? "", + deleted_at: d?.deleted_at ?? null, created_by: d?.created_by ?? "test_runner", created_at: d?.created_at ?? new Date(), updated_by: d?.updated_by ?? "updater", @@ -112,8 +112,16 @@ export const makeTestAccount = async ( account_id: accountId, role: d?.role ?? "admin none", author_id: d?.author_id ?? undefined, - accepted_eula_version: d?.accepted_eula_version ?? "1.0", - accepted_dpa_version: d?.accepted_dpa_version ?? "1.0", + accepted_eula_version: + d?.accepted_eula_version !== undefined + ? d.accepted_eula_version + : "1.0", + accepted_privacy_notice_version: + d?.accepted_privacy_notice_version !== undefined + ? d.accepted_privacy_notice_version + : "1.0", + accepted_dpa_version: + d?.accepted_dpa_version !== undefined ? d.accepted_dpa_version : "1.0", email_verified: d?.email_verified ?? true, auto_renew: d?.auto_renew ?? true, notification: d?.notification ?? true, diff --git a/dictation_function/src/test/licenseAlert.spec.ts b/dictation_function/src/test/licenseAlert.spec.ts index c3891a0..f013f47 100644 --- a/dictation_function/src/test/licenseAlert.spec.ts +++ b/dictation_function/src/test/licenseAlert.spec.ts @@ -80,7 +80,7 @@ describe("licenseAlert", () => { // redisからキャッシュが削除されていることを確認 const getAsync = promisify(redisClient.keys).bind(redisClient); const keys = await getAsync(`*`); - expect(keys).toHaveLength(0); + expect(keys).toHaveLength(0); }); it("ライセンス在庫不足メール、ライセンス失効警告メールが送信されること", async () => { @@ -224,6 +224,51 @@ describe("licenseAlert", () => { const keys = await getAsync(`*`); expect(keys).toHaveLength(0); }); + + it("規約同意していない管理者ユーザーに対して、ライセンス失効警告メール・在庫不足メールが送信されないこと", async () => { + if (!source) fail(); + const context = new InvocationContext(); + const sendgridMock = new SendGridServiceMock() as SendGridService; + const adb2cMock = new AdB2cServiceMock() as AdB2cService; + + // 呼び出し回数でテスト成否を判定 + const spySend = jest.spyOn(sendgridMock, "sendMail"); + + const currentDate = new DateWithZeroTime(); + const expiringSoonDate = new DateWithDayEndTime(currentDate.getTime()); + const { account, admin } = await makeTestAccount( + source, + { tier: 5 }, + { + external_id: "external_id5", + auto_renew: false, + accepted_dpa_version: null, + accepted_eula_version: null, + accepted_privacy_notice_version: null, + } + ); + await createLicense( + source, + 1, + expiringSoonDate, + account.id, + "NORMAL", + "Allocated", + admin.id, + null, + null, + null + ); + await licenseAlertProcessing( + context, + source, + redisClient, + sendgridMock, + adb2cMock + ); + // メール送信がされていないことを確認 + expect(spySend.mock.calls).toHaveLength(0); + }); }); // テスト用sendgrid @@ -305,6 +350,17 @@ export class AdB2cServiceMock { }, ], }, + { + id: "external_id5", + displayName: "test5", + identities: [ + { + signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS, + issuer: "issuer", + issuerAssignedId: "test5@mail.com", + }, + ], + }, ]; return AdB2cMockUsers; } From 566da623bf51f28585857507c053da32f45999f1 Mon Sep 17 00:00:00 2001 From: "saito.k" Date: Wed, 17 Apr 2024 01:01:31 +0000 Subject: [PATCH 7/7] =?UTF-8?q?Merged=20PR=20873:=20dev=E5=8B=95=E4=BD=9C?= =?UTF-8?q?=E7=A2=BA=E8=AA=8D=E4=B8=8D=E5=85=B7=E5=90=88=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task4131: dev動作確認不具合修正](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/4131) - メール送信対象のアカウント取得条件を修正 - 第五階層はDPAの規約に同意することがないため、accepted_dpa_versionは常にNULLとなる - 取得条件にaccepted_dpa_versionがNOTNULLを追加するとカラムに値が入る契機がないのでアカウントを取得できなくなってしまっていた。 ## レビューポイント - 特になし ## 動作確認状況 - ローカルで確認 - 行った修正がデグレを発生させていないことを確認できるか - ほかのテストケースで使用しているユーザーデータをaccepted_dpa_versionはNULLの状態で作成するようにし、テストがすべて通ることを確認 ## 補足 - 相談、参考資料などがあれば --- .../src/functions/licenseAlert.ts | 3 ++- .../src/test/licenseAlert.spec.ts | 17 ++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/dictation_function/src/functions/licenseAlert.ts b/dictation_function/src/functions/licenseAlert.ts index b3735fc..5e7fd6d 100644 --- a/dictation_function/src/functions/licenseAlert.ts +++ b/dictation_function/src/functions/licenseAlert.ts @@ -168,12 +168,13 @@ async function getAlertMailTargetAccount( // 第五のアカウントを取得 const accountRepository = datasource.getRepository(Account); // 管理者ユーザーが規約に同意しているアカウントのみを取得 + // 第五階層が同意する規約はeulaとprivacy_noticeのみであるため、それらがnullでないことを条件に追加 + // 管理者が規約同意していない = 一度もログインしていないアカウントであるため、そのアカウントにはアラートメールを送信しない // プロダクト バックログ項目 4073: [保守]システムに一度もログインしていないユーザーにはライセンスアラートメールを送信しないようにしたい の対応 const accounts = await accountRepository.find({ where: { tier: TIERS.TIER5, primaryAdminUser: { - accepted_dpa_version: Not(IsNull()), accepted_eula_version: Not(IsNull()), accepted_privacy_notice_version: Not(IsNull()), }, diff --git a/dictation_function/src/test/licenseAlert.spec.ts b/dictation_function/src/test/licenseAlert.spec.ts index f013f47..610fe7e 100644 --- a/dictation_function/src/test/licenseAlert.spec.ts +++ b/dictation_function/src/test/licenseAlert.spec.ts @@ -54,7 +54,7 @@ describe("licenseAlert", () => { const { account, admin } = await makeTestAccount( source, { tier: 5 }, - { external_id: "external_id1" } + { external_id: "external_id1", accepted_dpa_version: null } ); await createLicense( source, @@ -97,7 +97,11 @@ describe("licenseAlert", () => { const { account, admin } = await makeTestAccount( source, { tier: 5 }, - { external_id: "external_id2", auto_renew: false } + { + external_id: "external_id2", + auto_renew: false, + accepted_dpa_version: null, + } ); await createLicense( source, @@ -141,7 +145,7 @@ describe("licenseAlert", () => { const { account, admin } = await makeTestAccount( source, { tier: 5 }, - { external_id: "external_id3" } + { external_id: "external_id3", accepted_dpa_version: null } ); await createLicense( source, @@ -196,7 +200,11 @@ describe("licenseAlert", () => { const { account, admin } = await makeTestAccount( source, { tier: 5 }, - { external_id: "external_id4", auto_renew: true } + { + external_id: "external_id4", + auto_renew: true, + accepted_dpa_version: null, + } ); await createLicense( source, @@ -242,7 +250,6 @@ describe("licenseAlert", () => { { external_id: "external_id5", auto_renew: false, - accepted_dpa_version: null, accepted_eula_version: null, accepted_privacy_notice_version: null, }