Merge branch 'develop' into release-ccb

This commit is contained in:
SAITO-PC-3\saito.k 2024-06-11 11:20:34 +09:00
commit c73340ec51
29 changed files with 576 additions and 63 deletions

View File

@ -13,7 +13,7 @@ describe("parse", () => {
email: "sample@example.com", email: "sample@example.com",
role: 1, role: 1,
author_id: "HOGE", author_id: "HOGE",
auto_renew: 1, auto_assign: 1,
notification: 1, notification: 1,
encryption: 1, encryption: 1,
encryption_password: "abcd", encryption_password: "abcd",
@ -58,7 +58,7 @@ describe("parse", () => {
email: "sample@example.com", email: "sample@example.com",
role: 1, role: 1,
author_id: null, author_id: null,
auto_renew: 1, auto_assign: 1,
notification: 1, notification: 1,
encryption: 1, encryption: 1,
encryption_password: "abcd", encryption_password: "abcd",
@ -76,7 +76,7 @@ describe("parse", () => {
email: "sample@example.com", email: "sample@example.com",
role: null, role: null,
author_id: "HOGE", author_id: "HOGE",
auto_renew: 1, auto_assign: 1,
notification: 1, notification: 1,
encryption: 1, encryption: 1,
encryption_password: "abcd", encryption_password: "abcd",
@ -94,7 +94,7 @@ describe("parse", () => {
email: "sample@example.com", email: "sample@example.com",
role: 1, role: 1,
author_id: "HOGE", author_id: "HOGE",
auto_renew: 1, auto_assign: 1,
notification: 1, notification: 1,
encryption: 1, encryption: 1,
encryption_password: "abcd", encryption_password: "abcd",
@ -105,7 +105,7 @@ describe("parse", () => {
email: "sample2@example.com", email: "sample2@example.com",
role: 1, role: 1,
author_id: "HOGE2", author_id: "HOGE2",
auto_renew: 1, auto_assign: 1,
notification: 1, notification: 1,
encryption: 1, encryption: 1,
encryption_password: "abcd2", encryption_password: "abcd2",
@ -119,7 +119,7 @@ describe("parse", () => {
const actualValue = actualData[i]; const actualValue = actualData[i];
const expectValue = expectData[i]; const expectValue = expectData[i];
expect(actualValue.author_id).toEqual(expectValue.author_id); expect(actualValue.author_id).toEqual(expectValue.author_id);
expect(actualValue.auto_renew).toEqual(expectValue.auto_renew); expect(actualValue.auto_assign).toEqual(expectValue.auto_assign);
expect(actualValue.email).toEqual(expectValue.email); expect(actualValue.email).toEqual(expectValue.email);
expect(actualValue.encryption).toEqual(expectValue.encryption); expect(actualValue.encryption).toEqual(expectValue.encryption);
expect(actualValue.encryption_password).toEqual( expect(actualValue.encryption_password).toEqual(
@ -141,7 +141,7 @@ describe("parse", () => {
email: "sample@example.com", email: "sample@example.com",
role: 1, role: 1,
author_id: "1111", author_id: "1111",
auto_renew: 1, auto_assign: 1,
notification: 1, notification: 1,
encryption: 1, encryption: 1,
encryption_password: "222222", encryption_password: "222222",

View File

@ -6,7 +6,7 @@ export type CSVType = {
email: string | null; email: string | null;
role: number | null; role: number | null;
author_id: string | null; author_id: string | null;
auto_renew: number | null; auto_assign: number | null;
notification: number; notification: number;
encryption: number | null; encryption: number | null;
encryption_password: string | null; encryption_password: string | null;
@ -19,7 +19,7 @@ const CSVTypeFields: (keyof CSVType)[] = [
"email", "email",
"role", "role",
"author_id", "author_id",
"auto_renew", "auto_assign",
"notification", "notification",
"encryption", "encryption",
"encryption_password", "encryption_password",
@ -45,7 +45,7 @@ export const parseCSV = async (csvString: string): Promise<CSVType[]> =>
dynamicTyping: { dynamicTyping: {
// author_id, encryption_passwordは数値のみの場合、numberに変換されたくないためdynamicTypingをtrueにしない // author_id, encryption_passwordは数値のみの場合、numberに変換されたくないためdynamicTypingをtrueにしない
role: true, role: true,
auto_renew: true, auto_assign: true,
notification: true, notification: true,
encryption: true, encryption: true,
prompt: true, prompt: true,

View File

@ -1,2 +1,2 @@
name,email,role,author_id,auto_renew,notification,encryption,encryption_password,prompt name,email,role,author_id,auto_assign,notification,encryption,encryption_password,prompt
hoge,sample@example.com,1,"HOGE",1,1,1,abcd,0 hoge,sample@example.com,1,"HOGE",1,1,1,abcd,0
1 name email role author_id auto_renew auto_assign notification encryption encryption_password prompt
2 hoge sample@example.com 1 HOGE 1 1 1 1 abcd 0

View File

@ -1,2 +1,2 @@
name,email,role,auto_renew,notification,encryption,encryption_password,prompt name,email,role,auto_assign,notification,encryption,encryption_password,prompt
hoge,sample@example.com,1,"HOGE",1,1,1,abcd,0 hoge,sample@example.com,1,"HOGE",1,1,1,abcd,0
Can't render this file because it has a wrong number of fields in line 2.

View File

@ -1,2 +1,2 @@
name,role,author_id,auto_renew,notification,encryption,encryption_password,prompt name,role,author_id,auto_assign,notification,encryption,encryption_password,prompt
hoge,sample@example.com,1,"HOGE",1,1,1,abcd,0 hoge,sample@example.com,1,"HOGE",1,1,1,abcd,0
Can't render this file because it has a wrong number of fields in line 2.

View File

@ -1,2 +1,2 @@
name,emeil,role,author_id,auto_renew,notification,encryption,encryption_password,prompt name,emeil,role,author_id,auto_assign,notification,encryption,encryption_password,prompt
hoge,sample@example.com,1,"HOGE",1,1,1,abcd,0 hoge,sample@example.com,1,"HOGE",1,1,1,abcd,0
1 name emeil role author_id auto_renew auto_assign notification encryption encryption_password prompt
2 hoge sample@example.com 1 HOGE 1 1 1 1 abcd 0

View File

@ -1,2 +1,2 @@
name,email,role,author_id,auto_renew,notification,encryption,encryption_password,prompt name,email,role,author_id,auto_assign,notification,encryption,encryption_password,prompt
hoge,sample@example.com,1,,1,1,1,abcd,0 hoge,sample@example.com,1,,1,1,1,abcd,0
1 name email role author_id auto_renew auto_assign notification encryption encryption_password prompt
2 hoge sample@example.com 1 1 1 1 1 abcd 0

View File

@ -1,2 +1,2 @@
name,email,role,author_id,auto_renew,notification,encryption,encryption_password,prompt name,email,role,author_id,auto_assign,notification,encryption,encryption_password,prompt
hoge,sample@example.com,,"HOGE",1,1,1,abcd,0 hoge,sample@example.com,,"HOGE",1,1,1,abcd,0
1 name email role author_id auto_renew auto_assign notification encryption encryption_password prompt
2 hoge sample@example.com HOGE 1 1 1 1 abcd 0

View File

@ -1,3 +1,3 @@
name,email,role,author_id,auto_renew,notification,encryption,encryption_password,prompt name,email,role,author_id,auto_assign,notification,encryption,encryption_password,prompt
hoge,sample@example.com,1,"HOGE",1,1,1,abcd,0,x hoge,sample@example.com,1,"HOGE",1,1,1,abcd,0,x
hoge2,sample2@example.com,1,"HOGE2",1,1,1,abcd2,0,1,32,4,aa hoge2,sample2@example.com,1,"HOGE2",1,1,1,abcd2,0,1,32,4,aa
Can't render this file because it has a wrong number of fields in line 2.

View File

@ -1,2 +1,2 @@
name,email,role,author_id,auto_renew,notification,encryption,encryption_password,prompt name,email,role,author_id,auto_assign,notification,encryption,encryption_password,prompt
hoge,sample@example.com,1,1111,1,1,1,222222,0 hoge,sample@example.com,1,1111,1,1,1,222222,0
1 name email role author_id auto_renew auto_assign notification encryption encryption_password prompt
2 hoge sample@example.com 1 1111 1 1 1 1 222222 0

View File

@ -534,7 +534,7 @@ export const importUsersAsync = createAsyncThunk<
email: user.email ?? "", email: user.email ?? "",
role: user.role ?? 0, role: user.role ?? 0,
authorId: user.author_id ?? undefined, authorId: user.author_id ?? undefined,
autoRenew: user.auto_renew ?? 0, autoRenew: user.auto_assign ?? 0,
notification: user.notification ?? 0, notification: user.notification ?? 0,
encryption: user.encryption ?? undefined, encryption: user.encryption ?? undefined,
encryptionPassword: user.encryption_password ?? undefined, encryptionPassword: user.encryption_password ?? undefined,

View File

@ -493,8 +493,8 @@ export const selectImportValidationErrors = (state: RootState) => {
} }
} }
// auto_renew // auto_assign
if (csvUser.auto_renew === null || ![0, 1].includes(csvUser.auto_renew)) { if (csvUser.auto_assign === null || ![0, 1].includes(csvUser.auto_assign)) {
invalidInput.push(rowNumber); invalidInput.push(rowNumber);
// eslint-disable-next-line no-continue // eslint-disable-next-line no-continue
continue; continue;

View File

@ -104,6 +104,15 @@ export const FilePropertyPopup: React.FC<FilePropertyPopupProps> = (props) => {
name="submit" name="submit"
value={t(getTranslationID("dictationPage.label.fileNameSave"))} value={t(getTranslationID("dictationPage.label.fileNameSave"))}
className={`${styles.formSubmit} ${styles.isActive}`} className={`${styles.formSubmit} ${styles.isActive}`}
style={{
position: "relative",
marginTop: "0.2rem",
right: "auto",
maxWidth: "18rem",
whiteSpace: "normal",
overflowWrap: "break-word",
fontSize: "small",
}}
onClick={saveFileName} onClick={saveFileName}
/> />
{isPushSaveButton && fileName.length === 0 && ( {isPushSaveButton && fileName.length === 0 && (

View File

@ -52,7 +52,7 @@ export const ImportPopup: React.FC<UserAddPopupProps> = (props) => {
"email", "email",
"role", "role",
"author_id", "author_id",
"auto_renew", "auto_assign",
"notification", "notification",
"encryption", "encryption",
"encryption_password", "encryption_password",

View File

@ -15,7 +15,7 @@
"copyRight": "© OM Digital Solutions Corporation", "copyRight": "© OM Digital Solutions Corporation",
"edit": "Editar", "edit": "Editar",
"save": "Ahorrar", "save": "Ahorrar",
"delete": "Delete", "delete": "Borrar",
"return": "Devolver", "return": "Devolver",
"operationInsteadOf": "Operar la nube ODMS en nombre de:", "operationInsteadOf": "Operar la nube ODMS en nombre de:",
"headerAccount": "Cuenta", "headerAccount": "Cuenta",

View File

@ -15,7 +15,7 @@
"copyRight": "© OM Digital Solutions Corporation", "copyRight": "© OM Digital Solutions Corporation",
"edit": "Éditer", "edit": "Éditer",
"save": "Sauvegarder", "save": "Sauvegarder",
"delete": "Delete", "delete": "Supprimer",
"return": "Retour", "return": "Retour",
"operationInsteadOf": "Exploiter le Cloud ODMS pour le compte de :", "operationInsteadOf": "Exploiter le Cloud ODMS pour le compte de :",
"headerAccount": "Compte", "headerAccount": "Compte",

View File

@ -9,6 +9,8 @@ import {
GetPartnerUsersRequest, GetPartnerUsersRequest,
UpdatePartnerInfoRequest, UpdatePartnerInfoRequest,
CreateWorktypesRequest, CreateWorktypesRequest,
UpdateWorktypesRequest,
UpdateWorktypeRequestParam,
} from './types/types'; } from './types/types';
import { plainToClass } from 'class-transformer'; import { plainToClass } from 'class-transformer';
import { validate } from 'class-validator'; import { validate } from 'class-validator';
@ -124,6 +126,101 @@ describe('AccountsController', () => {
}); });
}); });
describe('valdation UpdateWorktypesRequest', () => {
it('最低限の有効なリクエストが成功する', async () => {
const request = new UpdateWorktypesRequest();
request.worktypeId = 'TEST';
const valdationObject = plainToClass(UpdateWorktypesRequest, request);
const errors = await validate(valdationObject);
expect(errors.length).toBe(0);
});
it('worktypeIdが指定されていない場合、リクエストが失敗する', async () => {
const request = new UpdateWorktypesRequest();
const valdationObject = plainToClass(UpdateWorktypesRequest, request);
const errors = await validate(valdationObject);
expect(errors.length).toBe(1);
});
it('worktypeIdが空文字の場合、リクエストが失敗する', async () => {
const request = new UpdateWorktypesRequest();
request.worktypeId = '';
const valdationObject = plainToClass(UpdateWorktypesRequest, request);
const errors = await validate(valdationObject);
expect(errors.length).toBe(1);
});
it('worktypeIdが16文字を超える場合、リクエストが失敗する', async () => {
const request = new UpdateWorktypesRequest();
request.worktypeId = '123456789A1234567';
const valdationObject = plainToClass(UpdateWorktypesRequest, request);
const errors = await validate(valdationObject);
expect(errors.length).toBe(1);
});
it('worktypeIdが16文字の場合、リクエストが成功する', async () => {
const request = new UpdateWorktypesRequest();
request.worktypeId = '123456789A123456';
const valdationObject = plainToClass(UpdateWorktypesRequest, request);
const errors = await validate(valdationObject);
expect(errors.length).toBe(0);
});
it('worktypeIdに使用不可文字が含まれる場合、リクエストが失敗する', async () => {
const request = new UpdateWorktypesRequest();
request.worktypeId = 'test.test';
const valdationObject = plainToClass(UpdateWorktypesRequest, request);
const errors = await validate(valdationObject);
expect(errors.length).toBe(1);
});
it('descriptionが255文字を超える場合、リクエストが失敗する', async () => {
const request = new UpdateWorktypesRequest();
request.worktypeId = 'TEST';
request.description =
'1234567A0A1234567A1A1234567A2A1234567A3A1234567A4A1234567A5A1234567A6A1234567A7A1234567A8A1234567A9A' +
'1234567B0B1234567B1B1234567B2B1234567B3B1234567B4B1234567B5B1234567B6B1234567B7B1234567B8B1234567B9B' +
'1234567A0A1234567A1A1234567A2A1234567A3A1234567A4A123456';
const valdationObject = plainToClass(UpdateWorktypesRequest, request);
const errors = await validate(valdationObject);
expect(errors.length).toBe(1);
});
it('descriptionが255文字の場合、リクエストが成功する', async () => {
const request = new UpdateWorktypesRequest();
request.worktypeId = 'TEST';
request.description =
'1234567A0A1234567A1A1234567A2A1234567A3A1234567A4A1234567A5A1234567A6A1234567A7A1234567A8A1234567A9A' +
'1234567B0B1234567B1B1234567B2B1234567B3B1234567B4B1234567B5B1234567B6B1234567B7B1234567B8B1234567B9B' +
'1234567A0A1234567A1A1234567A2A1234567A3A1234567A4A12345';
const valdationObject = plainToClass(UpdateWorktypesRequest, request);
const errors = await validate(valdationObject);
expect(errors.length).toBe(0);
});
});
describe('valdation UpdateWorktypeRequestParam', () => {
it('最低限の有効なリクエストが成功する', async () => {
const request = new UpdateWorktypeRequestParam();
request.id = 1;
const valdationObject = plainToClass(UpdateWorktypeRequestParam, request);
const errors = await validate(valdationObject);
expect(errors.length).toBe(0);
});
it('idが1より小さい場合、リクエストが失敗する', async () => {
const request = new UpdateWorktypeRequestParam();
request.id = 0;
const valdationObject = plainToClass(UpdateWorktypeRequestParam, request);
const errors = await validate(valdationObject);
expect(errors.length).toBe(1);
});
it('idが数値でない場合、リクエストが失敗する', async () => {
const request = { id: '0' };
const valdationObject = plainToClass(UpdateWorktypeRequestParam, request);
const errors = await validate(valdationObject);
expect(errors.length).toBe(1);
});
});
describe('valdation switchParentRequest', () => { describe('valdation switchParentRequest', () => {
it('最低限の有効なリクエストが成功する', async () => { it('最低限の有効なリクエストが成功する', async () => {
const request = new SwitchParentRequest(); const request = new SwitchParentRequest();

View File

@ -25,6 +25,7 @@ import {
} from '../../constants'; } from '../../constants';
import { import {
makeHierarchicalAccounts, makeHierarchicalAccounts,
makeTestAccount,
makeTestSimpleAccount, makeTestSimpleAccount,
makeTestUser, makeTestUser,
} from '../../common/test/utility'; } from '../../common/test/utility';
@ -387,8 +388,12 @@ describe('カードライセンスを取り込む', () => {
if (!source) fail(); if (!source) fail();
const module = await makeTestingModule(source); const module = await makeTestingModule(source);
if (!module) fail(); if (!module) fail();
// 明日の日付を取得
// ミリ秒以下は切り捨てる
const tommorow = new Date();
tommorow.setDate(tommorow.getDate() + 1);
tommorow.setMilliseconds(0);
const now = new Date();
const { id: accountId } = await makeTestSimpleAccount(source); const { id: accountId } = await makeTestSimpleAccount(source);
const { external_id: externalId } = await makeTestUser(source, { const { external_id: externalId } = await makeTestUser(source, {
account_id: accountId, account_id: accountId,
@ -402,7 +407,7 @@ describe('カードライセンスを取り込む', () => {
await createLicense( await createLicense(
source, source,
1, 1,
new Date(now.getTime() + 60 * 60 * 1000), new Date(tommorow.getTime() + 60 * 60 * 1000),
accountId, accountId,
LICENSE_TYPE.NORMAL, LICENSE_TYPE.NORMAL,
LICENSE_ALLOCATED_STATUS.UNALLOCATED, LICENSE_ALLOCATED_STATUS.UNALLOCATED,
@ -428,7 +433,7 @@ describe('カードライセンスを取り込む', () => {
await createLicense( await createLicense(
source, source,
3, 3,
new Date(now.getTime() + 60 * 60 * 1000), new Date(tommorow.getTime() + 60 * 60 * 1000),
accountId, accountId,
LICENSE_TYPE.NORMAL, LICENSE_TYPE.NORMAL,
LICENSE_ALLOCATED_STATUS.UNALLOCATED, LICENSE_ALLOCATED_STATUS.UNALLOCATED,
@ -441,7 +446,7 @@ describe('カードライセンスを取り込む', () => {
await createLicense( await createLicense(
source, source,
4, 4,
new Date(now.getTime() + 60 * 60 * 1000 * 2), new Date(tommorow.getTime() + 60 * 60 * 1000 * 2),
accountId, accountId,
LICENSE_TYPE.NORMAL, LICENSE_TYPE.NORMAL,
LICENSE_ALLOCATED_STATUS.UNALLOCATED, LICENSE_ALLOCATED_STATUS.UNALLOCATED,
@ -467,7 +472,7 @@ describe('カードライセンスを取り込む', () => {
await createLicense( await createLicense(
source, source,
6, 6,
new Date(now.getTime() + 60 * 60 * 1000 * 2), new Date(tommorow.getTime() + 60 * 60 * 1000 * 2),
accountId, accountId,
LICENSE_TYPE.NORMAL, LICENSE_TYPE.NORMAL,
LICENSE_ALLOCATED_STATUS.ALLOCATED, LICENSE_ALLOCATED_STATUS.ALLOCATED,
@ -480,7 +485,7 @@ describe('カードライセンスを取り込む', () => {
await createLicense( await createLicense(
source, source,
7, 7,
new Date(now.getTime() + 60 * 60 * 1000 * 2), new Date(tommorow.getTime() + 60 * 60 * 1000 * 2),
accountId, accountId,
LICENSE_TYPE.NORMAL, LICENSE_TYPE.NORMAL,
LICENSE_ALLOCATED_STATUS.DELETED, LICENSE_ALLOCATED_STATUS.DELETED,
@ -493,7 +498,7 @@ describe('カードライセンスを取り込む', () => {
await createLicense( await createLicense(
source, source,
8, 8,
new Date(now.getTime() + 60 * 60 * 1000), new Date(tommorow.getTime() + 60 * 60 * 1000),
accountId + 1, accountId + 1,
LICENSE_TYPE.NORMAL, LICENSE_TYPE.NORMAL,
LICENSE_ALLOCATED_STATUS.UNALLOCATED, LICENSE_ALLOCATED_STATUS.UNALLOCATED,
@ -506,7 +511,7 @@ describe('カードライセンスを取り込む', () => {
await createLicense( await createLicense(
source, source,
9, 9,
new Date(now.getTime() - 60 * 60 * 1000 * 24), new Date(tommorow.getTime() - 60 * 60 * 1000 * 24),
accountId, accountId,
LICENSE_TYPE.NORMAL, LICENSE_TYPE.NORMAL,
LICENSE_ALLOCATED_STATUS.UNALLOCATED, LICENSE_ALLOCATED_STATUS.UNALLOCATED,
@ -1610,3 +1615,397 @@ describe('ライセンス注文キャンセル', () => {
); );
}); });
}); });
describe('割り当て可能なライセンス取得', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
port: 3306,
username: 'user',
password: 'password',
database: 'odms',
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
synchronize: false, // trueにすると自動的にmigrationが行われるため注意
logger: new TestLogger('none'),
logging: true,
});
return await s.initialize();
})();
}
});
beforeEach(async () => {
if (source) {
await truncateAllTable(source);
}
});
afterAll(async () => {
await source?.destroy();
source = null;
});
it('割り当て可能なライセンスを取得できる', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account, admin } = await makeTestAccount(source, {
company_name: 'AAA',
tier: 5,
});
// ライセンスを作成
// 有効期限が当日のライセンスをつ、有効期限が翌日のライセンスを1つ、有効期限が翌々日のライセンスを1つ作成
// ミリ秒以下は切り捨てる DBで扱っていないため
const today = new Date();
today.setMilliseconds(0);
const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
tomorrow.setMilliseconds(0);
const dayAfterTomorrow = new Date();
dayAfterTomorrow.setDate(dayAfterTomorrow.getDate() + 2);
dayAfterTomorrow.setMilliseconds(0);
await createLicense(
source,
1,
today,
account.id,
LICENSE_TYPE.NORMAL,
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
null,
null,
null,
null,
);
await createLicense(
source,
2,
tomorrow,
account.id,
LICENSE_TYPE.CARD,
LICENSE_ALLOCATED_STATUS.REUSABLE,
null,
null,
null,
null,
);
await createLicense(
source,
3,
dayAfterTomorrow,
account.id,
LICENSE_TYPE.TRIAL,
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
null,
null,
null,
null,
);
// ライセンス作成したデータを確認
{
const license1 = await selectLicense(source, 1);
expect(license1.license?.id).toBe(1);
expect(license1.license?.expiry_date).toEqual(today);
expect(license1.license?.allocated_user_id).toBe(null);
expect(license1.license?.status).toBe(
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
);
expect(license1.license?.account_id).toBe(account.id);
expect(license1.license?.type).toBe(LICENSE_TYPE.NORMAL);
const license2 = await selectLicense(source, 2);
expect(license2.license?.id).toBe(2);
expect(license2.license?.expiry_date).toEqual(tomorrow);
expect(license2.license?.allocated_user_id).toBe(null);
expect(license2.license?.status).toBe(LICENSE_ALLOCATED_STATUS.REUSABLE);
expect(license2.license?.account_id).toBe(account.id);
expect(license2.license?.type).toBe(LICENSE_TYPE.CARD);
const license3 = await selectLicense(source, 3);
expect(license3.license?.id).toBe(3);
expect(license3.license?.expiry_date).toEqual(dayAfterTomorrow);
expect(license3.license?.allocated_user_id).toBe(null);
expect(license3.license?.status).toBe(
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
);
expect(license3.license?.account_id).toBe(account.id);
expect(license3.license?.type).toBe(LICENSE_TYPE.TRIAL);
}
const service = module.get<LicensesService>(LicensesService);
const context = makeContext('trackingId', 'requestId');
const response = await service.getAllocatableLicenses(
context,
admin.external_id,
);
// 有効期限が当日のライセンスは取得されない
// 有効期限が長い順に取得される
expect(response.allocatableLicenses.length).toBe(2);
expect(response.allocatableLicenses[0].licenseId).toBe(3);
expect(response.allocatableLicenses[0].expiryDate).toEqual(
dayAfterTomorrow,
);
expect(response.allocatableLicenses[1].licenseId).toBe(2);
expect(response.allocatableLicenses[1].expiryDate).toEqual(tomorrow);
});
it('割り当て可能なライセンスが存在しない場合、空の配列を返却する', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account, admin } = await makeTestAccount(source, {
company_name: 'AAA',
tier: 5,
});
// ライセンスを作成
// 有効期限が当日のライセンスを3つ、有効期限が昨日のライセンスを1つ作成
// ミリ秒以下は切り捨てる DBで扱っていないため
const today = new Date();
today.setMilliseconds(0);
const yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
yesterday.setMilliseconds(0);
for (let i = 1; i <= 3; i++) {
await createLicense(
source,
i,
today,
account.id,
LICENSE_TYPE.NORMAL,
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
null,
null,
null,
null,
);
}
await createLicense(
source,
4,
yesterday,
account.id,
LICENSE_TYPE.NORMAL,
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
null,
null,
null,
null,
);
// ライセンス作成したデータを確認
{
const license1 = await selectLicense(source, 1);
expect(license1.license?.id).toBe(1);
expect(license1.license?.expiry_date).toEqual(today);
expect(license1.license?.allocated_user_id).toBe(null);
expect(license1.license?.status).toBe(
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
);
expect(license1.license?.account_id).toBe(account.id);
expect(license1.license?.type).toBe(LICENSE_TYPE.NORMAL);
const license2 = await selectLicense(source, 2);
expect(license2.license?.id).toBe(2);
expect(license2.license?.expiry_date).toEqual(today);
expect(license2.license?.allocated_user_id).toBe(null);
expect(license2.license?.status).toBe(
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
);
expect(license2.license?.account_id).toBe(account.id);
expect(license2.license?.type).toBe(LICENSE_TYPE.NORMAL);
const license3 = await selectLicense(source, 3);
expect(license3.license?.id).toBe(3);
expect(license3.license?.expiry_date).toEqual(today);
expect(license3.license?.allocated_user_id).toBe(null);
expect(license3.license?.status).toBe(
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
);
expect(license3.license?.account_id).toBe(account.id);
expect(license3.license?.type).toBe(LICENSE_TYPE.NORMAL);
const license4 = await selectLicense(source, 4);
expect(license4.license?.id).toBe(4);
expect(license4.license?.expiry_date).toEqual(yesterday);
expect(license4.license?.allocated_user_id).toBe(null);
expect(license4.license?.status).toBe(
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
);
expect(license4.license?.account_id).toBe(account.id);
expect(license4.license?.type).toBe(LICENSE_TYPE.NORMAL);
}
const service = module.get<LicensesService>(LicensesService);
const context = makeContext('trackingId', 'requestId');
const response = await service.getAllocatableLicenses(
context,
admin.external_id,
);
// 有効期限が当日のライセンスは取得されない
// 有効期限が切れているライセンスは取得されない
expect(response.allocatableLicenses.length).toBe(0);
expect(response.allocatableLicenses).toEqual([]);
});
it('割り当て可能なライセンスを100件取得できる', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account, admin } = await makeTestAccount(source, {
company_name: 'AAA',
tier: 5,
});
// ライセンスを作成
// 有効期限が30日後のライセンスを100件作成
// ミリ秒以下は切り捨てる DBで扱っていないため
const date = new Date();
date.setDate(date.getDate() + 30);
date.setMilliseconds(0);
for (let i = 1; i <= 100; i++) {
await createLicense(
source,
i,
date,
account.id,
LICENSE_TYPE.NORMAL,
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
null,
null,
null,
null,
);
}
// ライセンス作成したデータを確認
for (let i = 1; i <= 100; i++) {
const license = await selectLicense(source, i);
expect(license.license?.id).toBe(i);
expect(license.license?.expiry_date).toEqual(date);
expect(license.license?.allocated_user_id).toBe(null);
expect(license.license?.status).toBe(
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
);
expect(license.license?.account_id).toBe(account.id);
expect(license.license?.type).toBe(LICENSE_TYPE.NORMAL);
}
const service = module.get<LicensesService>(LicensesService);
const context = makeContext('trackingId', 'requestId');
const response = await service.getAllocatableLicenses(
context,
admin.external_id,
);
// 100件取得できる
expect(response.allocatableLicenses.length).toBe(100);
});
it('既に割り当てられているライセンスは取得されない', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account, admin } = await makeTestAccount(source, {
company_name: 'AAA',
tier: 5,
});
// ライセンスを作成
// ライセンスを5件作成(10日後から1日ずつ有効期限を設定)
// 有効期限が設定されていないライセンス(新規ライセンス)を1件作成
// 既に割り当てられているライセンスを1件作成
// ミリ秒以下は切り捨てる DBで扱っていないため
const date = new Date();
date.setMinutes(0);
date.setSeconds(0);
date.setDate(date.getDate() + 10);
date.setMilliseconds(0);
for (let i = 1; i <= 5; i++) {
await createLicense(
source,
i,
date,
account.id,
LICENSE_TYPE.NORMAL,
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
admin.id,
null,
null,
null,
);
date.setDate(date.getDate() + 1);
}
// 新規ライセンス
await createLicense(
source,
6,
null,
account.id,
LICENSE_TYPE.NORMAL,
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
null,
null,
null,
null,
);
// 既に割り当てられているライセンス
await createLicense(
source,
7,
date,
account.id,
LICENSE_TYPE.NORMAL,
LICENSE_ALLOCATED_STATUS.ALLOCATED,
admin.id,
null,
null,
null,
);
// ライセンス作成したデータを確認
{
const date = new Date();
date.setMinutes(0);
date.setSeconds(0);
date.setDate(date.getDate() + 10);
date.setMilliseconds(0);
for (let i = 1; i <= 5; i++) {
const license = await selectLicense(source, i);
expect(license.license?.id).toBe(i);
expect(license.license?.expiry_date).toEqual(date);
expect(license.license?.allocated_user_id).toBe(admin.id);
expect(license.license?.status).toBe(
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
);
expect(license.license?.account_id).toBe(account.id);
expect(license.license?.type).toBe(LICENSE_TYPE.NORMAL);
date.setDate(date.getDate() + 1);
}
const newLicense = await selectLicense(source, 6);
expect(newLicense.license?.id).toBe(6);
expect(newLicense.license?.expiry_date).toBe(null);
expect(newLicense.license?.allocated_user_id).toBe(null);
expect(newLicense.license?.status).toBe(
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
);
const allocatedLicense = await selectLicense(source, 7);
expect(allocatedLicense.license?.id).toBe(7);
expect(allocatedLicense.license?.expiry_date).toEqual(date);
expect(allocatedLicense.license?.allocated_user_id).toBe(admin.id);
expect(allocatedLicense.license?.status).toBe(
LICENSE_ALLOCATED_STATUS.ALLOCATED,
);
expect(allocatedLicense.license?.account_id).toBe(account.id);
expect(allocatedLicense.license?.type).toBe(LICENSE_TYPE.NORMAL);
}
const service = module.get<LicensesService>(LicensesService);
const context = makeContext('trackingId', 'requestId');
const response = await service.getAllocatableLicenses(
context,
admin.external_id,
);
// 既に割り当てられているライセンスは取得されない
// 新規ライセンスは取得される
// 有効期限が長い順に取得される
expect(response.allocatableLicenses.length).toBe(6);
expect(response.allocatableLicenses[0].licenseId).toBe(6);
expect(response.allocatableLicenses[0].expiryDate).toBe(undefined);
expect(response.allocatableLicenses[1].licenseId).toBe(5); // 有効期限が最も長い
expect(response.allocatableLicenses[2].licenseId).toBe(4);
expect(response.allocatableLicenses[3].licenseId).toBe(3);
expect(response.allocatableLicenses[4].licenseId).toBe(2);
expect(response.allocatableLicenses[5].licenseId).toBe(1);
});
});

View File

@ -525,9 +525,14 @@ export class LicensesRepositoryService {
context: Context, context: Context,
myAccountId: number, myAccountId: number,
): Promise<AllocatableLicenseInfo[]> { ): Promise<AllocatableLicenseInfo[]> {
const nowDate = new DateWithZeroTime();
const licenseRepo = this.dataSource.getRepository(License); const licenseRepo = this.dataSource.getRepository(License);
// EntityManagerではorderBy句で、expiry_dateに対して複数条件でソートを使用するため出来ない為、createQueryBuilderを使用する。 // EntityManagerではorderBy句で、expiry_dateに対して複数条件でソートを使用するため出来ない為、createQueryBuilderを使用する。
// プロダクト バックログ項目 4218: [FB対応]有効期限当日のライセンスは一覧に表示しない の対応
// 有効期限が当日のライセンスは取得しない
// 明日の00:00:00を取得
const tomorrowDate = new DateWithZeroTime(
new Date().setDate(new Date().getDate() + 1),
);
const queryBuilder = licenseRepo const queryBuilder = licenseRepo
.createQueryBuilder('license') .createQueryBuilder('license')
.where('license.account_id = :accountId', { accountId: myAccountId }) .where('license.account_id = :accountId', { accountId: myAccountId })
@ -538,8 +543,8 @@ export class LicensesRepositoryService {
], ],
}) })
.andWhere( .andWhere(
'(license.expiry_date >= :nowDate OR license.expiry_date IS NULL)', '(license.expiry_date >= :tomorrowDate OR license.expiry_date IS NULL)',
{ nowDate }, { tomorrowDate },
) )
.comment(`${context.getTrackingId()}_${new Date().toUTCString()}`) .comment(`${context.getTrackingId()}_${new Date().toUTCString()}`)
.orderBy('license.expiry_date IS NULL', 'DESC') .orderBy('license.expiry_date IS NULL', 'DESC')
@ -597,6 +602,9 @@ export class LicensesRepositoryService {
} }
// 期限切れの場合はエラー // 期限切れの場合はエラー
// 有効期限が当日のライセンスは割り当て不可
// XXX 記述は「有効期限が過去のライセンスは割り当て不可」のような意図だと思われるが、実際の処理は「有効期限が当日のライセンスは割り当て不可」になっている
// より正確な記述に修正したほうが良いが、リリース後のため、修正は保留2024年6月7日
if (targetLicense.expiry_date) { if (targetLicense.expiry_date) {
const currentDay = new Date(); const currentDay = new Date();
currentDay.setHours(23, 59, 59, 999); currentDay.setHours(23, 59, 59, 999);

View File

@ -13,7 +13,7 @@
<p> <p>
We have received your bulk user registration request. <br /> We have received your bulk user registration request. <br />
- Date and time: $REQUEST_TIME$<br /> - Date and time: $REQUEST_TIME$<br />
- SCV file name: $FILE_NAME$ - CSV file name: $FILE_NAME$
</p> </p>
<p> <p>
・Please wait until the registration is complete. This may take a few minutes to process.<br /> ・Please wait until the registration is complete. This may take a few minutes to process.<br />
@ -36,7 +36,7 @@
<p> <p>
Wir haben Ihre Anfrage zur Massenbenutzerregistrierung erhalten.<br /> Wir haben Ihre Anfrage zur Massenbenutzerregistrierung erhalten.<br />
- Datum und Uhrzeit: $REQUEST_TIME$<br /> - Datum und Uhrzeit: $REQUEST_TIME$<br />
- SCV-Dateiname: $FILE_NAME$ - CSV-Dateiname: $FILE_NAME$
</p> </p>
<p> <p>
・Bitte warten Sie, bis die Registrierung abgeschlossen ist. Die Bearbeitung kann einige Minuten dauern.<br /> ・Bitte warten Sie, bis die Registrierung abgeschlossen ist. Die Bearbeitung kann einige Minuten dauern.<br />
@ -59,7 +59,7 @@
<p> <p>
Nous avons reçu votre demande d'enregistrement groupé d'utilisateur.<br /> Nous avons reçu votre demande d'enregistrement groupé d'utilisateur.<br />
- Date et heure : $REQUEST_TIME$<br /> - Date et heure : $REQUEST_TIME$<br />
- Nom du fichier SCV : $FILE_NAME$ - Nom du fichier CSV : $FILE_NAME$
</p> </p>
<p> <p>
・Veuillez attendre que l'inscription soit terminée. Le traitement peut prendre quelques minutes.<br /> ・Veuillez attendre que l'inscription soit terminée. Le traitement peut prendre quelques minutes.<br />

View File

@ -4,7 +4,7 @@ Dear $CUSTOMER_NAME$,
We have received your bulk user registration request. We have received your bulk user registration request.
- Date and time: $REQUEST_TIME$ - Date and time: $REQUEST_TIME$
- SCV file name: $FILE_NAME$ - CSV file name: $FILE_NAME$
・Please wait until the registration is complete. This may take a few minutes to process. ・Please wait until the registration is complete. This may take a few minutes to process.
・Notification will be sent separately upon completion. ・Notification will be sent separately upon completion.
@ -21,7 +21,7 @@ Sehr geehrte(r) $CUSTOMER_NAME$,
Wir haben Ihre Anfrage zur Massenbenutzerregistrierung erhalten. Wir haben Ihre Anfrage zur Massenbenutzerregistrierung erhalten.
- Datum und Uhrzeit: $REQUEST_TIME$ - Datum und Uhrzeit: $REQUEST_TIME$
- SCV-Dateiname: $FILE_NAME$ - CSV-Dateiname: $FILE_NAME$
・Bitte warten Sie, bis die Registrierung abgeschlossen ist. Die Bearbeitung kann einige Minuten dauern. ・Bitte warten Sie, bis die Registrierung abgeschlossen ist. Die Bearbeitung kann einige Minuten dauern.
・Eine Benachrichtigung wird nach Abschluss separat verschickt. ・Eine Benachrichtigung wird nach Abschluss separat verschickt.
@ -38,7 +38,7 @@ Chère/Cher $CUSTOMER_NAME$,
Nous avons reçu votre demande d'enregistrement groupé d'utilisateur. Nous avons reçu votre demande d'enregistrement groupé d'utilisateur.
- Date et heure : $REQUEST_TIME$ - Date et heure : $REQUEST_TIME$
- Nom du fichier SCV : $FILE_NAME$ - Nom du fichier CSV : $FILE_NAME$
・Veuillez attendre que l'inscription soit terminée. Le traitement peut prendre quelques minutes. ・Veuillez attendre que l'inscription soit terminée. Le traitement peut prendre quelques minutes.
・Une notification sera envoyée séparément une fois terminée. ・Une notification sera envoyée séparément une fois terminée.

View File

@ -13,7 +13,7 @@
<p> <p>
We have received your bulk user registration request. <br /> We have received your bulk user registration request. <br />
- Date and time: $REQUEST_TIME$<br /> - Date and time: $REQUEST_TIME$<br />
- SCV file name: $FILE_NAME$ - CSV file name: $FILE_NAME$
</p> </p>
<p> <p>
・Please wait until the registration is complete. This may take a few minutes to process.<br /> ・Please wait until the registration is complete. This may take a few minutes to process.<br />
@ -33,7 +33,7 @@
<p> <p>
Wir haben Ihre Anfrage zur Massenbenutzerregistrierung erhalten.<br /> Wir haben Ihre Anfrage zur Massenbenutzerregistrierung erhalten.<br />
- Datum und Uhrzeit: $REQUEST_TIME$<br /> - Datum und Uhrzeit: $REQUEST_TIME$<br />
- SCV-Dateiname: $FILE_NAME$ - CSV-Dateiname: $FILE_NAME$
</p> </p>
<p> <p>
・Bitte warten Sie, bis die Registrierung abgeschlossen ist. Die Bearbeitung kann einige Minuten dauern.<br /> ・Bitte warten Sie, bis die Registrierung abgeschlossen ist. Die Bearbeitung kann einige Minuten dauern.<br />
@ -53,7 +53,7 @@
<p> <p>
Nous avons reçu votre demande d'enregistrement groupé d'utilisateur.<br /> Nous avons reçu votre demande d'enregistrement groupé d'utilisateur.<br />
- Date et heure : $REQUEST_TIME$<br /> - Date et heure : $REQUEST_TIME$<br />
- Nom du fichier SCV : $FILE_NAME$ - Nom du fichier CSV : $FILE_NAME$
</p> </p>
<p> <p>
・Veuillez attendre que l'inscription soit terminée. Le traitement peut prendre quelques minutes.<br /> ・Veuillez attendre que l'inscription soit terminée. Le traitement peut prendre quelques minutes.<br />

View File

@ -4,7 +4,7 @@ Dear $CUSTOMER_NAME$,
We have received your bulk user registration request. We have received your bulk user registration request.
- Date and time: $REQUEST_TIME$ - Date and time: $REQUEST_TIME$
- SCV file name: $FILE_NAME$ - CSV file name: $FILE_NAME$
・Please wait until the registration is complete. This may take a few minutes to process. ・Please wait until the registration is complete. This may take a few minutes to process.
・Notification will be sent separately upon completion. ・Notification will be sent separately upon completion.
@ -19,7 +19,7 @@ Sehr geehrte(r) $CUSTOMER_NAME$,
Wir haben Ihre Anfrage zur Massenbenutzerregistrierung erhalten. Wir haben Ihre Anfrage zur Massenbenutzerregistrierung erhalten.
- Datum und Uhrzeit: $REQUEST_TIME$ - Datum und Uhrzeit: $REQUEST_TIME$
- SCV-Dateiname: $FILE_NAME$ - CSV-Dateiname: $FILE_NAME$
・Bitte warten Sie, bis die Registrierung abgeschlossen ist. Die Bearbeitung kann einige Minuten dauern. ・Bitte warten Sie, bis die Registrierung abgeschlossen ist. Die Bearbeitung kann einige Minuten dauern.
・Eine Benachrichtigung wird nach Abschluss separat verschickt. ・Eine Benachrichtigung wird nach Abschluss separat verschickt.
@ -34,7 +34,7 @@ Chère/Cher $CUSTOMER_NAME$,
Nous avons reçu votre demande d'enregistrement groupé d'utilisateur. Nous avons reçu votre demande d'enregistrement groupé d'utilisateur.
- Date et heure : $REQUEST_TIME$ - Date et heure : $REQUEST_TIME$
- Nom du fichier SCV : $FILE_NAME$ - Nom du fichier CSV : $FILE_NAME$
・Veuillez attendre que l'inscription soit terminée. Le traitement peut prendre quelques minutes. ・Veuillez attendre que l'inscription soit terminée. Le traitement peut prendre quelques minutes.
・Une notification sera envoyée séparément une fois terminée. ・Une notification sera envoyée séparément une fois terminée.

View File

@ -10,7 +10,7 @@
<p> <p>
Bulk user registration using the CSV file has been completed.<br /> Bulk user registration using the CSV file has been completed.<br />
- Date and time: $REQUEST_TIME$<br /> - Date and time: $REQUEST_TIME$<br />
- SCV file name: $FILE_NAME$ - CSV file name: $FILE_NAME$
</p> </p>
<p> <p>
・User Registration Notification [U-114] will be sent to the registered users.<br /> ・User Registration Notification [U-114] will be sent to the registered users.<br />
@ -33,7 +33,7 @@
<p> <p>
Die Massenbenutzerregistrierung mithilfe der CSV-Datei wurde abgeschlossen.<br /> Die Massenbenutzerregistrierung mithilfe der CSV-Datei wurde abgeschlossen.<br />
- Datum und Uhrzeit: $REQUEST_TIME$<br /> - Datum und Uhrzeit: $REQUEST_TIME$<br />
- SCV-Dateiname: $FILE_NAME$ - CSV-Dateiname: $FILE_NAME$
</p> </p>
<p> <p>
・Die Benutzerregistrierungsbenachrichtigung [U-114] wird an die registrierten Benutzer gesendet.<br /> ・Die Benutzerregistrierungsbenachrichtigung [U-114] wird an die registrierten Benutzer gesendet.<br />
@ -57,7 +57,7 @@
<p> <p>
L'enregistrement groupé des utilisateurs à l'aide du fichier CSV est terminé.<br /> L'enregistrement groupé des utilisateurs à l'aide du fichier CSV est terminé.<br />
- Date et heure : $REQUEST_TIME$<br /> - Date et heure : $REQUEST_TIME$<br />
- Nom du fichier SCV : $FILE_NAME$ - Nom du fichier CSV : $FILE_NAME$
</p> </p>
<p> <p>
・La notification d'enregistrement de l'utilisateur [U-114] sera envoyée aux utilisateurs enregistrés.<br /> ・La notification d'enregistrement de l'utilisateur [U-114] sera envoyée aux utilisateurs enregistrés.<br />

View File

@ -4,7 +4,7 @@ Dear $CUSTOMER_NAME$,
Bulk user registration using the CSV file has been completed. Bulk user registration using the CSV file has been completed.
- Date and time: $REQUEST_TIME$ - Date and time: $REQUEST_TIME$
- SCV file name: $FILE_NAME$ - CSV file name: $FILE_NAME$
・User Registration Notification [U-114] will be sent to the registered users. ・User Registration Notification [U-114] will be sent to the registered users.
・Registration will not be completed unless the user verifies their email address. ・Registration will not be completed unless the user verifies their email address.
@ -21,7 +21,7 @@ Sehr geehrte(r) $CUSTOMER_NAME$,
Die Massenbenutzerregistrierung mithilfe der CSV-Datei wurde abgeschlossen. Die Massenbenutzerregistrierung mithilfe der CSV-Datei wurde abgeschlossen.
- Datum und Uhrzeit: $REQUEST_TIME$ - Datum und Uhrzeit: $REQUEST_TIME$
- SCV-Dateiname: $FILE_NAME$ - CSV-Dateiname: $FILE_NAME$
・Die Benutzerregistrierungsbenachrichtigung [U-114] wird an die registrierten Benutzer gesendet. ・Die Benutzerregistrierungsbenachrichtigung [U-114] wird an die registrierten Benutzer gesendet.
・Die Registrierung wird erst abgeschlossen, wenn der Benutzer seine E-Mail-Adresse bestätigt. ・Die Registrierung wird erst abgeschlossen, wenn der Benutzer seine E-Mail-Adresse bestätigt.
@ -38,7 +38,7 @@ Chère/Cher $CUSTOMER_NAME$,
L'enregistrement groupé des utilisateurs à l'aide du fichier CSV est terminé. L'enregistrement groupé des utilisateurs à l'aide du fichier CSV est terminé.
- Date et heure : $REQUEST_TIME$ - Date et heure : $REQUEST_TIME$
- Nom du fichier SCV : $FILE_NAME$ - Nom du fichier CSV : $FILE_NAME$
・La notification d'enregistrement de l'utilisateur [U-114] sera envoyée aux utilisateurs enregistrés. ・La notification d'enregistrement de l'utilisateur [U-114] sera envoyée aux utilisateurs enregistrés.
・L'inscription ne sera complétée que si l'utilisateur vérifie son adresse e-mail. ・L'inscription ne sera complétée que si l'utilisateur vérifie son adresse e-mail.

View File

@ -10,7 +10,7 @@
<p> <p>
Bulk user registration using the CSV file has been completed.<br /> Bulk user registration using the CSV file has been completed.<br />
- Date and time: $REQUEST_TIME$<br /> - Date and time: $REQUEST_TIME$<br />
- SCV file name: $FILE_NAME$ - CSV file name: $FILE_NAME$
</p> </p>
<p> <p>
・User Registration Notification [U-114] will be sent to the registered users.<br /> ・User Registration Notification [U-114] will be sent to the registered users.<br />
@ -30,7 +30,7 @@
<p> <p>
Die Massenbenutzerregistrierung mithilfe der CSV-Datei wurde abgeschlossen.<br /> Die Massenbenutzerregistrierung mithilfe der CSV-Datei wurde abgeschlossen.<br />
- Datum und Uhrzeit: $REQUEST_TIME$<br /> - Datum und Uhrzeit: $REQUEST_TIME$<br />
- SCV-Dateiname: $FILE_NAME$ - CSV-Dateiname: $FILE_NAME$
</p> </p>
<p> <p>
・Die Benutzerregistrierungsbenachrichtigung [U-114] wird an die registrierten Benutzer gesendet.<br /> ・Die Benutzerregistrierungsbenachrichtigung [U-114] wird an die registrierten Benutzer gesendet.<br />
@ -51,7 +51,7 @@
<p> <p>
L'enregistrement groupé des utilisateurs à l'aide du fichier CSV est terminé.<br /> L'enregistrement groupé des utilisateurs à l'aide du fichier CSV est terminé.<br />
- Date et heure : $REQUEST_TIME$<br /> - Date et heure : $REQUEST_TIME$<br />
- Nom du fichier SCV : $FILE_NAME$ - Nom du fichier CSV : $FILE_NAME$
</p> </p>
<p> <p>
・La notification d'enregistrement de l'utilisateur [U-114] sera envoyée aux utilisateurs enregistrés.<br /> ・La notification d'enregistrement de l'utilisateur [U-114] sera envoyée aux utilisateurs enregistrés.<br />

View File

@ -4,7 +4,7 @@ Dear $CUSTOMER_NAME$,
Bulk user registration using the CSV file has been completed. Bulk user registration using the CSV file has been completed.
- Date and time: $REQUEST_TIME$ - Date and time: $REQUEST_TIME$
- SCV file name: $FILE_NAME$ - CSV file name: $FILE_NAME$
・User Registration Notification [U-114] will be sent to the registered users. ・User Registration Notification [U-114] will be sent to the registered users.
・Registration will not be completed unless the user verifies their email address. ・Registration will not be completed unless the user verifies their email address.
@ -19,7 +19,7 @@ Sehr geehrte(r) $CUSTOMER_NAME$,
Die Massenbenutzerregistrierung mithilfe der CSV-Datei wurde abgeschlossen. Die Massenbenutzerregistrierung mithilfe der CSV-Datei wurde abgeschlossen.
- Datum und Uhrzeit: $REQUEST_TIME$ - Datum und Uhrzeit: $REQUEST_TIME$
- SCV-Dateiname: $FILE_NAME$ - CSV-Dateiname: $FILE_NAME$
・Die Benutzerregistrierungsbenachrichtigung [U-114] wird an die registrierten Benutzer gesendet. ・Die Benutzerregistrierungsbenachrichtigung [U-114] wird an die registrierten Benutzer gesendet.
・Die Registrierung wird erst abgeschlossen, wenn der Benutzer seine E-Mail-Adresse bestätigt. ・Die Registrierung wird erst abgeschlossen, wenn der Benutzer seine E-Mail-Adresse bestätigt.
@ -34,7 +34,7 @@ Chère/Cher $CUSTOMER_NAME$,
L'enregistrement groupé des utilisateurs à l'aide du fichier CSV est terminé. L'enregistrement groupé des utilisateurs à l'aide du fichier CSV est terminé.
- Date et heure : $REQUEST_TIME$ - Date et heure : $REQUEST_TIME$
- Nom du fichier SCV : $FILE_NAME$ - Nom du fichier CSV : $FILE_NAME$
・La notification d'enregistrement de l'utilisateur [U-114] sera envoyée aux utilisateurs enregistrés. ・La notification d'enregistrement de l'utilisateur [U-114] sera envoyée aux utilisateurs enregistrés.
・L'inscription ne sera complétée que si l'utilisateur vérifie son adresse e-mail. ・L'inscription ne sera complétée que si l'utilisateur vérifie son adresse e-mail.