Removed all todos from code and created corresponding JIRA tickets.

This commit is contained in:
Patrick Fic
2021-01-05 14:39:27 -08:00
parent 3e3b2780e3
commit af8ccfaff5
35 changed files with 65 additions and 143 deletions

View File

@@ -48,7 +48,6 @@ export function BillFormComponent({
setDiscount(opt.discount);
};
//TODO: Test this further. Required to set discount when viewing an invoice.
useEffect(() => {
if (form.getFieldValue("vendorid") && vendorAutoCompleteOptions) {
const vendorId = form.getFieldValue("vendorid");

View File

@@ -11,6 +11,7 @@ export const CalculateBillTotal = (invoice) => {
local_tax_rate,
state_tax_rate,
} = invoice;
//TODO Determine why this recalculates so many times.
let subtotal = Dinero({ amount: 0 });
let federalTax = Dinero({ amount: 0 });

View File

@@ -120,7 +120,7 @@ export function ContractConvertToRo({ bodyshop, currentUser, contract }) {
state_tax_rate: bodyshop.bill_tax_rates.state_tax_rate / 100,
local_tax_rate: bodyshop.bill_tax_rates.local_tax_rate / 100,
clm_no: `${contract.job.clm_no}-CC`,
clm_total: 1234, //TODO
clm_total: 1234,
ownr_fn: contract.job.owner.ownr_fn,
ownr_ln: contract.job.owner.ownr_ln,
ownr_co_nm: contract.job.owner.ownr_co_nm,

View File

@@ -20,7 +20,6 @@
// .add(otherTotals.rates.subtotal)
// .add(Dinero({ amount: (job.towing_payable || 0) * 100 }))
// .add(Dinero({ amount: (job.storage_payable || 0) * 100 }));
// //TODO Levies should be included??
// const statePartsTax = job.joblines.reduce((acc, val) => {
// if (!!!val.tax_part) return acc;
@@ -227,7 +226,7 @@
// subtotal: acc.sublets.subtotal.add(
// Dinero({ amount: Math.round(value.act_price * 100) })
// ),
// //TODO Add Adjustments in
//
// },
// };
// // case "PAA":
@@ -268,7 +267,7 @@
// value.part_qty
// )
// ),
// //TODO Add Adjustments in
//
// },
// };
// // default:
@@ -305,7 +304,7 @@
// function CalculateCustPayable(job) {
// let ret = {
// deductible: Dinero({ amount: (job.ded_amt || 0) * 100 }) || 0,
// federal_tax: Dinero({ amount: (job.federal_tax_payable || 0) * 100 }), //TODO Should this be renamed to make it more clear this is customer GST?
// federal_tax: Dinero({ amount: (job.federal_tax_payable || 0) * 100 }),
// other_customer_amount: Dinero({
// amount: (job.other_amount_payable || 0) * 100,
// }),

View File

@@ -193,14 +193,6 @@ export function JobsCreateJobsInfo({ bodyshop, form, selected }) {
</Select>
</Form.Item>
</LayoutFormRow>
TODO How to handle different taxes and marking them as exempt?
{
// <Form.Item label={t("jobs.fields.exempt")}>
// {getFieldDecorator("exempt", {
// initialValue: job.exempt
// })(<Input name='exempt' />)}
// </Form.Item>
}
</Collapse.Panel>
<Collapse.Panel
key="financial"

View File

@@ -96,7 +96,8 @@ export function JobsDetailHeaderCsi({
},
});
if (e.key === "text") console.log("TODO Handling texting"); //TODO Implement texting.
if (e.key === "text") {
}
} else {
notification["error"]({
message: t("csi.errors.notconfigured"),

View File

@@ -27,9 +27,6 @@ export default function OwnerTagPopoverComponent({ job }) {
</Descriptions.Item>
<Descriptions.Item key="4" label={t("owners.fields.ownr_ea")}>
{job.ownr_ea || ""}
{
//TODO Should add an email formatter.
}
</Descriptions.Item>
</Descriptions>
</Col>
@@ -56,9 +53,6 @@ export default function OwnerTagPopoverComponent({ job }) {
</Descriptions.Item>
<Descriptions.Item key="4" label={t("owners.fields.ownr_ea")}>
{job.owner.ownr_ea || ""}
{
//TODO Should add an email formatter.
}
</Descriptions.Item>
</Descriptions>
</Col>

View File

@@ -35,16 +35,16 @@ export function PrintCenterItemComponent({
displayTemplateInWindow(html);
};
if (disabled) return <li className='print-center-item'>{item.title} </li>;
if (disabled) return <li className="print-center-item">{item.title} </li>;
return (
<li className='print-center-item'>
<li className="print-center-item">
{item.title}
<PrinterOutlined onClick={renderToNewWindow} />
<MailOutlined
onClick={() => {
setEmailOptions({
messageOptions: {
Subject: "//TODO FIX ME",
Subject: "",
},
template: {
name: item.key,

View File

@@ -8,15 +8,12 @@ import { alphaSort } from "../../utils/sorters";
import ProductionSubletsManageComponent from "../production-sublets-manage/production-sublets-manage.component";
import ProductionListColumnAlert from "./production-list-columns.alert.component";
import ProductionListColumnBodyPriority from "./production-list-columns.bodypriority.component";
import ProductionListDate from "./production-list-columns.date.component";
import ProductionListColumnPaintPriority from "./production-list-columns.paintpriority.component";
import ProductionListColumnNote from "./production-list-columns.productionnote.component";
import ProductionListDate from "./production-list-columns.date.component";
import ProductionListColumnStatus from "./production-list-columns.status.component";
import ProductionlistColumnTouchTime from "./prodution-list-columns.touchtime.component";
const OneCalendarDay = 60 * 60 * 24 * 1000;
const Now = new Date();
const r = [
{
title: i18n.t("jobs.actions.viewdetail"),

View File

@@ -1,19 +1,15 @@
import { ExclamationCircleFilled } from "@ant-design/icons";
import { DatePicker, Dropdown, Menu } from "antd";
import React from "react";
import { useTranslation } from "react-i18next";
import { useMutation } from "@apollo/react-hooks";
import { UPDATE_JOB } from "../../graphql/jobs.queries";
import { logImEXEvent } from "../../firebase/firebase.utils";
import { DateFormatter } from "../../utils/DateFormatter";
import { DatePicker, Dropdown } from "antd";
import moment from "moment";
import React from "react";
import { logImEXEvent } from "../../firebase/firebase.utils";
import { UPDATE_JOB } from "../../graphql/jobs.queries";
import { DateFormatter } from "../../utils/DateFormatter";
const OneCalendarDay = 60 * 60 * 24 * 1000;
const Now = new Date();
export default function ProductionListDate({ record, field }) {
const { t } = useTranslation();
const [updateAlert] = useMutation(UPDATE_JOB);
const handleChange = (date) => {

View File

@@ -1,7 +1,7 @@
import { SyncOutlined } from "@ant-design/icons";
import { Button, Dropdown, Input, Menu, Table } from "antd";
import React, { useState } from "react";
import ReactDragListView from "react-drag-listview"; //TODO Is there a better way? This library is too big.
import ReactDragListView from "react-drag-listview";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
@@ -170,14 +170,14 @@ export function ProductionListTable({
loading={loading}
dataSource={dataSource}
onChange={handleTableChange}
rowClassName={(record, index) => {
// const classes = []; //TODO What could be good usage here?
// if (!!record.scheduled_completion) {
// if (new Date(record.scheduled_completion) - Now < OneCalendarDay)
// classes.push("production-completion-1");
// }
// return classes.join(" ");
}}
// rowClassName={(record, index) => {
// // const classes = [];
// // if (!!record.scheduled_completion) {
// // if (new Date(record.scheduled_completion) - Now < OneCalendarDay)
// // classes.push("production-completion-1");
// // }
// // return classes.join(" ");
// }}
/>
</ReactDragListView.DragColumn>
</div>

View File

@@ -78,7 +78,7 @@ export function ScheduleCalendarWrapperComponent({
bodyshop.schedule_start_time
? new Date(bodyshop.schedule_start_time)
: new Date("2020-01-01T06:00:00")
} //TODO Read from business settings.
}
max={
bodyshop.schedule_end_time
? new Date(bodyshop.schedule_end_time)

View File

@@ -62,7 +62,6 @@ export function ScheduleJobModalComponent({
}
};
//TODO Existing appointments list only refreshes sometimes after modal close. May have to do with the container class.
return (
<Row gutter={[32, 32]}>
<Col span={12}>

View File

@@ -130,9 +130,7 @@ export function ShopEmployeesFormComponent({
>
<FormDatePicker />
</Form.Item>
{
//TODO Make this a picklist.
}
<Form.Item
label={t("employees.fields.cost_center")}
name="cost_center"

View File

@@ -1,9 +1,10 @@
import { useMutation, useQuery } from "@apollo/react-hooks";
import { Form, notification } from "antd";
import React, { useState } from "react";
import { useMutation, useQuery } from "@apollo/react-hooks";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { logImEXEvent } from "../../firebase/firebase.utils";
import {
DELETE_EMPLOYEE,
INSERT_EMPLOYEES,
@@ -13,7 +14,6 @@ import {
import { selectBodyshop } from "../../redux/user/user.selectors";
import AlertComponent from "../alert/alert.component";
import ShopEmployeeComponent from "./shop-employees.component";
import { logImEXEvent } from "../../firebase/firebase.utils";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
@@ -38,7 +38,7 @@ function ShopEmployeesContainer({ bodyshop }) {
notification["success"]({
message: t("employees.successes.delete"),
});
//TODO Better way to reset the field decorators?
employeeState[1](null);
refetch().then((r) => form.resetFields());
})
@@ -63,7 +63,7 @@ function ShopEmployeesContainer({ bodyshop }) {
notification["success"]({
message: t("employees.successes.save"),
});
//TODO Better way to reset the field decorators?
employeeState[1](null);
refetch().then((r) => form.resetFields());
})
@@ -84,7 +84,6 @@ function ShopEmployeesContainer({ bodyshop }) {
notification["success"]({
message: t("employees.successes.save"),
});
//TODO Better way to reset the field decorators?
employeeState[1](null);
refetch().catch((error) => {
notification["error"]({

View File

@@ -12,7 +12,7 @@ const SelectorDiv = styled.div`
width: 200px;
}
`;
//TODO Fix up styles.
export default function ShopInfoIntakeChecklistComponent({ form }) {
const { t } = useTranslation();

View File

@@ -3,7 +3,7 @@ import { Button, Form, Input, Select, Row, Col } from "antd";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
//TODO Fix up styles.
export default function ShopInfoOrderStatusComponent({ form }) {
const { t } = useTranslation();

View File

@@ -2,7 +2,6 @@ import { Form, InputNumber } from "antd";
import React from "react";
import { useTranslation } from "react-i18next";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
//TODO Fix up styles.
export default function ShopInfoRbacComponent({ form }) {
const { t } = useTranslation();

View File

@@ -1,10 +1,10 @@
import { DeleteFilled } from "@ant-design/icons";
import { Button, Form, Input, Select, InputNumber } from "antd";
import { Button, Form, Input, InputNumber, Select } from "antd";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import styled from "styled-components";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
//TODO Fix up styles.
const SelectorDiv = styled.div`
.ant-form-item .ant-select {
width: 125px;

View File

@@ -1,5 +1,5 @@
import { DeleteFilled } from "@ant-design/icons";
import { Button, Form, Input, Select, Row, Col } from "antd";
import { Button, Col, Form, Input, Row, Select } from "antd";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import styled from "styled-components";
@@ -9,7 +9,7 @@ const SelectorDiv = styled.div`
width: 200px;
}
`;
//TODO Fix up styles.
export default function ShopInfoROStatusComponent({ form }) {
const { t } = useTranslation();

View File

@@ -12,9 +12,9 @@ import {
import React from "react";
import { useTranslation } from "react-i18next";
import ColorpickerFormItemComponent from "../form-items-formatted/colorpicker-form-item.component";
//TODO Fix up styles.
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
export default function ShopInfoSchedulingComponent({ form }) {
const { t } = useTranslation();

View File

@@ -4,7 +4,6 @@ import React from "react";
import { useTranslation } from "react-i18next";
import { TemplateList } from "../../utils/TemplateConstants";
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
//TODO Fix up styles.
export default function ShopInfoSpeedPrint({ bodyshop, form }) {
const { t } = useTranslation();

View File

@@ -2,13 +2,11 @@ import { LockOutlined, UserOutlined } from "@ant-design/icons";
import { Button, Form, Input, Typography } from "antd";
import queryString from "query-string";
import React from "react";
import { useApolloClient } from "react-apollo";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { Link, Redirect, useLocation } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import ImEXOnlineLogo from "../../assets/logo192.png";
import { UPSERT_USER } from "../../graphql/user.queries";
import {
emailSignInStart,
sendPasswordReset,
@@ -38,7 +36,7 @@ export function SignInComponent({
sendPasswordReset,
}) {
const { redirect } = queryString.parse(useLocation().search);
const apolloClient = useApolloClient();
const { t } = useTranslation();
const handleFinish = (values) => {
const { email, password } = values;
@@ -46,22 +44,6 @@ export function SignInComponent({
};
const [form] = Form.useForm();
//TODO - may be able to run this only on new user creation.
if (currentUser.authorized === true) {
apolloClient
.mutate({
mutation: UPSERT_USER,
variables: {
authEmail: currentUser.email,
authToken: currentUser.uid,
},
})
.then()
.catch((error) => {
console.log("User login upsert error.", error);
});
}
if (currentUser.authorized === true)
return <Redirect to={redirect || "/manage"} />;

View File

@@ -136,7 +136,7 @@ export default function VehicleDetailFormComponent({ form, loading }) {
<FormDatePicker />
</Form.Item>
{
//TODO Add handling for paint code json
//Removed as a part of IO-446.
//No values have been captured in this field as of yet.
// <Form.Item

View File

@@ -29,7 +29,7 @@ function VehicleDetailFormContainer({ vehicle, refetch }) {
notification["success"]({
message: t("vehicles.successes.save"),
});
//TODO Better way to reset the field decorators?
if (refetch) await refetch();
form.resetFields();
form.resetFields();

View File

@@ -46,7 +46,7 @@ function VendorsFormContainer({ refetch, bodyshop }) {
notification["success"]({
message: t("vendors.successes.deleted"),
});
//TODO Better way to reset the field decorators?
if (refetch)
refetch().then((r) => {
form.resetFields();
@@ -74,7 +74,7 @@ function VendorsFormContainer({ refetch, bodyshop }) {
notification["success"]({
message: t("vendors.successes.saved"),
});
//TODO Better way to reset the field decorators?
if (refetch)
refetch().then(() => {
form.resetFields();
@@ -99,7 +99,7 @@ function VendorsFormContainer({ refetch, bodyshop }) {
notification["success"]({
message: t("vendors.successes.saved"),
});
//TODO Better way to reset the field decorators?
if (refetch) refetch();
form.resetFields();
setFormLoading(false);

View File

@@ -58,7 +58,6 @@ export default function VendorsListComponent({
setState({ ...state, filteredInfo: filters, sortedInfo: sorter });
};
//TODO Implement search
return (
<Table
loading={loading}
@@ -71,10 +70,10 @@ export default function VendorsListComponent({
</div>
);
}}
size='small'
size="small"
pagination={{ position: "top" }}
columns={columns.map((item) => ({ ...item }))}
rowKey='id'
rowKey="id"
onChange={handleTableChange}
dataSource={vendors}
rowSelection={{

View File

@@ -837,7 +837,7 @@ export const SEARCH_FOR_JOBS = gql`
}
}
`;
//TODO Ensure this is always up to date.
export const QUERY_ALL_JOB_FIELDS = gql`
query QUERY_ALL_JOB_FIELDS($id: uuid!) {
jobs_by_pk(id: $id) {

View File

@@ -1,19 +1,19 @@
import React, { useState, useEffect } from "react";
import JobsCreateComponent from "./jobs-create.component";
import { useLazyQuery, useMutation } from "@apollo/react-hooks";
import { Form, notification } from "antd";
import JobCreateContext from "./jobs-create.context";
import { useMutation, useLazyQuery } from "@apollo/react-hooks";
import { INSERT_NEW_JOB } from "../../graphql/jobs.queries";
import { QUERY_OWNER_FOR_JOB_CREATION } from "../../graphql/owners.queries";
import React, { useEffect, 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 { useTranslation } from "react-i18next";
import RbacWrapper from "../../components/rbac-wrapper/rbac-wrapper.component";
import { INSERT_NEW_JOB } from "../../graphql/jobs.queries";
import { QUERY_OWNER_FOR_JOB_CREATION } from "../../graphql/owners.queries";
import {
setBreadcrumbs,
setSelectedHeader,
} from "../../redux/application/application.actions";
import RbacWrapper from "../../components/rbac-wrapper/rbac-wrapper.component";
import { selectBodyshop } from "../../redux/user/user.selectors";
import JobsCreateComponent from "./jobs-create.component";
import JobCreateContext from "./jobs-create.context";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
@@ -97,8 +97,7 @@ function JobsCreateContainer({ bodyshop, setBreadcrumbs, setSelectedHeader }) {
shopid: bodyshop.id,
}
);
//TODO Logic to ensure the owner is actually fetched.
console.log("job", job);
let ownerData;
if (!!!job.ownerid) {
ownerData = job.owner.data;

View File

@@ -1,18 +1,18 @@
import axios from "axios";
import phone from "phone";
import { all, call, put, select, takeLatest } from "redux-saga/effects";
import client from "../../utils/GraphQLClient";
import { logImEXEvent } from "../../firebase/firebase.utils";
import {
CONVERSATION_ID_BY_PHONE,
CREATE_CONVERSATION,
CREATE_CONVERSATION
} from "../../graphql/conversations.queries";
import { INSERT_CONVERSATION_TAG } from "../../graphql/job-conversations.queries";
import client from "../../utils/GraphQLClient";
import { selectBodyshop } from "../user/user.selectors";
import {
sendMessageFailure,
sendMessageSuccess,
setSelectedConversation,
setSelectedConversation
} from "./messaging.actions";
import MessagingActionTypes from "./messaging.types";
@@ -73,7 +73,7 @@ export function* openChatByPhone({ payload }) {
},
});
} else {
console.log("ERROR: Multiple conversations found. "); //TODO Graceful handling of this situation
console.log("ERROR: Multiple conversations found. ");
}
} catch (error) {
console.log("Error in sendMessage saga.", error);

View File

@@ -10,6 +10,9 @@ import {
} from "../../firebase/firebase.utils";
import {
checkInstanceId,
sendPasswordResetFailure,
sendPasswordResetSuccess,
setAuthlevel,
setInstanceConflict,
setInstanceId,
setLocalFingerprint,
@@ -19,11 +22,8 @@ import {
signOutSuccess,
unauthorizedUser,
updateUserDetailsSuccess,
sendPasswordResetFailure,
sendPasswordResetSuccess,
validatePasswordResetSuccess,
validatePasswordResetFailure,
setAuthlevel,
validatePasswordResetSuccess,
} from "./user.actions";
import UserActionTypes from "./user.types";
@@ -102,7 +102,6 @@ export function* updateUserDetails(userDetails) {
yield put(updateUserDetailsSuccess(userDetails.payload));
} catch (error) {
//yield put(signOutFailure(error.message));
//TODO error handling
}
}
export function* onSetInstanceId() {
@@ -127,8 +126,6 @@ export function* setInstanceIdSaga({ payload: uid }) {
if (process.env.NODE_ENV === "production") yield put(checkInstanceId(uid));
} catch (error) {
console.log("error", error);
//yield put(signOutFailure(error.message));
//TODO error handling
}
}
@@ -152,7 +149,6 @@ export function* checkInstanceIdSaga({ payload: uid }) {
}
} catch (error) {
console.log("error", error);
//TODO error handling
}
}

View File

@@ -2,30 +2,6 @@ const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp(functions.config().firebase);
// //TODO Move this to an environment parameter.
// const GRAPHQL_ENDPOINT = functions.config().auth.graphql_endpoint;
// const HASURA_SECRET_ADMIN_KEY = functions.config().auth.hasura_secret_admin_key;
// const UPSERT_USER = `
// mutation upsert_user($authEmail: String!, $authToken: String!) {
// insert_users(
// objects: [
// {
// email:$authEmail,
// authid:$authToken
// }
// ],
// on_conflict: {
// constraint: users_pkey,
// update_columns: [authid]
// }
// ) {
// returning {
// authid
// }
// }
// }
// `;
// On sign up.
exports.processSignUp = functions.auth.user().onCreate((user) => {
// Check if user meets role criteria:

View File

@@ -12,7 +12,6 @@ const { Headers } = require("cross-fetch");
global.Headers = global.Headers || Headers;
//TODO May need to use a different client that includes caching of resources.
exports.client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, {
headers: {
"x-hasura-admin-secret": process.env.HASURA_ADMIN_SECRET,

View File

@@ -220,7 +220,6 @@ function CalculateTaxesTotals(job, otherTotals) {
.add(otherTotals.additional)
.add(Dinero({ amount: (job.towing_payable || 0) * 100 }))
.add(Dinero({ amount: (job.storage_payable || 0) * 100 }));
//TODO Levies should be included??
//Potential issue here with Sublet Calculation. Sublets are calculated under labor in Mitchell, but it's done in IO
//Under the parts rates.

View File

@@ -29,7 +29,6 @@ exports.receive = (req, res) => {
phone: phone(req.body.From)[0],
})
.then((response) => {
//TODO Add logic for handling MMS.
let newMessage = {
msid: req.body.SmsMessageSid,
text: req.body.Body,