+ // {data.timetickets.length > 0 ? (
+ //
+ //
+ // {t("timetickets.labels.alreadyclockedon")}
+ //
+ //
(
+ //
+ //
+ // {`${
+ // ticket.job.ro_number || t("general.labels.na")
+ // } ${OwnerNameDisplayFunction(ticket.job)}`}
+ //
+ // }
+ // actions={[
+ // ,
+ // ]}
+ // >
+ //
+ // {`
+ // ${ticket.job.v_model_yr || ""} ${
+ // ticket.job.v_make_desc || ""
+ // } ${ticket.job.v_model_desc || ""}`}
+ //
+ //
+ // {ticket.clockon}
+ //
+ //
+ // {ticket.cost_center === "timetickets.labels.shift"
+ // ? t(ticket.cost_center)
+ // : ticket.cost_center}
+ //
+ //
+ //
+ // )}
+ // >
+ //
+ // ) : null}
+ //
+ );
+}
+
+export default connect(mapStateToProps, null)(EmployeeClockedInList);
diff --git a/components/time-ticket/screen-time-ticket-clockoff.component.jsx b/components/time-ticket/screen-time-ticket-clockoff.component.jsx
new file mode 100644
index 0000000..ad3c424
--- /dev/null
+++ b/components/time-ticket/screen-time-ticket-clockoff.component.jsx
@@ -0,0 +1,266 @@
+import { Formik } from "formik";
+import React, { useState, useRef, useCallback } from "react";
+import { StyleSheet, Text, View, ScrollView, FlatList } from "react-native";
+import { useTranslation } from "react-i18next";
+import { connect } from "react-redux";
+import { createStructuredSelector } from "reselect";
+import {
+ Button,
+ TextInput,
+ Card,
+} from "react-native-paper";
+import CostCenterSelect from "../Selects/select-cost-center";
+import {
+ selectCurrentEmployee,
+ selectRates,
+} from "../../redux/employee/employee.selectors";
+import {
+ selectBodyshop,
+ selectRestrictClaimableHoursFlag,
+} from "../../redux/user/user.selectors";
+import LaborAllocationsTable from "../labor-allocations-table/labor-allocations-table.component";
+import { UPDATE_TIME_TICKET } from "../../graphql/timetickets.queries";
+import { useMutation } from "@apollo/client";
+import { selectCurrentTmTicketJobId } from "../../redux/app/app.selectors";
+import ErrorDisplay from "../error-display/error-display.component";
+import { timeTicketClockOutStart } from "../../redux/timetickets/timetickets.actions";
+import axios from "axios";
+import { useNavigation } from "@react-navigation/native";
+import styles from "../styles";
+
+import { RefreshControl } from "react-native";
+
+const mapStateToProps = createStructuredSelector({
+ currentEmployee: selectCurrentEmployee,
+ currentRatesNCostCenters: selectRates,
+ currentBodyshop: selectBodyshop,
+ currentTmTicketJobId: selectCurrentTmTicketJobId,
+ currentRestrictClaimableHoursFlag: selectRestrictClaimableHoursFlag,
+});
+const mapDispatchToProps = (dispatch) => ({
+ timeTicketClockOutStart,
+});
+
+export function TimeTicketClockOff({
+ currentEmployee,
+ currentRatesNCostCenters,
+ currentBodyshop,
+ currentTmTicketJobId,
+ currentRestrictClaimableHoursFlag,
+ route,
+}) {
+ const costCenterDiff = useRef(0);
+ const setCostCenterDiff = (value) => {
+ countRef.current = val;
+ };
+ const navigation = useNavigation();
+ const { timeTicketId } = route.params;
+ const { t } = useTranslation();
+ const [loadingClockOut, setLoadingClockOut] = useState(false);
+ const [loading, setLoading] = useState(false);
+ const [error, setError] = useState(null);
+ const [currentSCC, setCurrentSCC] = useState(null);
+
+ const [updateTimeticket] = useMutation(UPDATE_TIME_TICKET, {
+ refetchQueries: ["QUERY_ACTIVE_TIME_TICKETS"],
+ });
+
+ const handleFinish = async (values) => {
+ if (
+ !!values.actualhours &&
+ !!values.productivehours &&
+ !!currentSCC?.value
+ ) {
+ if (isNaN(values.actualhours) | isNaN(values.productivehours)) {
+ setLoadingClockOut(false);
+ setError({ message: t("timeticketclockoff.errors.nan") });
+ return;
+ }
+ setError(null);
+ } else {
+ setLoadingClockOut(false);
+ setError({ message: t("timeticketclockoff.errors.missingvalues") });
+ return;
+ }
+ if (!!currentRestrictClaimableHoursFlag) {
+ if (values.productivehours > costCenterDiff.current) {
+ setLoadingClockOut(false);
+ setError({
+ message: t("timeticketclockoff.errors.hoursenteredmorethanavailable"),
+ });
+ return;
+ }
+ }
+
+ const tempcallobj = {
+ variables: {
+ timeticketId: timeTicketId,
+ timeticket: {
+ actualhrs: values?.actualhours,
+ ciecacode:
+ currentBodyshop?.cdk_dealerid || currentBodyshop?.pbs_serialnumber
+ ? currentSCC?.value
+ : Object.keys(
+ currentBodyshop.md_responsibility_centers.defaults.costs
+ ).find((key) => {
+ return (
+ currentBodyshop.md_responsibility_centers.defaults.costs[
+ key
+ ] === currentSCC?.value
+ );
+ }),
+ clockoff: (await axios.post("/utils/time")).data,
+ cost_center: currentSCC?.value,
+ flat_rate:
+ currentEmployee &&
+ currentEmployee.technician &&
+ currentEmployee.technician?.flat_rate,
+ productivehrs: values?.productivehours,
+ rate:
+ currentRatesNCostCenters &&
+ currentSCC?.value &&
+ currentRatesNCostCenters.filter(
+ (r) => r.cost_center === currentSCC?.value
+ )[0]?.rate,
+ },
+ },
+ };
+
+ setLoadingClockOut(true);
+ const result = await updateTimeticket(tempcallobj);
+ setLoadingClockOut(false);
+ if (!!result.errors) {
+ setError(JSON.stringify(result.errors));
+ } else {
+ navigation.goBack();
+ }
+ };
+
+ const onRefresh = useCallback(() => {
+ setLoading(true);
+ // refetch();
+ setTimeout(() => {
+ setLoading(false);
+ }, 500);
+ }, []);
+
+ return (
+