Merged in release/2021-10-08 (pull request #246)

release/2021-10-08
This commit is contained in:
Patrick Fic
2021-10-09 15:29:49 +00:00
85 changed files with 1212 additions and 336 deletions

View File

@@ -1,4 +1,4 @@
<babeledit_project version="1.2" be_version="2.7.1"> <babeledit_project be_version="2.7.1" version="1.2">
<!-- <!--
BabelEdit project file BabelEdit project file
@@ -16920,6 +16920,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>tax_part</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node> <concept_node>
<name>total</name> <name>total</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>
@@ -19569,6 +19590,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>date_last_contacted</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node> <concept_node>
<name>date_open</name> <name>date_open</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>
@@ -21369,6 +21411,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>ownr_ph2</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node> <concept_node>
<name>paa</name> <name>paa</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>
@@ -22303,6 +22366,48 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>referral_source_extra</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>referral_source_other</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node> <concept_node>
<name>referralsource</name> <name>referralsource</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>
@@ -29310,6 +29415,32 @@
</concept_node> </concept_node>
</children> </children>
</folder_node> </folder_node>
<folder_node>
<name>errors</name>
<children>
<concept_node>
<name>inserting</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
</children>
</folder_node>
<folder_node> <folder_node>
<name>fields</name> <name>fields</name>
<children> <children>
@@ -29444,6 +29575,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>notetoadd</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
</children> </children>
</folder_node> </folder_node>
<folder_node> <folder_node>
@@ -29847,6 +29999,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>ownr_ph2</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node> <concept_node>
<name>ownr_st</name> <name>ownr_st</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>
@@ -30375,6 +30548,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>comments</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node> <concept_node>
<name>cost</name> <name>cost</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>

View File

@@ -4,35 +4,35 @@
"private": true, "private": true,
"proxy": "http://localhost:5000", "proxy": "http://localhost:5000",
"dependencies": { "dependencies": {
"@apollo/client": "^3.4.15", "@apollo/client": "^3.4.16",
"@craco/craco": "^6.3.0", "@craco/craco": "^6.3.0",
"@fingerprintjs/fingerprintjs": "^3.3.0", "@fingerprintjs/fingerprintjs": "^3.3.0",
"@lourenci/react-kanban": "^2.1.0", "@lourenci/react-kanban": "^2.1.0",
"@openreplay/tracker": "^3.4.1", "@openreplay/tracker": "^3.4.4",
"@openreplay/tracker-assist": "^3.4.0", "@openreplay/tracker-assist": "^3.4.3",
"@openreplay/tracker-graphql": "^3.0.0", "@openreplay/tracker-graphql": "^3.0.0",
"@openreplay/tracker-redux": "^3.0.0", "@openreplay/tracker-redux": "^3.0.0",
"@sentry/react": "^6.13.2", "@sentry/react": "^6.13.2",
"@sentry/tracing": "^6.13.2", "@sentry/tracing": "^6.13.2",
"@stripe/react-stripe-js": "^1.5.0", "@stripe/react-stripe-js": "^1.5.0",
"@stripe/stripe-js": "^1.18.0", "@stripe/stripe-js": "^1.19.1",
"@tanem/react-nprogress": "^3.0.79", "@tanem/react-nprogress": "^3.0.79",
"antd": "^4.16.13", "antd": "^4.16.13",
"apollo-link-logger": "^2.0.0", "apollo-link-logger": "^2.0.0",
"axios": "^0.21.4", "axios": "^0.22.0",
"craco-less": "^1.20.0", "craco-less": "^1.20.0",
"dinero.js": "^1.9.0", "dinero.js": "^1.9.0",
"dotenv": "^10.0.0", "dotenv": "^10.0.0",
"enquire-js": "^0.2.1", "enquire-js": "^0.2.1",
"env-cmd": "^10.1.0", "env-cmd": "^10.1.0",
"exifr": "^7.1.3", "exifr": "^7.1.3",
"firebase": "^9.1.0", "firebase": "^9.1.1",
"graphql": "^15.6.0", "graphql": "^15.6.0",
"i18next": "^21.2.0", "i18next": "^21.2.4",
"i18next-browser-languagedetector": "^6.1.2", "i18next-browser-languagedetector": "^6.1.2",
"jsoneditor": "^9.5.6", "jsoneditor": "^9.5.6",
"jsreport-browser-client-dist": "^1.3.0", "jsreport-browser-client-dist": "^1.3.0",
"libphonenumber-js": "^1.9.34", "libphonenumber-js": "^1.9.36",
"logrocket": "^2.0.0", "logrocket": "^2.0.0",
"markerjs2": "^2.13.0", "markerjs2": "^2.13.0",
"moment-business-days": "^1.2.0", "moment-business-days": "^1.2.0",
@@ -43,7 +43,7 @@
"rc-queue-anim": "^2.0.0", "rc-queue-anim": "^2.0.0",
"rc-scroll-anim": "^2.7.6", "rc-scroll-anim": "^2.7.6",
"react": "^17.0.1", "react": "^17.0.1",
"react-big-calendar": "^0.36.0", "react-big-calendar": "^0.36.1",
"react-color": "^2.19.3", "react-color": "^2.19.3",
"react-cookie": "^4.1.1", "react-cookie": "^4.1.1",
"react-dom": "^17.0.1", "react-dom": "^17.0.1",
@@ -51,7 +51,7 @@
"react-grid-gallery": "^0.5.5", "react-grid-gallery": "^0.5.5",
"react-grid-layout": "^1.3.0", "react-grid-layout": "^1.3.0",
"react-i18next": "^11.12.0", "react-i18next": "^11.12.0",
"react-icons": "^4.2.0", "react-icons": "^4.3.1",
"react-number-format": "^4.7.3", "react-number-format": "^4.7.3",
"react-redux": "^7.2.5", "react-redux": "^7.2.5",
"react-resizable": "^3.0.4", "react-resizable": "^3.0.4",
@@ -114,7 +114,7 @@
] ]
}, },
"devDependencies": { "devDependencies": {
"@sentry/webpack-plugin": "^1.17.1", "@sentry/webpack-plugin": "^1.17.2",
"patch-package": "^6.4.7", "patch-package": "^6.4.7",
"redux-logger": "^3.0.6", "redux-logger": "^3.0.6",
"source-map-explorer": "^2.5.2" "source-map-explorer": "^2.5.2"

View File

@@ -124,3 +124,7 @@
z-index: 2 !important; z-index: 2 !important;
} }
} }
.react-kanban-column {
background-color: #ddd !important;
}

View File

