Beta 1.0
This commit is contained in:
parent
f4182557a8
commit
1fd0a1b094
@ -407,7 +407,13 @@ module.exports = class UsersDBApi {
|
|||||||
|
|
||||||
|
|
||||||
output.employee_pay_types_employee = await users.getEmployee_pay_types_employee({
|
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',
|
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) {
|
if (filter) {
|
||||||
|
|||||||
@ -13,6 +13,63 @@ const EmailSender = require('./email');
|
|||||||
const AuthService = require('./auth');
|
const AuthService = require('./auth');
|
||||||
|
|
||||||
module.exports = class UsersService {
|
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) {
|
static async create(data, currentUser, sendInvitationEmails = true, host) {
|
||||||
let transaction = await db.sequelize.transaction();
|
let transaction = await db.sequelize.transaction();
|
||||||
|
|
||||||
@ -26,7 +83,7 @@ module.exports = class UsersService {
|
|||||||
'iam.errors.userAlreadyExists',
|
'iam.errors.userAlreadyExists',
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
await UsersDBApi.create(
|
const createdUser = await UsersDBApi.create(
|
||||||
{data},
|
{data},
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -34,6 +91,15 @@ module.exports = class UsersService {
|
|||||||
transaction,
|
transaction,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (data.pay_types !== undefined) {
|
||||||
|
await UsersService.syncEmployeePayTypes(
|
||||||
|
createdUser.id,
|
||||||
|
data.pay_types,
|
||||||
|
currentUser,
|
||||||
|
transaction,
|
||||||
|
);
|
||||||
|
}
|
||||||
emailsToInvite.push(email);
|
emailsToInvite.push(email);
|
||||||
}
|
}
|
||||||
} else {
|
} 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();
|
await transaction.commit();
|
||||||
return updatedUser;
|
return updatedUser;
|
||||||
|
|
||||||
|
|||||||
@ -17,6 +17,15 @@ import {hasPermission} from "../../helpers/userPermissions";
|
|||||||
|
|
||||||
type Params = (id: string) => void;
|
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 (
|
export const loadColumns = async (
|
||||||
onDelete: Params,
|
onDelete: Params,
|
||||||
entityName: string,
|
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) => (
|
||||||
|
<span className='whitespace-normal leading-5 py-2'>
|
||||||
|
{formatAssignedPayTypes(params?.row?.employee_pay_types_employee)}
|
||||||
|
</span>
|
||||||
|
),
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
field: 'actions',
|
field: 'actions',
|
||||||
type: 'actions',
|
type: 'actions',
|
||||||
|
|||||||
@ -261,6 +261,7 @@ const EditUsersPage = () => {
|
|||||||
|
|
||||||
|
|
||||||
custom_permissions: [],
|
custom_permissions: [],
|
||||||
|
pay_types: [],
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -278,16 +279,17 @@ const EditUsersPage = () => {
|
|||||||
dispatch(fetch({ id: id }))
|
dispatch(fetch({ id: id }))
|
||||||
}, [id])
|
}, [id])
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (typeof users === 'object') {
|
|
||||||
setInitialValues(users)
|
|
||||||
}
|
|
||||||
}, [users])
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (typeof users === 'object') {
|
if (typeof users === 'object') {
|
||||||
const newInitialVal = {...initVals};
|
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);
|
setInitialValues(newInitialVal);
|
||||||
}
|
}
|
||||||
}, [users])
|
}, [users])
|
||||||
@ -676,6 +678,18 @@ const EditUsersPage = () => {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<FormField label='Pay Types' labelFor='pay_types'>
|
||||||
|
<Field
|
||||||
|
name='pay_types'
|
||||||
|
id='pay_types'
|
||||||
|
component={SelectFieldMany}
|
||||||
|
options={initialValues.pay_types}
|
||||||
|
itemRef={'pay_types'}
|
||||||
|
showField={'name'}
|
||||||
|
></Field>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
|
|
||||||
<FormField
|
<FormField
|
||||||
label="Password"
|
label="Password"
|
||||||
>
|
>
|
||||||
|
|||||||
@ -155,6 +155,7 @@ const initialValues = {
|
|||||||
|
|
||||||
|
|
||||||
custom_permissions: [],
|
custom_permissions: [],
|
||||||
|
pay_types: [],
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -469,7 +470,16 @@ const UsersNew = () => {
|
|||||||
</Field>
|
</Field>
|
||||||
</FormField>
|
</FormField>
|
||||||
|
|
||||||
|
<FormField label='Pay Types' labelFor='pay_types'>
|
||||||
|
<Field
|
||||||
|
name='pay_types'
|
||||||
|
id='pay_types'
|
||||||
|
itemRef={'pay_types'}
|
||||||
|
options={[]}
|
||||||
|
component={SelectFieldMany}
|
||||||
|
showField={'name'}>
|
||||||
|
</Field>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -433,6 +433,7 @@ const UsersView = () => {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<th>Pay Type</th>
|
||||||
<th>Active</th>
|
<th>Active</th>
|
||||||
|
|
||||||
|
|
||||||
@ -456,6 +457,9 @@ const UsersView = () => {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<td data-label="pay_type">
|
||||||
|
{item?.pay_type?.name ?? 'No data'}
|
||||||
|
</td>
|
||||||
<td data-label="active">
|
<td data-label="active">
|
||||||
{ dataFormatter.booleanFormatter(item.active) }
|
{ dataFormatter.booleanFormatter(item.active) }
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user