Merge branch 'develop' into release-ccb
This commit is contained in:
commit
c73340ec51
@ -13,7 +13,7 @@ describe("parse", () => {
|
||||
email: "sample@example.com",
|
||||
role: 1,
|
||||
author_id: "HOGE",
|
||||
auto_renew: 1,
|
||||
auto_assign: 1,
|
||||
notification: 1,
|
||||
encryption: 1,
|
||||
encryption_password: "abcd",
|
||||
@ -58,7 +58,7 @@ describe("parse", () => {
|
||||
email: "sample@example.com",
|
||||
role: 1,
|
||||
author_id: null,
|
||||
auto_renew: 1,
|
||||
auto_assign: 1,
|
||||
notification: 1,
|
||||
encryption: 1,
|
||||
encryption_password: "abcd",
|
||||
@ -76,7 +76,7 @@ describe("parse", () => {
|
||||
email: "sample@example.com",
|
||||
role: null,
|
||||
author_id: "HOGE",
|
||||
auto_renew: 1,
|
||||
auto_assign: 1,
|
||||
notification: 1,
|
||||
encryption: 1,
|
||||
encryption_password: "abcd",
|
||||
@ -94,7 +94,7 @@ describe("parse", () => {
|
||||
email: "sample@example.com",
|
||||
role: 1,
|
||||
author_id: "HOGE",
|
||||
auto_renew: 1,
|
||||
auto_assign: 1,
|
||||
notification: 1,
|
||||
encryption: 1,
|
||||
encryption_password: "abcd",
|
||||
@ -105,7 +105,7 @@ describe("parse", () => {
|
||||
email: "sample2@example.com",
|
||||
role: 1,
|
||||
author_id: "HOGE2",
|
||||
auto_renew: 1,
|
||||
auto_assign: 1,
|
||||
notification: 1,
|
||||
encryption: 1,
|
||||
encryption_password: "abcd2",
|
||||
@ -119,7 +119,7 @@ describe("parse", () => {
|
||||
const actualValue = actualData[i];
|
||||
const expectValue = expectData[i];
|
||||
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.encryption).toEqual(expectValue.encryption);
|
||||
expect(actualValue.encryption_password).toEqual(
|
||||
@ -141,7 +141,7 @@ describe("parse", () => {
|
||||
email: "sample@example.com",
|
||||
role: 1,
|
||||
author_id: "1111",
|
||||
auto_renew: 1,
|
||||
auto_assign: 1,
|
||||
notification: 1,
|
||||
encryption: 1,
|
||||
encryption_password: "222222",
|
||||
|
||||
@ -6,7 +6,7 @@ export type CSVType = {
|
||||
email: string | null;
|
||||
role: number | null;
|
||||
author_id: string | null;
|
||||
auto_renew: number | null;
|
||||
auto_assign: number | null;
|
||||
notification: number;
|
||||
encryption: number | null;
|
||||
encryption_password: string | null;
|
||||
@ -19,7 +19,7 @@ const CSVTypeFields: (keyof CSVType)[] = [
|
||||
"email",
|
||||
"role",
|
||||
"author_id",
|
||||
"auto_renew",
|
||||
"auto_assign",
|
||||
"notification",
|
||||
"encryption",
|
||||
"encryption_password",
|
||||
@ -45,7 +45,7 @@ export const parseCSV = async (csvString: string): Promise<CSVType[]> =>
|
||||
dynamicTyping: {
|
||||
// author_id, encryption_passwordは数値のみの場合、numberに変換されたくないためdynamicTypingをtrueにしない
|
||||
role: true,
|
||||
auto_renew: true,
|
||||
auto_assign: true,
|
||||
notification: true,
|
||||
encryption: true,
|
||||
prompt: true,
|
||||
|
||||
@ -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
|
||||
|
@ -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
|
||||
|
Can't render this file because it has a wrong number of fields in line 2.
|
@ -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
|
||||
|
Can't render this file because it has a wrong number of fields in line 2.
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
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.
|
@ -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
|
||||
|
@ -534,7 +534,7 @@ export const importUsersAsync = createAsyncThunk<
|
||||
email: user.email ?? "",
|
||||
role: user.role ?? 0,
|
||||
authorId: user.author_id ?? undefined,
|
||||
autoRenew: user.auto_renew ?? 0,
|
||||
autoRenew: user.auto_assign ?? 0,
|
||||
notification: user.notification ?? 0,
|
||||
encryption: user.encryption ?? undefined,
|
||||
encryptionPassword: user.encryption_password ?? undefined,
|
||||
|
||||
@ -493,8 +493,8 @@ export const selectImportValidationErrors = (state: RootState) => {
|
||||
}
|
||||
}
|
||||
|
||||
// auto_renew
|
||||
if (csvUser.auto_renew === null || ![0, 1].includes(csvUser.auto_renew)) {
|
||||
// auto_assign
|
||||
if (csvUser.auto_assign === null || ![0, 1].includes(csvUser.auto_assign)) {
|
||||
invalidInput.push(rowNumber);
|
||||
// eslint-disable-next-line no-continue
|
||||
continue;
|
||||
|
||||
@ -104,6 +104,15 @@ export const FilePropertyPopup: React.FC<FilePropertyPopupProps> = (props) => {
|
||||
name="submit"
|
||||
value={t(getTranslationID("dictationPage.label.fileNameSave"))}
|
||||
className={`${styles.formSubmit} ${styles.isActive}`}
|
||||
style={{
|
||||
position: "relative",
|
||||
marginTop: "0.2rem",
|
||||
right: "auto",
|
||||
maxWidth: "18rem",
|
||||
whiteSpace: "normal",
|
||||
overflowWrap: "break-word",
|
||||
fontSize: "small",
|
||||
}}
|
||||
onClick={saveFileName}
|
||||
/>
|
||||
{isPushSaveButton && fileName.length === 0 && (
|
||||
|
||||
@ -52,7 +52,7 @@ export const ImportPopup: React.FC<UserAddPopupProps> = (props) => {
|
||||
"email",
|
||||
"role",
|
||||
"author_id",
|
||||
"auto_renew",
|
||||
"auto_assign",
|
||||
"notification",
|
||||
"encryption",
|
||||
"encryption_password",
|
||||
|
||||
@ -654,4 +654,4 @@
|
||||
"lowerLayerId": "Lower Layer ID"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -654,4 +654,4 @@
|
||||
"lowerLayerId": "Lower Layer ID"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -15,7 +15,7 @@
|
||||
"copyRight": "© OM Digital Solutions Corporation",
|
||||
"edit": "Editar",
|
||||
"save": "Ahorrar",
|
||||
"delete": "Delete",
|
||||
"delete": "Borrar",
|
||||
"return": "Devolver",
|
||||
"operationInsteadOf": "Operar la nube ODMS en nombre de:",
|
||||
"headerAccount": "Cuenta",
|
||||
@ -654,4 +654,4 @@
|
||||
"lowerLayerId": "Lower Layer ID"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -15,7 +15,7 @@
|
||||
"copyRight": "© OM Digital Solutions Corporation",
|
||||
"edit": "Éditer",
|
||||
"save": "Sauvegarder",
|
||||
"delete": "Delete",
|
||||
"delete": "Supprimer",
|
||||
"return": "Retour",
|
||||
"operationInsteadOf": "Exploiter le Cloud ODMS pour le compte de :",
|
||||
"headerAccount": "Compte",
|
||||
@ -654,4 +654,4 @@
|
||||
"lowerLayerId": "Lower Layer ID"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -9,6 +9,8 @@ import {
|
||||
GetPartnerUsersRequest,
|
||||
UpdatePartnerInfoRequest,
|
||||
CreateWorktypesRequest,
|
||||
UpdateWorktypesRequest,
|
||||
UpdateWorktypeRequestParam,
|
||||
} from './types/types';
|
||||
import { plainToClass } from 'class-transformer';
|
||||
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', () => {
|
||||
it('最低限の有効なリクエストが成功する', async () => {
|
||||
const request = new SwitchParentRequest();
|
||||
|
||||
@ -25,6 +25,7 @@ import {
|
||||
} from '../../constants';
|
||||
import {
|
||||
makeHierarchicalAccounts,
|
||||
makeTestAccount,
|
||||
makeTestSimpleAccount,
|
||||
makeTestUser,
|
||||
} from '../../common/test/utility';
|
||||
@ -387,8 +388,12 @@ describe('カードライセンスを取り込む', () => {
|
||||
if (!source) fail();
|
||||
const module = await makeTestingModule(source);
|
||||
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 { external_id: externalId } = await makeTestUser(source, {
|
||||
account_id: accountId,
|
||||
@ -402,7 +407,7 @@ describe('カードライセンスを取り込む', () => {
|
||||
await createLicense(
|
||||
source,
|
||||
1,
|
||||
new Date(now.getTime() + 60 * 60 * 1000),
|
||||
new Date(tommorow.getTime() + 60 * 60 * 1000),
|
||||
accountId,
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
@ -428,7 +433,7 @@ describe('カードライセンスを取り込む', () => {
|
||||
await createLicense(
|
||||
source,
|
||||
3,
|
||||
new Date(now.getTime() + 60 * 60 * 1000),
|
||||
new Date(tommorow.getTime() + 60 * 60 * 1000),
|
||||
accountId,
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
@ -441,7 +446,7 @@ describe('カードライセンスを取り込む', () => {
|
||||
await createLicense(
|
||||
source,
|
||||
4,
|
||||
new Date(now.getTime() + 60 * 60 * 1000 * 2),
|
||||
new Date(tommorow.getTime() + 60 * 60 * 1000 * 2),
|
||||
accountId,
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
@ -467,7 +472,7 @@ describe('カードライセンスを取り込む', () => {
|
||||
await createLicense(
|
||||
source,
|
||||
6,
|
||||
new Date(now.getTime() + 60 * 60 * 1000 * 2),
|
||||
new Date(tommorow.getTime() + 60 * 60 * 1000 * 2),
|
||||
accountId,
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.ALLOCATED,
|
||||
@ -480,7 +485,7 @@ describe('カードライセンスを取り込む', () => {
|
||||
await createLicense(
|
||||
source,
|
||||
7,
|
||||
new Date(now.getTime() + 60 * 60 * 1000 * 2),
|
||||
new Date(tommorow.getTime() + 60 * 60 * 1000 * 2),
|
||||
accountId,
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.DELETED,
|
||||
@ -493,7 +498,7 @@ describe('カードライセンスを取り込む', () => {
|
||||
await createLicense(
|
||||
source,
|
||||
8,
|
||||
new Date(now.getTime() + 60 * 60 * 1000),
|
||||
new Date(tommorow.getTime() + 60 * 60 * 1000),
|
||||
accountId + 1,
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
@ -506,7 +511,7 @@ describe('カードライセンスを取り込む', () => {
|
||||
await createLicense(
|
||||
source,
|
||||
9,
|
||||
new Date(now.getTime() - 60 * 60 * 1000 * 24),
|
||||
new Date(tommorow.getTime() - 60 * 60 * 1000 * 24),
|
||||
accountId,
|
||||
LICENSE_TYPE.NORMAL,
|
||||
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つ、有効期限が翌々日のライセンスを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);
|
||||
});
|
||||
});
|
||||
|
||||
@ -525,9 +525,14 @@ export class LicensesRepositoryService {
|
||||
context: Context,
|
||||
myAccountId: number,
|
||||
): Promise<AllocatableLicenseInfo[]> {
|
||||
const nowDate = new DateWithZeroTime();
|
||||
const licenseRepo = this.dataSource.getRepository(License);
|
||||
// EntityManagerではorderBy句で、expiry_dateに対して複数条件でソートを使用するため出来ない為、createQueryBuilderを使用する。
|
||||
// プロダクト バックログ項目 4218: [FB対応]有効期限当日のライセンスは一覧に表示しない の対応
|
||||
// 有効期限が当日のライセンスは取得しない
|
||||
// 明日の00:00:00を取得
|
||||
const tomorrowDate = new DateWithZeroTime(
|
||||
new Date().setDate(new Date().getDate() + 1),
|
||||
);
|
||||
const queryBuilder = licenseRepo
|
||||
.createQueryBuilder('license')
|
||||
.where('license.account_id = :accountId', { accountId: myAccountId })
|
||||
@ -538,8 +543,8 @@ export class LicensesRepositoryService {
|
||||
],
|
||||
})
|
||||
.andWhere(
|
||||
'(license.expiry_date >= :nowDate OR license.expiry_date IS NULL)',
|
||||
{ nowDate },
|
||||
'(license.expiry_date >= :tomorrowDate OR license.expiry_date IS NULL)',
|
||||
{ tomorrowDate },
|
||||
)
|
||||
.comment(`${context.getTrackingId()}_${new Date().toUTCString()}`)
|
||||
.orderBy('license.expiry_date IS NULL', 'DESC')
|
||||
@ -597,6 +602,9 @@ export class LicensesRepositoryService {
|
||||
}
|
||||
|
||||
// 期限切れの場合はエラー
|
||||
// 有効期限が当日のライセンスは割り当て不可
|
||||
// XXX 記述は「有効期限が過去のライセンスは割り当て不可」のような意図だと思われるが、実際の処理は「有効期限が当日のライセンスは割り当て不可」になっている
|
||||
// より正確な記述に修正したほうが良いが、リリース後のため、修正は保留(2024年6月7日)
|
||||
if (targetLicense.expiry_date) {
|
||||
const currentDay = new Date();
|
||||
currentDay.setHours(23, 59, 59, 999);
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
<p>
|
||||
We have received your bulk user registration request. <br />
|
||||
- Date and time: $REQUEST_TIME$<br />
|
||||
- SCV file name: $FILE_NAME$
|
||||
- CSV file name: $FILE_NAME$
|
||||
</p>
|
||||
<p>
|
||||
・Please wait until the registration is complete. This may take a few minutes to process.<br />
|
||||
@ -36,7 +36,7 @@
|
||||
<p>
|
||||
Wir haben Ihre Anfrage zur Massenbenutzerregistrierung erhalten.<br />
|
||||
- Datum und Uhrzeit: $REQUEST_TIME$<br />
|
||||
- SCV-Dateiname: $FILE_NAME$
|
||||
- CSV-Dateiname: $FILE_NAME$
|
||||
</p>
|
||||
<p>
|
||||
・Bitte warten Sie, bis die Registrierung abgeschlossen ist. Die Bearbeitung kann einige Minuten dauern.<br />
|
||||
@ -59,7 +59,7 @@
|
||||
<p>
|
||||
Nous avons reçu votre demande d'enregistrement groupé d'utilisateur.<br />
|
||||
- Date et heure : $REQUEST_TIME$<br />
|
||||
- Nom du fichier SCV : $FILE_NAME$
|
||||
- Nom du fichier CSV : $FILE_NAME$
|
||||
</p>
|
||||
<p>
|
||||
・Veuillez attendre que l'inscription soit terminée. Le traitement peut prendre quelques minutes.<br />
|
||||
|
||||
@ -4,7 +4,7 @@ Dear $CUSTOMER_NAME$,
|
||||
|
||||
We have received your bulk user registration request.
|
||||
- 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.
|
||||
・Notification will be sent separately upon completion.
|
||||
@ -21,7 +21,7 @@ Sehr geehrte(r) $CUSTOMER_NAME$,
|
||||
|
||||
Wir haben Ihre Anfrage zur Massenbenutzerregistrierung erhalten.
|
||||
- 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.
|
||||
・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.
|
||||
- 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.
|
||||
・Une notification sera envoyée séparément une fois terminée.
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
<p>
|
||||
We have received your bulk user registration request. <br />
|
||||
- Date and time: $REQUEST_TIME$<br />
|
||||
- SCV file name: $FILE_NAME$
|
||||
- CSV file name: $FILE_NAME$
|
||||
</p>
|
||||
<p>
|
||||
・Please wait until the registration is complete. This may take a few minutes to process.<br />
|
||||
@ -33,7 +33,7 @@
|
||||
<p>
|
||||
Wir haben Ihre Anfrage zur Massenbenutzerregistrierung erhalten.<br />
|
||||
- Datum und Uhrzeit: $REQUEST_TIME$<br />
|
||||
- SCV-Dateiname: $FILE_NAME$
|
||||
- CSV-Dateiname: $FILE_NAME$
|
||||
</p>
|
||||
<p>
|
||||
・Bitte warten Sie, bis die Registrierung abgeschlossen ist. Die Bearbeitung kann einige Minuten dauern.<br />
|
||||
@ -53,7 +53,7 @@
|
||||
<p>
|
||||
Nous avons reçu votre demande d'enregistrement groupé d'utilisateur.<br />
|
||||
- Date et heure : $REQUEST_TIME$<br />
|
||||
- Nom du fichier SCV : $FILE_NAME$
|
||||
- Nom du fichier CSV : $FILE_NAME$
|
||||
</p>
|
||||
<p>
|
||||
・Veuillez attendre que l'inscription soit terminée. Le traitement peut prendre quelques minutes.<br />
|
||||
|
||||
@ -4,7 +4,7 @@ Dear $CUSTOMER_NAME$,
|
||||
|
||||
We have received your bulk user registration request.
|
||||
- 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.
|
||||
・Notification will be sent separately upon completion.
|
||||
@ -19,7 +19,7 @@ Sehr geehrte(r) $CUSTOMER_NAME$,
|
||||
|
||||
Wir haben Ihre Anfrage zur Massenbenutzerregistrierung erhalten.
|
||||
- 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.
|
||||
・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.
|
||||
- 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.
|
||||
・Une notification sera envoyée séparément une fois terminée.
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
<p>
|
||||
Bulk user registration using the CSV file has been completed.<br />
|
||||
- Date and time: $REQUEST_TIME$<br />
|
||||
- SCV file name: $FILE_NAME$
|
||||
- CSV file name: $FILE_NAME$
|
||||
</p>
|
||||
<p>
|
||||
・User Registration Notification [U-114] will be sent to the registered users.<br />
|
||||
@ -33,7 +33,7 @@
|
||||
<p>
|
||||
Die Massenbenutzerregistrierung mithilfe der CSV-Datei wurde abgeschlossen.<br />
|
||||
- Datum und Uhrzeit: $REQUEST_TIME$<br />
|
||||
- SCV-Dateiname: $FILE_NAME$
|
||||
- CSV-Dateiname: $FILE_NAME$
|
||||
</p>
|
||||
<p>
|
||||
・Die Benutzerregistrierungsbenachrichtigung [U-114] wird an die registrierten Benutzer gesendet.<br />
|
||||
@ -57,7 +57,7 @@
|
||||
<p>
|
||||
L'enregistrement groupé des utilisateurs à l'aide du fichier CSV est terminé.<br />
|
||||
- Date et heure : $REQUEST_TIME$<br />
|
||||
- Nom du fichier SCV : $FILE_NAME$
|
||||
- Nom du fichier CSV : $FILE_NAME$
|
||||
</p>
|
||||
<p>
|
||||
・La notification d'enregistrement de l'utilisateur [U-114] sera envoyée aux utilisateurs enregistrés.<br />
|
||||
|
||||
@ -4,7 +4,7 @@ Dear $CUSTOMER_NAME$,
|
||||
|
||||
Bulk user registration using the CSV file has been completed.
|
||||
- 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.
|
||||
・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.
|
||||
- Datum und Uhrzeit: $REQUEST_TIME$
|
||||
- SCV-Dateiname: $FILE_NAME$
|
||||
- CSV-Dateiname: $FILE_NAME$
|
||||
|
||||
・Die Benutzerregistrierungsbenachrichtigung [U-114] wird an die registrierten Benutzer gesendet.
|
||||
・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é.
|
||||
- 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.
|
||||
・L'inscription ne sera complétée que si l'utilisateur vérifie son adresse e-mail.
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
<p>
|
||||
Bulk user registration using the CSV file has been completed.<br />
|
||||
- Date and time: $REQUEST_TIME$<br />
|
||||
- SCV file name: $FILE_NAME$
|
||||
- CSV file name: $FILE_NAME$
|
||||
</p>
|
||||
<p>
|
||||
・User Registration Notification [U-114] will be sent to the registered users.<br />
|
||||
@ -30,7 +30,7 @@
|
||||
<p>
|
||||
Die Massenbenutzerregistrierung mithilfe der CSV-Datei wurde abgeschlossen.<br />
|
||||
- Datum und Uhrzeit: $REQUEST_TIME$<br />
|
||||
- SCV-Dateiname: $FILE_NAME$
|
||||
- CSV-Dateiname: $FILE_NAME$
|
||||
</p>
|
||||
<p>
|
||||
・Die Benutzerregistrierungsbenachrichtigung [U-114] wird an die registrierten Benutzer gesendet.<br />
|
||||
@ -51,7 +51,7 @@
|
||||
<p>
|
||||
L'enregistrement groupé des utilisateurs à l'aide du fichier CSV est terminé.<br />
|
||||
- Date et heure : $REQUEST_TIME$<br />
|
||||
- Nom du fichier SCV : $FILE_NAME$
|
||||
- Nom du fichier CSV : $FILE_NAME$
|
||||
</p>
|
||||
<p>
|
||||
・La notification d'enregistrement de l'utilisateur [U-114] sera envoyée aux utilisateurs enregistrés.<br />
|
||||
|
||||
@ -4,7 +4,7 @@ Dear $CUSTOMER_NAME$,
|
||||
|
||||
Bulk user registration using the CSV file has been completed.
|
||||
- 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.
|
||||
・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.
|
||||
- Datum und Uhrzeit: $REQUEST_TIME$
|
||||
- SCV-Dateiname: $FILE_NAME$
|
||||
- CSV-Dateiname: $FILE_NAME$
|
||||
|
||||
・Die Benutzerregistrierungsbenachrichtigung [U-114] wird an die registrierten Benutzer gesendet.
|
||||
・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é.
|
||||
- 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.
|
||||
・L'inscription ne sera complétée que si l'utilisateur vérifie son adresse e-mail.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user