Autosave: 20260313-224411

This commit is contained in:
Flatlogic Bot 2026-03-13 22:44:11 +00:00
parent 74905956ef
commit 3fa7195d98
13 changed files with 368 additions and 726 deletions

View File

@ -90,6 +90,10 @@ module.exports = class Job_logsDBApi {
transaction,
});
await job_logs.setWorkersCompClass( data.workersCompClass || null, {
transaction,
});
@ -248,6 +252,15 @@ module.exports = class Job_logsDBApi {
);
}
if (data.workersCompClass !== undefined) {
await job_logs.setWorkersCompClass(
data.workersCompClass,
{ transaction }
);
}
@ -356,6 +369,10 @@ module.exports = class Job_logsDBApi {
transaction
});
output.workersCompClass = await job_logs.getWorkersCompClass({
transaction
});
return output;
@ -449,6 +466,21 @@ module.exports = class Job_logsDBApi {
} : {},
},
{
model: db.workers_comp_classes,
as: 'workersCompClass',
where: filter.workersCompClass ? {
[Op.or]: [
{ id: { [Op.in]: filter.workersCompClass.split('|').map(term => Utils.uuid(term)) } },
{
name: {
[Op.or]: filter.workersCompClass.split('|').map(term => ({ [Op.iLike]: `%${term}%` }))
}
},
]
} : {},
},

View File