@@ -12,7 +12,18 @@ const BillLineSearchSelect = ({ options, disabled, ...restProps }, ref) => {
disabled={disabled} disabled={disabled}
ref={ref} ref={ref}
showSearch showSearch
optionFilterProp="line_desc" // optionFilterProp="line_desc"
filterOption={(inputValue, option) => {
console.log(inputValue);
return (
(option.line_desc &&
option.line_desc
.toLowerCase()
.includes(inputValue.toLowerCase())) ||
(option.oem_partno &&
option.oem_partno.toLowerCase().includes(inputValue.toLowerCase()))
);
}}
notFoundContent={"Removed."} notFoundContent={"Removed."}
{...restProps} {...restProps}
> >
@@ -29,6 +40,7 @@ const BillLineSearchSelect = ({ options, disabled, ...restProps }, ref) => {
part_type={item.part_type} part_type={item.part_type}
line_desc={item.line_desc} line_desc={item.line_desc}
part_qty={item.part_qty} part_qty={item.part_qty}
oem_partno={item.oem_partno}
style={{ style={{
...(item.removed ? { textDecoration: "line-through" } : {}), ...(item.removed ? { textDecoration: "line-through" } : {}),
}} }}

View File

@@ -62,13 +62,16 @@ export default function GlobalSearch() {
}`, }`,
label: ( label: (
<Link to={`/manage/owners/${owner.id}`}> <Link to={`/manage/owners/${owner.id}`}>
<Space size="small" split={<Divider type="vertical" />}> <Space size="small" split={<Divider type="vertical" />} wrap>
<span>{`${owner.ownr_fn || ""} ${owner.ownr_ln || ""} ${ <span>{`${owner.ownr_fn || ""} ${owner.ownr_ln || ""} ${
owner.ownr_co_nm || "" owner.ownr_co_nm || ""
}`}</span> }`}</span>
<PhoneNumberFormatter> <PhoneNumberFormatter>
{owner.ownr_ph1} {owner.ownr_ph1}
</PhoneNumberFormatter> </PhoneNumberFormatter>
<PhoneNumberFormatter>
{owner.ownr_ph2}
</PhoneNumberFormatter>
</Space> </Space>
</Link> </Link>
), ),

View File

@@ -106,6 +106,12 @@ export function ScheduleEventComponent({
jobid={event.job.id} jobid={event.job.id}
/> />
</DataLabel> </DataLabel>
<DataLabel label={t("jobs.fields.ownr_ph2")}>
<ChatOpenButton
phone={event.job && event.job.ownr_ph2}
jobid={event.job.id}
/>
</DataLabel>
<DataLabel label={t("jobs.fields.alt_transport")}> <DataLabel label={t("jobs.fields.alt_transport")}>
{(event.job && event.job.alt_transport) || ""} {(event.job && event.job.alt_transport) || ""}
<ScheduleAtChange job={event && event.job} /> <ScheduleAtChange job={event && event.job} />

View File

@@ -167,7 +167,11 @@ export function JobChecklistForm({
title={t("checklist.labels.checklist")} title={t("checklist.labels.checklist")}
extra={ extra={
!readOnly && ( !readOnly && (
<Button loading={loading} onClick={() => form.submit()}> <Button
loading={loading}
type="primary"
onClick={() => form.submit()}
>
{t("general.actions.submit")} {t("general.actions.submit")}
</Button> </Button>
) )

View File

@@ -112,60 +112,46 @@ export function JobDetailCards({ setPrintCenterContext }) {
<Divider type="horizontal" /> <Divider type="horizontal" />
<Row gutter={[16, 16]}> <Row gutter={[16, 16]}>
<Col {...span}> <Col {...span}>
<Card.Grid style={{ width: "100%", height: "100%" }}> <JobDetailCardsInsuranceComponent
<JobDetailCardsInsuranceComponent loading={loading}
loading={loading} data={data ? data.jobs_by_pk : null}
data={data ? data.jobs_by_pk : null} />
/>
</Card.Grid>
</Col> </Col>
<Col {...span}> <Col {...span}>
<Card.Grid style={{ width: "100%", height: "100%" }}> <JobDetailCardsTotalsComponent
<JobDetailCardsTotalsComponent loading={loading}
loading={loading} data={data ? data.jobs_by_pk : null}
data={data ? data.jobs_by_pk : null} />
/>
</Card.Grid>
</Col> </Col>
<Col {...span}> <Col {...span}>
<Card.Grid style={{ width: "100%", height: "100%" }}> <JobDetailCardsDatesComponent
<JobDetailCardsDatesComponent loading={loading}
loading={loading} data={data ? data.jobs_by_pk : null}
data={data ? data.jobs_by_pk : null} />
/>
</Card.Grid>
</Col> </Col>
<Col {...span}> <Col {...span}>
<Card.Grid style={{ width: "100%", height: "100%" }}> <JobDetailCardsPartsComponent
<JobDetailCardsPartsComponent loading={loading}
loading={loading} data={data ? data.jobs_by_pk : null}
data={data ? data.jobs_by_pk : null} />
/>
</Card.Grid>
</Col> </Col>
<Col {...span}> <Col {...span}>
<Card.Grid style={{ width: "100%", height: "100%" }}> <JobDetailCardsNotesComponent
<JobDetailCardsNotesComponent loading={loading}
loading={loading} data={data ? data.jobs_by_pk : null}
data={data ? data.jobs_by_pk : null} />
/>
</Card.Grid>
</Col> </Col>
<Col {...span}> <Col {...span}>
<Card.Grid style={{ width: "100%", height: "100%" }}> <JobDetailCardsDocumentsComponent
<JobDetailCardsDocumentsComponent loading={loading}
loading={loading} data={data ? data.jobs_by_pk : null}
data={data ? data.jobs_by_pk : null} />
/>
</Card.Grid>
</Col> </Col>
<Col {...span}> <Col {...span}>
<Card.Grid style={{ width: "100%", height: "100%" }}> <JobDetailCardsDamageComponent
<JobDetailCardsDamageComponent loading={loading}
loading={loading} data={data ? data.jobs_by_pk : null}
data={data ? data.jobs_by_pk : null} />
/>
</Card.Grid>
</Col> </Col>
</Row> </Row>
</Card> </Card>

View File

@@ -1,7 +1,7 @@
import { Timeline } from "antd"; import { Timeline } from "antd";
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { DateFormatter } from "../../utils/DateFormatter"; import { DateTimeFormatter } from "../../utils/DateFormatter";
import CardTemplate from "./job-detail-cards.template.component"; import CardTemplate from "./job-detail-cards.template.component";
export default function JobDetailCardsDatesComponent({ loading, data }) { export default function JobDetailCardsDatesComponent({ loading, data }) {
@@ -26,80 +26,86 @@ export default function JobDetailCardsDatesComponent({ loading, data }) {
) ? ( ) ? (
<div>{t("jobs.errors.nodates")}</div> <div>{t("jobs.errors.nodates")}</div>
) : null} ) : null}
{data.date_last_contacted ? (
<Timeline.Item>
<label>{t("jobs.fields.date_last_contacted")}: </label>
<DateTimeFormatter>{data.date_last_contacted}</DateTimeFormatter>
</Timeline.Item>
) : null}
{data.date_open ? ( {data.date_open ? (
<Timeline.Item> <Timeline.Item>
<label>{t("jobs.fields.date_open")}: </label> <label>{t("jobs.fields.date_open")}: </label>
<DateFormatter>{data.date_open}</DateFormatter> <DateTimeFormatter>{data.date_open}</DateTimeFormatter>
</Timeline.Item> </Timeline.Item>
) : null} ) : null}
{data.date_estimated ? ( {data.date_estimated ? (
<Timeline.Item> <Timeline.Item>
<label>{t("jobs.fields.date_estimated")}: </label> <label>{t("jobs.fields.date_estimated")}: </label>
<DateFormatter>{data.date_estimated}</DateFormatter> <DateTimeFormatter>{data.date_estimated}</DateTimeFormatter>
</Timeline.Item> </Timeline.Item>
) : null} ) : null}
{data.date_scheduled ? ( {data.date_scheduled ? (
<Timeline.Item> <Timeline.Item>
<label>{t("jobs.fields.date_scheduled")}: </label> <label>{t("jobs.fields.date_scheduled")}: </label>
<DateFormatter>{data.date_scheduled}</DateFormatter> <DateTimeFormatter>{data.date_scheduled}</DateTimeFormatter>
</Timeline.Item> </Timeline.Item>
) : null} ) : null}
{data.scheduled_in ? ( {data.scheduled_in ? (
<Timeline.Item> <Timeline.Item>
<label>{t("jobs.fields.scheduled_in")}: </label> <label>{t("jobs.fields.scheduled_in")}: </label>
<DateFormatter>{data.scheduled_in}</DateFormatter> <DateTimeFormatter>{data.scheduled_in}</DateTimeFormatter>
</Timeline.Item> </Timeline.Item>
) : null} ) : null}
{data.actual_in ? ( {data.actual_in ? (
<Timeline.Item> <Timeline.Item>
<label>{t("jobs.fields.actual_in")}: </label> <label>{t("jobs.fields.actual_in")}: </label>
<DateFormatter>{data.actual_in}</DateFormatter> <DateTimeFormatter>{data.actual_in}</DateTimeFormatter>
</Timeline.Item> </Timeline.Item>
) : null} ) : null}
{data.scheduled_completion ? ( {data.scheduled_completion ? (
<Timeline.Item> <Timeline.Item>
<label>{t("jobs.fields.scheduled_completion")}: </label> <label>{t("jobs.fields.scheduled_completion")}: </label>
<DateFormatter>{data.scheduled_completion}</DateFormatter> <DateTimeFormatter>{data.scheduled_completion}</DateTimeFormatter>
</Timeline.Item> </Timeline.Item>
) : null} ) : null}
{data.actual_completion ? ( {data.actual_completion ? (
<Timeline.Item> <Timeline.Item>
<label>{t("jobs.fields.actual_completion")}: </label> <label>{t("jobs.fields.actual_completion")}: </label>
<DateFormatter>{data.actual_completion}</DateFormatter> <DateTimeFormatter>{data.actual_completion}</DateTimeFormatter>
</Timeline.Item> </Timeline.Item>
) : null} ) : null}
{data.scheduled_delivery ? ( {data.scheduled_delivery ? (
<Timeline.Item> <Timeline.Item>
<label>{t("jobs.fields.scheduled_delivery")}: </label> <label>{t("jobs.fields.scheduled_delivery")}: </label>
<DateFormatter>{data.scheduled_delivery}</DateFormatter> <DateTimeFormatter>{data.scheduled_delivery}</DateTimeFormatter>
</Timeline.Item> </Timeline.Item>
) : null} ) : null}
{data.actual_delivery ? ( {data.actual_delivery ? (
<Timeline.Item> <Timeline.Item>
<label>{t("jobs.fields.actual_delivery")}: </label> <label>{t("jobs.fields.actual_delivery")}: </label>
<DateFormatter>{data.actual_delivery}</DateFormatter> <DateTimeFormatter>{data.actual_delivery}</DateTimeFormatter>
</Timeline.Item> </Timeline.Item>
) : null} ) : null}
{data.date_invoiced ? ( {data.date_invoiced ? (
<Timeline.Item> <Timeline.Item>
<label>{t("jobs.fields.date_invoiced")}: </label> <label>{t("jobs.fields.date_invoiced")}: </label>
<DateFormatter>{data.date_invoiced}</DateFormatter> <DateTimeFormatter>{data.date_invoiced}</DateTimeFormatter>
</Timeline.Item> </Timeline.Item>
) : null} ) : null}
{data.date_exported ? ( {data.date_exported ? (
<Timeline.Item> <Timeline.Item>
<label>{t("jobs.fields.date_exported")}: </label> <label>{t("jobs.fields.date_exported")}: </label>
<DateFormatter>{data.date_exported}</DateFormatter> <DateTimeFormatter>{data.date_exported}</DateTimeFormatter>
</Timeline.Item> </Timeline.Item>
) : null} ) : null}
</Timeline> </Timeline>

View File

@@ -1,8 +1,8 @@
import { Carousel } from "antd"; import { Carousel } from "antd";
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { GenerateThumbUrl } from "../jobs-documents-gallery/job-documents.utility";
import CardTemplate from "./job-detail-cards.template.component"; import CardTemplate from "./job-detail-cards.template.component";
import { DetermineFileType } from "../documents-upload/documents-upload.utility";
export default function JobDetailCardsDocumentsComponent({ loading, data }) { export default function JobDetailCardsDocumentsComponent({ loading, data }) {
const { t } = useTranslation(); const { t } = useTranslation();
@@ -22,15 +22,7 @@ export default function JobDetailCardsDocumentsComponent({ loading, data }) {
{data.documents.length > 0 ? ( {data.documents.length > 0 ? (
<Carousel autoplay> <Carousel autoplay>
{data.documents.map((item) => ( {data.documents.map((item) => (
<img <img key={item.id} src={GenerateThumbUrl(item)} alt={item.name} />
key={item.id}
src={`${
process.env.REACT_APP_CLOUDINARY_ENDPOINT
}/${DetermineFileType(item.type)}/upload/${
process.env.REACT_APP_CLOUDINARY_THUMB_TRANSFORMATIONS
}/${item.key}`}
alt={item.name}
/>
))} ))}
</Carousel> </Carousel>
) : ( ) : (

View File

@@ -12,11 +12,13 @@ export default function JobDetailCardTemplate({
if (extraLink) extra = { extra: <Link to={extraLink}>More</Link> }; if (extraLink) extra = { extra: <Link to={extraLink}>More</Link> };
return ( return (
<Card <Card
size='small' size="small"
className='job-card' className="job-card"
title={title} title={title}
loading={loading} loading={loading}
{...extra}> style={{ height: "100%" }}
{...extra}
>
{otherProps.children} {otherProps.children}
</Card> </Card>
); );

View File

@@ -36,6 +36,7 @@ import JobLinesBillRefernece from "../job-lines-bill-reference/job-lines-bill-re
// import AllocationsBulkAssignmentContainer from "../allocations-bulk-assignment/allocations-bulk-assignment.container"; // import AllocationsBulkAssignmentContainer from "../allocations-bulk-assignment/allocations-bulk-assignment.container";
// import AllocationsEmployeeLabelContainer from "../allocations-employee-label/allocations-employee-label.container"; // import AllocationsEmployeeLabelContainer from "../allocations-employee-label/allocations-employee-label.container";
import PartsOrderModalContainer from "../parts-order-modal/parts-order-modal.container"; import PartsOrderModalContainer from "../parts-order-modal/parts-order-modal.container";
import _ from "lodash";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser //currentUser: selectCurrentUser
@@ -295,18 +296,17 @@ export function JobLinesComponent({
onClick={async () => { onClick={async () => {
await deleteJobLine({ await deleteJobLine({
variables: { joblineId: record.id }, variables: { joblineId: record.id },
// update(cache) { update(cache) {
// cache.modify({ cache.modify({
// id: cache.identify(job), fields: {
// fields: { joblines(existingJobLines, { readField }) {
// joblines(existingJobLines, { readField }) { return existingJobLines.filter(
// return existingJobLines.filter( (jlRef) => record.id !== readField("id", jlRef)
// (jlRef) => record.id !== readField("id", jlRef) );
// ); },
// }, },
// }, });
// }); },
// },
}); });
await axios.post("/job/totalsssu", { await axios.post("/job/totalsssu", {
id: job.id, id: job.id,
@@ -334,10 +334,12 @@ export function JobLinesComponent({
const markedTypes = [e.key]; const markedTypes = [e.key];
if (e.key === "PAN") markedTypes.push("PAP"); if (e.key === "PAN") markedTypes.push("PAP");
if (e.key === "PAS") markedTypes.push("PASL"); if (e.key === "PAS") markedTypes.push("PASL");
setSelectedLines([ setSelectedLines(
...selectedLines, _.uniq([
...jobLines.filter((item) => markedTypes.includes(item.part_type)), ...selectedLines,
]); ...jobLines.filter((item) => markedTypes.includes(item.part_type)),
])
);
} }
}; };

View File

@@ -1,4 +1,4 @@
import { Form, Input, InputNumber, Modal, Select } from "antd"; import { Form, Input, InputNumber, Modal, Select, Switch } from "antd";
import React, { useEffect } from "react"; import React, { useEffect } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import InputCurrency from "../form-items-formatted/currency-form-item.component"; import InputCurrency from "../form-items-formatted/currency-form-item.component";
@@ -184,9 +184,9 @@ export default function JobLinesUpsertModalComponent({
> >
<InputNumber precision={0} min={0} /> <InputNumber precision={0} min={0} />
</Form.Item> </Form.Item>
<Form.Item label={t("joblines.fields.db_price")} name="db_price"> {/* <Form.Item label={t("joblines.fields.db_price")} name="db_price">
<InputCurrency precision={2} min={0} /> <InputCurrency precision={2} min={0} />
</Form.Item> </Form.Item> */}
<Form.Item <Form.Item
label={t("joblines.fields.act_price")} label={t("joblines.fields.act_price")}
name="act_price" name="act_price"
@@ -222,6 +222,14 @@ export default function JobLinesUpsertModalComponent({
> >
<InputNumber precision={0} min={0} max={100} /> <InputNumber precision={0} min={0} max={100} />
</Form.Item> </Form.Item>
<Form.Item
label={t("joblines.fields.tax_part")}
name="tax_part"
valuePropName="checked"
initialValue={true}
>
<Switch />
</Form.Item>
</LayoutFormRow> </LayoutFormRow>
</Form> </Form>
</Modal> </Modal>

View File

@@ -44,6 +44,7 @@ function JobLinesUpsertModalContainer({
}, },
], ],
}, },
refetchQueries: ["GET_LINE_TICKET_BY_PK"],
}); });
if (!r.errors) { if (!r.errors) {
await Axios.post("/job/totalsssu", { await Axios.post("/job/totalsssu", {
@@ -69,6 +70,7 @@ function JobLinesUpsertModalContainer({
lineId: jobLineEditModal.context.id, lineId: jobLineEditModal.context.id,
line: values, line: values,
}, },
refetchQueries: ["GET_LINE_TICKET_BY_PK"],
}); });
if (!r.errors) { if (!r.errors) {
notification["success"]({ notification["success"]({

View File

@@ -108,6 +108,9 @@ export default function JobReconciliationBillsTable({
rowSelection={{ rowSelection={{
onChange: handleOnRowClick, onChange: handleOnRowClick,
selectedRowKeys: selectedLines, selectedRowKeys: selectedLines,
getCheckboxProps: (record) => {
return { disabled: record.deductedfromlbr };
},
}} }}
/> />
</div> </div>

View File

@@ -11,7 +11,7 @@ export const reconcileByAssocLine = (
const [selectedJobLines, setSelectedJobLines] = jobLineState; const [selectedJobLines, setSelectedJobLines] = jobLineState;
const allJoblinesFromBills = billLines const allJoblinesFromBills = billLines
.filter((bl) => bl.joblineid && !(bl.jobline && bl.jobline.removed)) .filter((bl) => bl.joblineid && bl.jobline && !bl.jobline.removed)
.map((bl) => bl.joblineid); .map((bl) => bl.joblineid);
const duplicatedJobLinesbyInvoiceId = _.filter( const duplicatedJobLinesbyInvoiceId = _.filter(

View File

@@ -74,7 +74,12 @@ export default function JobsAdminDatesChange({ job }) {
<Form.Item label={t("jobs.fields.actual_in")} name="actual_in"> <Form.Item label={t("jobs.fields.actual_in")} name="actual_in">
<DateTimePicker /> <DateTimePicker />
</Form.Item> </Form.Item>
<Form.Item
label={t("jobs.fields.date_last_contacted")}
name="date_last_contacted"
>
<DateTimePicker />
</Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.scheduled_completion")} label={t("jobs.fields.scheduled_completion")}
name="scheduled_completion" name="scheduled_completion"

View File

@@ -490,15 +490,14 @@ async function CheckTaxRates(estData, bodyshop) {
//IO-1387 If a sublet line is NOT R&R, use the labor tax. If it is, use the sublet tax rate. //IO-1387 If a sublet line is NOT R&R, use the labor tax. If it is, use the sublet tax rate.
//Currently limited to SK shops only. //Currently limited to SK shops only.
if (bodyshop.region_config === "CA_SK") { //if (bodyshop.region_config === "CA_SK") {
estData.joblines.data.forEach((jl, index) => { estData.joblines.data.forEach((jl, index) => {
if ( if (
(jl.part_type === "PASL" || jl.part_type === "PAS") && (jl.part_type === "PASL" || jl.part_type === "PAS") &&
jl.lbr_op !== "OP11" jl.lbr_op !== "OP11"
) { ) {
estData.joblines.data[index].tax_part = jl.lbr_tax; estData.joblines.data[index].tax_part = jl.lbr_tax;
console.log(estData.joblines.data[index], jl); }
} });
}); //}
}
} }

View File

@@ -2,6 +2,7 @@ import { useMutation } from "@apollo/client";
import { import {
Button, Button,
Form, Form,
Input,
notification, notification,
Popover, Popover,
Select, Select,
@@ -112,24 +113,32 @@ export function JobsConvertButton({
</Form.Item> </Form.Item>
)} )}
{bodyshop.enforce_referral && ( {bodyshop.enforce_referral && (
<Form.Item <>
name={"referral_source"} <Form.Item
label={t("jobs.fields.referralsource")} name={"referral_source"}
rules={[ label={t("jobs.fields.referralsource")}
{ rules={[
required: bodyshop.enforce_referral, {
//message: t("general.validation.required"), required: bodyshop.enforce_referral,
}, //message: t("general.validation.required"),
]} },
> ]}
<Select> >
{bodyshop.md_referral_sources.map((s) => ( <Select>
<Select.Option key={s} value={s}> {bodyshop.md_referral_sources.map((s) => (
{s} <Select.Option key={s} value={s}>
</Select.Option> {s}
))} </Select.Option>
</Select> ))}
</Form.Item> </Select>
</Form.Item>
<Form.Item
label={t("jobs.fields.referral_source_extra")}
name="referral_source_extra"
>
<Input />
</Form.Item>
</>
)} )}
<Form.Item <Form.Item
label={t("jobs.fields.ca_gst_registrant")} label={t("jobs.fields.ca_gst_registrant")}

View File

@@ -181,6 +181,12 @@ export function JobsCreateJobsInfo({ bodyshop, form, selected }) {
))} ))}
</Select> </Select>
</Form.Item> </Form.Item>
<Form.Item
label={t("jobs.fields.referral_source_extra")}
name="referral_source_extra"
>
<Input />
</Form.Item>
</LayoutFormRow> </LayoutFormRow>
</Collapse.Panel> </Collapse.Panel>
<Collapse.Panel <Collapse.Panel

View File

@@ -129,6 +129,19 @@ export default function JobsCreateOwnerInfoNewComponent() {
> >
<FormItemPhone disabled={!state.owner.new} /> <FormItemPhone disabled={!state.owner.new} />
</Form.Item> </Form.Item>
<Form.Item
label={t("owners.fields.ownr_ph2")}
name={["owner", "data", "ownr_ph2"]}
rules={[
({ getFieldValue }) =>
PhoneItemFormatterValidation(
getFieldValue,
"owner.data.ownr_ph2"
),
]}
>
<FormItemPhone disabled={!state.owner.new} />
</Form.Item>
</LayoutFormRow> </LayoutFormRow>
<LayoutFormRow grow> <LayoutFormRow grow>
<Form.Item <Form.Item

View File

@@ -84,6 +84,18 @@ export default function JobsCreateOwnerInfoSearchComponent({
tableState.sortedInfo.columnKey === "ownr_ph1" && tableState.sortedInfo.columnKey === "ownr_ph1" &&
tableState.sortedInfo.order, tableState.sortedInfo.order,
}, },
{
title: t("owners.fields.ownr_ph2"),
dataIndex: "ownr_ph2",
key: "ownr_ph2",
render: (text, record) => (
<PhoneFormatter>{record.ownr_ph2}</PhoneFormatter>
),
sorter: (a, b) => alphaSort(a.ownr_ph2, b.ownr_ph2),
sortOrder:
tableState.sortedInfo.columnKey === "ownr_ph2" &&
tableState.sortedInfo.order,
},
]; ];
const handleTableChange = (pagination, filters, sorter) => { const handleTableChange = (pagination, filters, sorter) => {

View File

@@ -69,6 +69,12 @@ export function JobsDetailDatesComponent({ jobRO, job, bodyshop }) {
</Tooltip> </Tooltip>
</FormRow> </FormRow>
<FormRow header={t("jobs.forms.repairdates")}> <FormRow header={t("jobs.forms.repairdates")}>
<Form.Item
label={t("jobs.fields.date_last_contacted")}
name="date_last_contacted"
>
<DateTimePicker />
</Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.scheduled_completion")} label={t("jobs.fields.scheduled_completion")}
name="scheduled_completion" name="scheduled_completion"
@@ -93,7 +99,6 @@ export function JobsDetailDatesComponent({ jobRO, job, bodyshop }) {
); );
}} }}
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.scheduled_delivery")} label={t("jobs.fields.scheduled_delivery")}
name="scheduled_delivery" name="scheduled_delivery"

View File

@@ -114,6 +114,12 @@ export function JobsDetailGeneral({ bodyshop, jobRO, job, form }) {
))} ))}
</Select> </Select>
</Form.Item> </Form.Item>
<Form.Item
label={t("jobs.fields.referral_source_extra")}
name="referral_source_extra"
>
<Input />
</Form.Item>
<Form.Item label={t("jobs.fields.alt_transport")} name="alt_transport"> <Form.Item label={t("jobs.fields.alt_transport")} name="alt_transport">
<Select disabled={jobRO} allowClear> <Select disabled={jobRO} allowClear>
{bodyshop.appt_alt_transport.map((s) => ( {bodyshop.appt_alt_transport.map((s) => (

View File

@@ -141,6 +141,9 @@ export function JobsDetailHeader({ job, bodyshop, disabled }) {
<DataLabel key="2" label={t("jobs.fields.ownr_ph1")}> <DataLabel key="2" label={t("jobs.fields.ownr_ph1")}>
<ChatOpenButton phone={job.ownr_ph1} jobid={job.id} /> <ChatOpenButton phone={job.ownr_ph1} jobid={job.id} />
</DataLabel> </DataLabel>
<DataLabel key="22" label={t("jobs.fields.ownr_ph2")}>
<ChatOpenButton phone={job.ownr_ph2} jobid={job.id} />
</DataLabel>
<DataLabel key="3" label={t("owners.fields.address")}> <DataLabel key="3" label={t("owners.fields.address")}>
{`${job.ownr_addr1 || ""} ${job.ownr_addr2 || ""} ${ {`${job.ownr_addr1 || ""} ${job.ownr_addr2 || ""} ${
job.ownr_city || "" job.ownr_city || ""

View File

@@ -38,7 +38,7 @@ export function JobsDetailRates({ jobRO, form, job, bodyshop }) {
label={t("jobs.fields.depreciation_taxes")} label={t("jobs.fields.depreciation_taxes")}
name="depreciation_taxes" name="depreciation_taxes"
> >
<CurrencyInput disabled={jobRO} /> <CurrencyInput disabled={jobRO} min={0} />
</Form.Item> </Form.Item>
<Tooltip title={t("jobs.labels.ca_gst_all_if_null")}> <Tooltip title={t("jobs.labels.ca_gst_all_if_null")}>
<Form.Item <Form.Item
@@ -47,6 +47,7 @@ export function JobsDetailRates({ jobRO, form, job, bodyshop }) {
> >
<CurrencyInput <CurrencyInput
disabled={jobRO} disabled={jobRO}
min={0}
max={ max={
Math.round( Math.round(
(job.job_totals && (job.job_totals &&
@@ -61,19 +62,19 @@ export function JobsDetailRates({ jobRO, form, job, bodyshop }) {
label={t("jobs.fields.other_amount_payable")} label={t("jobs.fields.other_amount_payable")}
name="other_amount_payable" name="other_amount_payable"
> >
<CurrencyInput disabled={jobRO} /> <CurrencyInput disabled={jobRO} min={0} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.towing_payable")} label={t("jobs.fields.towing_payable")}
name="towing_payable" name="towing_payable"
> >
<CurrencyInput disabled={jobRO} /> <CurrencyInput disabled={jobRO} min={0} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.storage_payable")} label={t("jobs.fields.storage_payable")}
name="storage_payable" name="storage_payable"
> >
<CurrencyInput disabled={jobRO} /> <CurrencyInput disabled={jobRO} min={0} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.adjustment_bottom_line")} label={t("jobs.fields.adjustment_bottom_line")}
@@ -83,7 +84,7 @@ export function JobsDetailRates({ jobRO, form, job, bodyshop }) {
</Form.Item> </Form.Item>
<Space align="end"> <Space align="end">
<Form.Item label={t("jobs.fields.ca_bc_pvrt")} name="ca_bc_pvrt"> <Form.Item label={t("jobs.fields.ca_bc_pvrt")} name="ca_bc_pvrt">
<CurrencyInput disabled={jobRO} /> <CurrencyInput disabled={jobRO} min={0} />
</Form.Item> </Form.Item>
<CABCpvrtCalculator form={form} disabled={jobRO} /> <CABCpvrtCalculator form={form} disabled={jobRO} />
</Space> </Space>
@@ -135,72 +136,72 @@ export function JobsDetailRates({ jobRO, form, job, bodyshop }) {
<Input disabled={jobRO} /> <Input disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_laa")} name="rate_laa"> <Form.Item label={t("jobs.fields.rate_laa")} name="rate_laa">
<CurrencyInput disabled={jobRO} /> <CurrencyInput min={0} disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_lab")} name="rate_lab"> <Form.Item label={t("jobs.fields.rate_lab")} name="rate_lab">
<CurrencyInput disabled={jobRO} /> <CurrencyInput min={0} disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_lad")} name="rate_lad"> <Form.Item label={t("jobs.fields.rate_lad")} name="rate_lad">
<CurrencyInput disabled={jobRO} /> <CurrencyInput min={0} disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_lae")} name="rate_lae"> <Form.Item label={t("jobs.fields.rate_lae")} name="rate_lae">
<CurrencyInput disabled={jobRO} /> <CurrencyInput min={0} disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_lar")} name="rate_lar"> <Form.Item label={t("jobs.fields.rate_lar")} name="rate_lar">
<CurrencyInput disabled={jobRO} /> <CurrencyInput min={0} disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_las")} name="rate_las"> <Form.Item label={t("jobs.fields.rate_las")} name="rate_las">
<CurrencyInput disabled={jobRO} /> <CurrencyInput min={0} disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_laf")} name="rate_laf"> <Form.Item label={t("jobs.fields.rate_laf")} name="rate_laf">
<CurrencyInput disabled={jobRO} /> <CurrencyInput min={0} disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_lam")} name="rate_lam"> <Form.Item label={t("jobs.fields.rate_lam")} name="rate_lam">
<CurrencyInput disabled={jobRO} /> <CurrencyInput min={0} disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_lag")} name="rate_lag"> <Form.Item label={t("jobs.fields.rate_lag")} name="rate_lag">
<CurrencyInput disabled={jobRO} /> <CurrencyInput min={0} disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_la1")} name="rate_la1"> <Form.Item label={t("jobs.fields.rate_la1")} name="rate_la1">
<CurrencyInput disabled={jobRO} /> <CurrencyInput min={0} disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_la2")} name="rate_la2"> <Form.Item label={t("jobs.fields.rate_la2")} name="rate_la2">
<CurrencyInput disabled={jobRO} /> <CurrencyInput min={0} disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_la3")} name="rate_la3"> <Form.Item label={t("jobs.fields.rate_la3")} name="rate_la3">
<CurrencyInput disabled={jobRO} /> <CurrencyInput min={0} disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_la4")} name="rate_la4"> <Form.Item label={t("jobs.fields.rate_la4")} name="rate_la4">
<CurrencyInput disabled={jobRO} /> <CurrencyInput min={0} disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_lau")} name="rate_lau"> <Form.Item label={t("jobs.fields.rate_lau")} name="rate_lau">
<CurrencyInput disabled={jobRO} /> <CurrencyInput min={0} disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_mapa")} name="rate_mapa"> <Form.Item label={t("jobs.fields.rate_mapa")} name="rate_mapa">
<CurrencyInput disabled={jobRO} /> <CurrencyInput min={0} disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_mash")} name="rate_mash"> <Form.Item label={t("jobs.fields.rate_mash")} name="rate_mash">
<CurrencyInput disabled={jobRO} /> <CurrencyInput min={0} disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_mahw")} name="rate_mahw"> <Form.Item label={t("jobs.fields.rate_mahw")} name="rate_mahw">
<CurrencyInput disabled={jobRO} /> <CurrencyInput min={0} disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_ma2s")} name="rate_ma2s"> <Form.Item label={t("jobs.fields.rate_ma2s")} name="rate_ma2s">
<CurrencyInput disabled={jobRO} /> <CurrencyInput min={0} disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_ma3s")} name="rate_ma3s"> <Form.Item label={t("jobs.fields.rate_ma3s")} name="rate_ma3s">
<CurrencyInput disabled={jobRO} /> <CurrencyInput min={0} disabled={jobRO} />
</Form.Item> </Form.Item>
{ {
// <Form.Item label={t("jobs.fields.rate_mabl")} name="rate_mabl"> // <Form.Item label={t("jobs.fields.rate_mabl")} name="rate_mabl">
// <CurrencyInput disabled={jobRO} /> // <CurrencyInput min={0}disabled={jobRO} />
// </Form.Item> // </Form.Item>
// <Form.Item label={t("jobs.fields.rate_macs")} name="rate_macs"> // <Form.Item label={t("jobs.fields.rate_macs")} name="rate_macs">
// <CurrencyInput disabled={jobRO} /> // <CurrencyInput min={0}disabled={jobRO} />
// </Form.Item> // </Form.Item>
} }
<Form.Item label={t("jobs.fields.rate_matd")} name="rate_matd"> <Form.Item label={t("jobs.fields.rate_matd")} name="rate_matd">
<CurrencyInput disabled={jobRO} /> <CurrencyInput min={0} disabled={jobRO} />
</Form.Item> </Form.Item>
</FormRow> </FormRow>
<JobsDetailRatesParts form={form} /> <JobsDetailRatesParts form={form} />

View File

@@ -29,20 +29,6 @@ function JobsDocumentsComponent({
setIndex(index); setIndex(index);
}; };
// useEffect(() => {
// console.log("Added event listening for reteching.");
// window.addEventListener("storage", (ev) => {
// if (ev.key === "refetch" && ev.newValue === true) {
// refetch && refetch();
// localStorage.setItem("refetch", false);
// }
// });
// return () => {
// window.removeEventListener("storage");
// };
// }, [refetch]);
useEffect(() => { useEffect(() => {
let documents = data.reduce( let documents = data.reduce(
(acc, value) => { (acc, value) => {

View File

@@ -69,6 +69,20 @@ export default function JobsFindModalComponent({
); );
}, },
}, },
{
title: t("jobs.fields.ownr_ph2"),
dataIndex: "ownr_ph2",
key: "ownr_ph2",
width: "12%",
ellipsis: true,
render: (text, record) => {
return record.ownr_ph2 ? (
<PhoneFormatter>{record.ownr_ph2}</PhoneFormatter>
) : (
t("general.labels.unknown")
);
},
},
{ {
title: t("jobs.fields.status"), title: t("jobs.fields.status"),
dataIndex: "status", dataIndex: "status",

View File

@@ -73,6 +73,16 @@ export function JobsList({ bodyshop, refetch, loading, jobs, total }) {
<StartChatButton phone={record.ownr_ph1} jobid={record.id} /> <StartChatButton phone={record.ownr_ph1} jobid={record.id} />
), ),
}, },
{
title: t("jobs.fields.ownr_ph2"),
dataIndex: "ownr_ph2",
key: "ownr_ph2",
width: "12%",
ellipsis: true,
render: (text, record) => (
<StartChatButton phone={record.ownr_ph2} jobid={record.id} />
),
},
{ {
title: t("jobs.fields.status"), title: t("jobs.fields.status"),
dataIndex: "status", dataIndex: "status",

View File

@@ -145,6 +145,16 @@ export function JobsList({ bodyshop }) {
<ChatOpenButton phone={record.ownr_ph1} jobid={record.id} /> <ChatOpenButton phone={record.ownr_ph1} jobid={record.id} />
), ),
}, },
{
title: t("jobs.fields.ownr_ph2"),
dataIndex: "ownr_ph2",
key: "ownr_ph2",
ellipsis: true,
responsive: ["md"],
render: (text, record) => (
<ChatOpenButton phone={record.ownr_ph2} jobid={record.id} />
),
},
{ {
title: t("jobs.fields.status"), title: t("jobs.fields.status"),

View File

@@ -81,6 +81,16 @@ export default function OwnerDetailFormComponent({ form, loading }) {
> >
<FormItemPhone /> <FormItemPhone />
</Form.Item> </Form.Item>
<Form.Item
label={t("owners.fields.ownr_ph2")}
name="ownr_ph2"
rules={[
({ getFieldValue }) =>
PhoneItemFormatterValidation(getFieldValue, "ownr_ph2"),
]}
>
<FormItemPhone />
</Form.Item>
<Form.Item <Form.Item
label={t("owners.fields.preferred_contact")} label={t("owners.fields.preferred_contact")}
name="preferred_contact" name="preferred_contact"

View File

@@ -51,6 +51,14 @@ export default function OwnerFindModalComponent({
<PhoneFormatter>{record.ownr_ph1}</PhoneFormatter> <PhoneFormatter>{record.ownr_ph1}</PhoneFormatter>
), ),
}, },
{
title: t("owners.fields.ownr_ph2"),
dataIndex: "ownr_ph2",
key: "ownr_ph2",
render: (text, record) => (
<PhoneFormatter>{record.ownr_ph2}</PhoneFormatter>
),
},
]; ];
const handleOnRowClick = (record) => { const handleOnRowClick = (record) => {

View File

@@ -16,6 +16,9 @@ export default function OwnerTagPopoverComponent({ job }) {
<Descriptions.Item key="2" label={t("jobs.fields.ownr_ph1")}> <Descriptions.Item key="2" label={t("jobs.fields.ownr_ph1")}>
<PhoneFormatter>{job.ownr_ph1 || ""}</PhoneFormatter> <PhoneFormatter>{job.ownr_ph1 || ""}</PhoneFormatter>
</Descriptions.Item> </Descriptions.Item>
<Descriptions.Item key="22" label={t("jobs.fields.ownr_ph2")}>
<PhoneFormatter>{job.ownr_ph2 || ""}</PhoneFormatter>
</Descriptions.Item>
<Descriptions.Item key="3" label={t("owners.fields.address")}> <Descriptions.Item key="3" label={t("owners.fields.address")}>
{`${job.ownr_addr1 || ""} ${job.ownr_addr2 || ""} ${ {`${job.ownr_addr1 || ""} ${job.ownr_addr2 || ""} ${
job.ownr_city || "" job.ownr_city || ""
@@ -36,6 +39,12 @@ export default function OwnerTagPopoverComponent({ job }) {
<Descriptions.Item key="2" label={t("jobs.fields.ownr_ph1")}> <Descriptions.Item key="2" label={t("jobs.fields.ownr_ph1")}>
<PhoneFormatter>{job.owner.ownr_ph1 || ""}</PhoneFormatter> <PhoneFormatter>{job.owner.ownr_ph1 || ""}</PhoneFormatter>
</Descriptions.Item> </Descriptions.Item>
<Descriptions.Item key="22" label={t("jobs.fields.ownr_ph2")}>
<PhoneFormatter>{job.owner.ownr_ph2 || ""}</PhoneFormatter>
</Descriptions.Item>
<Descriptions.Item key="2" label={t("jobs.fields.ownr_ph2")}>
<PhoneFormatter>{job.owner.ownr_ph2 || ""}</PhoneFormatter>
</Descriptions.Item>
<Descriptions.Item key="3" label={t("owners.fields.address")}> <Descriptions.Item key="3" label={t("owners.fields.address")}>
{`${job.owner.ownr_addr1 || ""} ${job.owner.ownr_addr2 || ""} ${ {`${job.owner.ownr_addr1 || ""} ${job.owner.ownr_addr2 || ""} ${
job.owner.ownr_city || "" job.owner.ownr_city || ""

View File

@@ -47,6 +47,14 @@ export default function OwnersListComponent({
return <PhoneFormatter>{record.ownr_ph1}</PhoneFormatter>; return <PhoneFormatter>{record.ownr_ph1}</PhoneFormatter>;
}, },
}, },
{
title: t("owners.fields.ownr_ph2"),
dataIndex: "ownr_ph2",
key: "ownr_ph2",
render: (text, record) => {
return <PhoneFormatter>{record.ownr_ph2}</PhoneFormatter>;
},
},
{ {
title: t("owners.fields.ownr_ea"), title: t("owners.fields.ownr_ea"),
dataIndex: "ownr_ea", dataIndex: "ownr_ea",

View File

@@ -27,6 +27,7 @@ import CurrencyFormatter from "../../utils/CurrencyFormatter";
import { DateFormatter } from "../../utils/DateFormatter"; import { DateFormatter } from "../../utils/DateFormatter";
import { alphaSort } from "../../utils/sorters"; import { alphaSort } from "../../utils/sorters";
import { TemplateList } from "../../utils/TemplateConstants"; import { TemplateList } from "../../utils/TemplateConstants";
import DataLabel from "../data-label/data-label.component";
import PartsOrderBackorderEta from "../parts-order-backorder-eta/parts-order-backorder-eta.component"; import PartsOrderBackorderEta from "../parts-order-backorder-eta/parts-order-backorder-eta.component";
import PartsOrderLineBackorderButton from "../parts-order-line-backorder-button/parts-order-line-backorder-button.component"; import PartsOrderLineBackorderButton from "../parts-order-line-backorder-button/parts-order-line-backorder-button.component";
import PartsReceiveModalContainer from "../parts-receive-modal/parts-receive-modal.container"; import PartsReceiveModalContainer from "../parts-receive-modal/parts-receive-modal.container";
@@ -379,6 +380,9 @@ export function PartsOrderListTableComponent({
rowKey="id" rowKey="id"
dataSource={record.parts_order_lines} dataSource={record.parts_order_lines}
/> />
<DataLabel label={t("parts_orders.fields.comments")}>
<div style={{ whiteSpace: "pre" }}>{record.comments}</div>
</DataLabel>
</div> </div>
); );
}; };

View File

@@ -73,7 +73,7 @@ export default function PartsOrderModalComponent({
<Form.Item required={false} key={field.key}> <Form.Item required={false} key={field.key}>
<LayoutFormRow grow noDivider> <LayoutFormRow grow noDivider>
<Form.Item <Form.Item
span={8} //span={8}
label={t("parts_orders.fields.line_desc")} label={t("parts_orders.fields.line_desc")}
key={`${index}line_desc`} key={`${index}line_desc`}
name={[field.name, "line_desc"]} name={[field.name, "line_desc"]}
@@ -132,19 +132,21 @@ export default function PartsOrderModalComponent({
</Form.Item> </Form.Item>
)} )}
<div> <Space wrap align="center">
<DeleteFilled <div>
style={{ margin: "1rem" }} <DeleteFilled
onClick={() => { style={{ margin: "1rem" }}
remove(field.name); onClick={() => {
}} remove(field.name);
/> }}
/>
</div>
<FormListMoveArrows <FormListMoveArrows
move={move} move={move}
index={index} index={index}
total={fields.length} total={fields.length}
/> />
</div> </Space>
</LayoutFormRow> </LayoutFormRow>
</Form.Item> </Form.Item>
))} ))}
@@ -152,6 +154,9 @@ export default function PartsOrderModalComponent({
); );
}} }}
</Form.List> </Form.List>
<Form.Item name="comments" label={t("parts_orders.fields.comments")}>
<Input.TextArea rows={3} />
</Form.Item>
<Radio.Group <Radio.Group
defaultValue={sendType} defaultValue={sendType}
onChange={(e) => setSendType(e.target.value)} onChange={(e) => setSendType(e.target.value)}

View File

@@ -260,7 +260,7 @@ export function PartsOrderModalContainer({
onCancel={() => toggleModalVisible()} onCancel={() => toggleModalVisible()}
onOk={() => form.submit()} onOk={() => form.submit()}
destroyOnClose destroyOnClose
width="50%" width="75%"
forceRender forceRender
> >
{error ? <AlertComponent message={error.message} type="error" /> : null} {error ? <AlertComponent message={error.message} type="error" /> : null}

View File

@@ -38,6 +38,7 @@ export function ProductionBoardFilters({
}} }}
/> />
<EmployeeSearchSelectComponent <EmployeeSearchSelectComponent
style={{ minWidth: "20rem" }}
options={bodyshop.employees.filter((e) => e.active)} options={bodyshop.employees.filter((e) => e.active)}
value={filter.employeeId} value={filter.employeeId}
placeholder={t("production.labels.employeesearch")} placeholder={t("production.labels.employeesearch")}

View File

@@ -15,6 +15,7 @@ import ProductionListColumnPaintPriority from "./production-list-columns.paintpr
import ProductionListColumnNote from "./production-list-columns.productionnote.component"; import ProductionListColumnNote from "./production-list-columns.productionnote.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";
import ProductionListLastContacted from "./production-list-columns.lastcontacted.component";
const r = ({ technician, state }) => { const r = ({ technician, state }) => {
return [ return [
@@ -97,6 +98,17 @@ const r = ({ technician, state }) => {
<ProductionListDate record={record} field="scheduled_completion" /> <ProductionListDate record={record} field="scheduled_completion" />
), ),
}, },
{
title: i18n.t("jobs.fields.date_last_contacted"),
dataIndex: "date_last_contacted",
key: "date_last_contacted",
ellipsis: true,
sorter: (a, b) => dateSort(a.date_last_contacted, b.date_last_contacted),
sortOrder:
state.sortedInfo.columnKey === "date_last_contacted" &&
state.sortedInfo.order,
render: (text, record) => <ProductionListLastContacted record={record} />,
},
{ {
title: i18n.t("jobs.fields.scheduled_delivery"), title: i18n.t("jobs.fields.scheduled_delivery"),
dataIndex: "scheduled_delivery", dataIndex: "scheduled_delivery",
@@ -161,6 +173,15 @@ const r = ({ technician, state }) => {
<PhoneFormatter>{record.ownr_ph1}</PhoneFormatter> <PhoneFormatter>{record.ownr_ph1}</PhoneFormatter>
), ),
}, },
{
title: i18n.t("jobs.fields.ownr_ph2"),
dataIndex: "ownr_ph2",
key: "ownr_ph2",
ellipsis: true,
render: (text, record) => (
<PhoneFormatter>{record.ownr_ph2}</PhoneFormatter>
),
},
{ {
title: i18n.t("jobs.fields.specialcoveragepolicy"), title: i18n.t("jobs.fields.specialcoveragepolicy"),
dataIndex: "special_coverage_policy", dataIndex: "special_coverage_policy",

View File

@@ -1,17 +1,20 @@
import { useMutation } from "@apollo/client"; import { useMutation } from "@apollo/client";
import { DatePicker, Dropdown } from "antd"; import { DatePicker, Dropdown, TimePicker, Button, Card } from "antd";
import moment from "moment"; import moment from "moment";
import React from "react"; import React, { useState } from "react";
import { logImEXEvent } from "../../firebase/firebase.utils"; import { logImEXEvent } from "../../firebase/firebase.utils";
import { UPDATE_JOB } from "../../graphql/jobs.queries"; import { UPDATE_JOB } from "../../graphql/jobs.queries";
import { DateFormatter } from "../../utils/DateFormatter"; import { DateFormatter } from "../../utils/DateFormatter";
import { useTranslation } from "react-i18next";
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, time }) {
const [updateAlert] = useMutation(UPDATE_JOB); const [updateAlert] = useMutation(UPDATE_JOB);
const [visible, setVisible] = useState(false);
const { t } = useTranslation();
const handleChange = (date) => { const handleChange = (date) => {
logImEXEvent("product_toggle_date", { field }); logImEXEvent("product_toggle_date", { field });
@@ -25,27 +28,47 @@ export default function ProductionListDate({ record, field }) {
}, },
}).then(() => { }).then(() => {
if (record.refetch) record.refetch(); if (record.refetch) record.refetch();
if (!time) {
setVisible(false);
}
}); });
}; };
return ( return (
<div> <div>
<Dropdown <Dropdown
trigger={["click"]} //trigger={["click"]}
visible={visible}
style={{ style={{
height: "19px", height: "19px",
}} }}
overlay={ overlay={
<div onClick={(e) => e.stopPropagation()}> <Card
style={{ padding: "1rem" }}
onClick={(e) => e.stopPropagation()}
>
<DatePicker <DatePicker
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
value={(record[field] && moment(record[field])) || null} value={(record[field] && moment(record[field])) || null}
onChange={handleChange} onChange={handleChange}
format="MM/DD/YYYY"
/> />
</div> {time && (
<TimePicker
onClick={(e) => e.stopPropagation()}
value={(record[field] && moment(record[field])) || null}
onChange={handleChange}
format="hh:mm a"
/>
)}
<Button onClick={() => setVisible(false)}>
{t("general.actions.close")}
</Button>
</Card>
} }
> >
<div <div
onClick={() => setVisible(true)}
style={{ style={{
height: "19px", height: "19px",
}} }}

View File

@@ -0,0 +1,132 @@
import { useMutation } from "@apollo/client";
import { Button, Card, Dropdown, Form, Input, notification, Space } from "antd";
import moment from "moment";
import React, { useState, useEffect } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { logImEXEvent } from "../../firebase/firebase.utils";
import { UPDATE_JOB } from "../../graphql/jobs.queries";
import { INSERT_NEW_NOTE } from "../../graphql/notes.queries";
import { selectCurrentUser } from "../../redux/user/user.selectors";
import { DateFormatter } from "../../utils/DateFormatter";
import FormDateTimePickerComponent from "../form-date-time-picker/form-date-time-picker.component";
const mapStateToProps = createStructuredSelector({
currentUser: selectCurrentUser,
});
const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language))
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(ProductionLastContacted);
export function ProductionLastContacted({ currentUser, record }) {
const [updateAlert] = useMutation(UPDATE_JOB);
const [insertNote] = useMutation(INSERT_NEW_NOTE);
const [visible, setVisible] = useState(false);
const { t } = useTranslation();
const [form] = Form.useForm();
const handleFinish = async ({ date_last_contacted, note }) => {
logImEXEvent("production_last_contacted");
//e.stopPropagation();
const res = await updateAlert({
variables: {
jobId: record.id,
job: {
date_last_contacted,
},
},
});
if (res.errors) {
notification.open({
type: "error",
message: t("jobs.errors.saving", {
error: JSON.stringify(res.errors),
}),
});
}
if (note && note.trim() !== "") {
//Insert a note.
const res2 = await insertNote({
variables: {
noteInput: {
jobid: record.id,
text: note,
created_by: currentUser.email,
},
},
});
if (res2.errors) {
notification.open({
type: "error",
message: t("notes.errors.inserting", {
error: JSON.stringify(res.errors),
}),
});
}
}
if (record.refetch) record.refetch();
setVisible(false);
};
useEffect(() => {
if (visible) {
form.setFieldsValue({
note: null,
date_last_contacted:
record.date_last_contacted && moment(record.date_last_contacted),
});
}
}, [visible, form, record.date_last_contacted]);
return (
<div>
<Dropdown
//trigger={["click"]}
visible={visible}
style={{
height: "19px",
}}
overlay={
<Card
style={{ padding: "1rem" }}
onClick={(e) => e.stopPropagation()}
>
<Form form={form} onFinish={handleFinish} layout="vertical">
<Form.Item name="date_last_contacted">
<FormDateTimePickerComponent />
</Form.Item>
<Form.Item label={t("notes.labels.notetoadd")} name="note">
<Input.TextArea rows={4} />
</Form.Item>
<Space>
<Button type="primary" htmlType="submit">
{t("general.actions.save")}
</Button>
<Button onClick={() => setVisible(false)}>
{t("general.actions.close")}
</Button>
</Space>
</Form>
</Card>
}
>
<div
onClick={() => setVisible(true)}
style={{
height: "19px",
}}
>
<DateFormatter bordered={false}>
{record.date_last_contacted}
</DateFormatter>
</div>
</Dropdown>
</div>
);
}

View File

@@ -77,6 +77,10 @@ export default function ProductionListDetail({ jobs }) {
phone={data.jobs_by_pk.ownr_ph1} phone={data.jobs_by_pk.ownr_ph1}
jobid={data.jobs_by_pk.id} jobid={data.jobs_by_pk.id}
/> />
<StartChatButton
phone={data.jobs_by_pk.ownr_ph2}
jobid={data.jobs_by_pk.id}
/>
</Descriptions.Item> </Descriptions.Item>
<Descriptions.Item label={t("jobs.fields.vehicle")}> <Descriptions.Item label={t("jobs.fields.vehicle")}>
{`${theJob.v_model_yr || ""} ${theJob.v_color || ""} ${ {`${theJob.v_model_yr || ""} ${theJob.v_color || ""} ${

View File

@@ -66,12 +66,7 @@ export function ProductionListSaveConfigButton({
}; };
const popMenu = ( const popMenu = (
<div> <div>
<Form <Form layout="vertical" form={form} onFinish={handleSaveConfig}>
layout="vertical"
form={form}
onFinish={handleSaveConfig}
initialValues={{ driveable: true, towin: false }}
>
<Form.Item <Form.Item
label={t("production.labels.viewname")} label={t("production.labels.viewname")}
name="name" name="name"

View File

@@ -55,6 +55,19 @@ export function ProductionListTable({
if (assoc) { if (assoc) {
await updateDefaultProdView({ await updateDefaultProdView({
variables: { assocId: assoc.id, view: value }, variables: { assocId: assoc.id, view: value },
update(cache) {
cache.modify({
id: cache.identify(bodyshop),
fields: {
associations(existingAssociations, { readField }) {
return existingAssociations.map((a) => {
if (a.useremail !== currentUser.email) return a;
return { ...a, default_prod_list_view: value };
});
},
},
});
},
}); });
} }
}; };
@@ -85,13 +98,18 @@ export function ProductionListTable({
setState(bodyshop.production_config[0].columns.tableState); setState(bodyshop.production_config[0].columns.tableState);
}; };
const assoc = bodyshop.associations.find(
(a) => a.useremail === currentUser.email
);
const defaultView = assoc && assoc.default_prod_list_view;
return ( return (
<div style={{ width: "10rem" }}> <div style={{ width: "10rem" }}>
<Select <Select
onSelect={handleSelect} onSelect={handleSelect}
placeholder={t("production.labels.selectview")} placeholder={t("production.labels.selectview")}
optionLabelProp="label" optionLabelProp="label"
defaultValue={defaultView}
> >
{bodyshop.production_config.map((config) => ( {bodyshop.production_config.map((config) => (
<Select.Option key={config.name} label={config.name}> <Select.Option key={config.name} label={config.name}>

View File

@@ -32,12 +32,11 @@ export function ProductionListTable({
}) { }) {
const [searchText, setSearchText] = useState(""); const [searchText, setSearchText] = useState("");
const defaultView = useMemo(() => { const assoc = bodyshop.associations.find(
const assoc = bodyshop.associations.find( (a) => a.useremail === currentUser.email
(a) => a.useremail === currentUser.email );
);
return assoc && assoc.default_prod_list_view; const defaultView = assoc && assoc.default_prod_list_view;
}, [bodyshop.associations, currentUser.email]);
const [state, setState] = useState( const [state, setState] = useState(
(bodyshop.production_config && (bodyshop.production_config &&

View File

@@ -124,7 +124,7 @@ export function ScheduleJobModalComponent({
handleDateBlur(); handleDateBlur();
}} }}
> >
<DateFormatter>{d}</DateFormatter> <DateFormatter includeDay>{d}</DateFormatter>
</Button> </Button>
))} ))}
</Space> </Space>

View File

@@ -42,7 +42,7 @@ export default function ShopInfoLaborRates({ form }) {
}, },
]} ]}
> >
<CurrencyInput /> <CurrencyInput min={0} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.rate_lab")} label={t("jobs.fields.rate_lab")}
@@ -55,7 +55,7 @@ export default function ShopInfoLaborRates({ form }) {
}, },
]} ]}
> >
<CurrencyInput /> <CurrencyInput min={0} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.rate_lad")} label={t("jobs.fields.rate_lad")}
@@ -68,7 +68,7 @@ export default function ShopInfoLaborRates({ form }) {
}, },
]} ]}
> >
<CurrencyInput /> <CurrencyInput min={0} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.rate_lae")} label={t("jobs.fields.rate_lae")}
@@ -81,7 +81,7 @@ export default function ShopInfoLaborRates({ form }) {
}, },
]} ]}
> >
<CurrencyInput /> <CurrencyInput min={0} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.rate_laf")} label={t("jobs.fields.rate_laf")}
@@ -94,7 +94,7 @@ export default function ShopInfoLaborRates({ form }) {
}, },
]} ]}
> >
<CurrencyInput /> <CurrencyInput min={0} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.rate_lag")} label={t("jobs.fields.rate_lag")}
@@ -107,7 +107,7 @@ export default function ShopInfoLaborRates({ form }) {
}, },
]} ]}
> >
<CurrencyInput /> <CurrencyInput min={0} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.rate_lam")} label={t("jobs.fields.rate_lam")}
@@ -120,7 +120,7 @@ export default function ShopInfoLaborRates({ form }) {
}, },
]} ]}
> >
<CurrencyInput /> <CurrencyInput min={0} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.rate_lar")} label={t("jobs.fields.rate_lar")}
@@ -133,7 +133,7 @@ export default function ShopInfoLaborRates({ form }) {
}, },
]} ]}
> >
<CurrencyInput /> <CurrencyInput min={0} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.rate_las")} label={t("jobs.fields.rate_las")}
@@ -146,7 +146,7 @@ export default function ShopInfoLaborRates({ form }) {
}, },
]} ]}
> >
<CurrencyInput /> <CurrencyInput min={0} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.rate_la1")} label={t("jobs.fields.rate_la1")}
@@ -159,7 +159,7 @@ export default function ShopInfoLaborRates({ form }) {
}, },
]} ]}
> >
<CurrencyInput /> <CurrencyInput min={0} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.rate_la2")} label={t("jobs.fields.rate_la2")}
@@ -172,7 +172,7 @@ export default function ShopInfoLaborRates({ form }) {
}, },
]} ]}
> >
<CurrencyInput /> <CurrencyInput min={0} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.rate_la3")} label={t("jobs.fields.rate_la3")}
@@ -185,7 +185,7 @@ export default function ShopInfoLaborRates({ form }) {
}, },
]} ]}
> >
<CurrencyInput /> <CurrencyInput min={0} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.rate_la4")} label={t("jobs.fields.rate_la4")}
@@ -198,7 +198,7 @@ export default function ShopInfoLaborRates({ form }) {
}, },
]} ]}
> >
<CurrencyInput /> <CurrencyInput min={0} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.rate_mash")} label={t("jobs.fields.rate_mash")}
@@ -211,7 +211,7 @@ export default function ShopInfoLaborRates({ form }) {
}, },
]} ]}
> >
<CurrencyInput /> <CurrencyInput min={0} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.rate_mapa")} label={t("jobs.fields.rate_mapa")}
@@ -224,7 +224,7 @@ export default function ShopInfoLaborRates({ form }) {
}, },
]} ]}
> >
<CurrencyInput /> <CurrencyInput min={0} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.rate_ma2s")} label={t("jobs.fields.rate_ma2s")}
@@ -237,7 +237,7 @@ export default function ShopInfoLaborRates({ form }) {
}, },
]} ]}
> >
<CurrencyInput /> <CurrencyInput min={0} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.rate_ma3s")} label={t("jobs.fields.rate_ma3s")}
@@ -250,7 +250,7 @@ export default function ShopInfoLaborRates({ form }) {
}, },
]} ]}
> >
<CurrencyInput /> <CurrencyInput min={0} />
</Form.Item> </Form.Item>
{ {
// <Form.Item // <Form.Item
@@ -264,7 +264,7 @@ export default function ShopInfoLaborRates({ form }) {
// }, // },
// ]} // ]}
// > // >
// <CurrencyInput /> // <CurrencyInput min={0} />
// </Form.Item> // </Form.Item>
// <Form.Item // <Form.Item
// label={t("jobs.fields.rate_macs")} // label={t("jobs.fields.rate_macs")}
@@ -277,7 +277,7 @@ export default function ShopInfoLaborRates({ form }) {
// }, // },
// ]} // ]}
// > // >
// <CurrencyInput /> // <CurrencyInput min={0} />
// </Form.Item> // </Form.Item>
} }
<Form.Item <Form.Item
@@ -291,7 +291,7 @@ export default function ShopInfoLaborRates({ form }) {
}, },
]} ]}
> >
<CurrencyInput /> <CurrencyInput min={0} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.rate_mahw")} label={t("jobs.fields.rate_mahw")}
@@ -304,7 +304,7 @@ export default function ShopInfoLaborRates({ form }) {
}, },
]} ]}
> >
<CurrencyInput /> <CurrencyInput min={0} />
</Form.Item> </Form.Item>
<DeleteFilled <DeleteFilled
onClick={() => { onClick={() => {

View File

@@ -50,7 +50,9 @@ export function TechClockInComponent({ form, bodyshop, technician }) {
{emps && {emps &&
emps.rates.map((item) => ( emps.rates.map((item) => (
<Select.Option key={item.cost_center}> <Select.Option key={item.cost_center}>
{item.cost_center} {item.cost_center === "timetickets.labels.shift"
? t(item.cost_center)
: item.cost_center}
</Select.Option> </Select.Option>
))} ))}
</Select> </Select>

View File

@@ -139,7 +139,9 @@ export function TechClockOffButton({
emps && emps &&
emps.rates.map((item) => ( emps.rates.map((item) => (
<Select.Option key={item.cost_center}> <Select.Option key={item.cost_center}>
{item.cost_center} {item.cost_center === "timetickets.labels.shift"
? t(item.cost_center)
: item.cost_center}
</Select.Option> </Select.Option>
)) ))
)} )}

View File

@@ -83,7 +83,9 @@ export function TechClockedInList({ technician }) {
<DateTimeFormatter>{ticket.clockon}</DateTimeFormatter> <DateTimeFormatter>{ticket.clockon}</DateTimeFormatter>
</DataLabel> </DataLabel>
<DataLabel label={t("timetickets.fields.cost_center")}> <DataLabel label={t("timetickets.fields.cost_center")}>
{ticket.cost_center} {ticket.cost_center === "timetickets.labels.shift"
? t(ticket.cost_center)
: ticket.cost_center}
</DataLabel> </DataLabel>
</Card> </Card>
</List.Item> </List.Item>

View File

@@ -28,6 +28,7 @@ export const QUERY_ALL_ACTIVE_APPOINTMENTS = gql`
ownr_co_nm ownr_co_nm
ownr_fn ownr_fn
ownr_ph1 ownr_ph1
ownr_ph2
ownr_ea ownr_ea
clm_total clm_total
id id
@@ -126,6 +127,7 @@ export const QUERY_APPOINTMENT_BY_DATE = gql`
ownr_ln ownr_ln
ownr_fn ownr_fn
ownr_ph1 ownr_ph1
ownr_ph2
ownr_ea ownr_ea
clm_total clm_total
id id

View File

@@ -93,6 +93,7 @@ export const QUERY_BILLS_BY_JOBID = gql`
backordered_on backordered_on
} }
order_number order_number
comments
user_email user_email
} }
bills(where: { jobid: { _eq: $jobid } }, order_by: { date: desc }) { bills(where: { jobid: { _eq: $jobid } }, order_by: { date: desc }) {

View File

@@ -10,6 +10,7 @@ export const QUERY_ALL_ACTIVE_JOBS = gql`
ownr_ln ownr_ln
ownr_co_nm ownr_co_nm
ownr_ph1 ownr_ph1
ownr_ph2
ownr_ea ownr_ea
owner { owner {
id id
@@ -79,6 +80,7 @@ export const QUERY_PARTS_QUEUE = gql`
ownr_ln ownr_ln
ownr_co_nm ownr_co_nm
ownr_ph1 ownr_ph1
ownr_ph2
ownr_ea ownr_ea
plate_no plate_no
plate_st plate_st
@@ -122,9 +124,11 @@ export const SUBSCRIPTION_JOBS_IN_PRODUCTION = gql`
actual_in actual_in
scheduled_completion scheduled_completion
scheduled_delivery scheduled_delivery
date_last_contacted
ins_co_nm ins_co_nm
clm_total clm_total
ownr_ph1 ownr_ph1
ownr_ph2
special_coverage_policy special_coverage_policy
owner_owing owner_owing
production_vars production_vars
@@ -359,6 +363,7 @@ export const GET_JOB_BY_PK = gql`
kmin kmin
kmout kmout
referral_source referral_source
referral_source_extra
unit_number unit_number
po_number po_number
special_coverage_policy special_coverage_policy
@@ -454,6 +459,7 @@ export const GET_JOB_BY_PK = gql`
ownr_zip ownr_zip
ownr_ctry ownr_ctry
ownr_ph1 ownr_ph1
ownr_ph2
production_vars production_vars
ca_gst_registrant ca_gst_registrant
ownerid ownerid
@@ -470,6 +476,7 @@ export const GET_JOB_BY_PK = gql`
ownr_zip ownr_zip
ownr_ctry ownr_ctry
ownr_ph1 ownr_ph1
ownr_ph2
} }
labor_rate_desc labor_rate_desc
rate_la1 rate_la1
@@ -508,6 +515,7 @@ export const GET_JOB_BY_PK = gql`
date_open date_open
date_scheduled date_scheduled
date_invoiced date_invoiced
date_last_contacted
date_exported date_exported
status status
owner_owing owner_owing
@@ -563,6 +571,7 @@ export const GET_JOB_BY_PK = gql`
parts_order { parts_order {
id id
order_number order_number
comments
order_date order_date
user_email user_email
vendor { vendor {
@@ -626,7 +635,7 @@ export const GET_JOB_RECONCILIATION_BY_PK = gql`
is_credit_memo is_credit_memo
isinhouse isinhouse
exported exported
billlines { billlines(where: { deductedfromlbr: { _eq: false } }) {
actual_price actual_price
quantity quantity
actual_cost actual_cost
@@ -684,8 +693,10 @@ export const QUERY_JOB_CARD_DETAILS = gql`
ownr_ln ownr_ln
ownr_co_nm ownr_co_nm
ownr_ph1 ownr_ph1
ownr_ph2
ownr_ea ownr_ea
ca_gst_registrant ca_gst_registrant
owner_owing
special_coverage_policy special_coverage_policy
available_jobs { available_jobs {
id id
@@ -745,6 +756,7 @@ export const QUERY_JOB_CARD_DETAILS = gql`
scheduled_in scheduled_in
scheduled_delivery scheduled_delivery
date_invoiced date_invoiced
date_last_contacted
date_open date_open
date_exported date_exported
@@ -830,6 +842,7 @@ export const QUERY_TECH_JOB_DETAILS = gql`
scheduled_in scheduled_in
scheduled_delivery scheduled_delivery
date_invoiced date_invoiced
date_last_contacted
date_open date_open
date_exported date_exported
voided voided
@@ -964,6 +977,7 @@ export const CONVERT_JOB_TO_RO = gql`
$driveable: Boolean $driveable: Boolean
$towin: Boolean $towin: Boolean
$referral_source: String $referral_source: String
$referral_source_extra: String
) { ) {
update_jobs( update_jobs(
where: { id: { _eq: $jobId } } where: { id: { _eq: $jobId } }
@@ -975,6 +989,7 @@ export const CONVERT_JOB_TO_RO = gql`
towin: $towin towin: $towin
driveable: $driveable driveable: $driveable
referral_source: $referral_source referral_source: $referral_source
referral_source_extra: $referral_source_extra
} }
) { ) {
returning { returning {
@@ -984,6 +999,7 @@ export const CONVERT_JOB_TO_RO = gql`
class class
ins_co_nm ins_co_nm
referral_source referral_source
referral_source_extra
} }
} }
} }
@@ -1008,6 +1024,7 @@ export const GET_JOB_INFO_FOR_STRIPE = gql`
ownr_ln ownr_ln
ownr_co_nm ownr_co_nm
ownr_ph1 ownr_ph1
ownr_ph2
ownr_ea ownr_ea
} }
} }
@@ -1497,6 +1514,7 @@ export const QUERY_ALL_JOB_FIELDS = gql`
rate_mash rate_mash
rate_matd rate_matd
referral_source referral_source
referral_source_extra
regie_number regie_number
selling_dealer selling_dealer
selling_dealer_contact selling_dealer_contact
@@ -1643,6 +1661,7 @@ export const QUERY_ALL_JOBS_PAGINATED_STATUS_FILTERED = gql`
ownr_co_nm ownr_co_nm
ownerid ownerid
ownr_ph1 ownr_ph1
ownr_ph2
ownr_ea ownr_ea
plate_no plate_no
plate_st plate_st
@@ -1858,6 +1877,7 @@ export const GET_JOB_FOR_CC_CONTRACT = gql`
ownr_city ownr_city
ownr_zip ownr_zip
ownr_ph1 ownr_ph1
ownr_ph2
} }
} }
`; `;

