Compare commits
4 Commits
feature/IO
...
feature/IO
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a56b720e09 | ||
|
|
b89eede164 | ||
|
|
c21cc8d6b9 | ||
|
|
d02a6bc197 |
@@ -69,12 +69,17 @@ export function ScheduleEventComponent({
|
|||||||
variables: { id: event.job.id },
|
variables: { id: event.job.id },
|
||||||
onCompleted: (data) => {
|
onCompleted: (data) => {
|
||||||
if (data?.jobs_by_pk) {
|
if (data?.jobs_by_pk) {
|
||||||
|
const totalHours =
|
||||||
|
(data.jobs_by_pk.labhrs?.aggregate?.sum?.mod_lb_hrs || 0) +
|
||||||
|
(data.jobs_by_pk.larhrs?.aggregate?.sum?.mod_lb_hrs || 0);
|
||||||
form.setFieldsValue({
|
form.setFieldsValue({
|
||||||
actual_in: data.jobs_by_pk.actual_in ? data.jobs_by_pk.actual_in : dayjs(),
|
actual_in: data.jobs_by_pk.actual_in ? data.jobs_by_pk.actual_in : dayjs(),
|
||||||
scheduled_completion: data.jobs_by_pk.scheduled_completion,
|
scheduled_completion: data.jobs_by_pk.scheduled_completion
|
||||||
actual_completion: data.jobs_by_pk.actual_completion,
|
? data.jobs_by_pk.scheduled_completion
|
||||||
scheduled_delivery: data.jobs_by_pk.scheduled_delivery,
|
: totalHours && bodyshop.ss_configuration.nobusinessdays
|
||||||
actual_delivery: data.jobs_by_pk.actual_delivery
|
? dayjs().businessDaysAdd(totalHours / (bodyshop.target_touchtime || 1), "day")
|
||||||
|
: dayjs().add(totalHours / (bodyshop.target_touchtime || 1), "day"),
|
||||||
|
scheduled_delivery: data.jobs_by_pk.scheduled_delivery
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -44,18 +44,16 @@ export function JobsDetailHeaderActionsToggleProduction({
|
|||||||
variables: { id: job.id },
|
variables: { id: job.id },
|
||||||
onCompleted: (data) => {
|
onCompleted: (data) => {
|
||||||
if (data?.jobs_by_pk) {
|
if (data?.jobs_by_pk) {
|
||||||
|
const totalHours =
|
||||||
|
(data.jobs_by_pk.labhrs?.aggregate?.sum?.mod_lb_hrs || 0) +
|
||||||
|
(data.jobs_by_pk.larhrs?.aggregate?.sum?.mod_lb_hrs || 0);
|
||||||
form.setFieldsValue({
|
form.setFieldsValue({
|
||||||
actual_in: data.jobs_by_pk.actual_in ? data.jobs_by_pk.actual_in : dayjs(),
|
actual_in: data.jobs_by_pk.actual_in ? data.jobs_by_pk.actual_in : dayjs(),
|
||||||
scheduled_completion: data.jobs_by_pk.scheduled_completion
|
scheduled_completion: data.jobs_by_pk.scheduled_completion
|
||||||
? data.jobs_by_pk.scheduled_completion
|
? data.jobs_by_pk.scheduled_completion
|
||||||
: data.jobs_by_pk.labhrs &&
|
: totalHours && bodyshop.ss_configuration.nobusinessdays
|
||||||
data.jobs_by_pk.larhrs &&
|
? dayjs().businessDaysAdd(totalHours / (bodyshop.target_touchtime || 1), "day")
|
||||||
dayjs().businessDaysAdd(
|
: dayjs().add(totalHours / (bodyshop.target_touchtime || 1), "day"),
|
||||||
(data.jobs_by_pk.labhrs.aggregate.sum.mod_lb_hrs ||
|
|
||||||
0 + data.jobs_by_pk.larhrs.aggregate.sum.mod_lb_hrs ||
|
|
||||||
0) / bodyshop.target_touchtime,
|
|
||||||
"day"
|
|
||||||
),
|
|
||||||
actual_completion: data.jobs_by_pk.actual_completion,
|
actual_completion: data.jobs_by_pk.actual_completion,
|
||||||
scheduled_delivery: data.jobs_by_pk.scheduled_delivery,
|
scheduled_delivery: data.jobs_by_pk.scheduled_delivery,
|
||||||
actual_delivery: data.jobs_by_pk.actual_delivery
|
actual_delivery: data.jobs_by_pk.actual_delivery
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Button, Col, Form, Input, Row, Select, Space, Switch, Typography } from "antd";
|
import { Button, Col, Form, Input, Row, Select, Space, Switch, Typography } from "antd";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import React, { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
@@ -8,16 +8,16 @@ import { calculateScheduleLoad } from "../../redux/application/application.actio
|
|||||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
import { DateFormatter } from "../../utils/DateFormatter";
|
import { DateFormatter } from "../../utils/DateFormatter";
|
||||||
import dayjs from "../../utils/day";
|
import dayjs from "../../utils/day";
|
||||||
|
import BlurWrapper from "../feature-wrapper/blur-wrapper.component";
|
||||||
import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
|
import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
|
||||||
import DateTimePicker from "../form-date-time-picker/form-date-time-picker.component";
|
import DateTimePicker from "../form-date-time-picker/form-date-time-picker.component";
|
||||||
import EmailInput from "../form-items-formatted/email-form-item.component";
|
import EmailInput from "../form-items-formatted/email-form-item.component";
|
||||||
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
||||||
|
import LockWrapperComponent from "../lock-wrapper/lock-wrapper.component";
|
||||||
import ScheduleDayViewContainer from "../schedule-day-view/schedule-day-view.container";
|
import ScheduleDayViewContainer from "../schedule-day-view/schedule-day-view.container";
|
||||||
import ScheduleExistingAppointmentsList from "../schedule-existing-appointments-list/schedule-existing-appointments-list.component";
|
import ScheduleExistingAppointmentsList from "../schedule-existing-appointments-list/schedule-existing-appointments-list.component";
|
||||||
import "./schedule-job-modal.scss";
|
|
||||||
import LockWrapperComponent from "../lock-wrapper/lock-wrapper.component";
|
|
||||||
import BlurWrapper from "../feature-wrapper/blur-wrapper.component";
|
|
||||||
import UpsellComponent, { upsellEnum } from "../upsell/upsell.component";
|
import UpsellComponent, { upsellEnum } from "../upsell/upsell.component";
|
||||||
|
import "./schedule-job-modal.scss";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop
|
bodyshop: selectBodyshop
|
||||||
@@ -60,10 +60,12 @@ export function ScheduleJobModalComponent({
|
|||||||
const totalHours =
|
const totalHours =
|
||||||
lbrHrsData.jobs_by_pk.labhrs.aggregate.sum.mod_lb_hrs + lbrHrsData.jobs_by_pk.larhrs.aggregate.sum.mod_lb_hrs;
|
lbrHrsData.jobs_by_pk.labhrs.aggregate.sum.mod_lb_hrs + lbrHrsData.jobs_by_pk.larhrs.aggregate.sum.mod_lb_hrs;
|
||||||
|
|
||||||
if (values.start && !values.scheduled_completion)
|
if (values.start && !values.scheduled_completion) {
|
||||||
form.setFieldsValue({
|
const addDays = bodyshop.ss_configuration.nobusinessdays
|
||||||
scheduled_completion: dayjs(values.start).businessDaysAdd(totalHours / bodyshop.target_touchtime, "day")
|
? dayjs(values.start).add(totalHours / (bodyshop.target_touchtime || 1), "day")
|
||||||
});
|
: dayjs(values.start).businessDaysAdd(totalHours / (bodyshop.target_touchtime || 1), "day");
|
||||||
|
form.setFieldsValue({ scheduled_completion: addDays });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,15 @@
|
|||||||
import { DeleteFilled } from "@ant-design/icons";
|
import { DeleteFilled } from "@ant-design/icons";
|
||||||
import { Button, Divider, Form, Input, InputNumber, Select, Space, Switch, TimePicker } from "antd";
|
import { Button, Divider, Form, Input, InputNumber, Select, Space, Switch, TimePicker } from "antd";
|
||||||
import React from "react";
|
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import { createStructuredSelector } from "reselect";
|
||||||
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
|
import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
|
||||||
import ColorpickerFormItemComponent from "../form-items-formatted/colorpicker-form-item.component";
|
import ColorpickerFormItemComponent from "../form-items-formatted/colorpicker-form-item.component";
|
||||||
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
|
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
|
||||||
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
||||||
import { ColorPicker } from "./shop-info.rostatus.component";
|
import { ColorPicker } from "./shop-info.rostatus.component";
|
||||||
|
|
||||||
import { connect } from "react-redux";
|
|
||||||
import { createStructuredSelector } from "reselect";
|
|
||||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop
|
bodyshop: selectBodyshop
|
||||||
});
|
});
|
||||||
@@ -78,6 +77,13 @@ export function ShopInfoSchedulingComponent({ form, bodyshop }) {
|
|||||||
>
|
>
|
||||||
<InputNumber min={0} />
|
<InputNumber min={0} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
name={["ss_configuration", "nobusinessdays"]}
|
||||||
|
label={t("bodyshop.fields.ss_configuration.nobusinessdays")}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name={["md_lost_sale_reasons"]}
|
name={["md_lost_sale_reasons"]}
|
||||||
label={t("bodyshop.fields.md_lost_sale_reasons")}
|
label={t("bodyshop.fields.md_lost_sale_reasons")}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { useLazyQuery } from "@apollo/client";
|
import { useLazyQuery } from "@apollo/client";
|
||||||
import { useSplitTreatments } from "@splitsoftware/splitio-react";
|
import { useSplitTreatments } from "@splitsoftware/splitio-react";
|
||||||
import { Form, Input, InputNumber, Select, Switch } from "antd";
|
import { Card, Form, Input, InputNumber, Select, Space, Switch } from "antd";
|
||||||
import React from "react";
|
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
@@ -19,6 +18,7 @@ import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
|||||||
import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component";
|
import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component";
|
||||||
import { HasRbacAccess } from "../rbac-wrapper/rbac-wrapper.component";
|
import { HasRbacAccess } from "../rbac-wrapper/rbac-wrapper.component";
|
||||||
import TimeTicketList from "../time-ticket-list/time-ticket-list.component";
|
import TimeTicketList from "../time-ticket-list/time-ticket-list.component";
|
||||||
|
import JobEmployeeAssignmentsContainer from "./../job-employee-assignments/job-employee-assignments.container";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop,
|
bodyshop: selectBodyshop,
|
||||||
@@ -319,10 +319,15 @@ export function TimeTicketModalComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function LaborAllocationContainer({ jobid, loading, lineTicketData, hideTimeTickets = false }) {
|
export function LaborAllocationContainer({ jobid, loading, lineTicketData, hideTimeTickets = false }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
if (loading) return <LoadingSkeleton />;
|
if (loading) return <LoadingSkeleton />;
|
||||||
if (!lineTicketData) return null;
|
if (!lineTicketData) return null;
|
||||||
|
if (!jobid) return null;
|
||||||
return (
|
return (
|
||||||
<div>
|
<Space direction="vertical" style={{ width: "100%" }}>
|
||||||
|
<Card style={{ height: "100%" }} title={t("jobs.labels.employeeassignments")}>
|
||||||
|
<JobEmployeeAssignmentsContainer job={lineTicketData.jobs_by_pk} />
|
||||||
|
</Card>
|
||||||
<LaborAllocationsTable
|
<LaborAllocationsTable
|
||||||
jobId={jobid}
|
jobId={jobid}
|
||||||
joblines={lineTicketData.joblines}
|
joblines={lineTicketData.joblines}
|
||||||
@@ -332,6 +337,6 @@ export function LaborAllocationContainer({ jobid, loading, lineTicketData, hideT
|
|||||||
{!hideTimeTickets && (
|
{!hideTimeTickets && (
|
||||||
<TimeTicketList loading={loading} timetickets={jobid ? lineTicketData.timetickets : []} techConsole />
|
<TimeTicketList loading={loading} timetickets={jobid ? lineTicketData.timetickets : []} techConsole />
|
||||||
)}
|
)}
|
||||||
</div>
|
</Space>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,11 @@ import { PageHeader } from "@ant-design/pro-layout";
|
|||||||
import { useMutation, useQuery } from "@apollo/client";
|
import { useMutation, useQuery } from "@apollo/client";
|
||||||
import { useSplitTreatments } from "@splitsoftware/splitio-react";
|
import { useSplitTreatments } from "@splitsoftware/splitio-react";
|
||||||
import { Button, Form, Modal, Space } from "antd";
|
import { Button, Form, Modal, Space } from "antd";
|
||||||
import React, { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
|
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
|
||||||
import { QUERY_ACTIVE_EMPLOYEES } from "../../graphql/employees.queries";
|
import { QUERY_ACTIVE_EMPLOYEES } from "../../graphql/employees.queries";
|
||||||
import { INSERT_NEW_TIME_TICKET, UPDATE_TIME_TICKET } from "../../graphql/timetickets.queries";
|
import { INSERT_NEW_TIME_TICKET, UPDATE_TIME_TICKET } from "../../graphql/timetickets.queries";
|
||||||
import { toggleModalVisible } from "../../redux/modals/modals.actions";
|
import { toggleModalVisible } from "../../redux/modals/modals.actions";
|
||||||
@@ -14,7 +15,6 @@ import { selectBodyshop } from "../../redux/user/user.selectors";
|
|||||||
import dayjs from "../../utils/day";
|
import dayjs from "../../utils/day";
|
||||||
import TimeTicketsCommitToggleComponent from "../time-tickets-commit-toggle/time-tickets-commit-toggle.component";
|
import TimeTicketsCommitToggleComponent from "../time-tickets-commit-toggle/time-tickets-commit-toggle.component";
|
||||||
import TimeTicketModalComponent from "./time-ticket-modal.component";
|
import TimeTicketModalComponent from "./time-ticket-modal.component";
|
||||||
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
|
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
timeTicketModal: selectTimeTicket,
|
timeTicketModal: selectTimeTicket,
|
||||||
@@ -81,7 +81,7 @@ export function TimeTicketModalContainer({ timeTicketModal, toggleModalVisible,
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMutationSuccess = (response) => {
|
const handleMutationSuccess = () => {
|
||||||
notification["success"]({
|
notification["success"]({
|
||||||
message: t("timetickets.successes.created")
|
message: t("timetickets.successes.created")
|
||||||
});
|
});
|
||||||
@@ -123,7 +123,7 @@ export function TimeTicketModalContainer({ timeTicketModal, toggleModalVisible,
|
|||||||
if (timeTicketModal.open) form.resetFields();
|
if (timeTicketModal.open) form.resetFields();
|
||||||
}, [timeTicketModal.open, form]);
|
}, [timeTicketModal.open, form]);
|
||||||
|
|
||||||
const handleFieldsChange = (changedFields, allFields) => {
|
const handleFieldsChange = (changedFields) => {
|
||||||
if (!!changedFields.employeeid && !!EmployeeAutoCompleteData) {
|
if (!!changedFields.employeeid && !!EmployeeAutoCompleteData) {
|
||||||
const emps = EmployeeAutoCompleteData.employees.filter((e) => e.id === changedFields.employeeid);
|
const emps = EmployeeAutoCompleteData.employees.filter((e) => e.id === changedFields.employeeid);
|
||||||
form.setFieldsValue({
|
form.setFieldsValue({
|
||||||
@@ -182,6 +182,7 @@ export function TimeTicketModalContainer({ timeTicketModal, toggleModalVisible,
|
|||||||
</Space>
|
</Space>
|
||||||
}
|
}
|
||||||
destroyOnClose
|
destroyOnClose
|
||||||
|
id="time-ticket-modal"
|
||||||
>
|
>
|
||||||
<Form
|
<Form
|
||||||
onFinish={handleFinish}
|
onFinish={handleFinish}
|
||||||
|
|||||||
@@ -35,6 +35,30 @@ export const GET_LINE_TICKET_BY_PK = gql`
|
|||||||
lbr_adjustments
|
lbr_adjustments
|
||||||
converted
|
converted
|
||||||
status
|
status
|
||||||
|
employee_body
|
||||||
|
employee_body_rel {
|
||||||
|
id
|
||||||
|
first_name
|
||||||
|
last_name
|
||||||
|
}
|
||||||
|
employee_csr
|
||||||
|
employee_csr_rel {
|
||||||
|
id
|
||||||
|
first_name
|
||||||
|
last_name
|
||||||
|
}
|
||||||
|
employee_prep
|
||||||
|
employee_prep_rel {
|
||||||
|
id
|
||||||
|
first_name
|
||||||
|
last_name
|
||||||
|
}
|
||||||
|
employee_refinish
|
||||||
|
employee_refinish_rel {
|
||||||
|
id
|
||||||
|
first_name
|
||||||
|
last_name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
joblines(where: { jobid: { _eq: $id }, removed: { _eq: false } }) {
|
joblines(where: { jobid: { _eq: $id }, removed: { _eq: false } }) {
|
||||||
id
|
id
|
||||||
|
|||||||
@@ -601,7 +601,8 @@
|
|||||||
"templates": "Templates"
|
"templates": "Templates"
|
||||||
},
|
},
|
||||||
"ss_configuration": {
|
"ss_configuration": {
|
||||||
"dailyhrslimit": "Daily Incoming Hours Limit"
|
"dailyhrslimit": "Daily Incoming Hours Limit",
|
||||||
|
"nobusinessdays": "Include Weekends"
|
||||||
},
|
},
|
||||||
"ssbuckets": {
|
"ssbuckets": {
|
||||||
"color": "Job Color",
|
"color": "Job Color",
|
||||||
|
|||||||
@@ -601,7 +601,8 @@
|
|||||||
"templates": ""
|
"templates": ""
|
||||||
},
|
},
|
||||||
"ss_configuration": {
|
"ss_configuration": {
|
||||||
"dailyhrslimit": ""
|
"dailyhrslimit": "",
|
||||||
|
"nobusinessdays": ""
|
||||||
},
|
},
|
||||||
"ssbuckets": {
|
"ssbuckets": {
|
||||||
"color": "",
|
"color": "",
|
||||||
|
|||||||
@@ -601,7 +601,8 @@
|
|||||||
"templates": ""
|
"templates": ""
|
||||||
},
|
},
|
||||||
"ss_configuration": {
|
"ss_configuration": {
|
||||||
"dailyhrslimit": ""
|
"dailyhrslimit": "",
|
||||||
|
"nobusinessdays": ""
|
||||||
},
|
},
|
||||||
"ssbuckets": {
|
"ssbuckets": {
|
||||||
"color": "",
|
"color": "",
|
||||||
|
|||||||
Reference in New Issue
Block a user