@ -1,18 +1,12 @@
const db = require('../models');
const FileDBApi = require('./file');
const crypto = require('crypto');
const Utils = require('../utils');
const Sequelize = db.Sequelize;
const Op = Sequelize.Op;
module.exports = class Workers_comp_classesDBApi {
static async create(data, options) {
const currentUser = (options && options.currentUser) || { id: null };
const transaction = (options && options.transaction) || undefined;
@ -20,151 +14,33 @@ module.exports = class Workers_comp_classesDBApi {
const workers_comp_classes = await db.workers_comp_classes.create(
{
id: data.id || undefined,
name: data.name
||
null
,
pay_method: data.pay_method
||
null
,
hourly_rate: data.hourly_rate
||
null
,
commission_rate: data.commission_rate
||
null
,
active: data.active
||
false
,
description: data.description
||
null
,
importHash: data.importHash || null,
createdById: currentUser.id,
updatedById: currentUser.id,
},
{ transaction },
);
name: data.name || null,
percentage: data.percentage !== undefined ? data.percentage : null,
importHash: data.importHash || null,
createdById: currentUser.id,
updatedById: currentUser.id,
},
{ transaction },
);
return workers_comp_classes;
}
static async bulkImport(data, options) {
const currentUser = (options && options.currentUser) || { id: null };
const transaction = (options && options.transaction) || undefined;
// Prepare data - wrapping individual data transformations in a map() method
const workers_comp_classesData = data.map((item, index) => ({
id: item.id || undefined,
name: item.name
||
null
,
pay_method: item.pay_method
||
null
,
hourly_rate: item.hourly_rate
||
null
,
commission_rate: item.commission_rate
||
null
,
active: item.active
||
false
,
description: item.description
||
null
,
importHash: item.importHash || null,
createdById: currentUser.id,
updatedById: currentUser.id,
createdAt: new Date(Date.now() + index * 1000),
}));
// Bulk create items
const workers_comp_classes = await db.workers_comp_classes.bulkCreate(workers_comp_classesData, { transaction });
// For each item created, replace relation files
return workers_comp_classes;
}
static async update(id, data, options) {
static async update(id, data, options) {
const currentUser = (options && options.currentUser) || {id: null};
const transaction = (options && options.transaction) || undefined;
const workers_comp_classes = await db.workers_comp_classes.findByPk(id, {}, {transaction});
const updatePayload = {};
if (data.name !== undefined) updatePayload.name = data.name;
if (data.pay_method !== undefined) updatePayload.pay_method = data.pay_method;
if (data.hourly_rate !== undefined) updatePayload.hourly_rate = data.hourly_rate === "" ? null : data.hourly_rate;
if (data.commission_rate !== undefined) updatePayload.commission_rate = data.commission_rate === "" ? null : data.commission_rate;
if (data.active !== undefined) updatePayload.active = data.active;
if (data.description !== undefined) updatePayload.description = data.description;
if (data.percentage !== undefined) updatePayload.percentage = data.percentage === "" ? null : data.percentage;
updatePayload.updatedById = currentUser.id;
await workers_comp_classes.update(updatePayload, {transaction});
return workers_comp_classes;
}
@ -193,7 +69,6 @@ module.exports = class Workers_comp_classesDBApi {
}
});
return workers_comp_classes;
}
@ -230,208 +105,44 @@ module.exports = class Workers_comp_classesDBApi {
const output = workers_comp_classes.get({plain: true});
output.employee_workers_comp_classes_workers_comp_class = await workers_comp_classes.getEmployee_workers_comp_classes_workers_comp_class({
transaction
});
output.job_logs_workers_comp_class = await workers_comp_classes.getJob_logs_workers_comp_class({
transaction
});
return output;
}
static async findAll(
filter,
options
) {
static async findAll(filter, options) {
const limit = filter.limit || 0;
let offset = 0;
let where = {};
const currentPage = +filter.page;
offset = currentPage * limit;
const orderBy = null;
const transaction = (options && options.transaction) || undefined;
const transaction = (options && options.transaction) || undefined;
let include = [
];
let include = [];
if (filter) {
if (filter.id) {
where = {
...where,
['id']: Utils.uuid(filter.id),
};
where = { ...where, ['id']: Utils.uuid(filter.id) };
}
if (filter.name) {
where = {
...where,
[Op.and]: Utils.ilike(
'workers_comp_classes',
'name',
filter.name,
),
[Op.and]: Utils.ilike('workers_comp_classes', 'name', filter.name),
};
}
if (filter.description) {
where = {
...where,
[Op.and]: Utils.ilike(
'workers_comp_classes',
'description',
filter.description,
),
};
}
if (filter.hourly_rateRange) {
const [start, end] = filter.hourly_rateRange;
if (start !== undefined && start !== null && start !== '') {
where = {
...where,
hourly_rate: {
...where.hourly_rate,
[Op.gte]: start,
},
};
}
if (end !== undefined && end !== null && end !== '') {
where = {
...where,
hourly_rate: {
...where.hourly_rate,
[Op.lte]: end,
},
};
}
}
if (filter.commission_rateRange) {
const [start, end] = filter.commission_rateRange;
if (start !== undefined && start !== null && start !== '') {
where = {
...where,
commission_rate: {
...where.commission_rate,
[Op.gte]: start,
},
};
}
if (end !== undefined && end !== null && end !== '') {
where = {
...where,
commission_rate: {
...where.commission_rate,
[Op.lte]: end,
},
};
}
}
if (filter.active !== undefined) {
where = {
...where,
active: filter.active === true || filter.active === 'true'
};
}
if (filter.pay_method) {
where = {
...where,
pay_method: filter.pay_method,
};
}
if (filter.active) {
where = {
...where,
active: filter.active,
};
}
if (filter.createdAtRange) {
const [start, end] = filter.createdAtRange;
if (start !== undefined && start !== null && start !== '') {
where = {
...where,
['createdAt']: {
...where.createdAt,
[Op.gte]: start,
},
};
}
if (end !== undefined && end !== null && end !== '') {
where = {
...where,
['createdAt']: {
...where.createdAt,
[Op.lte]: end,
},
};
}
}
}
const queryOptions = {
where,
include,
distinct: true,
order: filter.field && filter.sort
order: filter && filter.field && filter.sort
? [[filter.field, filter.sort]]
: [['createdAt', 'desc']],
transaction: options?.transaction,
logging: console.log
transaction: options && options.transaction,
};
if (!options?.countOnly) {
if (!(options && options.countOnly)) {
queryOptions.limit = limit ? Number(limit) : undefined;
queryOptions.offset = offset ? Number(offset) : undefined;
}
@ -440,7 +151,7 @@ module.exports = class Workers_comp_classesDBApi {
const { rows, count } = await db.workers_comp_classes.findAndCountAll(queryOptions);
return {
rows: options?.countOnly ? [] : rows,
rows: (options && options.countOnly) ? [] : rows,
count: count
};
} catch (error) {
@ -449,20 +160,14 @@ module.exports = class Workers_comp_classesDBApi {
}
}
static async findAllAutocomplete(query, limit, offset, ) {
static async findAllAutocomplete(query, limit, offset) {
let where = {};
if (query) {
where = {
[Op.or]: [
{ ['id']: Utils.uuid(query) },
Utils.ilike(
'workers_comp_classes',
'name',
query,
),
Utils.ilike('workers_comp_classes', 'name', query),
],
};
}
@ -472,7 +177,7 @@ module.exports = class Workers_comp_classesDBApi {
where,
limit: limit ? Number(limit) : undefined,
offset: offset ? Number(offset) : undefined,
orderBy: [['name', 'ASC']],
order: [['name', 'ASC']],
});
return records.map((record) => ({
@ -480,7 +185,4 @@ module.exports = class Workers_comp_classesDBApi {
label: record.name,
}));
}
};
};

View File

@ -0,0 +1,39 @@
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
const createdAt = new Date();
const updatedAt = new Date();
// Find all roles
const roles = await queryInterface.sequelize.query(
`SELECT id, name FROM roles WHERE name != 'Public';`,
{ type: Sequelize.QueryTypes.SELECT }
);
// Find the read permission
const permissions = await queryInterface.sequelize.query(
`SELECT id, name FROM permissions WHERE name = 'READ_WORKERS_COMP_CLASSES';`,
{ type: Sequelize.QueryTypes.SELECT }
);
if (permissions.length === 0) return;
const readPerm = permissions[0];
const rolePermissions = [];
const existing = await queryInterface.sequelize.query(
`SELECT "roles_permissionsId", "permissionId" FROM "rolesPermissionsPermissions" WHERE "permissionId" = '${readPerm.id}';`,
{ type: Sequelize.QueryTypes.SELECT }
);
const existingSet = new Set(existing.map(e => e.roles_permissionsId + '-' + e.permissionId));
for (const role of roles) {
if (!existingSet.has(role.id + '-' + readPerm.id)) {
rolePermissions.push({
roles_permissionsId: role.id,
permissionId: readPerm.id,
createdAt,
updatedAt,
});
}
}
if (rolePermissions.length > 0) {
await queryInterface.bulkInsert('rolesPermissionsPermissions', rolePermissions);
}
},
down: async (queryInterface, Sequelize) => {}
};