View File

@@ -23,6 +23,7 @@ export const GLOBAL_SEARCH_QUERY = gql`
ownr_ln ownr_ln
ownr_co_nm ownr_co_nm
ownr_ph1 ownr_ph1
ownr_ph2
} }
search_vehicles(args: { search: $search }) { search_vehicles(args: { search: $search }) {
id id

View File

@@ -1055,6 +1055,7 @@
"profitcenter_part": "Profit Center: Part", "profitcenter_part": "Profit Center: Part",
"prt_dsmk_p": "Line Markup %", "prt_dsmk_p": "Line Markup %",
"status": "Status", "status": "Status",
"tax_part": "Tax Part",
"total": "Total", "total": "Total",
"unq_seq": "Seq #" "unq_seq": "Seq #"
}, },
@@ -1197,6 +1198,7 @@
"date_estimated": "Date Estimated", "date_estimated": "Date Estimated",
"date_exported": "Exported", "date_exported": "Exported",
"date_invoiced": "Invoiced", "date_invoiced": "Invoiced",
"date_last_contacted": "Last Contacted Date",
"date_open": "Open", "date_open": "Open",
"date_scheduled": "Scheduled", "date_scheduled": "Scheduled",
"ded_amt": "Deductible", "ded_amt": "Deductible",
@@ -1288,6 +1290,7 @@
"owner_owing": "Cust. Owes", "owner_owing": "Cust. Owes",
"ownr_ea": "Email", "ownr_ea": "Email",
"ownr_ph1": "Phone 1", "ownr_ph1": "Phone 1",
"ownr_ph2": "Phone 2",
"paa": "Aftermarket", "paa": "Aftermarket",
"pac": "Rechromed", "pac": "Rechromed",
"pae": "Existing", "pae": "Existing",
@@ -1336,6 +1339,8 @@
"rate_mapa": "Paint Materials", "rate_mapa": "Paint Materials",
"rate_mash": "Shop Material", "rate_mash": "Shop Material",
"rate_matd": "Tire Disposal", "rate_matd": "Tire Disposal",
"referral_source_extra": "Other Referral Source",
"referral_source_other": "",
"referralsource": "Referral Source", "referralsource": "Referral Source",
"regie_number": "Registration #", "regie_number": "Registration #",
"repairtotal": "Repair Total", "repairtotal": "Repair Total",
@@ -1734,6 +1739,9 @@
"edit": "Edit Note", "edit": "Edit Note",
"new": "New Note" "new": "New Note"
}, },
"errors": {
"inserting": "Error inserting note. {{error}}"
},
"fields": { "fields": {
"createdby": "Created By", "createdby": "Created By",
"critical": "Critical", "critical": "Critical",
@@ -1742,7 +1750,8 @@
"updatedat": "Updated At" "updatedat": "Updated At"
}, },
"labels": { "labels": {
"newnoteplaceholder": "Add a note..." "newnoteplaceholder": "Add a note...",
"notetoadd": "Note to Add"
}, },
"successes": { "successes": {
"create": "Note created successfully.", "create": "Note created successfully.",
@@ -1771,6 +1780,7 @@
"ownr_fn": "First Name", "ownr_fn": "First Name",
"ownr_ln": "Last Name", "ownr_ln": "Last Name",
"ownr_ph1": "Phone 1", "ownr_ph1": "Phone 1",
"ownr_ph2": "Phone 2",
"ownr_st": "Province/State", "ownr_st": "Province/State",
"ownr_title": "Title", "ownr_title": "Title",
"ownr_zip": "Zip/Postal Code", "ownr_zip": "Zip/Postal Code",
@@ -1812,9 +1822,10 @@
"act_price": "Price", "act_price": "Price",
"backordered_eta": "B.O. ETA", "backordered_eta": "B.O. ETA",
"backordered_on": "B.O. On", "backordered_on": "B.O. On",
"comments": "Comments",
"cost": "Cost", "cost": "Cost",
"db_price": "List Price", "db_price": "List Price",
"deliver_by": "Date", "deliver_by": "Deliver By",
"job_line_id": "Job Line Id", "job_line_id": "Job Line Id",
"line_desc": "Line Description", "line_desc": "Line Description",
"line_remarks": "Remarks", "line_remarks": "Remarks",
@@ -2022,7 +2033,7 @@
}, },
"subjects": { "subjects": {
"jobs": { "jobs": {
"parts_order": "$t(printcenter.jobs.parts_order) PO: {{ro_number}}" "parts_order": "Parts Order PO: {{ro_number}}"
} }
}, },
"vendors": { "vendors": {

View File

@@ -1055,6 +1055,7 @@
"profitcenter_part": "", "profitcenter_part": "",
"prt_dsmk_p": "", "prt_dsmk_p": "",
"status": "Estado", "status": "Estado",
"tax_part": "",
"total": "", "total": "",
"unq_seq": "Seq #" "unq_seq": "Seq #"
}, },
@@ -1197,6 +1198,7 @@
"date_estimated": "Fecha estimada", "date_estimated": "Fecha estimada",
"date_exported": "Exportado", "date_exported": "Exportado",
"date_invoiced": "Facturado", "date_invoiced": "Facturado",
"date_last_contacted": "",
"date_open": "Abierto", "date_open": "Abierto",
"date_scheduled": "Programado", "date_scheduled": "Programado",
"ded_amt": "Deducible", "ded_amt": "Deducible",
@@ -1288,6 +1290,7 @@
"owner_owing": "Cust. Debe", "owner_owing": "Cust. Debe",
"ownr_ea": "Email", "ownr_ea": "Email",
"ownr_ph1": "Teléfono 1", "ownr_ph1": "Teléfono 1",
"ownr_ph2": "",
"paa": "", "paa": "",
"pac": "", "pac": "",
"pae": "", "pae": "",
@@ -1336,6 +1339,8 @@
"rate_mapa": "Tasa de materiales de pintura", "rate_mapa": "Tasa de materiales de pintura",
"rate_mash": "Comprar material de tarifa", "rate_mash": "Comprar material de tarifa",
"rate_matd": "Tasa de eliminación de neumáticos", "rate_matd": "Tasa de eliminación de neumáticos",
"referral_source_extra": "",
"referral_source_other": "",
"referralsource": "Fuente de referencia", "referralsource": "Fuente de referencia",
"regie_number": "N. ° de registro", "regie_number": "N. ° de registro",
"repairtotal": "Reparación total", "repairtotal": "Reparación total",
@@ -1734,6 +1739,9 @@
"edit": "Editar nota", "edit": "Editar nota",
"new": "Nueva nota" "new": "Nueva nota"
}, },
"errors": {
"inserting": ""
},
"fields": { "fields": {
"createdby": "Creado por", "createdby": "Creado por",
"critical": "Crítico", "critical": "Crítico",
@@ -1742,7 +1750,8 @@
"updatedat": "Actualizado en" "updatedat": "Actualizado en"
}, },
"labels": { "labels": {
"newnoteplaceholder": "Agrega una nota..." "newnoteplaceholder": "Agrega una nota...",
"notetoadd": ""
}, },
"successes": { "successes": {
"create": "Nota creada con éxito.", "create": "Nota creada con éxito.",
@@ -1771,6 +1780,7 @@
"ownr_fn": "Nombre de pila", "ownr_fn": "Nombre de pila",
"ownr_ln": "Apellido", "ownr_ln": "Apellido",
"ownr_ph1": "Teléfono 1", "ownr_ph1": "Teléfono 1",
"ownr_ph2": "",
"ownr_st": "Provincia del estado", "ownr_st": "Provincia del estado",
"ownr_title": "Título", "ownr_title": "Título",
"ownr_zip": "código postal", "ownr_zip": "código postal",
@@ -1812,6 +1822,7 @@
"act_price": "", "act_price": "",
"backordered_eta": "", "backordered_eta": "",
"backordered_on": "", "backordered_on": "",
"comments": "",
"cost": "", "cost": "",
"db_price": "", "db_price": "",
"deliver_by": "", "deliver_by": "",

View File

@@ -1055,6 +1055,7 @@
"profitcenter_part": "", "profitcenter_part": "",
"prt_dsmk_p": "", "prt_dsmk_p": "",
"status": "Statut", "status": "Statut",
"tax_part": "",
"total": "", "total": "",
"unq_seq": "Seq #" "unq_seq": "Seq #"
}, },
@@ -1197,6 +1198,7 @@
"date_estimated": "Date estimée", "date_estimated": "Date estimée",
"date_exported": "Exportés", "date_exported": "Exportés",
"date_invoiced": "Facturé", "date_invoiced": "Facturé",
"date_last_contacted": "",
"date_open": "Ouvrir", "date_open": "Ouvrir",
"date_scheduled": "Prévu", "date_scheduled": "Prévu",
"ded_amt": "Déductible", "ded_amt": "Déductible",
@@ -1288,6 +1290,7 @@
"owner_owing": "Cust. Owes", "owner_owing": "Cust. Owes",
"ownr_ea": "Email", "ownr_ea": "Email",
"ownr_ph1": "Téléphone 1", "ownr_ph1": "Téléphone 1",
"ownr_ph2": "",
"paa": "", "paa": "",
"pac": "", "pac": "",
"pae": "", "pae": "",
@@ -1336,6 +1339,8 @@
"rate_mapa": "Taux de matériaux de peinture", "rate_mapa": "Taux de matériaux de peinture",
"rate_mash": "Tarif du matériel de la boutique", "rate_mash": "Tarif du matériel de la boutique",
"rate_matd": "Taux d'élimination des pneus", "rate_matd": "Taux d'élimination des pneus",
"referral_source_extra": "",
"referral_source_other": "",
"referralsource": "Source de référence", "referralsource": "Source de référence",
"regie_number": "Enregistrement #", "regie_number": "Enregistrement #",
"repairtotal": "Réparation totale", "repairtotal": "Réparation totale",
@@ -1734,6 +1739,9 @@
"edit": "Note éditée", "edit": "Note éditée",
"new": "Nouvelle note" "new": "Nouvelle note"
}, },
"errors": {
"inserting": ""
},
"fields": { "fields": {
"createdby": "Créé par", "createdby": "Créé par",
"critical": "Critique", "critical": "Critique",
@@ -1742,7 +1750,8 @@
"updatedat": "Mis à jour à" "updatedat": "Mis à jour à"
}, },
"labels": { "labels": {
"newnoteplaceholder": "Ajouter une note..." "newnoteplaceholder": "Ajouter une note...",
"notetoadd": ""
}, },
"successes": { "successes": {
"create": "Remarque créée avec succès.", "create": "Remarque créée avec succès.",
@@ -1771,6 +1780,7 @@
"ownr_fn": "Prénom", "ownr_fn": "Prénom",
"ownr_ln": "Nom de famille", "ownr_ln": "Nom de famille",
"ownr_ph1": "Téléphone 1", "ownr_ph1": "Téléphone 1",
"ownr_ph2": "",
"ownr_st": "Etat / Province", "ownr_st": "Etat / Province",
"ownr_title": "Titre", "ownr_title": "Titre",
"ownr_zip": "Zip / code postal", "ownr_zip": "Zip / code postal",
@@ -1812,6 +1822,7 @@
"act_price": "", "act_price": "",
"backordered_eta": "", "backordered_eta": "",
"backordered_on": "", "backordered_on": "",
"comments": "",
"cost": "", "cost": "",
"db_price": "", "db_price": "",
"deliver_by": "", "deliver_by": "",

View File

@@ -3,7 +3,11 @@ import moment from "moment";
import React from "react"; import React from "react";
export function DateFormatter(props) { export function DateFormatter(props) {
return props.children ? moment(props.children).format("MM/DD/YYYY") : null; return props.children
? moment(props.children).format(
props.includeDay ? "ddd MM/DD/YYYY" : "MM/DD/YYYY"
)
: null;
} }
export function DateTimeFormatter(props) { export function DateTimeFormatter(props) {

View File

@@ -144,6 +144,7 @@ export async function RenderTemplates(
// ...rootTemplate.templateObject.context, // ...rootTemplate.templateObject.context,
headerpath: `/${bodyshop.imexshopid}/header.html`, headerpath: `/${bodyshop.imexshopid}/header.html`,
bodyshop: bodyshop, bodyshop: bodyshop,
offset: moment().utcOffset(),
}, },
}; };

View File

@@ -36,10 +36,10 @@
lodash "^4.17.21" lodash "^4.17.21"
resize-observer-polyfill "^1.5.0" resize-observer-polyfill "^1.5.0"
"@apollo/client@^3.4.15": "@apollo/client@^3.4.16":
version "3.4.15" version "3.4.16"
resolved "https://registry.yarnpkg.com/@apollo/client/-/client-3.4.15.tgz#0aa05ff2bb54092919b501ef348ade6330911670" resolved "https://registry.yarnpkg.com/@apollo/client/-/client-3.4.16.tgz#67090d5655aa843fa64d26f1913315e384a5fa0f"
integrity sha512-CnlT9i7TgHagkKQNvti81A9KcbIMqgpUPGJJL6bg5spTsB2R/5J6E7qiPcMvXuuXwR2xe4FmE4Ey4HizStb8Hg== integrity sha512-iF4zEYwvebkri0BZQyv8zfavPfVEafsK0wkOofa6eC2yZu50J18uTutKtC174rjHZ2eyxZ8tV7NvAPKRT+OtZw==
dependencies: dependencies:
"@graphql-typed-document-node/core" "^3.0.0" "@graphql-typed-document-node/core" "^3.0.0"
"@wry/context" "^0.6.0" "@wry/context" "^0.6.0"
@@ -1383,12 +1383,12 @@
"@firebase/util" "1.4.0" "@firebase/util" "1.4.0"
tslib "^2.1.0" tslib "^2.1.0"
"@firebase/app-compat@0.1.2": "@firebase/app-compat@0.1.3":
version "0.1.2" version "0.1.3"
resolved "https://registry.yarnpkg.com/@firebase/app-compat/-/app-compat-0.1.2.tgz#ed9682325bbec6e177449f4b7403c60b088c89db" resolved "https://registry.yarnpkg.com/@firebase/app-compat/-/app-compat-0.1.3.tgz#4757c8f65d2a067d24afdfef4f736a5f53c66656"
integrity sha512-kF1maoqA8bZqJ4v/ojVvA7kIyyXEPkJmL48otGrC8LIgdcen7xCx3JFDe0DGeQywg+qujvdkJz/TptFN1cvAgw== integrity sha512-+/U2RgRLfLznPuluIMW3bsAehTBTVWKxA6l6jjk9noozPuP99xOulReMqf5kCrXVdW1aMHdRuKfntjbTAR8+aw==
dependencies: dependencies:
"@firebase/app" "0.7.1" "@firebase/app" "0.7.2"
"@firebase/component" "0.5.7" "@firebase/component" "0.5.7"
"@firebase/logger" "0.3.0" "@firebase/logger" "0.3.0"
"@firebase/util" "1.4.0" "@firebase/util" "1.4.0"
@@ -1399,26 +1399,26 @@
resolved "https://registry.yarnpkg.com/@firebase/app-types/-/app-types-0.7.0.tgz#c9e16d1b8bed1a991840b8d2a725fb58d0b5899f" resolved "https://registry.yarnpkg.com/@firebase/app-types/-/app-types-0.7.0.tgz#c9e16d1b8bed1a991840b8d2a725fb58d0b5899f"
integrity sha512-6fbHQwDv2jp/v6bXhBw2eSRbNBpxHcd1NBF864UksSMVIqIyri9qpJB1Mn6sGZE+bnDsSQBC5j2TbMxYsJQkQg== integrity sha512-6fbHQwDv2jp/v6bXhBw2eSRbNBpxHcd1NBF864UksSMVIqIyri9qpJB1Mn6sGZE+bnDsSQBC5j2TbMxYsJQkQg==
"@firebase/app@0.7.1": "@firebase/app@0.7.2":
version "0.7.1" version "0.7.2"
resolved "https://registry.yarnpkg.com/@firebase/app/-/app-0.7.1.tgz#b594ac4cd15bf94d2a3b97681354a52fa5cfca29" resolved "https://registry.yarnpkg.com/@firebase/app/-/app-0.7.2.tgz#0df26d6e9861d5ebe038d4e1f10b63111a28a1f7"
integrity sha512-B4z6E1EPQc0mOjF35IPKdDRCFnT/fNQIHfM+v7F9obB7ItPhGILK3LxaQfuampSQpF6GG6TPFDbrWK6myXAq+g== integrity sha512-xKO3KWxVqCLijJToaBGvBnXCaVGvIw+rT2Dtd9B2iyOFJieQQ+xx8/zRWgoSqbMBIZ2crQVr0KdsoyP9D2nQfg==
dependencies: dependencies:
"@firebase/component" "0.5.7" "@firebase/component" "0.5.7"
"@firebase/logger" "0.3.0" "@firebase/logger" "0.3.0"
"@firebase/util" "1.4.0" "@firebase/util" "1.4.0"
tslib "^2.1.0" tslib "^2.1.0"
"@firebase/auth-compat@0.1.3": "@firebase/auth-compat@0.1.4":
version "0.1.3" version "0.1.4"
resolved "https://registry.yarnpkg.com/@firebase/auth-compat/-/auth-compat-0.1.3.tgz#0110398e665e7b709dfbb81ab9410f58e3d1a98d" resolved "https://registry.yarnpkg.com/@firebase/auth-compat/-/auth-compat-0.1.4.tgz#d55084f0d37086d58a1da4748c9bbec2ede0a80a"
integrity sha512-eDDtY5If+ERJxalt+plvX6avZspuwo4/kPXssvV+csm414awhDzQBtSDPDajgbH3YB9V+O3LAFHeWcP3rrHS5w== integrity sha512-Vn7Dsxa7B50ihgDAMQAVb/IxU9tcQyR1JDbWjZzf2b1212hBuuwEs1V1u01xoKunMXMSg+P8ztbG7IRxOj2FdQ==
dependencies: dependencies:
"@firebase/auth" "0.18.0" "@firebase/auth" "0.18.1"
"@firebase/auth-types" "0.11.0" "@firebase/auth-types" "0.11.0"
"@firebase/component" "0.5.7" "@firebase/component" "0.5.7"
"@firebase/util" "1.4.0" "@firebase/util" "1.4.0"
node-fetch "2.6.2" node-fetch "2.6.5"
selenium-webdriver "^4.0.0-beta.2" selenium-webdriver "^4.0.0-beta.2"
tslib "^2.1.0" tslib "^2.1.0"
@@ -1432,15 +1432,15 @@
resolved "https://registry.yarnpkg.com/@firebase/auth-types/-/auth-types-0.11.0.tgz#b9c73c60ca07945b3bbd7a097633e5f78fa9e886" resolved "https://registry.yarnpkg.com/@firebase/auth-types/-/auth-types-0.11.0.tgz#b9c73c60ca07945b3bbd7a097633e5f78fa9e886"
integrity sha512-q7Bt6cx+ySj9elQHTsKulwk3+qDezhzRBFC9zlQ1BjgMueUOnGMcvqmU0zuKlQ4RhLSH7MNAdBV2znVaoN3Vxw== integrity sha512-q7Bt6cx+ySj9elQHTsKulwk3+qDezhzRBFC9zlQ1BjgMueUOnGMcvqmU0zuKlQ4RhLSH7MNAdBV2znVaoN3Vxw==
"@firebase/auth@0.18.0": "@firebase/auth@0.18.1":
version "0.18.0" version "0.18.1"
resolved "https://registry.yarnpkg.com/@firebase/auth/-/auth-0.18.0.tgz#00de488a43f84bd9b1e2f8e1d9887a499d30b93d" resolved "https://registry.yarnpkg.com/@firebase/auth/-/auth-0.18.1.tgz#2cba86c5ac614aea8ea1bdc55e479530c187b5ce"
integrity sha512-iK+VXkdDkum8SmJNgz9ZcOboRLrUN1VW7AHHkpZb76VJvoYRoCPD+A9O/v/ziI0LpwIZJwi1GFes9XjZTlfLiA== integrity sha512-q455ls7Hjug3yGp7htLL/LABqySoXGXL/ADLJPyiSnVl22a5oQWuTKUL6N5PAXHc5LwygFfHYiHrNhpQDaGm3w==
dependencies: dependencies:
"@firebase/component" "0.5.7" "@firebase/component" "0.5.7"
"@firebase/logger" "0.3.0" "@firebase/logger" "0.3.0"
"@firebase/util" "1.4.0" "@firebase/util" "1.4.0"
node-fetch "2.6.2" node-fetch "2.6.5"
selenium-webdriver "4.0.0-rc-1" selenium-webdriver "4.0.0-rc-1"
tslib "^2.1.0" tslib "^2.1.0"
@@ -2005,10 +2005,10 @@
mkdirp "^1.0.4" mkdirp "^1.0.4"
rimraf "^3.0.2" rimraf "^3.0.2"
"@openreplay/tracker-assist@^3.4.0": "@openreplay/tracker-assist@^3.4.3":
version "3.4.0" version "3.4.3"
resolved "https://registry.yarnpkg.com/@openreplay/tracker-assist/-/tracker-assist-3.4.0.tgz#93a5e5314b3af55c23979cfe654e7617f76844af" resolved "https://registry.yarnpkg.com/@openreplay/tracker-assist/-/tracker-assist-3.4.3.tgz#02eb6c41ec7a78f38e6fc30df9f637e79c4c1877"
integrity sha512-tKxb0FuUmSo76gH7fBeZ+KYj+G7nDe0N8Ii7dwPCmljfi+0gCXNEtju1+ioQM1XVlT0IWl3a3/JUBvE5MXLEAA== integrity sha512-N+HdVdNZiJcIsakxDzhGr4qGrWLeYNaYgfW7kzbAOxZXWJ9hKU5OH/LUZPl74QfYN0cw0/AbXqBi2sJc71a3aw==
dependencies: dependencies:
npm-dragndrop "^1.2.0" npm-dragndrop "^1.2.0"
peerjs "^1.3.2" peerjs "^1.3.2"
@@ -2023,18 +2023,12 @@
resolved "https://registry.yarnpkg.com/@openreplay/tracker-redux/-/tracker-redux-3.0.0.tgz#7d71c8d2b58b08229e6af2c677d53980cee0b9ef" resolved "https://registry.yarnpkg.com/@openreplay/tracker-redux/-/tracker-redux-3.0.0.tgz#7d71c8d2b58b08229e6af2c677d53980cee0b9ef"
integrity sha512-ctybOquoDj8QNj82pETftgXjEoAzwEoKSxIhwstJaUv5xUkBVv0rDIjMBgCSys8cB/vbRkI/QhvksDaFr9hY0g== integrity sha512-ctybOquoDj8QNj82pETftgXjEoAzwEoKSxIhwstJaUv5xUkBVv0rDIjMBgCSys8cB/vbRkI/QhvksDaFr9hY0g==
"@openreplay/tracker-vuex@^3.0.0": "@openreplay/tracker@^3.4.4":
version "3.0.0" version "3.4.4"
resolved "https://registry.yarnpkg.com/@openreplay/tracker-vuex/-/tracker-vuex-3.0.0.tgz#116ee59ffd27d062f9ae9ea9171db2ed3f03f775" resolved "https://registry.yarnpkg.com/@openreplay/tracker/-/tracker-3.4.4.tgz#4d79fb738f7704aefbea55117d52d61999beb571"
integrity sha512-cH5W4dKkYdkSSvOYKApupgGhfDcmV+UOsraaPa7fgOsnmWoczUFOapTyInQDxxgf1Q3HfPJVw7dOI1xdL5HzKg== integrity sha512-IcuxwwTt1RtLZw9QlQVAVNqoybv0ZkD2ZDk2FeHEQ/+BItsMhG61/4/lB2yXKLTLr6ydeKTzwYvxfr1vwxn2dw==
"@openreplay/tracker@^3.4.1":
version "3.4.1"
resolved "https://registry.yarnpkg.com/@openreplay/tracker/-/tracker-3.4.1.tgz#0ceb5deef0ed71483dbac0d282335d12e273d349"
integrity sha512-aeeChCOGx4DpGefKIdGzheBy6btoBVH82qIogROOIcooiFVmONQXGERbgqhyf1a4qYqh8G3ABmzjDm9RpMXLMg==
dependencies: dependencies:
"@medv/finder" "^2.0.0" "@medv/finder" "^2.0.0"
"@openreplay/tracker-vuex" "^3.0.0"
error-stack-parser "^2.0.6" error-stack-parser "^2.0.6"
"@pmmmwh/react-refresh-webpack-plugin@0.4.3": "@pmmmwh/react-refresh-webpack-plugin@0.4.3":
@@ -2273,10 +2267,10 @@
"@sentry/types" "6.13.2" "@sentry/types" "6.13.2"
tslib "^1.9.3" tslib "^1.9.3"
"@sentry/webpack-plugin@^1.17.1": "@sentry/webpack-plugin@^1.17.2":
version "1.17.1" version "1.17.2"
resolved "https://registry.yarnpkg.com/@sentry/webpack-plugin/-/webpack-plugin-1.17.1.tgz#1b3ebbe9991e4d77125ace2b24594059a088268a" resolved "https://registry.yarnpkg.com/@sentry/webpack-plugin/-/webpack-plugin-1.17.2.tgz#0076c4b6b57959aa7f43a96904756549af069c23"
integrity sha512-L47a0hxano4a+9jbvQSBzHCT1Ph8fYAvGGUvFg8qc69yXS9si5lXRNIH/pavN6mqJjhQjAcEsEp+vxgvT4xZDQ== integrity sha512-1XKNP6FAzB+V58WPCX7DTRLu8BaB/ho11Y2VweqZn10m/MZuqKlHI1PzjJsf4hLoMOZBTt9KdkRi4vjgI6TmPA==
dependencies: dependencies:
"@sentry/cli" "^1.68.0" "@sentry/cli" "^1.68.0"
@@ -2306,10 +2300,10 @@
dependencies: dependencies:
prop-types "^15.7.2" prop-types "^15.7.2"
"@stripe/stripe-js@^1.18.0": "@stripe/stripe-js@^1.19.1":
version "1.18.0" version "1.19.1"
resolved "https://registry.yarnpkg.com/@stripe/stripe-js/-/stripe-js-1.18.0.tgz#687268d7cd68b44b92b86300d7c7f2a6e4df0b98" resolved "https://registry.yarnpkg.com/@stripe/stripe-js/-/stripe-js-1.19.1.tgz#51017bb1c6e12f0e74747534667e42e77b2c9978"
integrity sha512-yBRHAMKHnF3kbzv0tpKB82kSow43wW5qXLK8ofg3V9NaaCyObSTO7wJfktWAtG/NBgkJOdUL+pV8dHBj0qvDkQ== integrity sha512-gvaQ51FXHHKMypXMlSPZbpb7e5671oqySqEfU2MviAQCsikV/+vnvPPxOged4RvNwNM7v4ocsKadQwqIwPhgrQ==
"@surma/rollup-plugin-off-main-thread@^1.1.1": "@surma/rollup-plugin-off-main-thread@^1.1.1":
version "1.4.2" version "1.4.2"
@@ -3498,12 +3492,12 @@ axe-core@^4.0.2:
resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.3.3.tgz#b55cd8e8ddf659fe89b064680e1c6a4dceab0325" resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.3.3.tgz#b55cd8e8ddf659fe89b064680e1c6a4dceab0325"
integrity sha512-/lqqLAmuIPi79WYfRpy2i8z+x+vxU3zX2uAm0gs1q52qTuKwolOj1P8XbufpXcsydrpKx2yGn2wzAnxCMV86QA== integrity sha512-/lqqLAmuIPi79WYfRpy2i8z+x+vxU3zX2uAm0gs1q52qTuKwolOj1P8XbufpXcsydrpKx2yGn2wzAnxCMV86QA==
axios@^0.21.4: axios@^0.22.0:
version "0.21.4" version "0.22.0"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" resolved "https://registry.yarnpkg.com/axios/-/axios-0.22.0.tgz#bf702c41fb50fbca4539589d839a077117b79b25"
integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== integrity sha512-Z0U3uhqQeg1oNcihswf4ZD57O3NrR1+ZXhxaROaWpDmsDTx7T2HNBV2ulBtie2hwJptu8UvgnJoK+BIqdzh/1w==
dependencies: dependencies:
follow-redirects "^1.14.0" follow-redirects "^1.14.4"
axobject-query@^2.2.0: axobject-query@^2.2.0:
version "2.2.0" version "2.2.0"
@@ -6373,20 +6367,20 @@ find-yarn-workspace-root@^2.0.0:
dependencies: dependencies:
micromatch "^4.0.2" micromatch "^4.0.2"
firebase@^9.1.0: firebase@^9.1.1:
version "9.1.0" version "9.1.1"
resolved "https://registry.yarnpkg.com/firebase/-/firebase-9.1.0.tgz#f284634ae4f4e7c789ff36494f4534cba5dffbf2" resolved "https://registry.yarnpkg.com/firebase/-/firebase-9.1.1.tgz#a2980cf397cdbf9933430576c0413ec5c30e2f62"
integrity sha512-Pj9/FwNzT4pdSS6vpXZzm4mFscI73N+AH70gaWZPnZrQBvyMAPTuKXXscjrFePPlqs94b4Emq+2mSwLGcwod/A== integrity sha512-106PqKLwWo4vINQUwEbk2aU/nAFhRbCBE2IdnQmf7UDaW4wqJGZcgRvy3jSyuZr/dkqnT7ymKX0GGrDSzNLU6g==
dependencies: dependencies:
"@firebase/analytics" "0.7.1" "@firebase/analytics" "0.7.1"
"@firebase/analytics-compat" "0.1.2" "@firebase/analytics-compat" "0.1.2"
"@firebase/app" "0.7.1" "@firebase/app" "0.7.2"
"@firebase/app-check" "0.4.1" "@firebase/app-check" "0.4.1"
"@firebase/app-check-compat" "0.1.2" "@firebase/app-check-compat" "0.1.2"
"@firebase/app-compat" "0.1.2" "@firebase/app-compat" "0.1.3"
"@firebase/app-types" "0.7.0" "@firebase/app-types" "0.7.0"
"@firebase/auth" "0.18.0" "@firebase/auth" "0.18.1"
"@firebase/auth-compat" "0.1.3" "@firebase/auth-compat" "0.1.4"
"@firebase/database" "0.12.1" "@firebase/database" "0.12.1"
"@firebase/database-compat" "0.1.1" "@firebase/database-compat" "0.1.1"
"@firebase/firestore" "3.1.0" "@firebase/firestore" "3.1.0"
@@ -6443,11 +6437,16 @@ flush-write-stream@^1.0.0:
inherits "^2.0.3" inherits "^2.0.3"
readable-stream "^2.3.6" readable-stream "^2.3.6"
follow-redirects@^1.0.0, follow-redirects@^1.14.0: follow-redirects@^1.0.0:
version "1.14.3" version "1.14.3"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.3.tgz#6ada78118d8d24caee595595accdc0ac6abd022e" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.3.tgz#6ada78118d8d24caee595595accdc0ac6abd022e"
integrity sha512-3MkHxknWMUtb23apkgz/83fDoe+y+qr0TdgacGIA7bew+QLBo3vdgEN2xEsuXNivpFy4CyDhBBZnNZOtalmenw== integrity sha512-3MkHxknWMUtb23apkgz/83fDoe+y+qr0TdgacGIA7bew+QLBo3vdgEN2xEsuXNivpFy4CyDhBBZnNZOtalmenw==
follow-redirects@^1.14.4:
version "1.14.4"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.4.tgz#838fdf48a8bbdd79e52ee51fb1c94e3ed98b9379"
integrity sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==
for-in@^1.0.2: for-in@^1.0.2:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
@@ -7094,10 +7093,10 @@ i18next-browser-languagedetector@^6.1.2:
dependencies: dependencies:
"@babel/runtime" "^7.14.6" "@babel/runtime" "^7.14.6"
i18next@^21.2.0: i18next@^21.2.4:
version "21.2.0" version "21.2.4"
resolved "https://registry.yarnpkg.com/i18next/-/i18next-21.2.0.tgz#07346948d8c1e7be91518897839f8158c50dd76d" resolved "https://registry.yarnpkg.com/i18next/-/i18next-21.2.4.tgz#ac56044099c83a0a8e2c596acf57f35da8ca327e"
integrity sha512-I2BLM/YNyEjCzRak1kL3uYYawwkfduQbNramMx7uMjjbos3zGZB1ag6dgbdoTR0baR34fpG4X4oWKaQExNo8wg== integrity sha512-+81XmiwJOLWJFjRZJK5ASFahAo5TXZGz5IrBT4CfLJ3CyXho61A1cj1Kmh8za8TYtGFou0cEkUSjEaqfya7Wfg==
dependencies: dependencies:
"@babel/runtime" "^7.12.0" "@babel/runtime" "^7.12.0"
@@ -8500,10 +8499,10 @@ levn@~0.3.0:
prelude-ls "~1.1.2" prelude-ls "~1.1.2"
type-check "~0.3.2" type-check "~0.3.2"
libphonenumber-js@^1.9.34: libphonenumber-js@^1.9.36:
version "1.9.34" version "1.9.36"
resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.9.34.tgz#ddddc778a9b2f53c70500fcf10c9483596e3574f" resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.9.36.tgz#ba56c2f5600ba34677389d0acc1a5fe8a1206561"
integrity sha512-gHTNU9xTtVgSp30IDX/57W4pETMXDIYXFfwEOJVXiYosiY7Hc7ogJwlBjOqlCcU04X0aA8DT57hdwUC1sJBJnA== integrity sha512-eaQRvOHmBKOxd2TKNml5lx1/7+nm4MftXTUXPTcBS70mm7U3AUNBNPF99tNBpkrYQNu+YFP553ranMsbshqqTA==
lie@~3.3.0: lie@~3.3.0:
version "3.3.0" version "3.3.0"
@@ -9162,6 +9161,13 @@ node-fetch@2.6.2:
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.2.tgz#986996818b73785e47b1965cc34eb093a1d464d0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.2.tgz#986996818b73785e47b1965cc34eb093a1d464d0"
integrity sha512-aLoxToI6RfZ+0NOjmWAgn9+LEd30YCkJKFSyWacNZdEKTit/ZMcKjGkTRo8uWEsnIb/hfKecNPEbln02PdWbcA== integrity sha512-aLoxToI6RfZ+0NOjmWAgn9+LEd30YCkJKFSyWacNZdEKTit/ZMcKjGkTRo8uWEsnIb/hfKecNPEbln02PdWbcA==
node-fetch@2.6.5:
version "2.6.5"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.5.tgz#42735537d7f080a7e5f78b6c549b7146be1742fd"
integrity sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==
dependencies:
whatwg-url "^5.0.0"
node-fetch@^2.6.0: node-fetch@^2.6.0:
version "2.6.1" version "2.6.1"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
@@ -11292,10 +11298,10 @@ react-beautiful-dnd@^13.0.0:
redux "^4.0.4" redux "^4.0.4"
use-memo-one "^1.1.1" use-memo-one "^1.1.1"
react-big-calendar@^0.36.0: react-big-calendar@^0.36.1:
version "0.36.0" version "0.36.1"
resolved "https://registry.yarnpkg.com/react-big-calendar/-/react-big-calendar-0.36.0.tgz#97be7e26f3ed8d49dc988b5fdd716ec62a8f72ba" resolved "https://registry.yarnpkg.com/react-big-calendar/-/react-big-calendar-0.36.1.tgz#3a74db72dc293de899759e01bfb72ec1715f8787"
integrity sha512-imQlz5Db8gLacS6WEFH+LZqd96N9fPD1Ho0wBfRWKvB3PRdXy81FXDUSzv50jF6+TAMqgly66mVX05GhUxhPzw== integrity sha512-pzg8X/Tc1szg//KoV2GP9YnPPRhE3uCIXSP10Jlr46jMcBiMZ/wP7WGhpgaGVKEL30rR/BDLz7rhXaAYDX/UuQ==
dependencies: dependencies:
"@babel/runtime" "^7.1.5" "@babel/runtime" "^7.1.5"
clsx "^1.0.4" clsx "^1.0.4"
@@ -11418,10 +11424,10 @@ react-i18next@^11.12.0:
"@babel/runtime" "^7.14.5" "@babel/runtime" "^7.14.5"
html-parse-stringify "^3.0.1" html-parse-stringify "^3.0.1"
react-icons@^4.2.0: react-icons@^4.3.1:
version "4.2.0" version "4.3.1"
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.2.0.tgz#6dda80c8a8f338ff96a1851424d63083282630d0" resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.3.1.tgz#2fa92aebbbc71f43d2db2ed1aed07361124e91ca"
integrity sha512-rmzEDFt+AVXRzD7zDE21gcxyBizD/3NqjbX6cmViAgdqfJ2UiLer8927/QhhrXQV7dEj/1EGuOTPp7JnLYVJKQ== integrity sha512-cB10MXLTs3gVuXimblAdI71jrJx8njrJZmNMEMC+sQu5B/BIOmlsAjskdqpn81y8UBVEGuHODd7/ci5DvoSzTQ==
react-images@^0.5.16: react-images@^0.5.16:
version "0.5.19" version "0.5.19"
@@ -13484,6 +13490,11 @@ tr46@^2.1.0:
dependencies: dependencies:
punycode "^2.1.1" punycode "^2.1.1"
tr46@~0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=
tryer@^1.0.1: tryer@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8"
@@ -13997,6 +14008,11 @@ web-vitals@^2.1.0:
resolved "https://registry.yarnpkg.com/web-vitals/-/web-vitals-2.1.0.tgz#ebf5428875ab5bfc1056c2e80cd177001287de7b" resolved "https://registry.yarnpkg.com/web-vitals/-/web-vitals-2.1.0.tgz#ebf5428875ab5bfc1056c2e80cd177001287de7b"
integrity sha512-npEyJP8jHf3J71t1tRTEtz9FeKp8H2udWJUUq5ykfPhhstr//TUxiYhIEzLNwk4zv2ybAilMn7v7N6Mxmuitmg== integrity sha512-npEyJP8jHf3J71t1tRTEtz9FeKp8H2udWJUUq5ykfPhhstr//TUxiYhIEzLNwk4zv2ybAilMn7v7N6Mxmuitmg==
webidl-conversions@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=
webidl-conversions@^5.0.0: webidl-conversions@^5.0.0:
version "5.0.0" version "5.0.0"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff"
@@ -14163,6 +14179,14 @@ whatwg-mimetype@^2.3.0:
resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"
integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==
whatwg-url@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0=
dependencies:
tr46 "~0.0.3"
webidl-conversions "^3.0.0"
whatwg-url@^8.0.0, whatwg-url@^8.5.0: whatwg-url@^8.0.0, whatwg-url@^8.5.0:
version "8.7.0" version "8.7.0"
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77"

View File

@@ -2581,6 +2581,7 @@
- date_estimated - date_estimated
- date_exported - date_exported
- date_invoiced - date_invoiced
- date_last_contacted
- date_open - date_open
- date_scheduled - date_scheduled
- ded_amt - ded_amt
@@ -2716,6 +2717,7 @@
- rate_mash - rate_mash
- rate_matd - rate_matd
- referral_source - referral_source
- referral_source_extra
- regie_number - regie_number
- ro_number - ro_number
- scheduled_completion - scheduled_completion
@@ -2828,6 +2830,7 @@
- date_estimated - date_estimated
- date_exported - date_exported
- date_invoiced - date_invoiced
- date_last_contacted
- date_open - date_open
- date_scheduled - date_scheduled
- ded_amt - ded_amt
@@ -2963,6 +2966,7 @@
- rate_mash - rate_mash
- rate_matd - rate_matd
- referral_source - referral_source
- referral_source_extra
- regie_number - regie_number
- ro_number - ro_number
- scheduled_completion - scheduled_completion
@@ -3085,6 +3089,7 @@
- date_estimated - date_estimated
- date_exported - date_exported
- date_invoiced - date_invoiced
- date_last_contacted
- date_open - date_open
- date_scheduled - date_scheduled
- ded_amt - ded_amt
@@ -3220,6 +3225,7 @@
- rate_mash - rate_mash
- rate_matd - rate_matd
- referral_source - referral_source
- referral_source_extra
- regie_number - regie_number
- ro_number - ro_number
- scheduled_completion - scheduled_completion
@@ -3779,6 +3785,7 @@
- active: - active:
_eq: true _eq: true
columns: columns:
- comments
- created_at - created_at
- deliver_by - deliver_by
- id - id
@@ -3796,6 +3803,7 @@
- role: user - role: user
permission: permission:
columns: columns:
- comments
- created_at - created_at
- deliver_by - deliver_by
- id - id
@@ -3823,6 +3831,7 @@
- role: user - role: user
permission: permission:
columns: columns:
- comments
- created_at - created_at
- deliver_by - deliver_by
- id - id

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."jobs" add column "referral_soure_other" text
-- null;

View File

@@ -0,0 +1,2 @@
alter table "public"."jobs" add column "referral_soure_other" text
null;

View File

@@ -0,0 +1 @@
alter table "public"."jobs" rename column "referral_source_other" to "referral_soure_other";

View File

@@ -0,0 +1 @@
alter table "public"."jobs" rename column "referral_soure_other" to "referral_source_other";

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."parts_orders" add column "comments" text
-- null;

View File

@@ -0,0 +1,2 @@
alter table "public"."parts_orders" add column "comments" text
null;

View File

@@ -0,0 +1,2 @@
alter table "public"."jobs" alter column "referral_source_other" drop not null;
alter table "public"."jobs" add column "referral_source_other" text;

View File

@@ -0,0 +1 @@
alter table "public"."jobs" drop column "referral_source_other" cascade;

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."jobs" add column "referral_source_other" text
-- null;

View File

@@ -0,0 +1,2 @@
alter table "public"."jobs" add column "referral_source_other" text
null;

View File

@@ -0,0 +1,2 @@
alter table "public"."jobs" alter column "referral_source_other" drop not null;
alter table "public"."jobs" add column "referral_source_other" text;

View File

@@ -0,0 +1 @@
alter table "public"."jobs" drop column "referral_source_other" cascade;

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."jobs" add column "referral_source_extra" text
-- null;

View File

@@ -0,0 +1,2 @@
alter table "public"."jobs" add column "referral_source_extra" text
null;

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."jobs" add column "date_last_contacted" timestamptz
-- null;

View File

@@ -0,0 +1,2 @@
alter table "public"."jobs" add column "date_last_contacted" timestamptz
null;

View File

@@ -0,0 +1,51 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- CREATE
-- OR REPLACE FUNCTION public.search_owners (search text) RETURNS SETOF owners LANGUAGE plpgsql STABLE AS $function$
-- BEGIN
-- IF search = ''
-- THEN
-- RETURN query
-- SELECT
-- *
-- FROM
-- owners;
-- ELSE
-- RETURN query
-- SELECT
-- *
-- FROM
-- owners
-- WHERE
-- (
-- ownr_fn || ' ' || ownr_ln
-- )
-- ILIKE '%' || search || '%'
-- OR ownr_ln ILIKE '%' || search || '%'
-- OR ownr_fn ILIKE '%' || search || '%'
-- OR ownr_fn ILIKE '%' || search || '%'
-- OR ownr_co_nm ILIKE '%' || search || '%'
-- OR ownr_ph1 ILIKE '%' || search || '%'
-- OR ownr_ph2 ILIKE '%' || search || '%'
-- OR ownr_addr1 ILIKE '%' || search || '%'
-- ORDER BY
-- (ownr_fn || ' ' || ownr_ln) ILIKE '%' || search || '%'
-- OR NULL,
-- ownr_ln ILIKE '%' || search || '%'
-- OR NULL,
-- ownr_fn ILIKE '%' || search || '%'
-- OR NULL,
-- ownr_co_nm ILIKE '%' || search || '%'
-- OR NULL,
-- ownr_fn ILIKE '%' || search || '%'
-- OR NULL,
-- ownr_ph1 ILIKE '%' || search || '%'
-- OR NULL,
-- ownr_ph2 ILIKE '%' || search || '%'
-- OR NULL,
-- ownr_addr1 ILIKE '%' || search || '%'
-- OR NULL;
-- END
-- IF;
-- END
-- $function$;

View File

@@ -0,0 +1,49 @@
CREATE
OR REPLACE FUNCTION public.search_owners (search text) RETURNS SETOF owners LANGUAGE plpgsql STABLE AS $function$
BEGIN
IF search = ''
THEN
RETURN query
SELECT
*
FROM
owners;
ELSE
RETURN query
SELECT
*
FROM
owners
WHERE
(
ownr_fn || ' ' || ownr_ln
)
ILIKE '%' || search || '%'
OR ownr_ln ILIKE '%' || search || '%'
OR ownr_fn ILIKE '%' || search || '%'
OR ownr_fn ILIKE '%' || search || '%'
OR ownr_co_nm ILIKE '%' || search || '%'
OR ownr_ph1 ILIKE '%' || search || '%'
OR ownr_ph2 ILIKE '%' || search || '%'
OR ownr_addr1 ILIKE '%' || search || '%'
ORDER BY
(ownr_fn || ' ' || ownr_ln) ILIKE '%' || search || '%'
OR NULL,
ownr_ln ILIKE '%' || search || '%'
OR NULL,
ownr_fn ILIKE '%' || search || '%'
OR NULL,
ownr_co_nm ILIKE '%' || search || '%'
OR NULL,
ownr_fn ILIKE '%' || search || '%'
OR NULL,
ownr_ph1 ILIKE '%' || search || '%'
OR NULL,
ownr_ph2 ILIKE '%' || search || '%'
OR NULL,
ownr_addr1 ILIKE '%' || search || '%'
OR NULL;
END
IF;
END
$function$;

View File

@@ -17,7 +17,7 @@
"start": "node server.js" "start": "node server.js"
}, },
"dependencies": { "dependencies": {
"aws-sdk": "^2.998.0", "aws-sdk": "^2.1000.0",
"bluebird": "^3.7.2", "bluebird": "^3.7.2",
"body-parser": "^1.18.3", "body-parser": "^1.18.3",
"cloudinary": "^1.27.0", "cloudinary": "^1.27.0",
@@ -50,7 +50,7 @@
"xmlbuilder2": "^3.0.2" "xmlbuilder2": "^3.0.2"
}, },
"devDependencies": { "devDependencies": {
"concurrently": "^6.2.2", "concurrently": "^6.3.0",
"eslint": "^7.31.0", "eslint": "^7.31.0",
"eslint-plugin-promise": "^5.1.0", "eslint-plugin-promise": "^5.1.0",
"source-map-explorer": "^2.5.2" "source-map-explorer": "^2.5.2"

View File

@@ -180,6 +180,85 @@ exports.default = async function (socket, jobid) {
// console.log("NO MASH ACCOUNT FOUND!!"); // console.log("NO MASH ACCOUNT FOUND!!");
} }
} }
const { ca_bc_pvrt } = job;
if (ca_bc_pvrt) {
// const pvrtAccount = bodyshop.md_responsibility_centers.profits.find(
// (c) => c.name === mashAccountName
// );
taxAllocations.state.sale = taxAllocations.state.sale.add(
Dinero({ amount: (ca_bc_pvrt || 0) * 100 })
);
}
if (job.towing_payable && job.towing_payable !== 0) {
const towAccountName =
bodyshop.md_responsibility_centers.defaults.profits.TOW;
const towAccount = bodyshop.md_responsibility_centers.profits.find(
(c) => c.name === towAccountName
);
if (towAccount) {
if (!profitCenterHash[towAccountName])
profitCenterHash[towAccountName] = Dinero();
profitCenterHash[towAccountName] = profitCenterHash[towAccountName].add(
Dinero({
amount: Math.round((job.towing_payable || 0) * 100),
})
);
} else {
// console.log("NO MASH ACCOUNT FOUND!!");
}
}
if (job.storage_payable && job.storage_payable !== 0) {
const storageAccountName =
bodyshop.md_responsibility_centers.defaults.profits.TOW;
const towAccount = bodyshop.md_responsibility_centers.profits.find(
(c) => c.name === storageAccountName
);
if (towAccount) {
if (!profitCenterHash[storageAccountName])
profitCenterHash[storageAccountName] = Dinero();
profitCenterHash[storageAccountName] = profitCenterHash[
storageAccountName
].add(
Dinero({
amount: Math.round((job.storage_payable || 0) * 100),
})
);
} else {
// console.log("NO MASH ACCOUNT FOUND!!");
}
}
if (job.adjustment_bottom_line && job.adjustment_bottom_line !== 0) {
const otherAccountName =
bodyshop.md_responsibility_centers.defaults.profits.PAO;
const otherAccount = bodyshop.md_responsibility_centers.profits.find(
(c) => c.name === otherAccountName
);
if (otherAccount) {
if (!profitCenterHash[otherAccountName])
profitCenterHash[otherAccountName] = Dinero();
profitCenterHash[otherAccountName] = profitCenterHash[
otherAccountName
].add(
Dinero({
amount: Math.round((job.adjustment_bottom_line || 0) * 100),
})
);
} else {
// console.log("NO MASH ACCOUNT FOUND!!");
}
}
const jobAllocations = _.union( const jobAllocations = _.union(
Object.keys(profitCenterHash), Object.keys(profitCenterHash),

View File

@@ -15,6 +15,8 @@ const CalcualteAllocations = require("./cdk-calculate-allocations").default;
const moment = require("moment"); const moment = require("moment");
const replaceSpecialRegex = `[^a-zA-Z0-9 .,\n #]+`;
exports.default = async function (socket, { txEnvelope, jobid }) { exports.default = async function (socket, { txEnvelope, jobid }) {
socket.logEvents = []; socket.logEvents = [];
socket.recordid = jobid; socket.recordid = jobid;
@@ -175,9 +177,9 @@ async function CdkSelectedCustomer(socket, selectedCustomerId) {
CdkBase.createLogEvent( CdkBase.createLogEvent(
socket, socket,
"DEBUG", "DEBUG",
`{5} Updating Service Vehicle History. ***SKIPPING FOR NOW TO PRESERVE RO NUMBERS ***` `{5} Updating Service Vehicle History.`
); );
//socket.DMSVehHistory = await InsertServiceVehicleHistory(socket); socket.DMSVehHistory = await InsertServiceVehicleHistory(socket);
socket.emit("export-success", socket.JobData.id); socket.emit("export-success", socket.JobData.id);
} else { } else {
//Get the error code //Get the error code
@@ -437,7 +439,7 @@ async function QueryDmsCustomerByName(socket, JobData) {
arg1: { dealerId: JobData.bodyshop.cdk_dealerid }, //TODO: Verify why this does not follow the other standards. arg1: { dealerId: JobData.bodyshop.cdk_dealerid }, //TODO: Verify why this does not follow the other standards.
arg2: { arg2: {
verb: "EXACT", verb: "EXACT",
key: ownerName, key: ownerName.replaceAll(replaceSpecialRegex, ""),
}, },
}); });
@@ -574,8 +576,14 @@ async function InsertDmsCustomer(socket, newCustomerNumber) {
//TODO: Verify whether we need to bring more information in. //TODO: Verify whether we need to bring more information in.
id: { value: newCustomerNumber }, id: { value: newCustomerNumber },
address: { address: {
addressLine: socket.JobData.ownr_addr1, addressLine: socket.JobData.ownr_addr1.replaceAll(
city: socket.JobData.ownr_city, replaceSpecialRegex,
""
),
city: socket.JobData.ownr_city.replaceAll(
replaceSpecialRegex,
""
),
country: null, country: null,
postalCode: postalCode:
socket.JobData.ownr_zip && socket.JobData.ownr_zip &&
@@ -597,19 +605,24 @@ async function InsertDmsCustomer(socket, newCustomerNumber) {
}, },
demographics: null, demographics: null,
name1: { name1: {
companyname: socket.JobData.ownr_co_nm, companyname: socket.JobData.ownr_co_nm.replaceAll(
firstName: socket.JobData.ownr_fn, replaceSpecialRegex,
""
),
firstName: socket.JobData.ownr_fn.replaceAll(
replaceSpecialRegex,
""
),
fullname: null, fullname: null,
lastName: socket.JobData.ownr_ln, lastName: socket.JobData.ownr_ln.replaceAll(
replaceSpecialRegex,
""
),
middleName: null, middleName: null,
nameType: "Person", nameType: "Person",
suffix: null, suffix: null,
title: null, title: null,
}, },
//TODO - REMOVE THIS AFTER TESTING.
...(process.env.NODE_ENV !== "production"
? { arStatus: { dealerField1: "Testing" } }
: {}),
}, },
}, },
@@ -873,7 +886,7 @@ async function InsertDmsStartWip(socket) {
arg2: { arg2: {
acctgDate: moment().format("YYYY-MM-DD"), acctgDate: moment().format("YYYY-MM-DD"),
//socket.JobData.invoice_date //socket.JobData.invoice_date
desc: socket.txEnvelope.story, desc: socket.txEnvelope.story.replaceAll(replaceSpecialRegex, ""),
docType: 10 || 7, //Need to check what this usually would be? Apparently it is almost always 10 or 7. docType: 10 || 7, //Need to check what this usually would be? Apparently it is almost always 10 or 7.
//1 Cash Receipt , 2 Check, 3 Journal Voucher, 4 Parts invoice, 5 Payable Invoice, 6 Recurring Entry, 7 Repair Order Invoice, 8 Vehicle Purchase Invoice, 9 Vehicle Sale Invoice, 10 Other, 11 Payroll, 12 Finance Charge, 13 FMLR Invoice, 14 Parts Credit Memo, 15 Manufacturer Document, 16 FMLR Credit Memo //1 Cash Receipt , 2 Check, 3 Journal Voucher, 4 Parts invoice, 5 Payable Invoice, 6 Recurring Entry, 7 Repair Order Invoice, 8 Vehicle Purchase Invoice, 9 Vehicle Sale Invoice, 10 Other, 11 Payroll, 12 Finance Charge, 13 FMLR Invoice, 14 Parts Credit Memo, 15 Manufacturer Document, 16 FMLR Credit Memo
m13Flag: 0, m13Flag: 0,

View File

@@ -90,10 +90,12 @@ exports.sendEmail = async (req, res) => {
to: req.body.to, to: req.body.to,
cc: req.body.cc, cc: req.body.cc,
subject: req.body.subject, subject: req.body.subject,
info, // info,
}); });
res.json({ success: true, response: info }); res.json({
success: true, //response: info
});
} else { } else {
logger.log("send-email-failure", "ERROR", req.user.email, null, { logger.log("send-email-failure", "ERROR", req.user.email, null, {
from: `${req.body.from.name} <${req.body.from.address}>`, from: `${req.body.from.name} <${req.body.from.address}>`,

View File

@@ -149,6 +149,7 @@ query QUERY_JOBS_FOR_CDK_EXPORT($id: uuid!) {
ownr_addr1 ownr_addr1
ownr_addr2 ownr_addr2
ownr_ph1 ownr_ph1
ownr_ph2
ownr_zip ownr_zip
ownr_city ownr_city
ownr_st ownr_st
@@ -555,6 +556,7 @@ exports.GET_JOB_BY_PK = ` query GET_JOB_BY_PK($id: uuid!) {
kmin kmin
kmout kmout
referral_source referral_source
referral_source_extra
unit_number unit_number
po_number po_number
special_coverage_policy special_coverage_policy
@@ -628,6 +630,7 @@ exports.GET_JOB_BY_PK = ` query GET_JOB_BY_PK($id: uuid!) {
ownr_zip ownr_zip
ownr_ctry ownr_ctry
ownr_ph1 ownr_ph1
ownr_ph2
production_vars production_vars
ca_gst_registrant ca_gst_registrant
labor_rate_desc labor_rate_desc

View File

@@ -595,10 +595,10 @@ atob@2.1.2:
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
aws-sdk@^2.998.0: aws-sdk@^2.1000.0:
version "2.998.0" version "2.1000.0"
resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.998.0.tgz#e37d98a522c4b6cfbfc41d85bd99fa61b5f90d20" resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1000.0.tgz#408e02dd299541b9e35c85244df9df51cbb2f76a"
integrity sha512-jenbMcGxOg9AeH6p1m0vbsJYNaeJXBnOM58GXsaKecPgRnCm/IykTPlB6aQKfNDk0WQnw5BHDcy7iQPnEjEkUQ== integrity sha512-PhL4WPIJ5fyOBbmWdEaskD6+qvu9VD4kVLEBK/SchcZXmivUKhED3POR6dbfskhwTksxwkrwa6G4NNI3yY7d1g==
dependencies: dependencies:
buffer "4.9.2" buffer "4.9.2"
events "1.1.1" events "1.1.1"
@@ -935,10 +935,10 @@ concat-stream@^2.0.0:
readable-stream "^3.0.2" readable-stream "^3.0.2"
typedarray "^0.0.6" typedarray "^0.0.6"
concurrently@^6.2.2: concurrently@^6.3.0:
version "6.2.2" version "6.3.0"
resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-6.2.2.tgz#81c11b85d9a7de56ad4388ff6aab4a94ddea51f2" resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-6.3.0.tgz#63128cb4a6ed54d3c0ed8528728590a5fe54582a"
integrity sha512-7a45BjVakAl3pprLOeqaOoZfIWZRmdC68NkjyzPbKu0/pE6CRmqS3l8RG7Q2cX9LnRHkB0oPM6af8PS7NEQvYQ== integrity sha512-k4k1jQGHHKsfbqzkUszVf29qECBrkvBKkcPJEUDTyVR7tZd1G/JOfnst4g1sYbFvJ4UjHZisj1aWQR8yLKpGPw==
dependencies: dependencies:
chalk "^4.1.0" chalk "^4.1.0"
date-fns "^2.16.1" date-fns "^2.16.1"