diff --git a/backend/src/db/api/users.js b/backend/src/db/api/users.js
index 251dcd9..1ecccb9 100644
--- a/backend/src/db/api/users.js
+++ b/backend/src/db/api/users.js
@@ -407,7 +407,13 @@ module.exports = class UsersDBApi {
output.employee_pay_types_employee = await users.getEmployee_pay_types_employee({
- transaction
+ transaction,
+ include: [
+ {
+ model: db.pay_types,
+ as: 'pay_type',
+ },
+ ],
});
@@ -501,6 +507,21 @@ module.exports = class UsersDBApi {
as: 'avatar',
},
+ {
+ model: db.employee_pay_types,
+ as: 'employee_pay_types_employee',
+ required: false,
+ where: {
+ active: true,
+ },
+ include: [
+ {
+ model: db.pay_types,
+ as: 'pay_type',
+ },
+ ],
+ },
+
];
if (filter) {
diff --git a/backend/src/services/users.js b/backend/src/services/users.js
index 555d193..e8093a1 100644
--- a/backend/src/services/users.js
+++ b/backend/src/services/users.js
@@ -13,6 +13,63 @@ const EmailSender = require('./email');
const AuthService = require('./auth');
module.exports = class UsersService {
+ static normalizePayTypeIds(payTypes = []) {
+ return [...new Set((payTypes || [])
+ .map((payType) => {
+ if (typeof payType === 'string') {
+ return payType;
+ }
+
+ return payType?.id || payType?.value || null;
+ })
+ .filter(Boolean))];
+ }
+
+ static async syncEmployeePayTypes(employeeId, payTypes, currentUser, transaction) {
+ const payTypeIds = UsersService.normalizePayTypeIds(payTypes);
+ const selectedPayTypeIds = new Set(payTypeIds);
+
+ const existingAssignments = await db.employee_pay_types.findAll({
+ where: { employeeId },
+ transaction,
+ });
+
+ const existingPayTypeIds = new Set();
+
+ for (const assignment of existingAssignments) {
+ existingPayTypeIds.add(assignment.pay_typeId);
+
+ const shouldBeActive = selectedPayTypeIds.has(assignment.pay_typeId);
+
+ if (assignment.active !== shouldBeActive) {
+ await assignment.update(
+ {
+ active: shouldBeActive,
+ updatedById: currentUser.id,
+ },
+ { transaction },
+ );
+ }
+ }
+
+ for (const payTypeId of payTypeIds) {
+ if (existingPayTypeIds.has(payTypeId)) {
+ continue;
+ }
+
+ await db.employee_pay_types.create(
+ {
+ employeeId,
+ pay_typeId: payTypeId,
+ active: true,
+ createdById: currentUser.id,
+ updatedById: currentUser.id,
+ },
+ { transaction },
+ );
+ }
+ }
+
static async create(data, currentUser, sendInvitationEmails = true, host) {
let transaction = await db.sequelize.transaction();
@@ -26,7 +83,7 @@ module.exports = class UsersService {
'iam.errors.userAlreadyExists',
);
} else {
- await UsersDBApi.create(
+ const createdUser = await UsersDBApi.create(
{data},
{
@@ -34,6 +91,15 @@ module.exports = class UsersService {
transaction,
},
);
+
+ if (data.pay_types !== undefined) {
+ await UsersService.syncEmployeePayTypes(
+ createdUser.id,
+ data.pay_types,
+ currentUser,
+ transaction,
+ );
+ }
emailsToInvite.push(email);
}
} else {
@@ -127,6 +193,15 @@ module.exports = class UsersService {
},
);
+ if (data.pay_types !== undefined) {
+ await UsersService.syncEmployeePayTypes(
+ id,
+ data.pay_types,
+ currentUser,
+ transaction,
+ );
+ }
+
await transaction.commit();
return updatedUser;
diff --git a/frontend/src/components/Users/configureUsersCols.tsx b/frontend/src/components/Users/configureUsersCols.tsx
index 37cebd3..b53c5eb 100644
--- a/frontend/src/components/Users/configureUsersCols.tsx
+++ b/frontend/src/components/Users/configureUsersCols.tsx
@@ -17,6 +17,15 @@ import {hasPermission} from "../../helpers/userPermissions";
type Params = (id: string) => void;
+const formatAssignedPayTypes = (assignments = []) => {
+ const uniquePayTypeNames = [...new Set((assignments || [])
+ .filter((assignment) => assignment?.active !== false)
+ .map((assignment) => assignment?.pay_type?.name)
+ .filter(Boolean))];
+
+ return uniquePayTypeNames.length ? uniquePayTypeNames.join(', ') : '—';
+};
+
export const loadColumns = async (
onDelete: Params,
entityName: string,
@@ -180,6 +189,27 @@ export const loadColumns = async (
},
+ {
+ field: 'employee_pay_types_employee',
+ headerName: 'Pay Types',
+ flex: 1,
+ minWidth: 180,
+ filterable: false,
+ headerClassName: 'datagrid--header',
+ cellClassName: 'datagrid--cell',
+
+ editable: false,
+ sortable: false,
+ valueGetter: (params: GridValueGetterParams) =>
+ formatAssignedPayTypes(params?.row?.employee_pay_types_employee),
+ renderCell: (params: GridValueGetterParams) => (
+
+ {formatAssignedPayTypes(params?.row?.employee_pay_types_employee)}
+
+ ),
+
+ },
+
{
field: 'actions',
type: 'actions',
diff --git a/frontend/src/pages/users/users-edit.tsx b/frontend/src/pages/users/users-edit.tsx
index c6fb274..de84708 100644
--- a/frontend/src/pages/users/users-edit.tsx
+++ b/frontend/src/pages/users/users-edit.tsx
@@ -261,6 +261,7 @@ const EditUsersPage = () => {
custom_permissions: [],
+ pay_types: [],
@@ -278,16 +279,17 @@ const EditUsersPage = () => {
dispatch(fetch({ id: id }))
}, [id])
- useEffect(() => {
- if (typeof users === 'object') {
- setInitialValues(users)
- }
- }, [users])
-
useEffect(() => {
if (typeof users === 'object') {
const newInitialVal = {...initVals};
- Object.keys(initVals).forEach(el => newInitialVal[el] = (users)[el])
+ Object.keys(initVals).forEach((el) => {
+ newInitialVal[el] = users[el]
+ })
+ newInitialVal.pay_types = Array.isArray(users.employee_pay_types_employee)
+ ? users.employee_pay_types_employee
+ .filter((item) => item?.active && item?.pay_type)
+ .map((item) => item.pay_type)
+ : []
setInitialValues(newInitialVal);
}
}, [users])
@@ -676,6 +678,18 @@ const EditUsersPage = () => {
+