View File

@ -0,0 +1,42 @@
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
const createdAt = new Date();
const updatedAt = new Date();
const roles = await queryInterface.sequelize.query(
`SELECT id, name FROM roles WHERE name != 'Public';`,
{ type: Sequelize.QueryTypes.SELECT }
);
const permissions = await queryInterface.sequelize.query(
`SELECT id, name FROM permissions WHERE name = 'READ_EMPLOYEE_PAY_TYPES';`,
{ type: Sequelize.QueryTypes.SELECT }
);
if (permissions.length === 0) return;
const readPerm = permissions[0];
const rolePermissions = [];
const existing = await queryInterface.sequelize.query(
`SELECT "roles_permissionsId", "permissionId" FROM "rolesPermissionsPermissions" WHERE "permissionId" = '${readPerm.id}';`,
{ type: Sequelize.QueryTypes.SELECT }
);
const existingSet = new Set(existing.map(e => e.roles_permissionsId + '-' + e.permissionId));
for (const role of roles) {
if (!existingSet.has(role.id + '-' + readPerm.id)) {
rolePermissions.push({
roles_permissionsId: role.id,
permissionId: readPerm.id,
createdAt,
updatedAt,
});
}
}
if (rolePermissions.length > 0) {
await queryInterface.bulkInsert('rolesPermissionsPermissions', rolePermissions);
}
},
down: async (queryInterface, Sequelize) => {}
};

View File

