From 9ca9b7a1445ebb829a850bb7815c1c1003359fc9 Mon Sep 17 00:00:00 2001
From: Kentaro Fukunaga
Date: Thu, 29 Feb 2024 06:36:23 +0000
Subject: [PATCH 01/13] =?UTF-8?q?Merged=20PR=20790:=20Author=E3=81=AENotif?=
=?UTF-8?q?ication=E3=83=95=E3=83=A9=E3=82=B0=E3=82=92=E8=A6=8B=E3=81=A6?=
=?UTF-8?q?=E3=82=BF=E3=82=B9=E3=82=AF=E5=AE=8C=E4=BA=86=E3=83=A1=E3=83=BC?=
=?UTF-8?q?=E3=83=AB=E3=81=AE=E9=80=81=E4=BF=A1=E5=85=88=E3=82=92=E5=A4=89?=
=?UTF-8?q?=E6=9B=B4=E3=81=99=E3=82=8B=E3=82=88=E3=81=86=E4=BF=AE=E6=AD=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## 概要
[Task3818: 対応](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3818)
- AuthorのNotificationフラグがOFFのときには、Authorに対してタスク完了通知メールが送信されないよう修正しました。
## レビューポイント
- 動作確認項目に不足はないか?
## 動作確認状況
- ローカルで確認しました
- AuthorのNotificationON時にはメール宛先に入っており、OFF時には宛先から外れること
- TypistはNotificationON/OFF関わらずメール宛先に入っていること
---
dictation_server/src/features/tasks/tasks.service.ts | 5 +++--
dictation_server/src/gateways/sendgrid/sendgrid.service.ts | 4 ++--
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/dictation_server/src/features/tasks/tasks.service.ts b/dictation_server/src/features/tasks/tasks.service.ts
index 7b7c127..898a8f9 100644
--- a/dictation_server/src/features/tasks/tasks.service.ts
+++ b/dictation_server/src/features/tasks/tasks.service.ts
@@ -435,7 +435,7 @@ export class TasksService {
`author_id not found. audioFileId: ${audioFileId}. account_id: ${user.account_id}`,
);
}
- const { external_id: authorExternalId } =
+ const { external_id: authorExternalId, notification: authorNotification } =
await this.usersRepository.findUserByAuthorId(
context,
task.file.author_id,
@@ -454,6 +454,7 @@ export class TasksService {
]);
// メール送信に必要な情報を取得
+ // Author通知ON/OFF関わらずAuthor名は必要なため、情報の取得は行う
const author = usersInfo.find((x) => x.id === authorExternalId);
if (!author) {
throw new Error(`author not found. id=${authorExternalId}`);
@@ -488,7 +489,7 @@ export class TasksService {
// メール送信
this.sendgridService.sendMailWithU117(
context,
- authorEmail,
+ authorNotification ? authorEmail : null,
typistEmail,
authorName,
task.file.file_name.replace('.zip', ''),
diff --git a/dictation_server/src/gateways/sendgrid/sendgrid.service.ts b/dictation_server/src/gateways/sendgrid/sendgrid.service.ts
index 17fa39b..ac9a5df 100644
--- a/dictation_server/src/gateways/sendgrid/sendgrid.service.ts
+++ b/dictation_server/src/gateways/sendgrid/sendgrid.service.ts
@@ -875,7 +875,7 @@ export class SendGridService {
*/
async sendMailWithU117(
context: Context,
- authorEmail: string,
+ authorEmail: string | null,
typistEmail: string,
authorName: string,
fileName: string,
@@ -903,7 +903,7 @@ export class SendGridService {
// メールを送信する
await this.sendMail(
context,
- [authorEmail, typistEmail],
+ [authorEmail, typistEmail].filter((x): x is string => x !== null), // authorEmailがnullの場合は除外する
[],
this.mailFrom,
subject,
From 0ebd2ab17eadc50d53a51539b9557871dd802a09 Mon Sep 17 00:00:00 2001
From: "maruyama.t"
Date: Thu, 29 Feb 2024 06:55:34 +0000
Subject: [PATCH 02/13] =?UTF-8?q?Merged=20PR=20793:=20account=E3=81=AB?=
=?UTF-8?q?=E5=90=8D=E5=89=8D=E3=81=8C=E3=81=AA=E3=81=84=E3=83=87=E3=83=BC?=
=?UTF-8?q?=E3=82=BF=E3=81=8C=E5=AD=98=E5=9C=A8=E3=81=99=E3=82=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## 概要
[Task3831: accountに名前がないデータが存在する](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3831)
移行元データのアカウントユーザーにfirtst_nameおよびlast_nameが存在しない行が存在しており、
変換ツール側で対応していなかったためAdminNameが空のアカウントユーザーを作成しようとして登録ツール側でエラーになってしまっていた。
→バックログに起票しOMDSさんに確認中
■暫定対応
first_name\last_nameが存在しない場合はユーザーと同様にメールアドレスをAdminNameとするように修正。
## レビューポイント
- とくになし
## 動作確認状況
- ローカルで確認
## 補足
- 相談、参考資料などがあれば
---
.../server/src/features/transfer/transfer.service.ts | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/data_migration_tools/server/src/features/transfer/transfer.service.ts b/data_migration_tools/server/src/features/transfer/transfer.service.ts
index 34102cb..269f609 100644
--- a/data_migration_tools/server/src/features/transfer/transfer.service.ts
+++ b/data_migration_tools/server/src/features/transfer/transfer.service.ts
@@ -63,8 +63,13 @@ export class TransferService {
(country) => country.label === line.country
)?.value;
// adminNameの変換(last_name + " "+ first_name)
- const adminName = `${line.last_name} ${line.first_name}`;
-
+ // もしline.last_nameとline.first_nameが存在しない場合、line.admin_mailをnameにする
+ let adminName = line.email;
+ if (line.last_name && line.first_name) {
+ adminName = `${line.last_name} ${line.first_name}`;
+ // スペースが前後に入っている場合があるのでTrimする
+ adminName = adminName.trim();
+ }
// ランダムパスワードの生成(データ登録ツール側で行うのでやらない)
// common/password/password.tsのmakePasswordを使用
// const autoGeneratedPassword = makePassword();
From cad3a99f705ec51c07526386eb959a55f8836806 Mon Sep 17 00:00:00 2001
From: "maruyama.t"
Date: Thu, 29 Feb 2024 12:50:17 +0000
Subject: [PATCH 03/13] =?UTF-8?q?Merged=20PR=20794:=20=E7=99=BB=E9=8C=B2?=
=?UTF-8?q?=E3=83=84=E3=83=BC=E3=83=AB=E3=81=AB=E3=83=AD=E3=82=B0=E3=82=92?=
=?UTF-8?q?=E4=BB=95=E8=BE=BC=E3=82=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## 概要
[Task3839: 登録ツールにログを仕込む](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3839)
登録ツールが途中で動かなくなってしまう原因調査のために各関数にログを仕込みました。
## レビューポイント
- 特になし
## 動作確認状況
- ローカルで確認
## 補足
- 相談、参考資料などがあれば
---
.../server/src/common/password/password.ts | 8 +++++++-
.../server/src/features/accounts/accounts.service.ts | 3 +++
.../server/src/features/register/register.controller.ts | 3 +++
.../server/src/features/users/users.service.ts | 6 +++++-
.../server/src/gateways/adb2c/adb2c.service.ts | 3 +++
5 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/data_migration_tools/server/src/common/password/password.ts b/data_migration_tools/server/src/common/password/password.ts
index 6fbe071..15d52ce 100644
--- a/data_migration_tools/server/src/common/password/password.ts
+++ b/data_migration_tools/server/src/common/password/password.ts
@@ -18,7 +18,8 @@ export const makePassword = (): string => {
let autoGeneratedPassword: string = "";
while (!valid) {
- // パスワードをランダムに決定
+ autoGeneratedPassword = "";
+ // パスワードをランダムに決定+
while (autoGeneratedPassword.length < passLength) {
// 上で決定したcharsの中からランダムに1文字ずつ追加
const index = Math.floor(Math.random() * chars.length);
@@ -30,6 +31,11 @@ export const makePassword = (): string => {
valid =
autoGeneratedPassword.length == passLength &&
charaTypePattern.test(autoGeneratedPassword);
+ if (!valid) {
+ // autoGeneratedPasswordをログに出す
+ console.log("Password is not valid");
+ console.log(autoGeneratedPassword);
+ }
}
return autoGeneratedPassword;
};
diff --git a/data_migration_tools/server/src/features/accounts/accounts.service.ts b/data_migration_tools/server/src/features/accounts/accounts.service.ts
index 2954cbd..fdfb458 100644
--- a/data_migration_tools/server/src/features/accounts/accounts.service.ts
+++ b/data_migration_tools/server/src/features/accounts/accounts.service.ts
@@ -79,6 +79,7 @@ export class AccountsService {
HttpStatus.INTERNAL_SERVER_ERROR
);
}
+ this.logger.log("idpにユーザーを作成成功");
// メールアドレス重複エラー
if (isConflictError(externalUser)) {
@@ -90,6 +91,7 @@ export class AccountsService {
HttpStatus.BAD_REQUEST
);
}
+ this.logger.log("メールアドレスは重複していません");
let account: Account;
let user: User;
@@ -138,6 +140,7 @@ export class AccountsService {
account.id,
country
);
+ this.logger.log("コンテナー作成成功");
} catch (e) {
this.logger.error(`[${context.getTrackingId()}] error=${e}`);
this.logger.error(
diff --git a/data_migration_tools/server/src/features/register/register.controller.ts b/data_migration_tools/server/src/features/register/register.controller.ts
index cb36d2a..d9b968f 100644
--- a/data_migration_tools/server/src/features/register/register.controller.ts
+++ b/data_migration_tools/server/src/features/register/register.controller.ts
@@ -106,8 +106,10 @@ export class RegisterController {
}
for (const AccountsFile of accountsObject) {
+ this.logger.log("ランダムパスワード生成開始");
// ランダムなパスワードを生成する
const ramdomPassword = makePassword();
+ this.logger.log("ランダムパスワード生成完了");
// roleの設定
// roleの値がnullなら"none"、null以外ならroleの値、
// また、roleの値が"author"なら"author"を設定
@@ -123,6 +125,7 @@ export class RegisterController {
// ありえないが、roleの値が"none"または"author"の文字列以外の場合はエラーを返す
throw new Error("Invalid role value");
}
+ this.logger.log("account生成開始");
await this.accountsService.createAccount(
context,
AccountsFile.companyName,
diff --git a/data_migration_tools/server/src/features/users/users.service.ts b/data_migration_tools/server/src/features/users/users.service.ts
index cb639cd..8134462 100644
--- a/data_migration_tools/server/src/features/users/users.service.ts
+++ b/data_migration_tools/server/src/features/users/users.service.ts
@@ -74,6 +74,9 @@ export class UsersService {
accountId,
authorId
);
+ this.logger.log(
+ `[${context.getTrackingId()}] isAuthorIdDuplicated=${isAuthorIdDuplicated}`
+ );
} catch (e) {
this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw new HttpException(
@@ -88,9 +91,10 @@ export class UsersService {
);
}
}
-
+ this.logger.log("ランダムパスワード生成開始");
// ランダムなパスワードを生成する
const ramdomPassword = makePassword();
+ this.logger.log("ランダムパスワード生成完了");
//Azure AD B2Cにユーザーを新規登録する
let externalUser: { sub: string } | ConflictError;
diff --git a/data_migration_tools/server/src/gateways/adb2c/adb2c.service.ts b/data_migration_tools/server/src/gateways/adb2c/adb2c.service.ts
index 5ba0f0e..5dbe646 100644
--- a/data_migration_tools/server/src/gateways/adb2c/adb2c.service.ts
+++ b/data_migration_tools/server/src/gateways/adb2c/adb2c.service.ts
@@ -82,6 +82,9 @@ export class AdB2cService {
},
],
});
+ this.logger.log(
+ `[${context.getTrackingId()}] [ADB2C CREATE] newUser: ${newUser}`
+ );
return { sub: newUser.id };
} catch (e) {
this.logger.error(`[${context.getTrackingId()}] error=${e}`);
From 88ce6a2c9e399e92c622ecefea1cf45cecddeab2 Mon Sep 17 00:00:00 2001
From: masaaki
Date: Fri, 1 Mar 2024 12:00:42 +0000
Subject: [PATCH 04/13] =?UTF-8?q?Merged=20PR=20796:=20[3=E5=9B=9E=E7=9B=AE?=
=?UTF-8?q?=E5=AE=9F=E8=A1=8C][=E3=83=95=E3=83=AB=E3=83=87=E3=83=BC?=
=?UTF-8?q?=E3=82=BF]develop=E7=92=B0=E5=A2=83=E3=81=A7=E3=81=AE=E7=A7=BB?=
=?UTF-8?q?=E8=A1=8C=E5=AE=9F=E6=96=BD=E5=BE=8C=E3=81=AE=E4=BF=AE=E6=AD=A3?=
=?UTF-8?q?=E4=BD=9C=E6=A5=AD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## 概要
[Task3802: [3回目実行][フルデータ]develop環境での移行実施後の修正作業](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3802)
- 元PBI or タスクへのリンク(内容・目的などはそちらにあるはず)
- 何をどう変更したか、追加したライブラリなど
- このPull Requestでの対象/対象外
- 影響範囲(他の機能にも影響があるか)
## レビューポイント
- 特にレビューしてほしい箇所
- 軽微なものや自明なものは記載不要
- 修正範囲が大きい場合などに記載
- 全体的にや仕様を満たしているか等は本当に必要な時のみ記載
## UIの変更
- Before/Afterのスクショなど
- スクショ置き場
## 動作確認状況
- ローカルで確認、develop環境で確認など
## 補足
- 相談、参考資料などがあれば
---
.../features/transfer/transfer.controller.ts | 105 ++++++------
.../src/features/transfer/transfer.service.ts | 160 +++++++++++++-----
.../verification/verification.service.ts | 53 ++++--
3 files changed, 221 insertions(+), 97 deletions(-)
diff --git a/data_migration_tools/server/src/features/transfer/transfer.controller.ts b/data_migration_tools/server/src/features/transfer/transfer.controller.ts
index ee38969..507ed3f 100644
--- a/data_migration_tools/server/src/features/transfer/transfer.controller.ts
+++ b/data_migration_tools/server/src/features/transfer/transfer.controller.ts
@@ -73,7 +73,8 @@ export class TransferController {
const matchList = line.match(regExp);
if (matchList) {
matchList.forEach((match) => {
- const replaced = match.replace(/,/g, " ");
+ // カンマを\に変換
+ const replaced = match.replace(/,/g, "\\");
line = line.replace(match, replaced);
});
}
@@ -95,49 +96,50 @@ export class TransferController {
HttpStatus.BAD_REQUEST
);
}
-
- csvInputFile.push({
- type: data[0],
- account_id: data[1],
- parent_id: data[2],
- email: data[3],
- company_name: data[4],
- first_name: data[5],
- last_name: data[6],
- country: data[7],
- state: data[8],
- start_date: data[9],
- expired_date: data[10],
- user_email: data[11],
- author_id: data[12],
- recording_mode: data[13],
- wt1: data[14],
- wt2: data[15],
- wt3: data[16],
- wt4: data[17],
- wt5: data[18],
- wt6: data[19],
- wt7: data[20],
- wt8: data[21],
- wt9: data[22],
- wt10: data[23],
- wt11: data[24],
- wt12: data[25],
- wt13: data[26],
- wt14: data[27],
- wt15: data[28],
- wt16: data[29],
- wt17: data[30],
- wt18: data[31],
- wt19: data[32],
- wt20: data[33],
- });
+ // data[1]がundefinedの場合、配列には格納しない
+ if (data[1] !== undefined) {
+ // バックスラッシュをカンマに戻す
+ data.forEach((value, index) => {
+ data[index] = value.replace(/\\/g, ",");
+ });
+ csvInputFile.push({
+ type: data[0],
+ account_id: data[1],
+ parent_id: data[2],
+ email: data[3],
+ company_name: data[4],
+ first_name: data[5],
+ last_name: data[6],
+ country: data[7],
+ state: data[8],
+ start_date: data[9],
+ expired_date: data[10],
+ user_email: data[11],
+ author_id: data[12],
+ recording_mode: data[13],
+ wt1: data[14],
+ wt2: data[15],
+ wt3: data[16],
+ wt4: data[17],
+ wt5: data[18],
+ wt6: data[19],
+ wt7: data[20],
+ wt8: data[21],
+ wt9: data[22],
+ wt10: data[23],
+ wt11: data[24],
+ wt12: data[25],
+ wt13: data[26],
+ wt14: data[27],
+ wt15: data[28],
+ wt16: data[29],
+ wt17: data[30],
+ wt18: data[31],
+ wt19: data[32],
+ wt20: data[33],
+ });
+ }
});
- // 最後の行がundefinedの場合はその行を削除
- if (csvInputFile[csvInputFile.length - 1].account_id === undefined) {
- csvInputFile.pop();
- }
-
// 各データのバリデーションチェック
await this.transferService.validateInputData(context, csvInputFile);
@@ -153,12 +155,12 @@ export class TransferController {
// アカウントID numberとstring対応表の出力
const accountsMappingFiles: AccountsMappingFile[] = [];
accountIdMap.forEach((value, key) => {
- const accountsMappingFile = new AccountsMappingFile();
+ const accountsMappingFile = new AccountsMappingFile();
accountsMappingFile.accountIdNumber = value;
- accountsMappingFile.accountIdText = key
- accountsMappingFiles.push(accountsMappingFile)
+ accountsMappingFile.accountIdText = key;
+ accountsMappingFiles.push(accountsMappingFile);
});
-
+
fs.writeFileSync(
`${inputFilePath}account_map.json`,
JSON.stringify(accountsMappingFiles)
@@ -188,6 +190,13 @@ export class TransferController {
LicensesFile
);
+ // AuthorIDが重複している場合通番を付与する
+ const transferDuplicateAuthorResultUsers =
+ await this.transferService.transferDuplicateAuthor(
+ context,
+ resultDuplicateEmail.usersFileLines
+ );
+
// transferResponseCsvを4つのJSONファイルの出力する(出力先はinputと同じにする)
const outputFilePath = body.inputFilePath;
const WorktypesFile = transferResponseCsv.worktypesFileLines;
@@ -195,7 +204,7 @@ export class TransferController {
context,
outputFilePath,
resultDuplicateEmail.accountsFileLines,
- resultDuplicateEmail.usersFileLines,
+ transferDuplicateAuthorResultUsers,
resultDuplicateEmail.licensesFileLines,
WorktypesFile
);
diff --git a/data_migration_tools/server/src/features/transfer/transfer.service.ts b/data_migration_tools/server/src/features/transfer/transfer.service.ts
index 269f609..60b8d5c 100644
--- a/data_migration_tools/server/src/features/transfer/transfer.service.ts
+++ b/data_migration_tools/server/src/features/transfer/transfer.service.ts
@@ -54,6 +54,12 @@ export class TransferService {
let userIdIndex = 0;
// authorIdとuserIdの対応関係を保持するMapを定義
const authorIdToUserIdMap: Map = new Map();
+
+ // countryのリストを生成
+ const countryAccounts = csvInputFile.filter(
+ (item) => item.type === "Country"
+ );
+
// csvInputFileを一行読み込みする
csvInputFile.forEach((line) => {
// typeが"USER"以外の場合、アカウントデータの作成を行う
@@ -105,8 +111,13 @@ export class TransferService {
authorId: null,
});
} else {
- // typeが"USER"の場合
- if (line.type == MIGRATION_TYPE.USER) {
+ // typeが"USER"の場合、かつcountryのアカウントIDに所属していない場合
+ if (
+ line.type == MIGRATION_TYPE.USER &&
+ !countryAccounts.some(
+ (countryAccount) => countryAccount.account_id === line.account_id
+ )
+ ) {
// line.author_idが存在する場合のみユーザーデータを作成する
if (line.author_id) {
// userIdIndexをインクリメントする
@@ -229,46 +240,38 @@ export class TransferService {
const relocatedAccounts: AccountsFile[] = [];
const dealerRecords: Map = new Map();
- // accountsFileTypeをループ
- accountsFileType.forEach((account) => {
- // Distributorの場合はdealerを検索し、COUNTRYかチェックする
- if (account.type === MIGRATION_TYPE.DISTRIBUTOR) {
- const distributorParent = accountsFileType.find(
- (a) => a.accountId === account.dealerAccountId
- );
- if (distributorParent.type === MIGRATION_TYPE.COUNTRY) {
- dealerRecords.set(
- account.accountId,
- distributorParent.dealerAccountId // Countryの親、BCのIDを設定
- );
+ const countryAccounts = accountsFileType.filter(
+ (item) => item.type === MIGRATION_TYPE.COUNTRY
+ );
+
+ const notCountryAccounts = accountsFileType.filter(
+ (item) => item.type !== MIGRATION_TYPE.COUNTRY
+ );
+
+ notCountryAccounts.forEach((notCountryAccount) => {
+ let assignDealerAccountId = notCountryAccount.dealerAccountId;
+ // 親アカウントIDがcountryの場合、countryの親アカウントIDを設定する
+ for (const countryAccount of countryAccounts) {
+ if (countryAccount.accountId === notCountryAccount.dealerAccountId) {
+ assignDealerAccountId = countryAccount.dealerAccountId;
}
- } else {
- dealerRecords.set(account.accountId, account.dealerAccountId);
}
- });
- // AccountsFileTypeのループを行い、階層情報の置換と新たな配列へのpushを行う
- accountsFileType.forEach((account) => {
- // Countryのレコードは除外する
- if (account.type !== MIGRATION_TYPE.COUNTRY) {
- const dealerAccountId =
- dealerRecords.get(account.accountId) ?? account.dealerAccountId;
- const type = this.getAccountType(account.type);
- const newAccount: AccountsFile = {
- accountId: account.accountId,
- type: type,
- companyName: account.companyName,
- country: account.country,
- dealerAccountId: dealerAccountId,
- adminName: account.adminName,
- adminMail: account.adminMail,
- userId: account.userId,
- role: account.role,
- authorId: account.authorId,
- };
+ const assignType = this.getAccountType(notCountryAccount.type);
- relocatedAccounts.push(newAccount);
- }
+ const newAccount: AccountsFile = {
+ accountId: notCountryAccount.accountId,
+ type: assignType,
+ companyName: notCountryAccount.companyName,
+ country: notCountryAccount.country,
+ dealerAccountId: assignDealerAccountId,
+ adminName: notCountryAccount.adminName,
+ adminMail: notCountryAccount.adminMail,
+ userId: notCountryAccount.userId,
+ role: notCountryAccount.role,
+ authorId: notCountryAccount.authorId,
+ };
+ relocatedAccounts.push(newAccount);
});
return relocatedAccounts;
@@ -364,6 +367,8 @@ export class TransferService {
);
try {
+ // エラー配列を定義
+ let errorArray: string[] = [];
// アカウントに対するworktypeのMap配列を作成する
const accountWorktypeMap = new Map();
// csvInputFileのバリデーションチェックを行う
@@ -383,6 +388,13 @@ export class TransferService {
HttpStatus.BAD_REQUEST
);
}
+ // typeがUSER以外の場合で、countryがnullの場合エラー配列に格納する
+ if (line.type !== MIGRATION_TYPE.USER) {
+ if (!line.country) {
+ // countryがnullの場合エラー配列に格納する
+ errorArray.push(`country is null. index=${index}`);
+ }
+ }
// countryのバリデーションチェック
if (line.country) {
if (!COUNTRY_LIST.find((country) => country.label === line.country)) {
@@ -451,6 +463,15 @@ export class TransferService {
}
}
});
+ // エラー配列に値が存在する場合はエラーファイルを出力する
+ if (errorArray.length > 0) {
+ const errorFileJson = JSON.stringify(errorArray);
+ fs.writeFileSync(`error.json`, errorFileJson);
+ throw new HttpException(
+ `errorArray is invalid. errorArray=${errorArray}`,
+ HttpStatus.BAD_REQUEST
+ );
+ }
} catch (e) {
this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw new HttpException(
@@ -603,4 +624,67 @@ export class TransferService {
);
}
}
+
+ /**
+ * transferDuplicateAuthor
+ * @param usersFileLines: UsersFile[]
+ * @returns UsersFile[]
+ */
+ async transferDuplicateAuthor(
+ context: Context,
+ usersFileLines: UsersFile[]
+ ): Promise {
+ // パラメータ内容が長大なのでログには出さない
+ this.logger.log(
+ `[IN] [${context.getTrackingId()}] ${this.transferDuplicateAuthor.name}`
+ );
+
+ try {
+ const newUsersFileLines: UsersFile[] = [];
+
+ let processingAccountId: number = 0; //処理中のアカウントID
+ let duplicateSequence: number = 2;
+ let authorIdList: String[] = [];
+ for (const user of usersFileLines) {
+ if (user.accountId !== processingAccountId) {
+ //アカウントIDが別になった場合、通番を初期化する
+ duplicateSequence = 2;
+ processingAccountId = user.accountId;
+ authorIdList = [];
+ }
+ let assignAuthorId = user.authorId;
+ if (authorIdList.includes(user.authorId)) {
+ // 同じauthorIdがいる場合、自分のauthorIdに連番を付与する
+ assignAuthorId = assignAuthorId + duplicateSequence;
+ duplicateSequence = duplicateSequence + 1;
+ }
+ authorIdList.push(user.authorId);
+
+ // 新しいAuthorIdのユーザに詰め替え
+ const newUser: UsersFile = {
+ accountId: user.accountId,
+ userId: user.userId,
+ name: user.name,
+ role: user.role,
+ authorId: assignAuthorId,
+ email: user.email,
+ };
+ newUsersFileLines.push(newUser);
+ }
+
+ return newUsersFileLines;
+ } catch (e) {
+ this.logger.error(`[${context.getTrackingId()}] error=${e}`);
+ throw new HttpException(
+ makeErrorResponse("E009999"),
+ HttpStatus.INTERNAL_SERVER_ERROR
+ );
+ } finally {
+ this.logger.log(
+ `[OUT] [${context.getTrackingId()}] ${
+ this.transferDuplicateAuthor.name
+ }`
+ );
+ }
+ }
}
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 1de9596..4fda7d7 100644
--- a/data_migration_tools/server/src/features/verification/verification.service.ts
+++ b/data_migration_tools/server/src/features/verification/verification.service.ts
@@ -53,9 +53,11 @@ export class VerificationService {
// 件数情報の取得
this.logger.log(`入力ファイルから件数情報を取得する`);
- const accountCountFromFile = csvInputFiles.filter(
+ const accountFromFile = csvInputFiles.filter(
(item) => item.type !== "USER" && item.type !== "Country"
- ).length;
+ );
+ const accountCountFromFile = accountFromFile.length;
+
const cardLicensesCountFromFile = cardlicensesInputFiles.length;
const licensesCountFromFile =
@@ -66,18 +68,35 @@ export class VerificationService {
// 管理ユーザ数のカウント
const administratorCountFromFile = accountCountFromFile;
+
// 一般ユーザ数のカウント
- const normaluserCountFromFile = csvInputFiles.filter(
- (item) => item.type === "USER" && item.user_email.length !== 0
- ).length;
+ // countryのアカウントに所属するユーザをカウント対象外とする
+ const countryAccountFromFile = csvInputFiles.filter(
+ (item) => item.type === "Country"
+ );
+
+ // USER、かつuser_emailが設定なし、かつcountryのアカウントID以外をユーザとする
+ const normaluserFromFile = csvInputFiles.filter(
+ (item) =>
+ item.type === "USER" &&
+ item.user_email.length !== 0 &&
+ !countryAccountFromFile.some(
+ (countryItem) => countryItem.account_id === item.account_id
+ )
+ );
+
+ const normaluserCountFromFile = normaluserFromFile.length;
// ユーザ重複数のカウント
let mailAdresses: string[] = [];
- csvInputFiles.forEach((item) => {
- // メールアドレスの要素を配列に追加(入力データとして管理者とユーザの両方に入ることはない)
+ accountFromFile.forEach((item) => {
+ // メールアドレスの要素を配列に追加
if (item.email.length !== 0) {
mailAdresses.push(item.email);
}
+ });
+ normaluserFromFile.forEach((item) => {
+ // メールアドレスの要素を配列に追加
if (item.user_email.length !== 0) {
mailAdresses.push(item.user_email);
}
@@ -232,7 +251,11 @@ export class VerificationService {
}
// dateを任意のフォーマットに変換する
-const getFormattedDate = (date: Date | null, format: string) => {
+const getFormattedDate = (
+ date: Date | null,
+ format: string,
+ padHours: boolean = false // trueの場合、hhについてゼロパディングする(00→0、01→1、23→23)
+) => {
if (!date) {
return null;
}
@@ -244,9 +267,13 @@ const getFormattedDate = (date: Date | null, format: string) => {
s: date.getSeconds(),
};
+ // hhの値をゼロパディングするかどうかのフラグを確認
+ const hourSymbol = padHours ? "hh" : "h";
+
const formatted = format.replace(/(M+|d+|h+|m+|s+)/g, (v) =>
(
- (v.length > 1 ? "0" : "") + symbol[v.slice(-1) as keyof typeof symbol]
+ (v.length > 1 && v !== hourSymbol ? "0" : "") +
+ symbol[v.slice(-1) as keyof typeof symbol]
).slice(-2)
);
@@ -542,12 +569,15 @@ function compareLicenses(
VerificationResultDetails.push(VerificationResultDetailsOne);
isNoError = false;
}
+
+ // expiry_dateについて、時はゼロパディングした値で比較する(×01~09 ○1~9)
if (
!licensesFromDatabase[i] ||
licensesFromFile[i].expired_date !==
getFormattedDate(
licensesFromDatabase[i].expiry_date,
- `yyyy/MM/dd hh:mm:ss`
+ `yyyy/MM/dd hh:mm:ss`,
+ true
)
) {
const VerificationResultDetailsOne: VerificationResultDetails = {
@@ -559,7 +589,8 @@ function compareLicenses(
databaseData: licensesFromDatabase[i]
? getFormattedDate(
licensesFromDatabase[i].expiry_date,
- `yyyy/MM/dd hh:mm:ss`
+ `yyyy/MM/dd hh:mm:ss`,
+ true
)
: "undifined",
reason: "内容不一致",
From a47ebaa9dfb668bf44c1f5308eb1d37f503976ba Mon Sep 17 00:00:00 2001
From: masaaki
Date: Sat, 2 Mar 2024 02:21:19 +0000
Subject: [PATCH 05/13] =?UTF-8?q?Merged=20PR=20798:=20[4=E5=9B=9E=E7=9B=AE?=
=?UTF-8?q?=E5=AE=9F=E8=A1=8C][=E3=83=95=E3=83=AB=E3=83=87=E3=83=BC?=
=?UTF-8?q?=E3=82=BF]develop=E7=92=B0=E5=A2=83=E3=81=A7=E3=81=AE=E7=A7=BB?=
=?UTF-8?q?=E8=A1=8C=E5=AE=9F=E6=96=BD=E5=BE=8C=E3=81=AE=E4=BF=AE=E6=AD=A3?=
=?UTF-8?q?=E4=BD=9C=E6=A5=AD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## 概要
[Task3821: [4回目実行][フルデータ]develop環境での移行実施後の修正作業](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3821)
- 元PBI or タスクへのリンク(内容・目的などはそちらにあるはず)
- 移行ツールに対して以下の修正を実施しました。
- アカウントとユーザ間でAuthorIDが重複する際、通番を付与して重複を避けるようにしました
- AADB2Cのエラー発生時、リトライ処理を行うように対応しました
## レビューポイント
- 特にありません
## UIの変更
- 無し
## 動作確認状況
- ローカルで確認
## 補足
- 相談、参考資料などがあれば
---
.../features/transfer/transfer.controller.ts | 1 +
.../src/features/transfer/transfer.service.ts | 61 +++++++-------
.../src/gateways/adb2c/adb2c.service.ts | 81 +++++++++++--------
3 files changed, 82 insertions(+), 61 deletions(-)
diff --git a/data_migration_tools/server/src/features/transfer/transfer.controller.ts b/data_migration_tools/server/src/features/transfer/transfer.controller.ts
index 507ed3f..c3c2dce 100644
--- a/data_migration_tools/server/src/features/transfer/transfer.controller.ts
+++ b/data_migration_tools/server/src/features/transfer/transfer.controller.ts
@@ -194,6 +194,7 @@ export class TransferController {
const transferDuplicateAuthorResultUsers =
await this.transferService.transferDuplicateAuthor(
context,
+ resultDuplicateEmail.accountsFileLines,
resultDuplicateEmail.usersFileLines
);
diff --git a/data_migration_tools/server/src/features/transfer/transfer.service.ts b/data_migration_tools/server/src/features/transfer/transfer.service.ts
index 60b8d5c..8168c04 100644
--- a/data_migration_tools/server/src/features/transfer/transfer.service.ts
+++ b/data_migration_tools/server/src/features/transfer/transfer.service.ts
@@ -627,11 +627,13 @@ export class TransferService {
/**
* transferDuplicateAuthor
+ * @param accountsFileLines: AccountsFile[]
* @param usersFileLines: UsersFile[]
* @returns UsersFile[]
*/
async transferDuplicateAuthor(
context: Context,
+ accountsFileLines: AccountsFile[],
usersFileLines: UsersFile[]
): Promise {
// パラメータ内容が長大なのでログには出さない
@@ -642,34 +644,39 @@ export class TransferService {
try {
const newUsersFileLines: UsersFile[] = [];
- let processingAccountId: number = 0; //処理中のアカウントID
- let duplicateSequence: number = 2;
- let authorIdList: String[] = [];
- for (const user of usersFileLines) {
- if (user.accountId !== processingAccountId) {
- //アカウントIDが別になった場合、通番を初期化する
- duplicateSequence = 2;
- processingAccountId = user.accountId;
- authorIdList = [];
- }
- let assignAuthorId = user.authorId;
- if (authorIdList.includes(user.authorId)) {
- // 同じauthorIdがいる場合、自分のauthorIdに連番を付与する
- assignAuthorId = assignAuthorId + duplicateSequence;
- duplicateSequence = duplicateSequence + 1;
- }
- authorIdList.push(user.authorId);
+ for (const accountsFileLine of accountsFileLines) {
+ let duplicateSequence: number = 2;
+ let authorIdList: String[] = [];
- // 新しいAuthorIdのユーザに詰め替え
- const newUser: UsersFile = {
- accountId: user.accountId,
- userId: user.userId,
- name: user.name,
- role: user.role,
- authorId: assignAuthorId,
- email: user.email,
- };
- newUsersFileLines.push(newUser);
+ // メールアドレス重複時はアカウントにもAuthorIdが設定されるので重複チェック用のリストに追加しておく
+ if (accountsFileLine.authorId) {
+ authorIdList.push(accountsFileLine.authorId);
+ }
+
+ const targetaccountUsers = usersFileLines.filter(
+ (item) => item.accountId === accountsFileLine.accountId
+ );
+
+ for (const targetaccountUser of targetaccountUsers) {
+ let assignAuthorId = targetaccountUser.authorId;
+ if (authorIdList.includes(targetaccountUser.authorId)) {
+ // 同じauthorIdがいる場合、自分のauthorIdに連番を付与する
+ assignAuthorId = assignAuthorId + duplicateSequence;
+ duplicateSequence = duplicateSequence + 1;
+ }
+ authorIdList.push(targetaccountUser.authorId);
+
+ // 新しいAuthorIdのユーザに詰め替え
+ const newUser: UsersFile = {
+ accountId: targetaccountUser.accountId,
+ userId: targetaccountUser.userId,
+ name: targetaccountUser.name,
+ role: targetaccountUser.role,
+ authorId: assignAuthorId,
+ email: targetaccountUser.email,
+ };
+ newUsersFileLines.push(newUser);
+ }
}
return newUsersFileLines;
diff --git a/data_migration_tools/server/src/gateways/adb2c/adb2c.service.ts b/data_migration_tools/server/src/gateways/adb2c/adb2c.service.ts
index 5dbe646..afb2ab2 100644
--- a/data_migration_tools/server/src/gateways/adb2c/adb2c.service.ts
+++ b/data_migration_tools/server/src/gateways/adb2c/adb2c.service.ts
@@ -64,44 +64,57 @@ export class AdB2cService {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.createUser.name}`
);
- try {
- // ユーザをADB2Cに登録
- const newUser = await this.graphClient.api("users/").post({
- accountEnabled: true,
- displayName: username,
- passwordPolicies: "DisableStrongPassword",
- passwordProfile: {
- forceChangePasswordNextSignIn: false,
- password: password,
- },
- identities: [
- {
- signinType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
- issuer: `${this.tenantName}.onmicrosoft.com`,
- issuerAssignedId: email,
+
+ const retryCount: number = 3;
+ let retry = 0;
+
+ while (retry < retryCount) {
+ try {
+ // ユーザをADB2Cに登録
+ const newUser = await this.graphClient.api("users/").post({
+ accountEnabled: true,
+ displayName: username,
+ passwordPolicies: "DisableStrongPassword",
+ passwordProfile: {
+ forceChangePasswordNextSignIn: false,
+ password: password,
},
- ],
- });
- this.logger.log(
- `[${context.getTrackingId()}] [ADB2C CREATE] newUser: ${newUser}`
- );
- return { sub: newUser.id };
- } catch (e) {
- this.logger.error(`[${context.getTrackingId()}] error=${e}`);
- if (e?.statusCode === 400 && e?.body) {
- const error = JSON.parse(e.body);
+ identities: [
+ {
+ signinType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
+ issuer: `${this.tenantName}.onmicrosoft.com`,
+ issuerAssignedId: email,
+ },
+ ],
+ });
+ this.logger.log(
+ `[${context.getTrackingId()}] [ADB2C CREATE] newUser: ${newUser}`
+ );
+ return { sub: newUser.id };
+ } catch (e) {
+ this.logger.error(`[${context.getTrackingId()}] error=${e}`);
+
+ if (e?.statusCode === 400 && e?.body) {
+ const error = JSON.parse(e.body);
- // エラーが競合エラーである場合は、メールアドレス重複としてエラーを返す
- if (error?.details?.find((x) => x.code === "ObjectConflict")) {
- return { reason: "email", message: "ObjectConflict" };
+ // エラーが競合エラーである場合は、メールアドレス重複としてエラーを返す
+ if (error?.details?.find((x) => x.code === "ObjectConflict")) {
+ return { reason: "email", message: "ObjectConflict" };
+ }
}
- }
- throw e;
- } finally {
- this.logger.log(
- `[OUT] [${context.getTrackingId()}] ${this.createUser.name}`
- );
+ if (++retry < retryCount) {
+ this.logger.log(`ADB2Cエラー発生。5秒sleepしてリトライします (${retry}/${retryCount})...`);
+ await new Promise(resolve => setTimeout(resolve, 5000));
+ } else {
+ this.logger.log(`リトライ数が上限に達したのでエラーを返却します`);
+ throw e;
+ }
+ } finally {
+ this.logger.log(
+ `[OUT] [${context.getTrackingId()}] ${this.createUser.name}`
+ );
+ }
}
}
From 2220e2560fa02d96e18426bd745c5003dfdbed8c Mon Sep 17 00:00:00 2001
From: masaaki
Date: Wed, 6 Mar 2024 01:19:23 +0000
Subject: [PATCH 06/13] =?UTF-8?q?Merged=20PR=20799:=20makepassword?=
=?UTF-8?q?=E3=81=A7=E6=9D=A1=E4=BB=B6=E3=81=AB=E5=90=88=E8=87=B4=E3=81=97?=
=?UTF-8?q?=E3=81=AA=E3=81=84=E3=83=91=E3=82=B9=E3=83=AF=E3=83=BC=E3=83=89?=
=?UTF-8?q?=E3=82=92=E7=94=9F=E6=88=90=E3=81=97=E3=81=9F=E9=9A=9B=E7=84=A1?=
=?UTF-8?q?=E9=99=90=E3=83=AB=E3=83=BC=E3=83=97=E3=81=AB=E3=81=AA=E3=82=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## 概要
[Task3840: makepasswordで条件に合致しないパスワードを生成した際無限ループになる](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3840)
- makepasswordで条件に合致しないパスワードを生成した場合、再度生成するループ処理としているが、初期化が行われていないため常に同じパスワードで条件合致のチェックが行われていました。結果、一度条件に合致しないパスワードを生成した場合無限ループとなっていました。
- ループ内で変数を初期化するよう対応。
## レビューポイント
- 特にありません
## UIの変更
- 無し
## 動作確認状況
- ユニットテストが通ることを確認
- ローカルでユーザー作成を実施し、これまで同様作成できることを確認
## 補足
- 相談、参考資料などがあれば
---
dictation_server/src/common/password/password.ts | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/dictation_server/src/common/password/password.ts b/dictation_server/src/common/password/password.ts
index f68bb3c..72950b8 100644
--- a/dictation_server/src/common/password/password.ts
+++ b/dictation_server/src/common/password/password.ts
@@ -15,9 +15,12 @@ export const makePassword = (): string => {
// autoGeneratedPasswordが以上の条件を満たせばvalidがtrueになる
let valid = false;
- let autoGeneratedPassword: string = '';
+ let autoGeneratedPassword = '';
while (!valid) {
+ // 再生成用に変数を初期化する
+ autoGeneratedPassword = '';
+
// パスワードをランダムに決定
while (autoGeneratedPassword.length < passLength) {
// 上で決定したcharsの中からランダムに1文字ずつ追加
From 7160e0ee2e9cf02d6555d9d211b19690ca8ba96e Mon Sep 17 00:00:00 2001
From: "saito.k"
Date: Wed, 6 Mar 2024 01:31:10 +0000
Subject: [PATCH 07/13] =?UTF-8?q?Merged=20PR=20804:=20=E3=83=87=E3=82=B0?=
=?UTF-8?q?=E3=83=AC=E5=86=8D=E7=99=BA=E9=98=B2=E6=AD=A2=E3=81=AE=E3=81=9F?=
=?UTF-8?q?=E3=82=81=E3=80=81=E4=BF=AE=E6=AD=A3=E3=82=92=E3=83=81=E3=82=A7?=
=?UTF-8?q?=E3=83=83=E3=82=AF=E3=81=99=E3=82=8B=E3=83=86=E3=82=B9=E3=83=88?=
=?UTF-8?q?=E3=82=92=E4=BD=9C=E6=88=90?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## 概要
[Task3830: デグレ再発防止のため、修正をチェックするテストを作成](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3830)
- タスクを100件取得できることを確認するテストを追加
## レビューポイント
- テストでかくにんする項目は足りているか
## UIの変更
- 特になし
## クエリの変更
- 特になし
## 動作確認状況
- ローカルでテストが通ることを確認
## 補足
- 相談、参考資料などがあれば
---
.../src/features/tasks/tasks.service.spec.ts | 66 +++++++++++++++++++
.../src/features/tasks/tasks.service.ts | 14 ++--
.../src/gateways/sendgrid/sendgrid.service.ts | 2 +-
3 files changed, 75 insertions(+), 7 deletions(-)
diff --git a/dictation_server/src/features/tasks/tasks.service.spec.ts b/dictation_server/src/features/tasks/tasks.service.spec.ts
index 1531077..97f4ee2 100644
--- a/dictation_server/src/features/tasks/tasks.service.spec.ts
+++ b/dictation_server/src/features/tasks/tasks.service.spec.ts
@@ -946,6 +946,72 @@ describe('TasksService', () => {
expect(task.jobNumber).toEqual('00000001');
}
});
+ it('[Admin] Taskが100件であっても取得できる', async () => {
+ const notificationhubServiceMockValue =
+ makeDefaultNotificationhubServiceMockValue();
+ if (!source) fail();
+ const module = await makeTaskTestingModuleWithNotificaiton(
+ source,
+ notificationhubServiceMockValue,
+ );
+ if (!module) fail();
+ const { id: accountId } = await makeTestSimpleAccount(source);
+ const { external_id } = await makeTestUser(source, {
+ account_id: accountId,
+ external_id: 'userId',
+ role: 'none',
+ });
+ const { id: authorUserId, author_id } = await makeTestUser(source, {
+ account_id: accountId,
+ external_id: 'userId',
+ author_id: 'MY_AUTHOR_ID',
+ role: 'author',
+ });
+
+ const service = module.get(TasksService);
+ for (let i = 0; i < 100; i++) {
+ await createTask(
+ source,
+ accountId,
+ authorUserId,
+ author_id ?? '',
+ `WORKTYPE${i + 1}`,
+ '01',
+ // 00000001 ~ 00000100
+ `000000${String(i + 1).padStart(2, '0')}`,
+ 'Uploaded',
+ );
+ }
+ const offset = 0;
+ const limit = 100;
+ const status = ['Uploaded', 'Backup'];
+ const paramName = 'WORK_TYPE';
+ const direction = 'DESC';
+
+ const { tasks, total } = await service.getTasks(
+ makeContext('trackingId', 'requestId'),
+ external_id,
+ [ADMIN_ROLES.ADMIN, USER_ROLES.NONE],
+ offset,
+ limit,
+ status,
+ paramName,
+ direction,
+ );
+ expect(tasks.length).toEqual(100);
+ expect(total).toEqual(100);
+ // ソート条件がWORK_TYPEのため、WORK_TYPEが降順になっていることを確認
+ expect(tasks[0].workType).toEqual('WORKTYPE99');
+ expect(tasks[99].workType).toEqual('WORKTYPE1');
+ expect(tasks[0].optionItemList).toEqual(
+ Array.from({ length: 10 }).map((_, i) => {
+ return {
+ optionItemLabel: `label${i}:audio_file_id${tasks[0].audioFileId}`,
+ optionItemValue: `value${i}:audio_file_id${tasks[0].audioFileId}`,
+ };
+ }),
+ );
+ });
});
});
diff --git a/dictation_server/src/features/tasks/tasks.service.ts b/dictation_server/src/features/tasks/tasks.service.ts
index 898a8f9..8ddf007 100644
--- a/dictation_server/src/features/tasks/tasks.service.ts
+++ b/dictation_server/src/features/tasks/tasks.service.ts
@@ -435,12 +435,14 @@ export class TasksService {
`author_id not found. audioFileId: ${audioFileId}. account_id: ${user.account_id}`,
);
}
- const { external_id: authorExternalId, notification: authorNotification } =
- await this.usersRepository.findUserByAuthorId(
- context,
- task.file.author_id,
- user.account_id,
- );
+ const {
+ external_id: authorExternalId,
+ notification: authorNotification,
+ } = await this.usersRepository.findUserByAuthorId(
+ context,
+ task.file.author_id,
+ user.account_id,
+ );
// プライマリ管理者を取得
const { external_id: primaryAdminExternalId } =
diff --git a/dictation_server/src/gateways/sendgrid/sendgrid.service.ts b/dictation_server/src/gateways/sendgrid/sendgrid.service.ts
index ac9a5df..cd3edc4 100644
--- a/dictation_server/src/gateways/sendgrid/sendgrid.service.ts
+++ b/dictation_server/src/gateways/sendgrid/sendgrid.service.ts
@@ -903,7 +903,7 @@ export class SendGridService {
// メールを送信する
await this.sendMail(
context,
- [authorEmail, typistEmail].filter((x): x is string => x !== null), // authorEmailがnullの場合は除外する
+ [authorEmail, typistEmail].filter((x): x is string => x !== null), // authorEmailがnullの場合は除外する
[],
this.mailFrom,
subject,
From e448e8d249048a7fcfd561b17ea16c70d8ecba0e Mon Sep 17 00:00:00 2001
From: "saito.k"
Date: Thu, 7 Mar 2024 02:26:15 +0000
Subject: [PATCH 08/13] =?UTF-8?q?Merged=20PR=20806:=20=E3=83=A1=E3=83=BC?=
=?UTF-8?q?=E3=83=AB=E6=96=87=E9=9D=A2=E3=81=AE=E4=BF=AE=E6=AD=A3=E5=8F=8D?=
=?UTF-8?q?=E6=98=A0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## 概要
[Task3792: メール文面の修正反映](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3792)
- メール文面を修正
- ドイツ語の部分
## レビューポイント
- タスクに添付しているエクセルの内容と修正した内容を照らし合わせて確認していただきたいです。
## UIの変更
- Before/Afterのスクショなど
- スクショ置き場
## クエリの変更
- Repositoryを変更し、クエリが変更された場合は変更内容を確認する
- Before/Afterのクエリ
- クエリ置き場
## 動作確認状況
- ローカル環境でメールを確認
- メール文面のみの修正のため、他機能に影響はない
## 補足
- 相談、参考資料などがあれば
---
.../mailContents/U103ShortageAlert.ts | 8 +-
.../mailContents/U104ExpiringSoonAlert.ts | 4 +-
.../src/templates/template_U_101.html | 11 +-
.../src/templates/template_U_101.txt | 6 +-
.../src/templates/template_U_102.html | 9 +-
.../src/templates/template_U_102.txt | 4 +-
.../src/templates/template_U_105.html | 23 ++--
.../src/templates/template_U_105.txt | 12 +-
.../src/templates/template_U_106.html | 11 +-
.../src/templates/template_U_106.txt | 6 +-
.../src/templates/template_U_107.html | 11 +-
.../src/templates/template_U_107.txt | 6 +-
.../src/templates/template_U_108.html | 9 +-
.../src/templates/template_U_108.txt | 4 +-
.../templates/template_U_108_no_parent.html | 9 +-
.../templates/template_U_108_no_parent.txt | 4 +-
.../src/templates/template_U_109.html | 110 ++++++++++--------
.../src/templates/template_U_109.txt | 6 +-
.../src/templates/template_U_111.html | 9 +-
.../src/templates/template_U_111.txt | 4 +-
.../src/templates/template_U_112.html | 9 +-
.../src/templates/template_U_112.txt | 4 +-
.../templates/template_U_112_no_parent.html | 9 +-
.../templates/template_U_112_no_parent.txt | 4 +-
.../src/templates/template_U_113.html | 9 +-
.../src/templates/template_U_113.txt | 4 +-
.../src/templates/template_U_114.html | 9 +-
.../src/templates/template_U_114.txt | 4 +-
.../src/templates/template_U_115.html | 9 +-
.../src/templates/template_U_115.txt | 4 +-
.../src/templates/template_U_117.html | 7 +-
.../src/templates/template_U_117.txt | 4 +-
32 files changed, 186 insertions(+), 156 deletions(-)
diff --git a/dictation_function/src/sendgrid/mailContents/U103ShortageAlert.ts b/dictation_function/src/sendgrid/mailContents/U103ShortageAlert.ts
index 4f3b30e..06dae63 100644
--- a/dictation_function/src/sendgrid/mailContents/U103ShortageAlert.ts
+++ b/dictation_function/src/sendgrid/mailContents/U103ShortageAlert.ts
@@ -100,11 +100,11 @@ This is an automatically generated e-mail and this mailbox is not monitored. Ple
<Deutsch>
Sehr geehrte(r) ${companyName},
-Eine oder mehrere Ihrer zugewiesenen ODMS Cloud-Lizenzen laufen innerhalb von 14 Tagen ab. In Ihrem Bestand ist nicht genügend Anzahl nicht zugewiesener Lizenzen Inventar, um diese an Benutzer mit ablaufenden Lizenzen auszugeben.
+Eine oder mehrere Ihrer zugewiesenen ODMS Cloud-Lizenzen laufen innerhalb von 14 Tagen ab. In Ihrem Bestand sind nicht ausreichend viele Lizenzen, um diese an Benutzer mit ablaufenden Lizenzen auszugeben.
Unzureichende Lizenzanzahl: ${shortage}
-Bitte bestellen Sie zusätzliche Jahreslizenzen bei Ihrem ${dealer} um sicherzustellen, dass Sie über ausreichend Lagerbestände Inventar.
+Bitte bestellen Sie zusätzliche Jahreslizenzen bei Ihrem ${dealer} um sicherzustellen, dass Sie über eine ausreichende Anzahl an Lizenzen verfügen.
Sie können Benutzern entweder automatisch oder manuell Lizenzen zuweisen. Benutzern mit aktivierter Option „Automatische Zuweisung“ (Standard) wird die Lizenz am Ablaufdatum automatisch aus Ihrem Lizenzbestand zugewiesen. Wenn Sie die Option „Automatisch zuweisen“ deaktivieren, müssen Sie Lizenzen manuell zuweisen.
@@ -113,8 +113,8 @@ URL: https://odmscloud.omsystem.com/
Wenn Sie Unterstützung bezüglich ODMS benötigen, wenden Sie sich bitte an ${dealer}.
-Wenn Sie diese E-Mail fälschlicherweise erhalten haben, löschen Sie diese E-Mail bitte aus Ihrem System.
-Dies ist eine automatisch generierte E-Mail und dieses Postfach wird nicht überwacht. Bitte nicht antworten.
+Wenn Sie diese E-Mail irrtümlich erhalten haben, löschen Sie diese E-Mail bitte aus Ihrem System.
+Dies ist eine automatisch generierte E-Mail und diese Mailbox wird nicht überwacht. Bitte antworten Sie nicht.
<Français>
diff --git a/dictation_function/src/sendgrid/mailContents/U104ExpiringSoonAlert.ts b/dictation_function/src/sendgrid/mailContents/U104ExpiringSoonAlert.ts
index 71cd68a..a05b2ee 100644
--- a/dictation_function/src/sendgrid/mailContents/U104ExpiringSoonAlert.ts
+++ b/dictation_function/src/sendgrid/mailContents/U104ExpiringSoonAlert.ts
@@ -98,8 +98,8 @@ URL: https://odmscloud.omsystem.com/
Wenn Sie Unterstützung bezüglich ODMS benötigen, wenden Sie sich bitte an ${dealer}.
-Wenn Sie diese E-Mail fälschlicherweise erhalten haben, löschen Sie diese E-Mail bitte aus Ihrem System.
-Dies ist eine automatisch generierte E-Mail und dieses Postfach wird nicht überwacht. Bitte nicht antworten.
+Wenn Sie diese E-Mail irrtümlich erhalten haben, löschen Sie diese E-Mail bitte aus Ihrem System.
+Dies ist eine automatisch generierte E-Mail und diese Mailbox wird nicht überwacht. Bitte antworten Sie nicht.
<Français>
diff --git a/dictation_server/src/templates/template_U_101.html b/dictation_server/src/templates/template_U_101.html
index 8b822de..449ee8e 100644
--- a/dictation_server/src/templates/template_U_101.html
+++ b/dictation_server/src/templates/template_U_101.html
@@ -50,7 +50,7 @@
wurde erfolgreich registriert.
- Wir haben Ihrem Konto [100] Testlizenzen gewährt, die 30 Tage gültig
+ Wir haben Ihrem Konto [100] Testlizenzen hinzugefügt, die 30 Tage gültig
sind. Während der Testversion können Sie alle Funktionen von ODMS Cloud
ausprobieren.
@@ -77,10 +77,11 @@
Ihren ausgewählten zugelassenen OM SYSTEM-Audiohändler.
- Wenn Sie diese E-Mail fälschlicherweise erhalten haben, löschen Sie
- diese E-Mail bitte aus Ihrem System.
- Dies ist eine automatisch generierte E-Mail und dieses Postfach wird
- nicht überwacht. Bitte nicht antworten.
+ Wenn Sie diese E-Mail irrtümlich erhalten haben, löschen Sie diese
+ E-Mail bitte aus Ihrem System.
+ Dies ist eine automatisch generierte
+ E-Mail und diese Mailbox wird nicht überwacht. Bitte antworten Sie
+ nicht.
diff --git a/dictation_server/src/templates/template_U_101.txt b/dictation_server/src/templates/template_U_101.txt
index bb152a9..ed3b0ea 100644
--- a/dictation_server/src/templates/template_U_101.txt
+++ b/dictation_server/src/templates/template_U_101.txt
@@ -24,7 +24,7 @@ Sehr geehrte(r) $CUSTOMER_NAME$,
Vielen Dank, dass Sie sich für ODMS Cloud entschieden haben. Ihr Konto wurde erfolgreich registriert.
-Wir haben Ihrem Konto [100] Testlizenzen gewährt, die 30 Tage gültig sind. Während der Testversion können Sie alle Funktionen von ODMS Cloud ausprobieren.
+Wir haben Ihrem Konto [100] Testlizenzen hinzugefügt, die 30 Tage gültig sind. Während der Testversion können Sie alle Funktionen von ODMS Cloud ausprobieren.
Wenn Sie ODMS Cloud nach Ablauf des Testzeitraums weiterhin nutzen möchten, wenden Sie sich bitte an einen autorisierten OM SYSTEM-Audiohändler, um Jahreslizenzen zu erwerben. Verschiedene Einstellungen, einschließlich der Händlerauswahl, können in der ODMS Cloud auf der Registerkarte „Konto“ konfiguriert werden.
@@ -35,8 +35,8 @@ Nachdem Sie einen Händler ausgewählt haben, wählen Sie bitte die Registerkart
Wenn Sie Hilfe mit ODMS Cloud benötigen, wenden Sie sich bitte direkt an Ihren ausgewählten zugelassenen OM SYSTEM-Audiohändler.
-Wenn Sie diese E-Mail fälschlicherweise erhalten haben, löschen Sie diese E-Mail bitte aus Ihrem System.
-Dies ist eine automatisch generierte E-Mail und dieses Postfach wird nicht überwacht. Bitte nicht antworten.
+Wenn Sie diese E-Mail irrtümlich erhalten haben, löschen Sie diese E-Mail bitte aus Ihrem System.
+Dies ist eine automatisch generierte E-Mail und diese Mailbox wird nicht überwacht. Bitte antworten Sie nicht.
diff --git a/dictation_server/src/templates/template_U_102.html b/dictation_server/src/templates/template_U_102.html
index b08db53..61922d1 100644
--- a/dictation_server/src/templates/template_U_102.html
+++ b/dictation_server/src/templates/template_U_102.html
@@ -32,10 +32,11 @@
URL: $VERIFY_LINK$
- Wenn Sie diese E-Mail fälschlicherweise erhalten haben, löschen Sie
- diese E-Mail bitte aus Ihrem System.
- Dies ist eine automatisch generierte E-Mail und dieses Postfach wird
- nicht überwacht. Bitte nicht antworten.
+ Wenn Sie diese E-Mail irrtümlich erhalten haben, löschen Sie diese
+ E-Mail bitte aus Ihrem System.
+ Dies ist eine automatisch generierte
+ E-Mail und diese Mailbox wird nicht überwacht. Bitte antworten Sie
+ nicht.
diff --git a/dictation_server/src/templates/template_U_102.txt b/dictation_server/src/templates/template_U_102.txt
index 9202e58..443055d 100644
--- a/dictation_server/src/templates/template_U_102.txt
+++ b/dictation_server/src/templates/template_U_102.txt
@@ -13,8 +13,8 @@ Ihre Benutzerinformationen wurden von Ihnen selbst in der ODMS Cloud registriert
URL: $VERIFY_LINK$
-Wenn Sie diese E-Mail fälschlicherweise erhalten haben, löschen Sie diese E-Mail bitte aus Ihrem System.
-Dies ist eine automatisch generierte E-Mail und dieses Postfach wird nicht überwacht. Bitte nicht antworten.
+Wenn Sie diese E-Mail irrtümlich erhalten haben, löschen Sie diese E-Mail bitte aus Ihrem System.
+Dies ist eine automatisch generierte E-Mail und diese Mailbox wird nicht überwacht. Bitte antworten Sie nicht.
diff --git a/dictation_server/src/templates/template_U_105.html b/dictation_server/src/templates/template_U_105.html
index 8290aab..7199d6c 100644
--- a/dictation_server/src/templates/template_U_105.html
+++ b/dictation_server/src/templates/template_U_105.html
@@ -35,24 +35,29 @@
<Deutsch>
Sehr geehrte(r) $CUSTOMER_NAME$,
- Wir haben Ihre gewünschte Lizenzbestellung erhalten.
+ wir habenn Ihre Lizenzbestellung erhalten.
- Anzahl der bestellten Lizenzen: $LICENSE_QUANTITY$
- - Bestellnummer: $PO_NUMBER$
+ - PO-Nummer: $PO_NUMBER$
- Die Lizenzen werden von Ihrem $DEALER_NAME$ ausgestellt, den Sie in den Einstellungen ausgewählt haben.
- Von Ihrem Händler ausgestellte Lizenzen werden in Ihrem Lizenzbestand gespeichert.
- Bitte melden Sie sich bei der ODMS Cloud an, um Lizenzen anzuzeigen und Ihren Benutzern zuzuweisen.
+ Die Lizenzen werden von $DEALER_NAME$ ausgestellt, die Sie in den
+ Einstellungen ausgewählt haben. Die von Ihrem Händler ausgestellten
+ Lizenzen werden in Ihrem Lizenzbestand gespeichert. Bitte loggen Sie
+ sich in die ODMS Cloud ein, um die Lizenzen einzusehen und sie Ihren
+ Nutzern zuzuordnen.
- Lizenzen sind ab dem Datum, an dem sie einem Benutzer zugewiesen wurden, 12 Monate lang gültig.
+ Die Lizenzen sind ab dem Datum, an dem sie einem Benutzer zugewiesen wurden, 12 Monate lang gültig.
- Wenn Sie Unterstützung bezüglich ODMS Cloud benötigen, wenden Sie sich bitte an $DEALER_NAME$.
+ Wenn Sie Unterstützung bezüglich ODMS Cloud benötigen, wenden Sie sich
+ bitte an $DEALER_NAME$.
- Wenn Sie diese E-Mail fälschlicherweise erhalten haben, löschen Sie diese E-Mail bitte aus Ihrem System.
- Dies ist eine automatisch generierte E-Mail und dieses Postfach wird nicht überwacht. Bitte nicht antworten.
+ Wenn Sie diese E-Mail irrtümlich erhalten haben, löschen Sie diese
+ E-Mail bitte aus Ihrem System.
+ Dies ist eine automatisch generierte E-Mail und diese Mailbox wird nicht
+ überwacht. Bitte antworten Sie nicht.
diff --git a/dictation_server/src/templates/template_U_105.txt b/dictation_server/src/templates/template_U_105.txt
index c569f9f..ac6c548 100644
--- a/dictation_server/src/templates/template_U_105.txt
+++ b/dictation_server/src/templates/template_U_105.txt
@@ -19,18 +19,18 @@ This is an automatically generated e-mail and this mailbox is not monitored. P
Sehr geehrte(r) $CUSTOMER_NAME$,
-Wir haben Ihre gewünschte Lizenzbestellung erhalten.
+wir habenn Ihre Lizenzbestellung erhalten.
- Anzahl der bestellten Lizenzen: $LICENSE_QUANTITY$
- - Bestellnummer: $PO_NUMBER$
+ - PO-Nummer: $PO_NUMBER$
-Die Lizenzen werden von Ihrem $DEALER_NAME$ ausgestellt, den Sie in den Einstellungen ausgewählt haben. Von Ihrem Händler ausgestellte Lizenzen werden in Ihrem Lizenzbestand gespeichert. Bitte melden Sie sich bei der ODMS Cloud an, um Lizenzen anzuzeigen und Ihren Benutzern zuzuweisen.
+Die Lizenzen werden von $DEALER_NAME$ ausgestellt, die Sie in den Einstellungen ausgewählt haben. Die von Ihrem Händler ausgestellten Lizenzen werden in Ihrem Lizenzbestand gespeichert. Bitte loggen Sie sich in die ODMS Cloud ein, um die Lizenzen einzusehen und sie Ihren Nutzern zuzuordnen.
-Lizenzen sind ab dem Datum, an dem sie einem Benutzer zugewiesen wurden, 12 Monate lang gültig.
+Die Lizenzen sind ab dem Datum, an dem sie einem Benutzer zugewiesen wurden, 12 Monate lang gültig.
Wenn Sie Unterstützung bezüglich ODMS Cloud benötigen, wenden Sie sich bitte an $DEALER_NAME$.
-Wenn Sie diese E-Mail fälschlicherweise erhalten haben, löschen Sie diese E-Mail bitte aus Ihrem System.
-Dies ist eine automatisch generierte E-Mail und dieses Postfach wird nicht überwacht. Bitte nicht antworten.
+Wenn Sie diese E-Mail irrtümlich erhalten haben, löschen Sie diese E-Mail bitte aus Ihrem System.
+Dies ist eine automatisch generierte E-Mail und diese Mailbox wird nicht überwacht. Bitte antworten Sie nicht.
diff --git a/dictation_server/src/templates/template_U_106.html b/dictation_server/src/templates/template_U_106.html
index 3854b11..36cde45 100644
--- a/dictation_server/src/templates/template_U_106.html
+++ b/dictation_server/src/templates/template_U_106.html
@@ -27,17 +27,18 @@
Wir haben die Stornierung Ihrer letzten Lizenzbestellung erhalten.
- Anzahl der gekündigten Lizenzen: $LICENSE_QUANTITY$
- - Bestellnummer: $PO_NUMBER$
+ - PO-Nummer: $PO_NUMBER$
Wenn Sie Unterstützung bezüglich ODMS Cloud benötigen, wenden Sie sich
bitte an $DEALER_NAME$.
- Wenn Sie diese E-Mail fälschlicherweise erhalten haben, löschen Sie
- diese E-Mail bitte aus Ihrem System.
- Dies ist eine automatisch generierte E-Mail und dieses Postfach wird
- nicht überwacht. Bitte nicht antworten.
+ Wenn Sie diese E-Mail irrtümlich erhalten haben, löschen Sie diese
+ E-Mail bitte aus Ihrem System.
+ Dies ist eine automatisch generierte
+ E-Mail und diese Mailbox wird nicht überwacht. Bitte antworten Sie
+ nicht.
diff --git a/dictation_server/src/templates/template_U_106.txt b/dictation_server/src/templates/template_U_106.txt
index accfe09..54e8e75 100644
--- a/dictation_server/src/templates/template_U_106.txt
+++ b/dictation_server/src/templates/template_U_106.txt
@@ -17,12 +17,12 @@ Sehr geehrte(r) $CUSTOMER_NAME$,
Wir haben die Stornierung Ihrer letzten Lizenzbestellung erhalten.
- Anzahl der gekündigten Lizenzen: $LICENSE_QUANTITY$
- - Bestellnummer: $PO_NUMBER$
+ - PO-Nummer: $PO_NUMBER$
Wenn Sie Unterstützung bezüglich ODMS Cloud benötigen, wenden Sie sich bitte an $DEALER_NAME$.
-Wenn Sie diese E-Mail fälschlicherweise erhalten haben, löschen Sie diese E-Mail bitte aus Ihrem System.
-Dies ist eine automatisch generierte E-Mail und dieses Postfach wird nicht überwacht. Bitte nicht antworten.
+Wenn Sie diese E-Mail irrtümlich erhalten haben, löschen Sie diese E-Mail bitte aus Ihrem System.
+Dies ist eine automatisch generierte E-Mail und diese Mailbox wird nicht überwacht. Bitte antworten Sie nicht.
diff --git a/dictation_server/src/templates/template_U_107.html b/dictation_server/src/templates/template_U_107.html
index 638b841..3595871 100644
--- a/dictation_server/src/templates/template_U_107.html
+++ b/dictation_server/src/templates/template_U_107.html
@@ -33,7 +33,7 @@
Die von Ihnen bestellten ODMS Cloud-Lizenzen wurden ausgestellt.
- Anzahl der ausgestellten Lizenzen: $LICENSE_QUANTITY$
- - Bestellnummer: $PO_NUMBER$
+ - PO-Nummer: $PO_NUMBER$
Um ODMS Cloud nutzen zu können, müssen Sie Ihre Benutzer im System
@@ -46,10 +46,11 @@
bitte an $DEALER_NAME$.
- Wenn Sie diese E-Mail fälschlicherweise erhalten haben, löschen Sie
- diese E-Mail bitte aus Ihrem System.
- Dies ist eine automatisch generierte E-Mail und dieses Postfach wird
- nicht überwacht. Bitte nicht antworten.
+ Wenn Sie diese E-Mail irrtümlich erhalten haben, löschen Sie diese
+ E-Mail bitte aus Ihrem System.
+ Dies ist eine automatisch generierte
+ E-Mail und diese Mailbox wird nicht überwacht. Bitte antworten Sie
+ nicht.
diff --git a/dictation_server/src/templates/template_U_107.txt b/dictation_server/src/templates/template_U_107.txt
index 93914f7..6b30347 100644
--- a/dictation_server/src/templates/template_U_107.txt
+++ b/dictation_server/src/templates/template_U_107.txt
@@ -19,14 +19,14 @@ Sehr geehrte(r) $CUSTOMER_NAME$,
Die von Ihnen bestellten ODMS Cloud-Lizenzen wurden ausgestellt.
- Anzahl der ausgestellten Lizenzen: $LICENSE_QUANTITY$
- - Bestellnummer: $PO_NUMBER$
+ - PO-Nummer: $PO_NUMBER$
Um ODMS Cloud nutzen zu können, müssen Sie Ihre Benutzer im System registrieren und diesen Benutzern Lizenzen zuweisen. Bitte melden Sie sich beim Starten der App mit der E-Mail-Adresse und dem Passwort Ihres registrierten Benutzers am System an.
Wenn Sie Unterstützung bezüglich ODMS Cloud benötigen, wenden Sie sich bitte an $DEALER_NAME$.
-Wenn Sie diese E-Mail fälschlicherweise erhalten haben, löschen Sie diese E-Mail bitte aus Ihrem System.
-Dies ist eine automatisch generierte E-Mail und dieses Postfach wird nicht überwacht. Bitte nicht antworten.
+Wenn Sie diese E-Mail irrtümlich erhalten haben, löschen Sie diese E-Mail bitte aus Ihrem System.
+Dies ist eine automatisch generierte E-Mail und diese Mailbox wird nicht überwacht. Bitte antworten Sie nicht.
diff --git a/dictation_server/src/templates/template_U_108.html b/dictation_server/src/templates/template_U_108.html
index ad61961..0ba001c 100644
--- a/dictation_server/src/templates/template_U_108.html
+++ b/dictation_server/src/templates/template_U_108.html
@@ -45,10 +45,11 @@
bitte an $DEALER_NAME$.
- Wenn Sie diese E-Mail fälschlicherweise erhalten haben, löschen Sie
- diese E-Mail bitte aus Ihrem System.
- Dies ist eine automatisch generierte E-Mail und dieses Postfach wird
- nicht überwacht. Bitte nicht antworten.
+ Wenn Sie diese E-Mail irrtümlich erhalten haben, löschen Sie diese
+ E-Mail bitte aus Ihrem System.
+ Dies ist eine automatisch generierte
+ E-Mail und diese Mailbox wird nicht überwacht. Bitte antworten Sie
+ nicht.
diff --git a/dictation_server/src/templates/template_U_108.txt b/dictation_server/src/templates/template_U_108.txt
index 8b695ca..3615550 100644
--- a/dictation_server/src/templates/template_U_108.txt
+++ b/dictation_server/src/templates/template_U_108.txt
@@ -27,8 +27,8 @@ URL: $TOP_URL$
Wenn Sie Unterstützung bezüglich ODMS Cloud benötigen, wenden Sie sich bitte an $DEALER_NAME$.
-Wenn Sie diese E-Mail fälschlicherweise erhalten haben, löschen Sie diese E-Mail bitte aus Ihrem System.
-Dies ist eine automatisch generierte E-Mail und dieses Postfach wird nicht überwacht. Bitte nicht antworten.
+Wenn Sie diese E-Mail irrtümlich erhalten haben, löschen Sie diese E-Mail bitte aus Ihrem System.
+Dies ist eine automatisch generierte E-Mail und diese Mailbox wird nicht überwacht. Bitte antworten Sie nicht.
diff --git a/dictation_server/src/templates/template_U_108_no_parent.html b/dictation_server/src/templates/template_U_108_no_parent.html
index b8b6b8b..6f93225 100644
--- a/dictation_server/src/templates/template_U_108_no_parent.html
+++ b/dictation_server/src/templates/template_U_108_no_parent.html
@@ -38,10 +38,11 @@
URL: $TOP_URL$
- Wenn Sie diese E-Mail fälschlicherweise erhalten haben, löschen Sie
- diese E-Mail bitte aus Ihrem System.
- Dies ist eine automatisch generierte E-Mail und dieses Postfach wird
- nicht überwacht. Bitte nicht antworten.
+ Wenn Sie diese E-Mail irrtümlich erhalten haben, löschen Sie diese
+ E-Mail bitte aus Ihrem System.
+ Dies ist eine automatisch generierte
+ E-Mail und diese Mailbox wird nicht überwacht. Bitte antworten Sie
+ nicht.
diff --git a/dictation_server/src/templates/template_U_108_no_parent.txt b/dictation_server/src/templates/template_U_108_no_parent.txt
index b0ce4a2..8c07856 100644
--- a/dictation_server/src/templates/template_U_108_no_parent.txt
+++ b/dictation_server/src/templates/template_U_108_no_parent.txt
@@ -23,8 +23,8 @@ Bitte beachten Sie, dass dem folgenden Benutzer eine Lizenz zugewiesen wurde.
Bitte melden Sie sich bei ODMS Cloud an, um das Ablaufdatum der Lizenz zu überprüfen.
URL: $TOP_URL$
-Wenn Sie diese E-Mail fälschlicherweise erhalten haben, löschen Sie diese E-Mail bitte aus Ihrem System.
-Dies ist eine automatisch generierte E-Mail und dieses Postfach wird nicht überwacht. Bitte nicht antworten.
+Wenn Sie diese E-Mail irrtümlich erhalten haben, löschen Sie diese E-Mail bitte aus Ihrem System.
+Dies ist eine automatisch generierte E-Mail und diese Mailbox wird nicht überwacht. Bitte antworten Sie nicht.
diff --git a/dictation_server/src/templates/template_U_109.html b/dictation_server/src/templates/template_U_109.html
index 5b0c746..c37b4a9 100644
--- a/dictation_server/src/templates/template_U_109.html
+++ b/dictation_server/src/templates/template_U_109.html
@@ -1,52 +1,62 @@
+
+ License Returned Notification [U-109]
+
-
- License Returned Notification [U-109]
-
-
-
-
-
<English>
-
Dear $DEALER_NAME$,
-
- Please be informed that the licenses issued with the following contents has been returned from your customer and placed back into your License inventory.
- - Company Name: $CUSTOMER_NAME$
- - Number of canceled licenses: $LICENSE_QUANTITY$
- - PO Number: $PO_NUMBER$
-
-
- If you have received this e-mail in error, please delete this e-mail from your system.
- This is an automatically generated e-mail and this mailbox is not monitored. Please do not reply.
-
-
-
-
<Deutsch>
-
Sehr geehrte(r) $DEALER_NAME$,
-
- Bitte beachten Sie, dass die ausgestellten Lizenzen mit den folgenden Inhalten von Ihrem Kunden zurückgegeben und wieder in Ihren Lizenzbestand aufgenommen wurden.
- - Name der Firma: $CUSTOMER_NAME$
- - Anzahl der gekündigten Lizenzen: $LICENSE_QUANTITY$
- - Bestellnummer: $PO_NUMBER$
-
-
- Wenn Sie diese E-Mail fälschlicherweise erhalten haben, löschen Sie diese E-Mail bitte aus Ihrem System.
- Dies ist eine automatisch generierte E-Mail und dieses Postfach wird nicht überwacht. Bitte nicht antworten.
-
-
-
-
<Français>
-
Chère/Cher $DEALER_NAME$,
-
- Veuillez noter que les licences émises avec le contenu suivant ont été retournées par votre client et replacées dans votre inventaire de licences.
- - Nom de l'entreprise: $CUSTOMER_NAME$
- - Nombre de licences annulées: $LICENSE_QUANTITY$
- - Numéro de bon de commande $PO_NUMBER$
-
-
- Si vous avez reçu cet e-mail par erreur, veuillez supprimer cet e-mail de votre système.
- Il s'agit d'un e-mail généré automatiquement et cette boîte aux lettres n'est pas surveillée. Merci de ne pas répondre.
-
-
-
-
-
\ No newline at end of file
+
+
+
<English>
+
Dear $DEALER_NAME$,
+
+ Please be informed that the licenses issued with the following contents
+ has been returned from your customer and placed back into your License
+ inventory.
+ - Company Name: $CUSTOMER_NAME$
+ - Number of canceled licenses: $LICENSE_QUANTITY$
+ - PO Number: $PO_NUMBER$
+
+
+ If you have received this e-mail in error, please delete this e-mail
+ from your system.
+ This is an automatically generated e-mail and this mailbox is not
+ monitored. Please do not reply.
+
+
+
+
<Deutsch>
+
Sehr geehrte(r) $DEALER_NAME$,
+
+ Bitte beachten Sie, dass die ausgestellten Lizenzen mit den folgenden
+ Inhalten von Ihrem Kunden zurückgegeben und wieder in Ihren
+ Lizenzbestand aufgenommen wurden.
+ - Name der Firma: $CUSTOMER_NAME$
+ - Anzahl der gekündigten Lizenzen: $LICENSE_QUANTITY$
+ - PO-Nummer: $PO_NUMBER$
+
+
+ Wenn Sie diese E-Mail irrtümlich erhalten haben, löschen Sie diese
+ E-Mail bitte aus Ihrem System.
+ Dies ist eine automatisch generierte E-Mail und diese Mailbox wird nicht
+ überwacht. Bitte antworten Sie nicht.
+
+
+
+
<Français>
+
Chère/Cher $DEALER_NAME$,
+
+ Veuillez noter que les licences émises avec le contenu suivant ont été
+ retournées par votre client et replacées dans votre inventaire de
+ licences.
+ - Nom de l'entreprise: $CUSTOMER_NAME$
+ - Nombre de licences annulées: $LICENSE_QUANTITY$
+ - Numéro de bon de commande $PO_NUMBER$
+
+
+ Si vous avez reçu cet e-mail par erreur, veuillez supprimer cet e-mail
+ de votre système.
+ Il s'agit d'un e-mail généré automatiquement et cette boîte aux lettres
+ n'est pas surveillée. Merci de ne pas répondre.
+
+
+
+