Merge branch 'develop' into ccb
# Conflicts: # dictation_server/src/features/users/users.service.spec.ts
This commit is contained in:
commit
ddd4d31f25
@ -134,7 +134,7 @@ export function isAccountsInputFile(obj: any): obj is AccountsInputFile {
|
||||
"country" in obj &&
|
||||
typeof obj.country === "string" &&
|
||||
("dealerAccountId" in obj
|
||||
? typeof obj.dealerAccountId === "number"
|
||||
? obj.dealerAccountId === null || typeof obj.dealerAccountId === "number"
|
||||
: true) &&
|
||||
"adminName" in obj &&
|
||||
typeof obj.adminName === "string" &&
|
||||
|
||||
@ -1,20 +1,18 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import {
|
||||
DataSource,
|
||||
} from 'typeorm';
|
||||
import { User } from '../users/entity/user.entity';
|
||||
import { Account } from './entity/account.entity';
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { DataSource } from "typeorm";
|
||||
import { User } from "../users/entity/user.entity";
|
||||
import { Account } from "./entity/account.entity";
|
||||
import {
|
||||
getDirection,
|
||||
getTaskListSortableAttribute,
|
||||
} from '../../common/types/sort/util';
|
||||
} from "../../common/types/sort/util";
|
||||
import { SortCriteria } from "../sort_criteria/entity/sort_criteria.entity";
|
||||
import {
|
||||
insertEntity,
|
||||
updateEntity,
|
||||
deleteEntity,
|
||||
} from '../../common/repository';
|
||||
import { Context } from '../../common/log';
|
||||
} from "../../common/repository";
|
||||
import { Context } from "../../common/log";
|
||||
|
||||
@Injectable()
|
||||
export class AccountsRepositoryService {
|
||||
@ -81,6 +79,7 @@ export class AccountsRepositoryService {
|
||||
user.accepted_privacy_notice_version =
|
||||
adminUserAcceptedPrivacyNoticeVersion ?? null;
|
||||
user.accepted_dpa_version = adminUserAcceptedDpaVersion ?? null;
|
||||
user.email_verified = true;
|
||||
}
|
||||
const usersRepo = entityManager.getRepository(User);
|
||||
const newUser = usersRepo.create(user);
|
||||
|
||||
@ -129,6 +129,33 @@ export class CardLicense {
|
||||
@Column({ nullable: true, type: "datetime" })
|
||||
updated_by: string | null;
|
||||
|
||||
@UpdateDateColumn({
|
||||
default: () => "datetime('now', 'localtime')",
|
||||
type: "datetime",
|
||||
})
|
||||
updated_at: Date;
|
||||
}
|
||||
|
||||
@Entity({ name: "card_license_issue" })
|
||||
export class CardLicenseIssue {
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@Column()
|
||||
issued_at: Date;
|
||||
|
||||
@Column({ nullable: true, type: "datetime" })
|
||||
created_by: string | null;
|
||||
|
||||
@CreateDateColumn({
|
||||
default: () => "datetime('now', 'localtime')",
|
||||
type: "datetime",
|
||||
})
|
||||
created_at: Date;
|
||||
|
||||
@Column({ nullable: true, type: "datetime" })
|
||||
updated_by: string | null;
|
||||
|
||||
@UpdateDateColumn({
|
||||
default: () => "datetime('now', 'localtime')",
|
||||
type: "datetime",
|
||||
|
||||
@ -2,6 +2,7 @@ import { Module } from "@nestjs/common";
|
||||
import { TypeOrmModule } from "@nestjs/typeorm";
|
||||
import {
|
||||
CardLicense,
|
||||
CardLicenseIssue,
|
||||
License,
|
||||
LicenseAllocationHistory,
|
||||
} from "./entity/license.entity";
|
||||
@ -9,7 +10,11 @@ import { LicensesRepositoryService } from "./licenses.repository.service";
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([License, CardLicense, LicenseAllocationHistory]),
|
||||
TypeOrmModule.forFeature([
|
||||
License,
|
||||
CardLicense,
|
||||
CardLicenseIssue, LicenseAllocationHistory,
|
||||
]),
|
||||
],
|
||||
providers: [LicensesRepositoryService],
|
||||
exports: [LicensesRepositoryService],
|
||||
|
||||
@ -4,14 +4,19 @@ import {
|
||||
License,
|
||||
LicenseAllocationHistory,
|
||||
CardLicense,
|
||||
CardLicenseIssue,
|
||||
} from "./entity/license.entity";
|
||||
import { insertEntities } from "../../common/repository";
|
||||
import { insertEntity, insertEntities } from "../../common/repository";
|
||||
import { Context } from "../../common/log";
|
||||
import {
|
||||
LicensesInputFile,
|
||||
CardLicensesInputFile,
|
||||
} from "../../common/types/types";
|
||||
|
||||
import {AUTO_INCREMENT_START} from "../../constants/index"
|
||||
import {
|
||||
LICENSE_ALLOCATED_STATUS,
|
||||
LICENSE_TYPE,
|
||||
} from "../../constants";
|
||||
@Injectable()
|
||||
export class LicensesRepositoryService {
|
||||
//クエリログにコメントを出力するかどうか
|
||||
@ -38,7 +43,9 @@ export class LicensesRepositoryService {
|
||||
license.account_id = licensesInputFile.account_id;
|
||||
license.status = licensesInputFile.status;
|
||||
license.type = licensesInputFile.type;
|
||||
license.expiry_date = (licensesInputFile.expiry_date) ? new Date(licensesInputFile.expiry_date) : null;
|
||||
license.expiry_date = licensesInputFile.expiry_date
|
||||
? new Date(licensesInputFile.expiry_date)
|
||||
: null;
|
||||
if (licensesInputFile.allocated_user_id) {
|
||||
license.allocated_user_id = licensesInputFile.allocated_user_id;
|
||||
}
|
||||
@ -97,22 +104,61 @@ export class LicensesRepositoryService {
|
||||
): Promise<{}> {
|
||||
return await this.dataSource.transaction(async (entityManager) => {
|
||||
const cardLicenseRepo = entityManager.getRepository(CardLicense);
|
||||
const licensesRepo = entityManager.getRepository(License);
|
||||
const cardLicenseIssueRepo =
|
||||
entityManager.getRepository(CardLicenseIssue);
|
||||
|
||||
const licenses: License[] = [];
|
||||
// ライセンステーブルを作成する(BULK INSERT)
|
||||
for (let i = 0; i < cardLicensesInputFiles.length; i++) {
|
||||
const license = new License();
|
||||
license.account_id = AUTO_INCREMENT_START; // 最初に登場するアカウント(第一アカウント)
|
||||
license.status = LICENSE_ALLOCATED_STATUS.UNALLOCATED;
|
||||
license.type = LICENSE_TYPE.CARD;
|
||||
licenses.push(license);
|
||||
}
|
||||
const savedLicenses = await insertEntities(
|
||||
License,
|
||||
licensesRepo,
|
||||
licenses,
|
||||
this.isCommentOut,
|
||||
context
|
||||
);
|
||||
|
||||
let newCardLicenses: CardLicense[] = [];
|
||||
cardLicensesInputFiles.forEach((cardLicensesInputFile) => {
|
||||
// カードライセンス発行テーブルを作成する
|
||||
const cardLicenseIssue = new CardLicenseIssue();
|
||||
cardLicenseIssue.issued_at = new Date();
|
||||
const newCardLicenseIssue = cardLicenseIssueRepo.create(cardLicenseIssue);
|
||||
const savedCardLicensesIssue = await insertEntity(
|
||||
CardLicenseIssue,
|
||||
cardLicenseIssueRepo,
|
||||
newCardLicenseIssue,
|
||||
this.isCommentOut,
|
||||
context
|
||||
);
|
||||
|
||||
const newCardLicenses: CardLicense[] = [];
|
||||
// カードライセンステーブルを作成する(BULK INSERT)
|
||||
for (let i = 0; i < cardLicensesInputFiles.length; i++) {
|
||||
const cardLicense = new CardLicense();
|
||||
cardLicense.license_id = cardLicensesInputFile.license_id;
|
||||
cardLicense.issue_id = cardLicensesInputFile.issue_id;
|
||||
cardLicense.card_license_key = cardLicensesInputFile.card_license_key;
|
||||
cardLicense.activated_at = (cardLicensesInputFile.activated_at) ? new Date(cardLicensesInputFile.activated_at) : null;
|
||||
cardLicense.created_at = (cardLicensesInputFile.created_at) ? new Date(cardLicensesInputFile.created_at) : null;
|
||||
cardLicense.created_by = cardLicensesInputFile.created_by;
|
||||
cardLicense.updated_at = (cardLicensesInputFile.updated_at) ? new Date(cardLicensesInputFile.updated_at) : null;
|
||||
cardLicense.updated_by = cardLicensesInputFile.updated_by;
|
||||
cardLicense.license_id = savedLicenses[i].id; // Licenseテーブルの自動採番されたIDを挿入
|
||||
cardLicense.issue_id = savedCardLicensesIssue.id; // CardLicenseIssueテーブルの自動採番されたIDを挿入
|
||||
cardLicense.card_license_key =
|
||||
cardLicensesInputFiles[i].card_license_key;
|
||||
cardLicense.activated_at = cardLicensesInputFiles[i].activated_at
|
||||
? new Date(cardLicensesInputFiles[i].activated_at)
|
||||
: null;
|
||||
cardLicense.created_at = cardLicensesInputFiles[i].created_at
|
||||
? new Date(cardLicensesInputFiles[i].created_at)
|
||||
: null;
|
||||
cardLicense.created_by = cardLicensesInputFiles[i].created_by;
|
||||
cardLicense.updated_at = cardLicensesInputFiles[i].updated_at
|
||||
? new Date(cardLicensesInputFiles[i].updated_at)
|
||||
: null;
|
||||
cardLicense.updated_by = cardLicensesInputFiles[i].updated_by;
|
||||
|
||||
newCardLicenses.push(cardLicense);
|
||||
});
|
||||
}
|
||||
|
||||
const query = cardLicenseRepo
|
||||
.createQueryBuilder()
|
||||
@ -126,5 +172,4 @@ export class LicensesRepositoryService {
|
||||
return {};
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ import {
|
||||
selectEmail,
|
||||
selectInputValidationErrors,
|
||||
selectIsLoading,
|
||||
selectOffset,
|
||||
} from "features/partner/selectors";
|
||||
import {
|
||||
changeAdminName,
|
||||
@ -19,7 +20,11 @@ import {
|
||||
changeEmail,
|
||||
cleanupAddPartner,
|
||||
} from "features/partner/partnerSlice";
|
||||
import { createPartnerAccountAsync } from "features/partner";
|
||||
import {
|
||||
LIMIT_PARTNER_VIEW_NUM,
|
||||
createPartnerAccountAsync,
|
||||
getPartnerInfoAsync,
|
||||
} from "features/partner";
|
||||
import close from "../../assets/images/close.svg";
|
||||
import progress_activit from "../../assets/images/progress_activit.svg";
|
||||
import { COUNTRY_LIST } from "../SignupPage/constants";
|
||||
@ -50,6 +55,7 @@ export const AddPartnerAccountPopup: React.FC<AddPartnerAccountPopup> = (
|
||||
const adminName = useSelector(selectAdminName);
|
||||
const email = useSelector(selectEmail);
|
||||
const isLoading = useSelector(selectIsLoading);
|
||||
const offset = useSelector(selectOffset);
|
||||
|
||||
// ポップアップを閉じる処理
|
||||
const closePopup = useCallback(() => {
|
||||
@ -84,6 +90,12 @@ export const AddPartnerAccountPopup: React.FC<AddPartnerAccountPopup> = (
|
||||
setIsPushCreateButton(false);
|
||||
|
||||
if (meta.requestStatus === "fulfilled") {
|
||||
dispatch(
|
||||
getPartnerInfoAsync({
|
||||
limit: LIMIT_PARTNER_VIEW_NUM,
|
||||
offset,
|
||||
})
|
||||
);
|
||||
closePopup();
|
||||
}
|
||||
}, [
|
||||
|
||||
@ -786,6 +786,103 @@ describe('TasksService', () => {
|
||||
expect(task.optionItemList).toEqual(audioOptionItems);
|
||||
}
|
||||
});
|
||||
|
||||
it('[Author] Authorは自分が作成者のTask一覧を取得できる(ソート条件がJob_number以外)', async () => {
|
||||
const notificationhubServiceMockValue =
|
||||
makeDefaultNotificationhubServiceMockValue();
|
||||
if (!source) fail();
|
||||
const module = await makeTaskTestingModuleWithNotificaiton(
|
||||
source,
|
||||
notificationhubServiceMockValue,
|
||||
);
|
||||
if (!module) fail();
|
||||
const { id: accountId } = await makeTestSimpleAccount(source);
|
||||
const { id: userId, external_id } = await makeTestUser(source, {
|
||||
account_id: accountId,
|
||||
external_id: 'userId',
|
||||
role: 'author',
|
||||
author_id: 'MY_AUTHOR_ID',
|
||||
});
|
||||
|
||||
//「バグ 3661: [FB対応]Option Itemにチェックを付けると真っ白な画面になる」の確認のため
|
||||
// audio_file_idをTaskIdと異なる値にするために、AudioFileを作成
|
||||
await createAudioFile(
|
||||
source,
|
||||
accountId,
|
||||
userId,
|
||||
'MY_AUTHOR_ID',
|
||||
'',
|
||||
'00',
|
||||
);
|
||||
|
||||
// Taskを作成
|
||||
await createTask(
|
||||
source,
|
||||
accountId,
|
||||
userId,
|
||||
'MY_AUTHOR_ID',
|
||||
'WORKTYPE1',
|
||||
'01',
|
||||
'00000001',
|
||||
'Uploaded',
|
||||
);
|
||||
await createTask(
|
||||
source,
|
||||
accountId,
|
||||
userId,
|
||||
'MY_AUTHOR_ID',
|
||||
'WORKTYPE2',
|
||||
'01',
|
||||
'00000002',
|
||||
'Uploaded',
|
||||
);
|
||||
|
||||
const service = module.get<TasksService>(TasksService);
|
||||
const offset = 0;
|
||||
const limit = 20;
|
||||
const status = ['Uploaded', 'Backup'];
|
||||
// バグ 3786: [FB対応]タスク一覧画面のOptionItemがソート条件によって表示順がおかしくなる の確認のため
|
||||
// Job_number以外のソート条件を指定
|
||||
const paramName = 'WORK_TYPE';
|
||||
const direction = 'DESC';
|
||||
|
||||
const { tasks, total } = await service.getTasks(
|
||||
makeContext('trackingId', 'requestId'),
|
||||
external_id,
|
||||
[USER_ROLES.AUTHOR],
|
||||
offset,
|
||||
limit,
|
||||
status,
|
||||
paramName,
|
||||
direction,
|
||||
);
|
||||
|
||||
expect(total).toEqual(2);
|
||||
{
|
||||
const task = tasks[0];
|
||||
expect(task.jobNumber).toEqual('00000002');
|
||||
// ソート条件がJob_number以外でもOptionItemがid順に取得されていることを確認
|
||||
const audioOptionItems = Array.from({ length: 10 }).map((_, i) => {
|
||||
return {
|
||||
optionItemLabel: `label${i}:audio_file_id${task.audioFileId}`,
|
||||
optionItemValue: `value${i}:audio_file_id${task.audioFileId}`,
|
||||
};
|
||||
});
|
||||
expect(task.optionItemList).toEqual(audioOptionItems);
|
||||
}
|
||||
{
|
||||
const task = tasks[1];
|
||||
expect(task.jobNumber).toEqual('00000001');
|
||||
// ソート条件がJob_number以外でもOptionItemがid順に取得されていることを確認
|
||||
const audioOptionItems = Array.from({ length: 10 }).map((_, i) => {
|
||||
return {
|
||||
optionItemLabel: `label${i}:audio_file_id${task.audioFileId}`,
|
||||
optionItemValue: `value${i}:audio_file_id${task.audioFileId}`,
|
||||
};
|
||||
});
|
||||
expect(task.optionItemList).toEqual(audioOptionItems);
|
||||
}
|
||||
});
|
||||
it('[Author] Authorは同一アカウントであっても自分以外のAuhtorのTaskは取得できない', async () => {
|
||||
const notificationhubServiceMockValue =
|
||||
makeDefaultNotificationhubServiceMockValue();
|
||||
|
||||
@ -179,7 +179,7 @@ describe('UsersService.confirmUser', () => {
|
||||
});
|
||||
expect(_subject).toBe('Account Registered Notification [U-101]');
|
||||
expect(_url).toBe('http://localhost:8081/');
|
||||
}, 600000);
|
||||
});
|
||||
|
||||
it('トークンの形式が不正な場合、形式不正エラーとなる。', async () => {
|
||||
if (!source) fail();
|
||||
@ -2744,17 +2744,21 @@ describe('UsersService.getRelations', () => {
|
||||
const worktype1 = await createWorktype(
|
||||
source,
|
||||
account.id,
|
||||
'worktype1',
|
||||
'worktypeB',
|
||||
undefined,
|
||||
true,
|
||||
);
|
||||
await createOptionItems(source, worktype1.id);
|
||||
|
||||
const worktype2 = await createWorktype(source, account.id, 'worktype2');
|
||||
const worktype2 = await createWorktype(source, account.id, 'worktypeC');
|
||||
await createOptionItems(source, worktype2.id);
|
||||
|
||||
const worktype3 = await createWorktype(source, account.id, 'worktypeA');
|
||||
await createOptionItems(source, worktype3.id);
|
||||
|
||||
await createWorkflow(source, account.id, user1, worktype1.id);
|
||||
await createWorkflow(source, account.id, user1, worktype2.id);
|
||||
await createWorkflow(source, account.id, user1, worktype3.id);
|
||||
await createWorkflow(source, account.id, user1);
|
||||
await createWorkflow(source, account.id, user2, worktype1.id);
|
||||
|
||||
@ -2762,15 +2766,18 @@ describe('UsersService.getRelations', () => {
|
||||
{
|
||||
const workflows = await getWorkflows(source, account.id);
|
||||
workflows.sort((a, b) => a.id - b.id);
|
||||
expect(workflows.length).toBe(4);
|
||||
|
||||
expect(workflows.length).toBe(5);
|
||||
expect(workflows[0].worktype_id).toBe(worktype1.id);
|
||||
expect(workflows[0].author_id).toBe(user1);
|
||||
expect(workflows[1].worktype_id).toBe(worktype2.id);
|
||||
expect(workflows[1].author_id).toBe(user1);
|
||||
expect(workflows[2].worktype_id).toBe(null);
|
||||
expect(workflows[2].worktype_id).toBe(worktype3.id);
|
||||
expect(workflows[2].author_id).toBe(user1);
|
||||
expect(workflows[3].worktype_id).toBe(worktype1.id);
|
||||
expect(workflows[3].author_id).toBe(user2);
|
||||
expect(workflows[3].worktype_id).toBe(null);
|
||||
expect(workflows[3].author_id).toBe(user1);
|
||||
expect(workflows[4].worktype_id).toBe(worktype1.id);
|
||||
expect(workflows[4].author_id).toBe(user2);
|
||||
}
|
||||
|
||||
const context = makeContext(external_id, 'requestId');
|
||||
@ -2786,14 +2793,17 @@ describe('UsersService.getRelations', () => {
|
||||
expect(relations.authorIdList[1]).toBe('AUTHOR_2');
|
||||
|
||||
const workTypeList = relations.workTypeList;
|
||||
expect(relations.workTypeList.length).toBe(2);
|
||||
expect(workTypeList[0].workTypeId).toBe(worktype1.custom_worktype_id);
|
||||
expect(relations.workTypeList.length).toBe(3);
|
||||
// Workflowの作成順ではなくcustom_worktype_idの昇順で取得するためWorkTypeListの先頭はworktype3
|
||||
expect(workTypeList[0].workTypeId).toBe(worktype3.custom_worktype_id);
|
||||
expect(workTypeList[0].optionItemList.length).toBe(10);
|
||||
expect(workTypeList[0].optionItemList[0].label).toBe('');
|
||||
expect(workTypeList[0].optionItemList[0].initialValueType).toBe(2);
|
||||
expect(workTypeList[0].optionItemList[0].defaultValue).toBe('');
|
||||
expect(workTypeList[1].workTypeId).toBe(worktype2.custom_worktype_id);
|
||||
expect(workTypeList[1].workTypeId).toBe(worktype1.custom_worktype_id);
|
||||
expect(workTypeList[1].optionItemList.length).toBe(10);
|
||||
expect(workTypeList[2].workTypeId).toBe(worktype2.custom_worktype_id);
|
||||
expect(workTypeList[2].optionItemList.length).toBe(10);
|
||||
|
||||
expect(relations.isEncrypted).toBe(true);
|
||||
expect(relations.encryptionPassword).toBe('password');
|
||||
|
||||
@ -1582,78 +1582,91 @@ const makeOrder = (
|
||||
priority: 'DESC',
|
||||
job_number: direction,
|
||||
id: 'ASC',
|
||||
option_items: { id: 'ASC' },
|
||||
};
|
||||
case 'STATUS':
|
||||
return {
|
||||
priority: 'DESC',
|
||||
status: direction,
|
||||
id: 'ASC',
|
||||
option_items: { id: 'ASC' },
|
||||
};
|
||||
case 'TRANSCRIPTION_FINISHED_DATE':
|
||||
return {
|
||||
priority: 'DESC',
|
||||
finished_at: direction,
|
||||
id: 'ASC',
|
||||
option_items: { id: 'ASC' },
|
||||
};
|
||||
case 'TRANSCRIPTION_STARTED_DATE':
|
||||
return {
|
||||
priority: 'DESC',
|
||||
started_at: direction,
|
||||
id: 'ASC',
|
||||
option_items: { id: 'ASC' },
|
||||
};
|
||||
case 'AUTHOR_ID':
|
||||
return {
|
||||
priority: 'DESC',
|
||||
file: { author_id: direction },
|
||||
id: 'ASC',
|
||||
option_items: { id: 'ASC' },
|
||||
};
|
||||
case 'ENCRYPTION':
|
||||
return {
|
||||
priority: 'DESC',
|
||||
file: { is_encrypted: direction },
|
||||
id: 'ASC',
|
||||
option_items: { id: 'ASC' },
|
||||
};
|
||||
case 'FILE_LENGTH':
|
||||
return {
|
||||
priority: 'DESC',
|
||||
file: { duration: direction },
|
||||
id: 'ASC',
|
||||
option_items: { id: 'ASC' },
|
||||
};
|
||||
case 'FILE_NAME':
|
||||
return {
|
||||
priority: 'DESC',
|
||||
file: { file_name: direction },
|
||||
id: 'ASC',
|
||||
option_items: { id: 'ASC' },
|
||||
};
|
||||
case 'FILE_SIZE':
|
||||
return {
|
||||
priority: 'DESC',
|
||||
file: { file_size: direction },
|
||||
id: 'ASC',
|
||||
option_items: { id: 'ASC' },
|
||||
};
|
||||
case 'RECORDING_FINISHED_DATE':
|
||||
return {
|
||||
priority: 'DESC',
|
||||
file: { finished_at: direction },
|
||||
id: 'ASC',
|
||||
option_items: { id: 'ASC' },
|
||||
};
|
||||
case 'RECORDING_STARTED_DATE':
|
||||
return {
|
||||
priority: 'DESC',
|
||||
file: { started_at: direction },
|
||||
id: 'ASC',
|
||||
option_items: { id: 'ASC' },
|
||||
};
|
||||
case 'UPLOAD_DATE':
|
||||
return {
|
||||
priority: 'DESC',
|
||||
file: { uploaded_at: direction },
|
||||
id: 'ASC',
|
||||
option_items: { id: 'ASC' },
|
||||
};
|
||||
case 'WORK_TYPE':
|
||||
return {
|
||||
priority: 'DESC',
|
||||
file: { work_type_id: direction },
|
||||
id: 'ASC',
|
||||
option_items: { id: 'ASC' },
|
||||
};
|
||||
default:
|
||||
// switchのcase漏れが発生した場合に型エラーになるようにする
|
||||
|
||||
@ -1166,6 +1166,14 @@ export class UsersRepositoryService {
|
||||
option_items: true,
|
||||
},
|
||||
},
|
||||
order: {
|
||||
worktype: {
|
||||
custom_worktype_id: 'ASC',
|
||||
option_items: {
|
||||
id: 'ASC',
|
||||
},
|
||||
},
|
||||
},
|
||||
comment: `${context.getTrackingId()}_${new Date().toUTCString()}`,
|
||||
});
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user