@ -724,7 +724,7 @@ const EditJob_logsPage = () => {
<FormField label="Workmans Comp Class" labelFor="workersCompClassId">
<Field name="workersCompClass" id="workersCompClass" component={SelectField} options={[]} itemRef={'workers_comp_classes'}></Field>
<Field name="workersCompClass" id="workersCompClass" component={SelectField} options={initialValues.workersCompClass} itemRef={'workers_comp_classes'} showField={'name'}></Field>
</FormField>

View File

@ -458,7 +458,7 @@ const Job_logsNew = () => {
<FormField label="Workmans Comp Class" labelFor="workersCompClassId">
<Field name="workersCompClass" id="workersCompClass" component={SelectField} options={[]} itemRef={'workers_comp_classes'}></Field>
<Field name="workersCompClass" id="workersCompClass" component={SelectField} options={[]} itemRef={'workers_comp_classes'} showField={'name'}></Field>
</FormField>

View File

@ -1,6 +1,6 @@
import { mdiPencil, mdiChartTimelineVariant } from '@mdi/js';
import Head from 'next/head';
import React, { ReactElement } from 'react';
import React, { ReactElement, useEffect, useState } from 'react';
import CardBox from '../components/CardBox';
import LayoutAuthenticated from '../layouts/Authenticated';
import SectionMain from '../components/SectionMain';
@ -16,11 +16,27 @@ import { SelectField } from '../components/SelectField';
import { useRouter } from 'next/router';
import { create } from '../stores/job_logs/job_logsSlice';
import { useAppDispatch, useAppSelector } from '../stores/hooks';
import axios from 'axios';
const LogWorkPage = () => {
const router = useRouter();
const dispatch = useAppDispatch();
const currentUser = useAppSelector((state) => state.auth.currentUser);
const [assignedPayTypes, setAssignedPayTypes] = useState<any[]>([]);
useEffect(() => {
if (currentUser?.id) {
axios.get(`/employee_pay_types?employee=${currentUser.id}&active=true`)
.then((res) => {
if (res.data && res.data.rows) {
// Ensure we are extracting the inner pay_type relation from employee_pay_types
const payTypes = res.data.rows.map((row: any) => row.pay_type).filter(Boolean);
setAssignedPayTypes(payTypes);
}
})
.catch((err) => console.error('Failed to fetch assigned pay types:', err));
}
}, [currentUser]);
const initialValues = {
work_date: new Date().toISOString().slice(0, 16),
@ -28,7 +44,7 @@ const LogWorkPage = () => {
customer: '',
hours_conducted: '',
client_paid: '',
workers_comp_class: 'roof',
workersCompClass: '',
pay_type: '',
vehicle: '',
odometer_start: '',
@ -67,15 +83,18 @@ const LogWorkPage = () => {
<FormField label="Client Paid">
<Field type="number" name="client_paid" placeholder="Amount" />
</FormField>
<FormField label="Worker's Comp Class" labelFor="workers_comp_class">
<Field name="workers_comp_class" id="workers_comp_class" component="select">
<option value="roof">Roof</option>
<option value="ladder">Ladder</option>
<option value="ground">Ground</option>
</Field>
<FormField label="Worker's Comp Class" labelFor="workersCompClass">
<Field name="workersCompClass" id="workersCompClass" component={SelectField} options={[]} itemRef={"workers_comp_classes"} showField={"name"} />
</FormField>
<FormField label="Pay Type" labelFor="pay_type">
<Field name="pay_type" id="pay_type" component={SelectField} options={[]} itemRef={'pay_types'} />
<Field name="pay_type" id="pay_type" as="select">
<option value="">Select an assigned pay type</option>
{assignedPayTypes.map((pt) => (
<option key={pt.id} value={pt.id}>
{pt.name || pt.pay_method}
</option>
))}
</Field>
</FormField>
<FormField label="Vehicle" labelFor="vehicle">
<Field name="vehicle" id="vehicle" component={SelectField} options={[]} itemRef={'vehicles'} />
@ -108,4 +127,4 @@ LogWorkPage.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated>{page}</LayoutAuthenticated>;
};
export default LogWorkPage;
export default LogWorkPage;

View File

@ -1,9 +1,6 @@
import { mdiChartTimelineVariant, mdiUpload } from '@mdi/js'
import { mdiChartTimelineVariant } from '@mdi/js'
import Head from 'next/head'
import React, { ReactElement, useEffect, useState } from 'react'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import CardBox from '../../components/CardBox'
import LayoutAuthenticated from '../../layouts/Authenticated'
@ -16,230 +13,44 @@ import FormField from '../../components/FormField'
import BaseDivider from '../../components/BaseDivider'
import BaseButtons from '../../components/BaseButtons'
import BaseButton from '../../components/BaseButton'
import FormCheckRadio from '../../components/FormCheckRadio'
import FormCheckRadioGroup from '../../components/FormCheckRadioGroup'
import FormFilePicker from '../../components/FormFilePicker'
import FormImagePicker from '../../components/FormImagePicker'
import { SelectField } from "../../components/SelectField";
import { SelectFieldMany } from "../../components/SelectFieldMany";
import { SwitchField } from '../../components/SwitchField'
import {RichTextField} from "../../components/RichTextField";
import { update, fetch } from '../../stores/workers_comp_classes/workers_comp_classesSlice'
import { useAppDispatch, useAppSelector } from '../../stores/hooks'
import { useRouter } from 'next/router'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
const EditWorkers_comp_classesPage = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const initVals = {
'name': '',
pay_method: '',
'hourly_rate': '',
'commission_rate': '',
'workers_comp_percentage': '',
active: false,
description: '',
name: '',
percentage: '',
}
const [initialValues, setInitialValues] = useState(initVals)
const { workers_comp_classes } = useAppSelector((state) => state.workers_comp_classes)
const { id } = router.query
useEffect(() => {
dispatch(fetch({ id: id }))
}, [id])
if (id) {
dispatch(fetch({ id: id as string }))
}
}, [id, dispatch])
useEffect(() => {
if (typeof workers_comp_classes === 'object') {
setInitialValues(workers_comp_classes)
if (typeof workers_comp_classes === 'object' && workers_comp_classes !== null) {
const newInitialVal = { ...initVals };
Object.keys(initVals).forEach(el => {
if (workers_comp_classes[el] !== undefined) {
newInitialVal[el] = workers_comp_classes[el];
}
});
setInitialValues(newInitialVal);
}
}, [workers_comp_classes])
useEffect(() => {
if (typeof workers_comp_classes === 'object') {
const newInitialVal = {...initVals};
Object.keys(initVals).forEach(el => newInitialVal[el] = (workers_comp_classes)[el])
setInitialValues(newInitialVal);
}
}, [workers_comp_classes])
const handleSubmit = async (data) => {
const handleSubmit = async (data: any) => {
await dispatch(update({ id: id, data }))
await router.push('/workers_comp_classes/workers_comp_classes-list')
}
@ -247,10 +58,10 @@ const EditWorkers_comp_classesPage = () => {
return (
<>
<Head>
<title>{getPageTitle('Edit workers_comp_classes')}</title>
<title>{getPageTitle('Edit Workers Comp Class')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={'Edit workers_comp_classes'} main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={'Edit Workers Comp Class'} main>
{''}
</SectionTitleLineWithButton>
<CardBox>
@ -260,18 +71,18 @@ const EditWorkers_comp_classesPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
<FormField label="Name" labelFor="name">
<Field name="name" id="name" type="text" />
</FormField>
<FormField label="Percentage" labelFor="percentage">
<Field name="percentage" id="percentage" type="number" step="0.01" />
</FormField>
<BaseDivider />
<BaseButtons>
<BaseButton type="submit" color="info" label="Submit" />
<BaseButton type="reset" color="info" outline label="Reset" />
</BaseButtons>
</Form>
<FormField label="Name" labelFor="name">
<Field name="name" id="name" type="text" />
</FormField>
<FormField label="Percentage" labelFor="percentage">
<Field name="percentage" id="percentage" type="number" step="0.01" />
</FormField>
<BaseDivider />
<BaseButtons>
<BaseButton type="submit" color="info" label="Submit" />
<BaseButton type="reset" color="info" outline label="Reset" />
</BaseButtons>
</Form>
</Formik>
</CardBox>
</SectionMain>
@ -281,14 +92,10 @@ const EditWorkers_comp_classesPage = () => {
EditWorkers_comp_classesPage.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'UPDATE_PAY_TYPES'}
>
<LayoutAuthenticated permission={'UPDATE_WORKERS_COMP_CLASSES'}>
{page}
</LayoutAuthenticated>
)
}
export default EditWorkers_comp_classesPage
export default EditWorkers_comp_classesPage

View File

@ -1,5 +1,6 @@
import { mdiChartTimelineVariant, mdiPlus } from '@mdi/js'
import Head from 'next/head'
import { uniqueId } from 'lodash'
import React, { ReactElement, useEffect, useState } from 'react'
import CardBox from '../../components/CardBox'
import LayoutAuthenticated from '../../layouts/Authenticated'
@ -8,18 +9,37 @@ import SectionTitleLineWithButton from '../../components/SectionTitleLineWithBut
import { getPageTitle } from '../../config'
import TableWorkers_comp_classes from '../../components/Workers_comp_classes/TableWorkers_comp_classes'
import BaseButton from '../../components/BaseButton'
import axios from 'axios';
import Link from 'next/link';
import { useAppDispatch, useAppSelector } from '../../stores/hooks';
import CardBoxModal from '../../components/CardBoxModal';
import DragDropFilePicker from '../../components/DragDropFilePicker';
import { setRefetch, uploadCsv } from '../../stores/workers_comp_classes/workers_comp_classesSlice';
import { hasPermission } from '../../helpers/userPermissions';
import axios from 'axios'
import Link from 'next/link'
import { useAppDispatch, useAppSelector } from '../../stores/hooks'
import CardBoxModal from '../../components/CardBoxModal'
import DragDropFilePicker from '../../components/DragDropFilePicker'
import { setRefetch, uploadCsv } from '../../stores/workers_comp_classes/workers_comp_classesSlice'
import { hasPermission } from '../../helpers/userPermissions'
const Workers_comp_classesList = () => {
const [filterItems, setFilterItems] = useState<any[]>([]);
const [filters] = useState([
{label: 'Name', title: 'name'},
{label: 'Percentage', title: 'percentage', number: 'true'},
]);
const dispatch = useAppDispatch();
const { currentUser } = useAppSelector((state) => state.auth);
const [reportData, setReportData] = useState(null);
const [reportData, setReportData] = useState<any>(null);
const addFilter = () => {
const newItem = {
id: uniqueId(),
fields: {
filterValue: '',
filterValueFrom: '',
filterValueTo: '',
selectedField: filters[0].title,
},
};
setFilterItems([...filterItems, newItem]);
};
useEffect(() => {
const fetchReport = async () => {
@ -46,6 +66,11 @@ const Workers_comp_classesList = () => {
>
{hasPermission(currentUser, 'CREATE_WORKERS_COMP_CLASSES') && (
<div className="flex items-center gap-2">
<BaseButton
color='info'
label='Filter'
onClick={addFilter}
/>
<Link href={'/workers_comp_classes/workers_comp_classes-new'}>
<BaseButton
color="info"
@ -68,7 +93,7 @@ const Workers_comp_classesList = () => {
{Object.entries(reportData.totalsByClass).map(([className, total]: any) => (
<div key={className} className="p-4 bg-gray-50 rounded shadow">
<p className="text-sm text-gray-500 font-bold">{className}</p>
<p className="text-xl font-semibold">${total.toFixed(2)}</p>
<p className="text-xl font-semibold">${Number(total).toFixed(2)}</p>
</div>
))}
</div>
@ -76,7 +101,12 @@ const Workers_comp_classesList = () => {
)}
<CardBox className="mb-6" hasTable>
<TableWorkers_comp_classes />
<TableWorkers_comp_classes
filterItems={filterItems}
setFilterItems={setFilterItems}
filters={filters}
showGrid={false}
/>
</CardBox>
</SectionMain>
</>

View File

@ -1,4 +1,4 @@
import { mdiAccount, mdiChartTimelineVariant, mdiMail, mdiUpload } from '@mdi/js'
import { mdiChartTimelineVariant } from '@mdi/js'
import Head from 'next/head'
import React, { ReactElement } from 'react'
import CardBox from '../../components/CardBox'
@ -12,167 +12,52 @@ import FormField from '../../components/FormField'
import BaseDivider from '../../components/BaseDivider'
import BaseButtons from '../../components/BaseButtons'
import BaseButton from '../../components/BaseButton'
import FormCheckRadio from '../../components/FormCheckRadio'
import FormCheckRadioGroup from '../../components/FormCheckRadioGroup'
import FormFilePicker from '../../components/FormFilePicker'
import FormImagePicker from '../../components/FormImagePicker'
import { SwitchField } from '../../components/SwitchField'
import { SelectField } from '../../components/SelectField'
import { SelectFieldMany } from "../../components/SelectFieldMany";
import {RichTextField} from "../../components/RichTextField";
import { create } from '../../stores/workers_comp_classes/workers_comp_classesSlice'
import { useAppDispatch } from '../../stores/hooks'
import { useRouter } from 'next/router'
import moment from 'moment';
const initialValues = {
name: '',
pay_method: 'hourly',
hourly_rate: '',
commission_rate: '',
workers_comp_percentage: '',
active: false,
description: '',
percentage: '',
}
const Workers_comp_classesNew = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const handleSubmit = async (data) => {
const handleSubmit = async (data: any) => {
await dispatch(create(data))
await router.push('/workers_comp_classes/workers_comp_classes-list')
}
return (
<>
<Head>
<title>{getPageTitle('New Item')}</title>
<title>{getPageTitle('New Workers Comp Class')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="New Item" main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="New Workers Comp Class" main>
{''}
</SectionTitleLineWithButton>
<CardBox>
<Formik
initialValues={
initialValues
}
initialValues={initialValues}
onSubmit={(values) => handleSubmit(values)}
>
<Form>
<FormField label="Name" labelFor="name">
<Field name="name" id="name" type="text" />
</FormField>
<FormField label="Percentage" labelFor="percentage">
<Field name="percentage" id="percentage" type="number" step="0.01" />
</FormField>
<BaseDivider />
<BaseButtons>
<BaseButton type="submit" color="info" label="Submit" />
<BaseButton type="reset" color="info" outline label="Reset" />
</BaseButtons>
</Form>
<FormField label="Name" labelFor="name">
<Field name="name" id="name" type="text" />
</FormField>
<FormField label="Percentage" labelFor="percentage">
<Field name="percentage" id="percentage" type="number" step="0.01" />
</FormField>
<BaseDivider />
<BaseButtons>
<BaseButton type="submit" color="info" label="Submit" />
<BaseButton type="reset" color="info" outline label="Reset" />
</BaseButtons>
</Form>
</Formik>
</CardBox>
</SectionMain>
@ -182,14 +67,10 @@ const Workers_comp_classesNew = () => {
Workers_comp_classesNew.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'CREATE_PAY_TYPES'}
>
<LayoutAuthenticated permission={'CREATE_WORKERS_COMP_CLASSES'}>
{page}
</LayoutAuthenticated>
)
}
export default Workers_comp_classesNew
export default Workers_comp_classesNew

View File

@ -1,21 +1,26 @@
const fs = require('fs');
const file = 'backend/src/services/payroll_line_items.js';
const file = 'backend/src/db/api/job_logs.js';
let content = fs.readFileSync(file, 'utf8');
const createLogic = `
if (data.job_logId && data.gross_pay) {
const jobLog = await db.job_logs.findByPk(data.job_logId, { transaction });
if (jobLog && jobLog.workersCompClassId) {
const compClass = await db.workers_comp_classes.findByPk(jobLog.workersCompClassId, { transaction });
if (compClass && compClass.percentage) {
data.workers_comp_amount = (Number(data.gross_pay || 0) * Number(compClass.percentage || 0)) / 100;
}
}
}
`;
if (!content.includes('setWorkersCompClass')) {
content = content.replace(
/await job_logs.setVehicle(\s*data.vehicle\s*||\s*null,\s*{\s*transaction,\s*})/g,
`await job_logs.setVehicle( data.vehicle || null, {\n transaction,\n });\n \n await job_logs.setWorkersCompClass( data.workersCompClass || null, {\n transaction,\n });`
);
content = content.replace(/try {\n await Payroll_line_itemsDBApi.create/g, 'try {' + createLogic + ' await Payroll_line_itemsDBApi.create');
content = content.replace(/try {\n const updatedPayroll_line_items = await Payroll_line_itemsDBApi.update/g, 'try {' + createLogic + ' const updatedPayroll_line_items = await Payroll_line_itemsDBApi.update');
content = content.replace(
/if\s*\(data.vehicle !== undefined\)\s*{\s*await job_logs.setVehicle\(\s*data.vehicle,\s*{\s*transaction\s*}\s*\);\s*}/g,
`if (data.vehicle !== undefined) {\n await job_logs.setVehicle(\n data.vehicle,\n { transaction }\n );\n }\n \n if (data.workersCompClass !== undefined) {\n await job_logs.setWorkersCompClass(\n data.workersCompClass,\n { transaction }\n );\n }`
);
fs.writeFileSync(file, content);
// Also let's update findBy to include workersCompClass
content = content.replace(
/output.vehicle = await job_logs.getVehicle({\s*transaction\s*})/g,
`output.vehicle = await job_logs.getVehicle({\n transaction\n });\n \n output.workersCompClass = await job_logs.getWorkersCompClass({\n transaction\n });`
);
fs.writeFileSync(file, content);
console.log("Patched!");
} else {
console.log("Already patched.");
}

24
patch.py Normal file
View File

@ -0,0 +1,24 @@
import re
with open('backend/src/db/api/job_logs.js', 'r') as f:
content = f.read()
content = content.replace(
'await job_logs.setVehicle( data.vehicle || null, {\n transaction,\n });',
'await job_logs.setVehicle( data.vehicle || null, {\n transaction,\n });\n \n await job_logs.setWorkersCompClass( data.workersCompClass || null, {\n transaction,\n });'
)
content = content.replace(
'''if (data.vehicle !== undefined) {\n await job_logs.setVehicle(\n \n data.vehicle,\n \n { transaction }\n );\n }''',
'''if (data.vehicle !== undefined) {\n await job_logs.setVehicle(\n \n data.vehicle,\n \n { transaction }\n );\n }\n \n if (data.workersCompClass !== undefined) {\n await job_logs.setWorkersCompClass(\n \n data.workersCompClass,\n \n { transaction }\n );\n }'''
)
content = content.replace(
'''output.vehicle = await job_logs.getVehicle({\n transaction\n });''',
'''output.vehicle = await job_logs.getVehicle({\n transaction\n });\n \n output.workersCompClass = await job_logs.getWorkersCompClass({\n transaction\n });'''
)
with open('backend/src/db/api/job_logs.js', 'w') as f:
f.write(content)
print("Patched correctly!")

61
patch2.py Normal file
View File

@ -0,0 +1,61 @@
import re
with open('backend/src/db/api/job_logs.js', 'r') as f:
content = f.read()
replacement = ''' {
model: db.vehicles,
as: 'vehicle',
where: filter.vehicle ? {
[Op.or]: [
{ id: { [Op.in]: filter.vehicle.split('|').map(term => Utils.uuid(term)) } },
{
name: {
[Op.or]: filter.vehicle.split('|').map(term => ({ [Op.iLike]: `%${term}%` }))
}
},
]
} : {},
},
{
model: db.workers_comp_classes,
as: 'workersCompClass',
where: filter.workersCompClass ? {
[Op.or]: [
{ id: { [Op.in]: filter.workersCompClass.split('|').map(term => Utils.uuid(term)) } },
{
name: {
[Op.or]: filter.workersCompClass.split('|').map(term => ({ [Op.iLike]: `%${term}%` }))
}
},
]
} : {},
},'''
content = content.replace(
''' {
model: db.vehicles,
as: 'vehicle',
where: filter.vehicle ? {
[Op.or]: [
{ id: { [Op.in]: filter.vehicle.split('|').map(term => Utils.uuid(term)) } },
{
name: {
[Op.or]: filter.vehicle.split('|').map(term => ({ [Op.iLike]: `%${term}%` }))
}
},
]
} : {},
},''',
replacement
)
with open('backend/src/db/api/job_logs.js', 'w') as f:
f.write(content)
print("Patched include!")