269 lines
12 KiB
JavaScript
269 lines
12 KiB
JavaScript
import {useQuery} from "@apollo/client";
|
|
import {Button, Form, InputNumber, Modal, Radio, Select, Space, Table, Typography,} from "antd";
|
|
import Dinero from "dinero.js";
|
|
import React, {useState} from "react";
|
|
import {useTranslation} from "react-i18next";
|
|
import {connect} from "react-redux";
|
|
import {createStructuredSelector} from "reselect";
|
|
import {GET_JOB_INFO_DRAW_CALCULATIONS} from "../../graphql/jobs-lines.queries";
|
|
import {selectBodyshop} from "../../redux/user/user.selectors";
|
|
import FormDatePicker from "../form-date-picker/form-date-picker.component";
|
|
import JobSearchSelectComponent from "../job-search-select/job-search-select.component";
|
|
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
|
|
|
const mapStateToProps = createStructuredSelector({
|
|
bodyshop: selectBodyshop,
|
|
});
|
|
const mapDispatchToProps = (dispatch) => ({});
|
|
export default connect(
|
|
mapStateToProps,
|
|
mapDispatchToProps
|
|
)(TimeTicketListTeamPay);
|
|
|
|
export function TimeTicketListTeamPay({bodyshop, context, actions}) {
|
|
//const { refetch } = actions;
|
|
const {jobId} = context;
|
|
const [visible, setVisible] = useState(false);
|
|
const [form] = Form.useForm();
|
|
const {t} = useTranslation();
|
|
const {
|
|
//loading,
|
|
data: lineTicketData,
|
|
} = useQuery(GET_JOB_INFO_DRAW_CALCULATIONS, {
|
|
variables: {id: jobId},
|
|
skip: !jobId,
|
|
fetchPolicy: "network-only",
|
|
nextFetchPolicy: "network-only",
|
|
});
|
|
|
|
const handleOk = () => {
|
|
setVisible(false);
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<Modal
|
|
width={"80%"}
|
|
open={visible}
|
|
destroyOnClose
|
|
onOk={handleOk}
|
|
onCancel={() => setVisible(false)}
|
|
>
|
|
<Form layout="vertical" form={form} initialValues={{jobid: jobId}}>
|
|
<LayoutFormRow grow noDivider>
|
|
<Form.Item shouldUpdate>
|
|
{() => (
|
|
<Form.Item
|
|
name="jobid"
|
|
label={t("timetickets.fields.ro_number")}
|
|
rules={[
|
|
{
|
|
required: !(
|
|
form.getFieldValue("cost_center") ===
|
|
"timetickets.labels.shift"
|
|
),
|
|
//message: t("general.validation.required"),
|
|
},
|
|
]}
|
|
>
|
|
<JobSearchSelectComponent
|
|
convertedOnly={!bodyshop.tt_allow_post_to_invoiced}
|
|
notExported={!bodyshop.tt_allow_post_to_invoiced}
|
|
/>
|
|
</Form.Item>
|
|
)}
|
|
</Form.Item>
|
|
<Form.Item
|
|
label={t("timetickets.fields.date")}
|
|
name="date"
|
|
rules={[
|
|
{
|
|
required: true,
|
|
//message: t("general.validation.required"),
|
|
},
|
|
]}
|
|
>
|
|
<FormDatePicker/>
|
|
</Form.Item>
|
|
</LayoutFormRow>
|
|
|
|
<LayoutFormRow grow noDivider>
|
|
<Form.Item name="team" label="Team">
|
|
<Select
|
|
options={Teams.map((team) => ({
|
|
value: team.name,
|
|
label: team.name,
|
|
}))}
|
|
/>
|
|
</Form.Item>
|
|
|
|
<Form.Item name="hourstype">
|
|
<Radio.Group>
|
|
<Radio value="LAB">Body</Radio>
|
|
<Radio value="LAR">Refinish</Radio>
|
|
<Radio value="LAM">Mechanical</Radio>
|
|
<Radio value="LAF">Frame</Radio>
|
|
<Radio value="LAG">Glass</Radio>
|
|
</Radio.Group>
|
|
</Form.Item>
|
|
|
|
<Form.Item name="percent">
|
|
<InputNumber min={0} max={100} precision={1} addonAfter="%"/>
|
|
</Form.Item>
|
|
</LayoutFormRow>
|
|
|
|
<Form.Item shouldUpdate noStyle>
|
|
{({getFieldsValue}) => {
|
|
const formData = getFieldsValue();
|
|
|
|
let data = [];
|
|
let eligibleHours = 0;
|
|
const theTeam = Teams.find((team) => team.name === formData.team);
|
|
if (theTeam) {
|
|
eligibleHours =
|
|
lineTicketData.joblines.reduce(
|
|
(acc, val) =>
|
|
acc +
|
|
(formData.hourstype === val.mod_lbr_ty
|
|
? val.mod_lb_hrs
|
|
: 0),
|
|
0
|
|
) * (formData.percent / 100 || 0);
|
|
|
|
data = theTeam.employees.map((e) => {
|
|
return {
|
|
employeeid: e.employeeid,
|
|
percentage: e.percentage,
|
|
rate: e.rates[formData.hourstype],
|
|
cost_center:
|
|
bodyshop.md_responsibility_centers.defaults.costs[
|
|
formData.hourstype
|
|
],
|
|
productivehrs:
|
|
Math.round(eligibleHours * 100 * (e.percentage / 100)) /
|
|
100,
|
|
pay: Dinero({
|
|
amount: Math.round(
|
|
(e.rates[formData.hourstype] || 0) * 100
|
|
),
|
|
})
|
|
.multiply(
|
|
Math.round(eligibleHours * 100 * (e.percentage / 100)) /
|
|
100
|
|
)
|
|
.toFormat("$0.00"),
|
|
};
|
|
});
|
|
}
|
|
|
|
return (
|
|
<Table
|
|
dataSource={data}
|
|
rowKey={"employeeid"}
|
|
title={() => (
|
|
<Space>
|
|
<Typography.Title level={4}>
|
|
Tickets to be Created
|
|
</Typography.Title>
|
|
<span>{`(${eligibleHours} hours to split)`}</span>
|
|
</Space>
|
|
)}
|
|
columns={[
|
|
{
|
|
title: t("timetickets.fields.employee"),
|
|
dataIndex: "employee",
|
|
key: "employee",
|
|
render: (text, record) => {
|
|
const emp = bodyshop.employees.find(
|
|
(e) => e.id === record.employeeid
|
|
);
|
|
return `${emp?.first_name} ${emp?.last_name}`;
|
|
},
|
|
},
|
|
{
|
|
title: t("timetickets.fields.cost_center"),
|
|
dataIndex: "cost_center",
|
|
key: "cost_center",
|
|
|
|
render: (text, record) =>
|
|
record.cost_center === "timetickets.labels.shift"
|
|
? t(record.cost_center)
|
|
: record.cost_center,
|
|
},
|
|
{
|
|
title: t("timetickets.fields.productivehrs"),
|
|
dataIndex: "productivehrs",
|
|
key: "productivehrs",
|
|
},
|
|
{
|
|
title: "Percentage",
|
|
dataIndex: "percentage",
|
|
key: "percentage",
|
|
},
|
|
{
|
|
title: "Rate",
|
|
dataIndex: "rate",
|
|
key: "rate",
|
|
},
|
|
{
|
|
title: "Pay",
|
|
dataIndex: "pay",
|
|
key: "pay",
|
|
},
|
|
]}
|
|
/>
|
|
);
|
|
}}
|
|
</Form.Item>
|
|
</Form>
|
|
</Modal>
|
|
<Button onClick={() => setVisible(true)}>Assign Team Pay </Button>
|
|
</>
|
|
);
|
|
}
|
|
|
|
const Teams = [
|
|
{
|
|
name: "Team A",
|
|
employees: [
|
|
{
|
|
employeeid: "9f1bdc23-8dc2-4b6a-8ca1-5f83a6fdcc22",
|
|
percentage: 50,
|
|
rates: {
|
|
LAB: 10,
|
|
LAR: 15,
|
|
},
|
|
},
|
|
{
|
|
employeeid: "201db66c-96c7-41ec-bed4-76842ba93087",
|
|
percentage: 50,
|
|
rates: {
|
|
LAB: 20,
|
|
LAR: 25,
|
|
},
|
|
},
|
|
],
|
|
},
|
|
{
|
|
name: "Team B",
|
|
employees: [
|
|
{
|
|
employeeid: "9f1bdc23-8dc2-4b6a-8ca1-5f83a6fdcc22",
|
|
percentage: 75,
|
|
rates: {
|
|
LAB: 100,
|
|
LAR: 150,
|
|
},
|
|
},
|
|
{
|
|
employeeid: "201db66c-96c7-41ec-bed4-76842ba93087",
|
|
percentage: 25,
|
|
rates: {
|
|
LAB: 200,
|
|
LAR: 250,
|
|
},
|
|
},
|
|
],
|
|
},
|
|
];
|