Merge branch 'develop' of github.com:Frappet/hrms-api-org into develop

This commit is contained in:
mamoss 2025-04-29 17:54:38 +07:00
commit fbda664337
4 changed files with 144 additions and 59 deletions

View file

@ -572,7 +572,7 @@ export class EmployeePositionController extends Controller {
const chk_SName0 = await this.employeePosMasterRepository.findOne({ const chk_SName0 = await this.employeePosMasterRepository.findOne({
where: { where: {
orgRevisionId: posMaster.orgRevisionId, orgRevisionId: posMaster.orgRevisionId,
orgRoot: { orgRootShortName: SName }, orgRoot: { orgRootShortName: SName, id: requestBody.orgRootId ?? "" },
orgChild1Id: IsNull(), orgChild1Id: IsNull(),
posMasterNo: requestBody.posMasterNo, posMasterNo: requestBody.posMasterNo,
}, },
@ -588,7 +588,7 @@ export class EmployeePositionController extends Controller {
const chk_SName1 = await this.employeePosMasterRepository.findOne({ const chk_SName1 = await this.employeePosMasterRepository.findOne({
where: { where: {
orgRevisionId: posMaster.orgRevisionId, orgRevisionId: posMaster.orgRevisionId,
orgChild1: { orgChild1ShortName: SName }, orgChild1: { orgChild1ShortName: SName, id: requestBody.orgChild1Id ?? "" },
orgChild2Id: IsNull(), orgChild2Id: IsNull(),
posMasterNo: requestBody.posMasterNo, posMasterNo: requestBody.posMasterNo,
}, },
@ -604,7 +604,7 @@ export class EmployeePositionController extends Controller {
const chk_SName2 = await this.employeePosMasterRepository.findOne({ const chk_SName2 = await this.employeePosMasterRepository.findOne({
where: { where: {
orgRevisionId: posMaster.orgRevisionId, orgRevisionId: posMaster.orgRevisionId,
orgChild2: { orgChild2ShortName: SName }, orgChild2: { orgChild2ShortName: SName, id: requestBody.orgChild2Id ?? "" },
orgChild3Id: IsNull(), orgChild3Id: IsNull(),
posMasterNo: requestBody.posMasterNo, posMasterNo: requestBody.posMasterNo,
}, },
@ -620,7 +620,7 @@ export class EmployeePositionController extends Controller {
const chk_SName3 = await this.employeePosMasterRepository.findOne({ const chk_SName3 = await this.employeePosMasterRepository.findOne({
where: { where: {
orgRevisionId: posMaster.orgRevisionId, orgRevisionId: posMaster.orgRevisionId,
orgChild3: { orgChild3ShortName: SName }, orgChild3: { orgChild3ShortName: SName, id: requestBody.orgChild3Id ?? "" },
orgChild4Id: IsNull(), orgChild4Id: IsNull(),
posMasterNo: requestBody.posMasterNo, posMasterNo: requestBody.posMasterNo,
}, },
@ -636,7 +636,7 @@ export class EmployeePositionController extends Controller {
const chk_SName4 = await this.employeePosMasterRepository.findOne({ const chk_SName4 = await this.employeePosMasterRepository.findOne({
where: { where: {
orgRevisionId: posMaster.orgRevisionId, orgRevisionId: posMaster.orgRevisionId,
orgChild4: { orgChild4ShortName: SName }, orgChild4: { orgChild4ShortName: SName, id: requestBody.orgChild4Id ?? "" },
posMasterNo: requestBody.posMasterNo, posMasterNo: requestBody.posMasterNo,
}, },
relations: ["orgChild4"], relations: ["orgChild4"],
@ -780,7 +780,7 @@ export class EmployeePositionController extends Controller {
const chk_SName0 = await this.employeePosMasterRepository.findOne({ const chk_SName0 = await this.employeePosMasterRepository.findOne({
where: { where: {
orgRevisionId: posMaster.orgRevisionId, orgRevisionId: posMaster.orgRevisionId,
orgRoot: { orgRootShortName: SName }, orgRoot: { orgRootShortName: SName, id: requestBody.orgRootId ?? "" },
orgChild1Id: IsNull(), orgChild1Id: IsNull(),
posMasterNo: requestBody.posMasterNo, posMasterNo: requestBody.posMasterNo,
id: Not(posMaster.id), id: Not(posMaster.id),
@ -797,7 +797,7 @@ export class EmployeePositionController extends Controller {
const chk_SName1 = await this.employeePosMasterRepository.findOne({ const chk_SName1 = await this.employeePosMasterRepository.findOne({
where: { where: {
orgRevisionId: posMaster.orgRevisionId, orgRevisionId: posMaster.orgRevisionId,
orgChild1: { orgChild1ShortName: SName }, orgChild1: { orgChild1ShortName: SName, id: requestBody.orgChild1Id ?? "" },
orgChild2Id: IsNull(), orgChild2Id: IsNull(),
posMasterNo: requestBody.posMasterNo, posMasterNo: requestBody.posMasterNo,
id: Not(posMaster.id), id: Not(posMaster.id),
@ -814,7 +814,7 @@ export class EmployeePositionController extends Controller {
const chk_SName2 = await this.employeePosMasterRepository.findOne({ const chk_SName2 = await this.employeePosMasterRepository.findOne({
where: { where: {
orgRevisionId: posMaster.orgRevisionId, orgRevisionId: posMaster.orgRevisionId,
orgChild2: { orgChild2ShortName: SName }, orgChild2: { orgChild2ShortName: SName, id: requestBody.orgChild2Id ?? "" },
orgChild3Id: IsNull(), orgChild3Id: IsNull(),
posMasterNo: requestBody.posMasterNo, posMasterNo: requestBody.posMasterNo,
id: Not(posMaster.id), id: Not(posMaster.id),
@ -831,7 +831,7 @@ export class EmployeePositionController extends Controller {
const chk_SName3 = await this.employeePosMasterRepository.findOne({ const chk_SName3 = await this.employeePosMasterRepository.findOne({
where: { where: {
orgRevisionId: posMaster.orgRevisionId, orgRevisionId: posMaster.orgRevisionId,
orgChild3: { orgChild3ShortName: SName }, orgChild3: { orgChild3ShortName: SName, id: requestBody.orgChild3Id ?? "" },
orgChild4Id: IsNull(), orgChild4Id: IsNull(),
posMasterNo: requestBody.posMasterNo, posMasterNo: requestBody.posMasterNo,
id: Not(posMaster.id), id: Not(posMaster.id),
@ -848,7 +848,7 @@ export class EmployeePositionController extends Controller {
const chk_SName4 = await this.employeePosMasterRepository.findOne({ const chk_SName4 = await this.employeePosMasterRepository.findOne({
where: { where: {
orgRevisionId: posMaster.orgRevisionId, orgRevisionId: posMaster.orgRevisionId,
orgChild4: { orgChild4ShortName: SName }, orgChild4: { orgChild4ShortName: SName, id: requestBody.orgChild4Id ?? "" },
posMasterNo: requestBody.posMasterNo, posMasterNo: requestBody.posMasterNo,
id: Not(posMaster.id), id: Not(posMaster.id),
}, },

View file

@ -2590,7 +2590,7 @@ export class ProfileEmployeeController extends Controller {
} }
const [profiles, total] = await this.profileRepo const [profiles, total] = await this.profileRepo
.createQueryBuilder("profileEmployee") .createQueryBuilder("profileEmployee")
.leftJoinAndSelect("profileEmployee.next_holders", "next_holders") .leftJoinAndSelect("profileEmployee.current_holders", "current_holders")
.leftJoinAndSelect("profileEmployee.posLevel", "posLevel") .leftJoinAndSelect("profileEmployee.posLevel", "posLevel")
.leftJoinAndSelect("profileEmployee.posType", "posType") .leftJoinAndSelect("profileEmployee.posType", "posType")
.where( .where(
@ -2606,12 +2606,29 @@ export class ProfileEmployeeController extends Controller {
new Brackets((qb) => { new Brackets((qb) => {
qb.where( qb.where(
requestBody.keyword != null && requestBody.keyword != "" requestBody.keyword != null && requestBody.keyword != ""
? `CONCAT(profileEmployee.prefix, profileEmployee.firstName," ",profileEmployee.lastName) LIKE :keyword` ? "profileEmployee.prefix LIKE :keyword"
: "1=1", : "1=1",
{ {
keyword: `%${requestBody.keyword}%`, keyword: `%${requestBody.keyword}%`,
}, },
).orWhere( )
.orWhere(
requestBody.keyword != null && requestBody.keyword != ""
? "profileEmployee.firstName LIKE :keyword"
: "1=1",
{
keyword: `%${requestBody.keyword}%`,
},
)
.orWhere(
requestBody.keyword != null && requestBody.keyword != ""
? "profileEmployee.lastName LIKE :keyword"
: "1=1",
{
keyword: `%${requestBody.keyword}%`,
},
)
.orWhere(
requestBody.keyword != null && requestBody.keyword != "" requestBody.keyword != null && requestBody.keyword != ""
? "profileEmployee.citizenId LIKE :keyword" ? "profileEmployee.citizenId LIKE :keyword"
: "1=1", : "1=1",
@ -2642,19 +2659,22 @@ export class ProfileEmployeeController extends Controller {
qb.where("profileEmployee.id NOT IN (:...ids)", { qb.where("profileEmployee.id NOT IN (:...ids)", {
ids: ids:
orgRevision.employeePosMasters orgRevision.employeePosMasters
.filter((x) => x.next_holderId != null) .filter((x) => x.current_holderId != null)
.map((x) => x.next_holderId).length == 0 .map((x) => x.current_holderId).length == 0
? ["zxc"] ? ["zxc"]
: orgRevision.employeePosMasters : orgRevision.employeePosMasters
.filter((x) => x.next_holderId != null) .filter((x) => x.current_holderId != null)
.map((x) => x.next_holderId), .map((x) => x.current_holderId),
}); });
}), }),
) )
.andWhere("profileEmployee.employeeClass = :employeeClass", { employeeClass: "PERM" }) .andWhere("profileEmployee.employeeClass = :employeeClass", { employeeClass: "PERM" })
.skip((requestBody.page - 1) * requestBody.pageSize) .skip((requestBody.page - 1) * requestBody.pageSize)
.take(requestBody.pageSize) .take(requestBody.pageSize)
.orderBy("posType.posTypeRank", "ASC")
.addOrderBy("posLevel.posLevelRank", "ASC")
.getManyAndCount(); .getManyAndCount();
const data = profiles.map((_data) => ({ const data = profiles.map((_data) => ({
id: _data.id, id: _data.id,
prefix: _data.prefix, prefix: _data.prefix,

View file

@ -1704,7 +1704,7 @@ export class ProfileEmployeeTempController extends Controller {
} }
const [profiles, total] = await this.profileRepo const [profiles, total] = await this.profileRepo
.createQueryBuilder("profileEmployee") .createQueryBuilder("profileEmployee")
.leftJoinAndSelect("profileEmployee.next_holderTemps", "next_holderTemps") .leftJoinAndSelect("profileEmployee.current_holderTemps", "current_holderTemps")
.leftJoinAndSelect("profileEmployee.posLevel", "posLevel") .leftJoinAndSelect("profileEmployee.posLevel", "posLevel")
.leftJoinAndSelect("profileEmployee.posType", "posType") .leftJoinAndSelect("profileEmployee.posType", "posType")
.where( .where(
@ -1720,12 +1720,29 @@ export class ProfileEmployeeTempController extends Controller {
new Brackets((qb) => { new Brackets((qb) => {
qb.where( qb.where(
requestBody.keyword != null && requestBody.keyword != "" requestBody.keyword != null && requestBody.keyword != ""
? `CONCAT(profileEmployee.prefix, profileEmployee.firstName," ",profileEmployee.lastName) LIKE :keyword` ? "profileEmployee.prefix LIKE :keyword"
: "1=1", : "1=1",
{ {
keyword: `%${requestBody.keyword}%`, keyword: `%${requestBody.keyword}%`,
}, },
).orWhere( )
.orWhere(
requestBody.keyword != null && requestBody.keyword != ""
? "profileEmployee.firstName LIKE :keyword"
: "1=1",
{
keyword: `%${requestBody.keyword}%`,
},
)
.orWhere(
requestBody.keyword != null && requestBody.keyword != ""
? "profileEmployee.lastName LIKE :keyword"
: "1=1",
{
keyword: `%${requestBody.keyword}%`,
},
)
.orWhere(
requestBody.keyword != null && requestBody.keyword != "" requestBody.keyword != null && requestBody.keyword != ""
? "profileEmployee.citizenId LIKE :keyword" ? "profileEmployee.citizenId LIKE :keyword"
: "1=1", : "1=1",
@ -1780,18 +1797,20 @@ export class ProfileEmployeeTempController extends Controller {
qb.where("profileEmployee.id NOT IN (:...ids)", { qb.where("profileEmployee.id NOT IN (:...ids)", {
ids: ids:
orgRevision.employeeTempPosMasters orgRevision.employeeTempPosMasters
.filter((x) => x.next_holderId != null) .filter((x) => x.current_holderId != null)
.map((x) => x.next_holderId).length == 0 .map((x) => x.current_holderId).length == 0
? ["zxc"] ? ["zxc"]
: orgRevision.employeeTempPosMasters : orgRevision.employeeTempPosMasters
.filter((x) => x.next_holderId != null) .filter((x) => x.current_holderId != null)
.map((x) => x.next_holderId), .map((x) => x.current_holderId),
}); });
}), }),
) )
.andWhere("profileEmployee.employeeClass = :employeeClass", { employeeClass: "TEMP" }) .andWhere("profileEmployee.employeeClass = :employeeClass", { employeeClass: "TEMP" })
.skip((requestBody.page - 1) * requestBody.pageSize) .skip((requestBody.page - 1) * requestBody.pageSize)
.take(requestBody.pageSize) .take(requestBody.pageSize)
.orderBy("posType.posTypeRank", "ASC")
.addOrderBy("posLevel.posLevelRank", "ASC")
.getManyAndCount(); .getManyAndCount();
const data = profiles.map((_data) => ({ const data = profiles.map((_data) => ({
id: _data.id, id: _data.id,

View file

@ -24,7 +24,7 @@ import { ProfileSalaryHistory } from "../entities/ProfileSalaryHistory";
import { RequestWithUser } from "../middlewares/user"; import { RequestWithUser } from "../middlewares/user";
import { ProfileEmployee } from "../entities/ProfileEmployee"; import { ProfileEmployee } from "../entities/ProfileEmployee";
import { Profile } from "../entities/Profile"; import { Profile } from "../entities/Profile";
import { In, LessThan, MoreThan } from "typeorm"; import { In, LessThan, IsNull, MoreThan } from "typeorm";
import permission from "../interfaces/permission"; import permission from "../interfaces/permission";
import { setLogDataDiff } from "../interfaces/utils"; import { setLogDataDiff } from "../interfaces/utils";
import { Command } from "../entities/Command"; import { Command } from "../entities/Command";
@ -47,7 +47,7 @@ export class ProfileSalaryEmployeeController extends Controller {
throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว"); throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว");
} }
const record = await this.salaryRepo.find({ const record = await this.salaryRepo.find({
where: { profileEmployeeId: profile.id }, where: { profileEmployeeId: profile.id, commandCode: In(["5", "6", "7"]) },
order: { order: "ASC" }, order: { order: "ASC" },
}); });
return new HttpSuccess(record); return new HttpSuccess(record);
@ -60,7 +60,28 @@ export class ProfileSalaryEmployeeController extends Controller {
throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว"); throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว");
} }
const record = await this.salaryRepo.find({ const record = await this.salaryRepo.find({
where: { profileEmployeeId: profile.id }, where: [
{
profileEmployeeId: profile.id,
commandCode: In([
"0",
"9",
"1",
"2",
"3",
"4",
"8",
"10",
"11",
"12",
"13",
"14",
"15",
"16",
]),
},
{ profileEmployeeId: profile.id, commandCode: IsNull() },
],
order: { order: "ASC" }, order: { order: "ASC" },
}); });
return new HttpSuccess(record); return new HttpSuccess(record);
@ -87,7 +108,28 @@ export class ProfileSalaryEmployeeController extends Controller {
if (_workflow == false) if (_workflow == false)
await new permission().PermissionOrgUserGet(req, "SYS_REGISTRY_EMP", profileId); await new permission().PermissionOrgUserGet(req, "SYS_REGISTRY_EMP", profileId);
const record = await this.salaryRepo.find({ const record = await this.salaryRepo.find({
where: { profileEmployeeId: profileId }, where: [
{
profileEmployeeId: profileId,
commandCode: In([
"0",
"9",
"1",
"2",
"3",
"4",
"8",
"10",
"11",
"12",
"13",
"14",
"15",
"16",
]),
},
{ profileEmployeeId: profileId, commandCode: IsNull() },
],
order: { order: "ASC" }, order: { order: "ASC" },
}); });
return new HttpSuccess(record); return new HttpSuccess(record);
@ -131,7 +173,9 @@ export class ProfileSalaryEmployeeController extends Controller {
[] as { name: string; days: number; year: number; month: number; day: number }[], [] as { name: string; days: number; year: number; month: number; day: number }[],
); );
const posLevel = await AppDataSource.query("CALL GetProfileEmployeeSalaryLevel(?)", [profile.id]); const posLevel = await AppDataSource.query("CALL GetProfileEmployeeSalaryLevel(?)", [
profile.id,
]);
const _posLevel = posLevel.length > 0 ? posLevel[0] : []; const _posLevel = posLevel.length > 0 ? posLevel[0] : [];
const mapPosLevel = const mapPosLevel =
_posLevel.length > 1 _posLevel.length > 1
@ -204,7 +248,9 @@ export class ProfileSalaryEmployeeController extends Controller {
[] as { name: string; days: number; year: number; month: number; day: number }[], [] as { name: string; days: number; year: number; month: number; day: number }[],
); );
const posLevel = await AppDataSource.query("CALL GetProfileEmployeeSalaryLevel(?)", [profileId]); const posLevel = await AppDataSource.query("CALL GetProfileEmployeeSalaryLevel(?)", [
profileId,
]);
const _posLevel = posLevel.length > 0 ? posLevel[0] : []; const _posLevel = posLevel.length > 0 ? posLevel[0] : [];
const mapPosLevel = const mapPosLevel =
_posLevel.length > 1 _posLevel.length > 1
@ -248,7 +294,7 @@ export class ProfileSalaryEmployeeController extends Controller {
let _workflow = await new permission().Workflow(req, profileId, "SYS_WAGE"); let _workflow = await new permission().Workflow(req, profileId, "SYS_WAGE");
if (_workflow == false) await new permission().PermissionGet(req, "SYS_WAGE"); if (_workflow == false) await new permission().PermissionGet(req, "SYS_WAGE");
const record = await this.salaryRepo.find({ const record = await this.salaryRepo.find({
where: { profileEmployeeId: profileId }, where: { profileEmployeeId: profileId, commandCode: In(["5", "6", "7"]) },
order: { order: "ASC" }, order: { order: "ASC" },
}); });
return new HttpSuccess(record); return new HttpSuccess(record);
@ -318,9 +364,9 @@ export class ProfileSalaryEmployeeController extends Controller {
lastUpdatedAt: new Date(), lastUpdatedAt: new Date(),
}; };
if (body.commandCode && !body.commandName) { if (body.commandCode && !body.commandName) {
if (body.commandCode == "7") body.commandName = "เงินพิเศษอื่น ๆ" if (body.commandCode == "7") body.commandName = "เงินพิเศษอื่น ๆ";
else if (body.commandCode == "6") body.commandName = "เลื่อนเงินเดือนกรณีอื่น ๆ" else if (body.commandCode == "6") body.commandName = "เลื่อนเงินเดือนกรณีอื่น ๆ";
else if (body.commandCode == "5") body.commandName = "เลื่อนเงินเดือนตามปกติ" else if (body.commandCode == "5") body.commandName = "เลื่อนเงินเดือนตามปกติ";
} }
Object.assign(data, { ...body, ...meta }); Object.assign(data, { ...body, ...meta });
const history = new ProfileSalaryHistory(); const history = new ProfileSalaryHistory();
@ -359,10 +405,10 @@ export class ProfileSalaryEmployeeController extends Controller {
order: { order: "DESC" }, order: { order: "DESC" },
}); });
const before = null; const before = null;
let _posNumCodeSit: string = "" let _posNumCodeSit: string = "";
let _posNumCodeSitAbb: string = "" let _posNumCodeSitAbb: string = "";
const _command = await this.commandRepository.findOne({ const _command = await this.commandRepository.findOne({
where: { id: body.commandId ?? "" } where: { id: body.commandId ?? "" },
}); });
if (_command) { if (_command) {
if (_command?.isBangkok?.toLocaleUpperCase() == "OFFICE") { if (_command?.isBangkok?.toLocaleUpperCase() == "OFFICE") {
@ -371,35 +417,35 @@ export class ProfileSalaryEmployeeController extends Controller {
isDeputy: true, isDeputy: true,
orgRevision: { orgRevision: {
orgRevisionIsCurrent: true, orgRevisionIsCurrent: true,
orgRevisionIsDraft: false orgRevisionIsDraft: false,
} },
}, },
relations: ["orgRevision"] relations: ["orgRevision"],
}) });
_posNumCodeSit = orgRootDeputy ? orgRootDeputy?.orgRootName : "สำนักปลัดกรุงเทพมหานคร"; _posNumCodeSit = orgRootDeputy ? orgRootDeputy?.orgRootName : "สำนักปลัดกรุงเทพมหานคร";
_posNumCodeSitAbb = orgRootDeputy ? orgRootDeputy?.orgRootShortName : "สนป."; _posNumCodeSitAbb = orgRootDeputy ? orgRootDeputy?.orgRootShortName : "สนป.";
} } else if (_command?.isBangkok?.toLocaleUpperCase() == "BANGKOK") {
else if (_command?.isBangkok?.toLocaleUpperCase() == "BANGKOK") { _posNumCodeSit = "กรุงเทพมหานคร";
_posNumCodeSit = "กรุงเทพมหานคร" _posNumCodeSitAbb = "กทม.";
_posNumCodeSitAbb = "กทม." } else {
}
else {
let _profileAdmin = await this.profileGovementRepo.findOne({ let _profileAdmin = await this.profileGovementRepo.findOne({
where: { where: {
keycloak: _command?.createdUserId.toString(), keycloak: _command?.createdUserId.toString(),
current_holders: { current_holders: {
orgRevision: { orgRevision: {
orgRevisionIsCurrent: true, orgRevisionIsCurrent: true,
orgRevisionIsDraft: false orgRevisionIsDraft: false,
} },
} },
}, },
relations: ["current_holders", "current_holders.orgRevision", "current_holders.orgRoot"] relations: ["current_holders", "current_holders.orgRevision", "current_holders.orgRoot"],
}); });
_posNumCodeSit = _profileAdmin?.current_holders _posNumCodeSit =
.find(x => x.orgRoot.orgRootName)?.orgRoot.orgRootName ?? "" _profileAdmin?.current_holders.find((x) => x.orgRoot.orgRootName)?.orgRoot.orgRootName ??
_posNumCodeSitAbb = _profileAdmin?.current_holders "";
.find(x => x.orgRoot.orgRootShortName)?.orgRoot.orgRootShortName ?? "" _posNumCodeSitAbb =
_profileAdmin?.current_holders.find((x) => x.orgRoot.orgRootShortName)?.orgRoot
.orgRootShortName ?? "";
} }
} }
const data = new ProfileSalary(); const data = new ProfileSalary();
@ -451,9 +497,9 @@ export class ProfileSalaryEmployeeController extends Controller {
const before = structuredClone(record); const before = structuredClone(record);
const history = new ProfileSalaryHistory(); const history = new ProfileSalaryHistory();
if (body.commandCode && !body.commandName) { if (body.commandCode && !body.commandName) {
if (body.commandCode == "7") body.commandName = "เงินพิเศษอื่น ๆ" if (body.commandCode == "7") body.commandName = "เงินพิเศษอื่น ๆ";
else if (body.commandCode == "6") body.commandName = "เลื่อนเงินเดือนกรณีอื่น ๆ" else if (body.commandCode == "6") body.commandName = "เลื่อนเงินเดือนกรณีอื่น ๆ";
else if (body.commandCode == "5") body.commandName = "เลื่อนเงินเดือนตามปกติ" else if (body.commandCode == "5") body.commandName = "เลื่อนเงินเดือนตามปกติ";
} }
Object.assign(record, body); Object.assign(record, body);
Object.assign(history, { ...record, id: undefined }); Object.assign(history, { ...record, id: undefined });