zip_post
false
diff --git a/client/src/components/form-date-picker/form-date-picker.component.jsx b/client/src/components/form-date-picker/form-date-picker.component.jsx
index 479cd8bf6..f37b3c6d1 100644
--- a/client/src/components/form-date-picker/form-date-picker.component.jsx
+++ b/client/src/components/form-date-picker/form-date-picker.component.jsx
@@ -26,6 +26,7 @@ const FormDatePicker = ({ value, onChange, onBlur, ...restProps }, ref) => {
value={value ? moment(value) : null}
onChange={handleChange}
format={dateFormat}
+ onBlur={onBlur}
{...restProps}
/>
diff --git a/client/src/components/form-date-time-picker/form-date-time-picker.component.jsx b/client/src/components/form-date-time-picker/form-date-time-picker.component.jsx
index 37faa4ad8..826e3a6a3 100644
--- a/client/src/components/form-date-time-picker/form-date-time-picker.component.jsx
+++ b/client/src/components/form-date-time-picker/form-date-time-picker.component.jsx
@@ -15,13 +15,14 @@ const DateTimePicker = ({ value, onChange, onBlur }, ref) => {
return (
-
+
diff --git a/client/src/components/schedule-job-modal/schedule-job-modal.component.jsx b/client/src/components/schedule-job-modal/schedule-job-modal.component.jsx
index 7404b81c7..7d45c1ac8 100644
--- a/client/src/components/schedule-job-modal/schedule-job-modal.component.jsx
+++ b/client/src/components/schedule-job-modal/schedule-job-modal.component.jsx
@@ -1,29 +1,43 @@
-import { Button, Checkbox, Col, Row } from "antd";
+import { Button, Col, Form, Row, Switch } from "antd";
import axios from "axios";
import moment from "moment";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
+import { connect } from "react-redux";
+import { createStructuredSelector } from "reselect";
+import { selectBodyshop } from "../../redux/user/user.selectors";
import { DateFormatter } from "../../utils/DateFormatter";
import DateTimePicker from "../form-date-time-picker/form-date-time-picker.component";
import EmailInput from "../form-items-formatted/email-form-item.component";
+import LayoutFormRow from "../layout-form-row/layout-form-row.component";
import ScheduleDayViewContainer from "../schedule-day-view/schedule-day-view.container";
import ScheduleExistingAppointmentsList from "../schedule-existing-appointments-list/schedule-existing-appointments-list.component";
-export default function ScheduleJobModalComponent({
- jobId,
+const mapStateToProps = createStructuredSelector({
+ bodyshop: selectBodyshop,
+});
+const mapDispatchToProps = (dispatch) => ({
+ //setUserLanguage: language => dispatch(setUserLanguage(language))
+});
+
+export function ScheduleJobModalComponent({
+ bodyshop,
+ form,
existingAppointments,
- appData,
- setAppData,
+ lbrHrsData,
+ jobId,
}) {
const { t } = useTranslation();
const [loading, setLoading] = useState(false);
+ const [smartOptions, setSmartOptions] = useState([]);
+
const handleAuto = async () => {
setLoading(true);
try {
const response = await axios.post("/scheduling/job", {
- jobId: "661dd1d5-bf06-426f-8bd2-bd9e41de8eb1",
+ jobId: jobId,
});
- setAppData({ ...appData, smartDates: response.data });
+ if (response.data) setSmartOptions(response.data);
} catch (error) {
console.log("error", error, error.message);
} finally {
@@ -34,60 +48,100 @@ export default function ScheduleJobModalComponent({
//TODO Existing appointments list only refreshes sometimes after modal close. May have to do with the container class.
return (
-
-
- {t("appointments.fields.time")}
- {
- setAppData({ ...appData, start: e });
- }}
- />
+
+
+
+ {
+ const values = form.getFieldsValue();
+ if (lbrHrsData) {
+ const totalHours =
+ 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)
+ form.setFieldsValue({
+ scheduled_completion: moment(values.start).businessAdd(
+ totalHours / bodyshop.target_touchtime,
+ "days"
+ ),
+ });
+ }
+ }}
+ />
+
-
-
- {appData.smartDates.map((d, idx) => (
-
- ))}
-
-
+
+ {smartOptions.map((d, idx) => (
+
+ ))}
+
+
+
+
+
+
+
+
+
+
+
+
+
{t("appointments.labels.history")}
-
-
- setAppData({ ...appData, notifyCustomer: e.target.checked })
- }
- >
- {t("jobs.labels.appointmentconfirmation")}
-
- setAppData({ ...appData, email: e.target.value })}
- />
-
-
-
-
+
+
+ {() => {
+ const values = form.getFieldsValue();
+
+ return (
+
+
+
+ );
+ }}
+
);
}
+export default connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(ScheduleJobModalComponent);
diff --git a/client/src/components/schedule-job-modal/schedule-job-modal.container.jsx b/client/src/components/schedule-job-modal/schedule-job-modal.container.jsx
index ac7557689..c929fcd86 100644
--- a/client/src/components/schedule-job-modal/schedule-job-modal.container.jsx
+++ b/client/src/components/schedule-job-modal/schedule-job-modal.container.jsx
@@ -1,23 +1,24 @@
-import React, { useState, useEffect } from "react";
-import ScheduleJobModalComponent from "./schedule-job-modal.component";
import { useMutation, useQuery } from "@apollo/react-hooks";
-import {
- INSERT_APPOINTMENT,
- CANCEL_APPOINTMENT_BY_ID,
- QUERY_APPOINTMENTS_BY_JOBID,
-} from "../../graphql/appointments.queries";
-import moment from "moment";
-import { notification, Modal } from "antd";
+//import moment from "moment";
+import { Form, Modal, notification } from "antd";
+import moment from "moment-business-days";
+import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
-import { UPDATE_JOBS } from "../../graphql/jobs.queries";
-import { setEmailOptions } from "../../redux/email/email.actions";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
-import { selectBodyshop } from "../../redux/user/user.selectors";
-import { selectSchedule } from "../../redux/modals/modals.selectors";
-import { toggleModalVisible } from "../../redux/modals/modals.actions";
-import { TemplateList } from "../../utils/TemplateConstants";
import { logImEXEvent } from "../../firebase/firebase.utils";
+import {
+ CANCEL_APPOINTMENT_BY_ID,
+ INSERT_APPOINTMENT,
+ QUERY_APPOINTMENTS_BY_JOBID,
+} from "../../graphql/appointments.queries";
+import { QUERY_LBR_HRS_BY_PK, UPDATE_JOBS } from "../../graphql/jobs.queries";
+import { setEmailOptions } from "../../redux/email/email.actions";
+import { toggleModalVisible } from "../../redux/modals/modals.actions";
+import { selectSchedule } from "../../redux/modals/modals.selectors";
+import { selectBodyshop } from "../../redux/user/user.selectors";
+import { TemplateList } from "../../utils/TemplateConstants";
+import ScheduleJobModalComponent from "./schedule-job-modal.component";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
@@ -36,26 +37,23 @@ export function ScheduleJobModalContainer({
}) {
const { visible, context, actions } = scheduleModal;
const { jobId, job, previousEvent } = context;
+
const { refetch } = actions;
- const [loading, setLoading] = useState(false);
- const [appData, setAppData] = useState({
- notifyCustomer: !!(job && job.ownr_ea),
- email: (job && job.ownr_ea) || "",
- start: null,
- smartDates: [],
+ const [form] = Form.useForm();
+
+ const { data: lbrHrsData } = useQuery(QUERY_LBR_HRS_BY_PK, {
+ variables: { id: job && job.id },
+ skip: !job || !job.id,
});
+
+ const [loading, setLoading] = useState(false);
const [cancelAppointment] = useMutation(CANCEL_APPOINTMENT_BY_ID);
const [insertAppointment] = useMutation(INSERT_APPOINTMENT);
const [updateJobStatus] = useMutation(UPDATE_JOBS);
useEffect(() => {
- setAppData({
- notifyCustomer: !!(job && job.ownr_ea),
- email: (job && job.ownr_ea) || "",
- start: null,
- smartDates: [],
- });
- }, [job, setAppData]);
+ form.resetFields();
+ }, [job, form]);
const { t } = useTranslation();
@@ -65,7 +63,7 @@ export function ScheduleJobModalContainer({
skip: !visible || !!!jobId,
});
- const handleOk = async () => {
+ const handleFinish = async (values) => {
logImEXEvent("schedule_new_appointment");
setLoading(true);
@@ -90,11 +88,10 @@ export function ScheduleJobModalContainer({
const appt = await insertAppointment({
variables: {
app: {
- //...appData,
jobid: jobId,
bodyshopid: bodyshop.id,
- start: moment(appData.start),
- end: moment(appData.start).add(bodyshop.appt_length || 60, "minutes"),
+ start: moment(values.start),
+ end: moment(values.start).add(bodyshop.appt_length || 60, "minutes"),
},
},
});
@@ -117,7 +114,8 @@ export function ScheduleJobModalContainer({
fields: {
status: bodyshop.md_ro_statuses.default_scheduled,
date_scheduled: new Date(),
- scheduled_in: appData.start,
+ scheduled_in: values.start,
+ scheduled_completion: values.scheduled_completion,
},
},
});
@@ -133,10 +131,10 @@ export function ScheduleJobModalContainer({
}
setLoading(false);
toggleModalVisible();
- if (appData.notifyCustomer) {
+ if (values.notifyCustomer) {
setEmailOptions({
messageOptions: {
- to: [appData.email],
+ to: [values.email],
replyTo: bodyshop.email,
},
template: {
@@ -154,21 +152,34 @@ export function ScheduleJobModalContainer({
toggleModalVisible()}
- onOk={handleOk}
+ onOk={() => form.submit()}
width={"90%"}
maskClosable={false}
destroyOnClose
+ forceRender
okButtonProps={{
- disabled: appData.start ? false : true,
loading: loading,
}}
>
-
+
);
}
diff --git a/client/src/components/shop-info/shop-info.component.jsx b/client/src/components/shop-info/shop-info.component.jsx
index ab0112eca..d2a0c8471 100644
--- a/client/src/components/shop-info/shop-info.component.jsx
+++ b/client/src/components/shop-info/shop-info.component.jsx
@@ -27,25 +27,65 @@ export default function ShopInfoComponent({ form, saveLoading }) {
const { t } = useTranslation();
return (
-