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); setDiscount(opt.discount);
}; };
//TODO: Test this further. Required to set discount when viewing an invoice.
useEffect(() => { useEffect(() => {
if (form.getFieldValue("vendorid") && vendorAutoCompleteOptions) { if (form.getFieldValue("vendorid") && vendorAutoCompleteOptions) {
const vendorId = form.getFieldValue("vendorid"); const vendorId = form.getFieldValue("vendorid");

View File

@@ -11,6 +11,7 @@ export const CalculateBillTotal = (invoice) => {
local_tax_rate, local_tax_rate,
state_tax_rate, state_tax_rate,
} = invoice; } = invoice;
//TODO Determine why this recalculates so many times. //TODO Determine why this recalculates so many times.
let subtotal = Dinero({ amount: 0 }); let subtotal = Dinero({ amount: 0 });
let federalTax = 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, state_tax_rate: bodyshop.bill_tax_rates.state_tax_rate / 100,
local_tax_rate: bodyshop.bill_tax_rates.local_tax_rate / 100, local_tax_rate: bodyshop.bill_tax_rates.local_tax_rate / 100,
clm_no: `${contract.job.clm_no}-CC`, clm_no: `${contract.job.clm_no}-CC`,
clm_total: 1234, //TODO clm_total: 1234,
ownr_fn: contract.job.owner.ownr_fn, ownr_fn: contract.job.owner.ownr_fn,
ownr_ln: contract.job.owner.ownr_ln, ownr_ln: contract.job.owner.ownr_ln,
ownr_co_nm: contract.job.owner.ownr_co_nm, ownr_co_nm: contract.job.owner.ownr_co_nm,

View File

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

View File

@@ -193,14 +193,6 @@ export function JobsCreateJobsInfo({ bodyshop, form, selected }) {
</Select> </Select>
</Form.Item> </Form.Item>
</LayoutFormRow> </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>
<Collapse.Panel <Collapse.Panel
key="financial" 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 { } else {
notification["error"]({ notification["error"]({
message: t("csi.errors.notconfigured"), message: t("csi.errors.notconfigured"),

View File

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

View File

@@ -35,16 +35,16 @@ export function PrintCenterItemComponent({
displayTemplateInWindow(html); 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 ( return (
<li className='print-center-item'> <li className="print-center-item">
{item.title} {item.title}
<PrinterOutlined onClick={renderToNewWindow} /> <PrinterOutlined onClick={renderToNewWindow} />
<MailOutlined <MailOutlined
onClick={() => { onClick={() => {
setEmailOptions({ setEmailOptions({
messageOptions: { messageOptions: {
Subject: "//TODO FIX ME", Subject: "",
}, },
template: { template: {
name: item.key, 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 ProductionSubletsManageComponent from "../production-sublets-manage/production-sublets-manage.component";
import ProductionListColumnAlert from "./production-list-columns.alert.component"; import ProductionListColumnAlert from "./production-list-columns.alert.component";
import ProductionListColumnBodyPriority from "./production-list-columns.bodypriority.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 ProductionListColumnPaintPriority from "./production-list-columns.paintpriority.component";
import ProductionListColumnNote from "./production-list-columns.productionnote.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 ProductionListColumnStatus from "./production-list-columns.status.component";
import ProductionlistColumnTouchTime from "./prodution-list-columns.touchtime.component"; import ProductionlistColumnTouchTime from "./prodution-list-columns.touchtime.component";
const OneCalendarDay = 60 * 60 * 24 * 1000;
const Now = new Date();
const r = [ const r = [
{ {
title: i18n.t("jobs.actions.viewdetail"), 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 { useMutation } from "@apollo/react-hooks";
import { UPDATE_JOB } from "../../graphql/jobs.queries"; import { DatePicker, Dropdown } from "antd";
import { logImEXEvent } from "../../firebase/firebase.utils";
import { DateFormatter } from "../../utils/DateFormatter";
import moment from "moment"; 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 OneCalendarDay = 60 * 60 * 24 * 1000;
const Now = new Date(); const Now = new Date();
export default function ProductionListDate({ record, field }) { export default function ProductionListDate({ record, field }) {
const { t } = useTranslation();
const [updateAlert] = useMutation(UPDATE_JOB); const [updateAlert] = useMutation(UPDATE_JOB);
const handleChange = (date) => { const handleChange = (date) => {

View File

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

View File

@@ -78,7 +78,7 @@ export function ScheduleCalendarWrapperComponent({
bodyshop.schedule_start_time bodyshop.schedule_start_time
? new Date(bodyshop.schedule_start_time) ? new Date(bodyshop.schedule_start_time)
: new Date("2020-01-01T06:00:00") : new Date("2020-01-01T06:00:00")
} //TODO Read from business settings. }
max={ max={
bodyshop.schedule_end_time bodyshop.schedule_end_time
? new Date(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 ( return (
<Row gutter={[32, 32]}> <Row gutter={[32, 32]}>
<Col span={12}> <Col span={12}>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,10 +1,10 @@
import { DeleteFilled } from "@ant-design/icons"; 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 React, { useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import styled from "styled-components"; import styled from "styled-components";
import LayoutFormRow from "../layout-form-row/layout-form-row.component"; import LayoutFormRow from "../layout-form-row/layout-form-row.component";
//TODO Fix up styles.
const SelectorDiv = styled.div` const SelectorDiv = styled.div`
.ant-form-item .ant-select { .ant-form-item .ant-select {
width: 125px; width: 125px;

View File

@@ -1,5 +1,5 @@
import { DeleteFilled } from "@ant-design/icons"; 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 React, { useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import styled from "styled-components"; import styled from "styled-components";
@@ -9,7 +9,7 @@ const SelectorDiv = styled.div`
width: 200px; width: 200px;
} }
`; `;
//TODO Fix up styles.
export default function ShopInfoROStatusComponent({ form }) { export default function ShopInfoROStatusComponent({ form }) {
const { t } = useTranslation(); const { t } = useTranslation();

View File

@@ -12,9 +12,9 @@ import {
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import ColorpickerFormItemComponent from "../form-items-formatted/colorpicker-form-item.component"; 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 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";
export default function ShopInfoSchedulingComponent({ form }) { export default function ShopInfoSchedulingComponent({ form }) {
const { t } = useTranslation(); const { t } = useTranslation();

View File

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

View File

@@ -2,13 +2,11 @@ import { LockOutlined, UserOutlined } from "@ant-design/icons";
import { Button, Form, Input, Typography } from "antd"; import { Button, Form, Input, Typography } from "antd";
import queryString from "query-string"; import queryString from "query-string";
import React from "react"; import React from "react";
import { useApolloClient } from "react-apollo";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { Link, Redirect, useLocation } from "react-router-dom"; import { Link, Redirect, useLocation } from "react-router-dom";
import { createStructuredSelector } from "reselect"; import { createStructuredSelector } from "reselect";
import ImEXOnlineLogo from "../../assets/logo192.png"; import ImEXOnlineLogo from "../../assets/logo192.png";
import { UPSERT_USER } from "../../graphql/user.queries";
import { import {
emailSignInStart, emailSignInStart,
sendPasswordReset, sendPasswordReset,
@@ -38,7 +36,7 @@ export function SignInComponent({
sendPasswordReset, sendPasswordReset,
}) { }) {
const { redirect } = queryString.parse(useLocation().search); const { redirect } = queryString.parse(useLocation().search);
const apolloClient = useApolloClient();
const { t } = useTranslation(); const { t } = useTranslation();
const handleFinish = (values) => { const handleFinish = (values) => {
const { email, password } = values; const { email, password } = values;
@@ -46,22 +44,6 @@ export function SignInComponent({
}; };
const [form] = Form.useForm(); 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) if (currentUser.authorized === true)
return <Redirect to={redirect || "/manage"} />; return <Redirect to={redirect || "/manage"} />;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,30 +2,6 @@ const functions = require("firebase-functions");
const admin = require("firebase-admin"); const admin = require("firebase-admin");
admin.initializeApp(functions.config().firebase); 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. // On sign up.
exports.processSignUp = functions.auth.user().onCreate((user) => { exports.processSignUp = functions.auth.user().onCreate((user) => {
// Check if user meets role criteria: // Check if user meets role criteria:

View File

@@ -12,7 +12,6 @@ const { Headers } = require("cross-fetch");
global.Headers = global.Headers || Headers; 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, { exports.client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, {
headers: { headers: {
"x-hasura-admin-secret": process.env.HASURA_ADMIN_SECRET, "x-hasura-admin-secret": process.env.HASURA_ADMIN_SECRET,

View File

@@ -220,7 +220,6 @@ function CalculateTaxesTotals(job, otherTotals) {
.add(otherTotals.additional) .add(otherTotals.additional)
.add(Dinero({ amount: (job.towing_payable || 0) * 100 })) .add(Dinero({ amount: (job.towing_payable || 0) * 100 }))
.add(Dinero({ amount: (job.storage_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 //Potential issue here with Sublet Calculation. Sublets are calculated under labor in Mitchell, but it's done in IO
//Under the parts rates. //Under the parts rates.

View File

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