Added hasura to circle ci.

Speed print resolution.

Resolve cc contract car query error with service dates IO-728

Updates to production list drawer. IO-221

Update template subjects IO-712

Rename load.

PVRT Handling IO-736

PVRT Handling IO-736

QB PVRT updates IO-736

Extensions to job totals calculation.
This commit is contained in:
Patrick Fic
2021-03-04 01:32:44 +00:00
35 changed files with 2538 additions and 27048 deletions

View File

@@ -1,12 +1,21 @@
{
"env": {
"browser": false,
"commonjs": true,
"es2021": true
env: {
es6: true,
node: true,
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": 12
extends: "eslint:recommended",
globals: {
Atomics: "readonly",
SharedArrayBuffer: "readonly",
},
"rules": {}
}
parserOptions: {
ecmaVersion: 2018,
sourceType: "module",
},
// plugins: [],
rules: {
"no-console": "off"
},
settings: {},
};

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
@@ -10654,6 +10654,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>calculate</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>cancel</name>
<definition_loaded>false</definition_loaded>
@@ -14733,6 +14754,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>totalscalc</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>updating</name>
<definition_loaded>false</definition_loaded>
@@ -14948,6 +14990,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>ca_bc_pvrt</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>ca_gst_registrant</name>
<definition_loaded>false</definition_loaded>
@@ -18564,6 +18627,53 @@
</translation>
</translations>
</concept_node>
<folder_node>
<name>ca_bc_pvrt</name>
<children>
<concept_node>
<name>days</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>rate</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>
<name>cards</name>
<children>
@@ -25424,6 +25534,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>coversheet_portrait</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>diagnostic_authorization</name>
<definition_loaded>false</definition_loaded>
@@ -25487,6 +25618,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>filing_coverhseet_portrait</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>final_invoice</name>
<definition_loaded>false</definition_loaded>
@@ -26504,27 +26656,6 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>cycletime</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>detailpriority</name>
<definition_loaded>false</definition_loaded>
@@ -26672,6 +26803,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>touchtime</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>

26777
client/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,46 @@
import React, { useState } from "react";
import { Button, Form, InputNumber, Popover } from "antd";
import { logImEXEvent } from "../../firebase/firebase.utils";
import { useTranslation } from "react-i18next";
import { CalculatorFilled } from "@ant-design/icons";
export default function CABCpvrtCalculator({ disabled, form }) {
const [visibility, setVisibility] = useState(false);
const { t } = useTranslation();
const handleFinish = async (values) => {
logImEXEvent("job_ca_bc_pvrt_calculate");
form.setFieldsValue({ ca_bc_pvrt: (values.rate * values.days).toFixed(2) });
setVisibility(false);
};
const popContent = (
<div>
<Form onFinish={handleFinish} initialValues={{ rate: 1.5 }}>
<Form.Item name="rate" label={t("jobs.labels.ca_bc_pvrt.rate")}>
<InputNumber precision={2} min={0} />
</Form.Item>
<Form.Item name="days" label={t("jobs.labels.ca_bc_pvrt.days")}>
<InputNumber precision={0} min={0} />
</Form.Item>
<Button type="primary" htmlType="submit">
{t("general.actions.calculate")}
</Button>
<Button onClick={() => setVisibility(false)}>Close</Button>
</Form>
</div>
);
return (
<Popover
destroyTooltipOnHide
content={popContent}
visible={visibility}
disabled={disabled}
>
<Button disabled={disabled} onClick={() => setVisibility(true)}>
<CalculatorFilled />
</Button>
</Popover>
);
}

View File

@@ -3,9 +3,12 @@ import React from "react";
import { QUERY_AVAILABLE_CC } from "../../graphql/courtesy-car.queries";
import AlertComponent from "../alert/alert.component";
import ContractCarsComponent from "./contract-cars.component";
import moment from "moment";
export default function ContractCarsContainer({ selectedCarState, form }) {
const { loading, error, data } = useQuery(QUERY_AVAILABLE_CC);
const { loading, error, data } = useQuery(QUERY_AVAILABLE_CC, {
variables: { today: moment().format("YYYY-MM-DD") },
});
const [selectedCar, setSelectedCar] = selectedCarState;

View File

@@ -1,5 +1,5 @@
import { InputNumber } from "antd";
import React from "react";
import React, { forwardRef } from "react";
// const locale = "en-us";
// const currencyFormatter = (value) => {
@@ -41,22 +41,17 @@ import React from "react";
// }
// };
export default function FormItemCurrency(props) {
function FormItemCurrency(props, ref) {
return (
<InputNumber
{...props}
precision={2}
// formatter={currencyFormatter}
// parser={currencyParser}
// formatter={(value) =>
// "$" +
// parseFloat(value)
// .toFixed(2)
// .replace(/(\d)(?=(\d{3})+\.)/g, "$1,")
// }
// parser={(value) => value.replace(/\$\s?|(,*)/g, "")}
ref={ref}
style={{ width: "initial" }}
// formatter={(value) => `$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ",")}
// parser={(value) => value.replace(/\$\s?|(,*)/g, "")}
precision={2}
/>
);
}
export default forwardRef(FormItemCurrency);

View File

@@ -4,7 +4,7 @@ import React, { useState } from "react";
import { useMutation } from "@apollo/client";
import { useTranslation } from "react-i18next";
import { UPDATE_JOB } from "../../graphql/jobs.queries";
import Dinero from "dinero.js";
export default function JobCalculateTotals({ job, disabled }) {
const { t } = useTranslation();
const [loading, setLoading] = useState(false);
@@ -25,6 +25,10 @@ export default function JobCalculateTotals({ job, disabled }) {
jobId: job.id,
job: {
job_totals: newTotals,
clm_total: Dinero(newTotals.totals.total_repairs).toFormat("0.00"),
owner_owing: Dinero(newTotals.totals.custPayable.total).toFormat(
"0.00"
),
},
},
});

View File

@@ -6,7 +6,7 @@ import { UPDATE_JOB } from "../../graphql/jobs.queries";
import JobEmployeeAssignmentsComponent from "./job-employee-assignments.component";
import { logImEXEvent } from "../../firebase/firebase.utils";
export default function JobEmployeeAssignmentsContainer({ job }) {
export default function JobEmployeeAssignmentsContainer({ job, refetch }) {
const { t } = useTranslation();
const [updateJob] = useMutation(UPDATE_JOB);
@@ -21,6 +21,7 @@ export default function JobEmployeeAssignmentsContainer({ job }) {
refetchQueries: ["GET_JOB_BY_PK"],
awaitRefetchQueries: true,
});
if (refetch) refetch();
if (!!result.errors) {
notification["error"]({

View File

@@ -1,4 +1,5 @@
import {
gql,
useApolloClient,
useLazyQuery,
useMutation,
@@ -7,9 +8,10 @@ import {
import { notification } from "antd";
import Axios from "axios";
import Dinero from "dinero.js";
import { gql } from "@apollo/client";
import _ from "lodash";
import React, { useState, useEffect, useCallback } from "react";
import moment from "moment";
import queryString from "query-string";
import React, { useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { useHistory, useLocation } from "react-router-dom";
@@ -21,6 +23,7 @@ import {
QUERY_AVAILABLE_NEW_JOBS_EST_DATA_BY_PK,
} from "../../graphql/available-jobs.queries";
import { INSERT_NEW_JOB, UPDATE_JOB } from "../../graphql/jobs.queries";
import { INSERT_NEW_NOTE } from "../../graphql/notes.queries";
import { SEARCH_VEHICLE_BY_VIN } from "../../graphql/vehicles.queries";
import {
selectBodyshop,
@@ -33,9 +36,6 @@ import OwnerFindModalContainer from "../owner-find-modal/owner-find-modal.contai
import { GetSupplementDelta } from "./jobs-available-supplement.estlines.util";
import HeaderFields from "./jobs-available-supplement.headerfields";
import JobsAvailableTableComponent from "./jobs-available-table.component";
import moment from "moment";
import { INSERT_NEW_NOTE } from "../../graphql/notes.queries";
import queryString from "query-string";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
@@ -71,6 +71,7 @@ export function JobsAvailableContainer({ bodyshop, currentUser }) {
const importOptions = importOptionsState[0];
const modalSearchState = useState("");
//Import Scenario
const onOwnerFindModalOk = async () => {
logImEXEvent("job_import_new");
@@ -171,6 +172,7 @@ export function JobsAvailableContainer({ bodyshop, currentUser }) {
});
};
//Suplement scenario
const onJobFindModalOk = async () => {
logImEXEvent("job_import_supplement");
@@ -199,15 +201,6 @@ export function JobsAvailableContainer({ bodyshop, currentUser }) {
HeaderFields.forEach((item) => delete supp[item]);
}
const newTotals = (
await Axios.post("/job/totals", {
job: {
...estData.data.available_jobs_by_pk.est_data,
joblines: estData.data.available_jobs_by_pk.est_data.joblines.data,
},
})
).data;
let suppDelta = await GetSupplementDelta(
client,
selectedJob,
@@ -220,46 +213,65 @@ export function JobsAvailableContainer({ bodyshop, currentUser }) {
${suppDelta}
`,
});
updateJob({
const updateResult = await updateJob({
variables: {
jobId: selectedJob,
job: {
...supp,
clm_total: Dinero(newTotals.totals.total_repairs).toFormat("0.00"),
owner_owing: Dinero(newTotals.totals.custPayable.total).toFormat(
"0.00"
),
job_totals: newTotals,
queued_for_parts: true,
// clm_total: Dinero(newTotals.totals.total_repairs).toFormat("0.00"),
// owner_owing: Dinero(newTotals.totals.custPayable.total).toFormat(
// "0.00"
// ),
// job_totals: newTotals,
// queued_for_parts: true,
},
},
})
.then((r) => {
notification["success"]({
message: t("jobs.successes.supplemented"),
onClick: () => {
history.push(
`/manage/jobs/${r.data.update_jobs.returning[0].id}`
);
},
});
//Job has been inserted. Clean up the available jobs record.
});
deleteJob({
variables: { id: estData.data.available_jobs_by_pk.id },
}).then((r) => {
refetch();
setInsertLoading(false);
});
})
.catch((r) => {
//error while inserting
notification["error"]({
message: t("jobs.errors.creating", { error: r.message }),
});
refetch();
setInsertLoading(false);
if (updateResult.errors) {
//error while inserting
notification["error"]({
message: t("jobs.errors.creating", {
error: JSON.stringify(updateResult.errors),
}),
});
refetch();
setInsertLoading(false);
return;
}
const newTotals = await Axios.post("/job/totalsssu", {
id: selectedJob,
});
console.log(
"🚀 ~ file: jobs-available-table.container.jsx ~ line 247 ~ newTotals",
newTotals
);
if (newTotals.status !== 200) {
notification["error"]({
message: t("jobs.errors.totalscalc"),
});
setInsertLoading(false);
return;
}
notification["success"]({
message: t("jobs.successes.supplemented"),
onClick: () => {
history.push(
`/manage/jobs/${updateResult.data.update_jobs.returning[0].id}`
);
},
});
//Job has been inserted. Clean up the available jobs record.
deleteJob({
variables: { id: estData.data.available_jobs_by_pk.id },
}).then((r) => {
refetch();
setInsertLoading(false);
});
await insertNote({
variables: {

View File

@@ -105,6 +105,15 @@ export function JobsDetailGeneral({ bodyshop, jobRO, job, form }) {
))}
</Select>
</Form.Item>
<Form.Item label={t("jobs.fields.alt_transport")} name="alt_transport">
<Select disabled={jobRO}>
{bodyshop.appt_alt_transport.map((s) => (
<Select.Option key={s} value={s}>
{s}
</Select.Option>
))}
</Select>
</Form.Item>
</FormRow>
<Row gutter={[16, 16]}>
<Col {...lossColFields}>

View File

@@ -1,9 +1,10 @@
import { Form, InputNumber, Select, Switch } from "antd";
import { Form, InputNumber, Select, Space, Switch } from "antd";
import React from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectJobReadOnly } from "../../redux/application/application.selectors";
import CABCpvrtCalculator from "../ca-bc-pvrt-calculator/ca-bc-pvrt-calculator.component";
import CurrencyInput from "../form-items-formatted/currency-form-item.component";
import JobsDetailRatesChangeButton from "../jobs-detail-rates-change-button/jobs-detail-rates-change-button.component";
import FormRow from "../layout-form-row/layout-form-row.component";
@@ -59,6 +60,12 @@ export function JobsDetailRates({ job, jobRO, form }) {
>
<Switch disabled={jobRO} />
</Form.Item>
<Space align="end">
<Form.Item label={t("jobs.fields.ca_bc_pvrt")} name="ca_bc_pvrt">
<CurrencyInput disabled={jobRO} />
</Form.Item>
<CABCpvrtCalculator form={form} disabled={jobRO} />
</Space>
</FormRow>
<JobsDetailRatesChangeButton form={form} disabled={jobRO} />
<FormRow header={t("jobs.forms.laborrates")}>

View File

@@ -191,9 +191,9 @@ const r = [
render: (text, record) => <ProductionListColumnNote record={record} />,
},
{
title: i18n.t("production.labels.cycletime"),
dataIndex: "ct",
key: "ct",
title: i18n.t("production.labels.touchtime"),
dataIndex: "tt",
key: "tt",
render: (text, record) => {
return <ProductionlistColumnTouchTime job={record} />;
},

View File

@@ -1,12 +1,21 @@
import { Descriptions, Drawer } from "antd";
import { useQuery } from "@apollo/client";
import { Descriptions, Drawer, Space } from "antd";
import queryString from "query-string";
import React from "react";
import { useTranslation } from "react-i18next";
import { useHistory, useLocation } from "react-router-dom";
import { QUERY_JOB_CARD_DETAILS } from "../../graphql/jobs.queries";
import CurrencyFormatter from "../../utils/CurrencyFormatter";
import { DateFormatter } from "../../utils/DateFormatter";
import PartsStatusPie from "../parts-status-pie/parts-status-pie.component";
import AlertComponent from "../alert/alert.component";
import StartChatButton from "../chat-open-button/chat-open-button.component";
import JobDetailCardsDocumentsComponent from "../job-detail-cards/job-detail-cards.documents.component";
import JobDetailCardsNotesComponent from "../job-detail-cards/job-detail-cards.notes.component";
import JobDetailCardsPartsComponent from "../job-detail-cards/job-detail-cards.parts.component";
import JobEmployeeAssignments from "../job-employee-assignments/job-employee-assignments.container";
import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component";
import ProductionRemoveButton from "../production-remove-button/production-remove-button.component";
import ScheduleEventAt from "../schedule-event/schedule-event.at.component";
export default function ProductionListDetail({ jobs }) {
const search = queryString.parse(useLocation().search);
@@ -20,45 +29,87 @@ export default function ProductionListDetail({ jobs }) {
delete search.selected;
history.push({ search: queryString.stringify(search) });
};
const { loading, error, data, refetch } = useQuery(QUERY_JOB_CARD_DETAILS, {
variables: { id: selected },
skip: !selected,
});
return (
<Drawer
title={t("production.labels.jobdetail")}
title={
<Space>
<span>{t("production.labels.jobdetail")}</span>
<span>{theJob.ro_number}</span>
<ProductionRemoveButton jobId={theJob.id} />
</Space>
}
placement="right"
width={"33%"}
onClose={handleClose}
visible={!!selected}
visible={selected}
>
<div>
<Descriptions bordered size="small" column={1}>
<Descriptions.Item label={t("jobs.fields.ro_number")}>
{theJob.ro_number || ""}
</Descriptions.Item>
<Descriptions.Item label={t("jobs.fields.owner")}>
{`${theJob.ownr_fn || ""} ${theJob.ownr_ln || ""} ${
theJob.ownr_co_nm || ""
}`}
</Descriptions.Item>
<Descriptions.Item label={t("jobs.fields.vehicle")}>
{`${theJob.v_model_yr || ""} ${theJob.v_color || ""} ${
theJob.v_make_desc || ""
} ${theJob.v_model_desc || ""}`}
</Descriptions.Item>
<Descriptions.Item label={t("jobs.fields.clm_total")}>
<CurrencyFormatter>{theJob.clm_total}</CurrencyFormatter>
</Descriptions.Item>
<Descriptions.Item label={t("jobs.fields.actual_in")}>
<DateFormatter>{theJob.actual_in}</DateFormatter>
</Descriptions.Item>
<Descriptions.Item label={t("jobs.fields.scheduled_completion")}>
<DateFormatter>{theJob.scheduled_completion}</DateFormatter>
</Descriptions.Item>
<Descriptions.Item label={t("jobs.labels.parts")}>
<PartsStatusPie joblines_status={theJob.joblines_status} />
</Descriptions.Item>
</Descriptions>
<ProductionRemoveButton jobId={theJob.id} />
</div>
{loading && <LoadingSkeleton />}
{error && <AlertComponent error={JSON.stringify(error)} />}
{!loading && data && (
<div>
<JobEmployeeAssignments job={data.jobs_by_pk} refetch={refetch} />
<Descriptions bordered size="small" column={1}>
<Descriptions.Item label={t("jobs.fields.ro_number")}>
{theJob.ro_number || ""}
</Descriptions.Item>
<Descriptions.Item label={t("jobs.fields.alt_transport")}>
<Space>
{data.jobs_by_pk.alt_transport || ""}
<ScheduleEventAt event={{ job: data.jobs_by_pk }} />
</Space>
</Descriptions.Item>
<Descriptions.Item label={t("jobs.fields.clm_no")}>
{theJob.clm_no || ""}
</Descriptions.Item>
<Descriptions.Item label={t("jobs.fields.ins_co_nm")}>
{theJob.ins_co_nm || ""}
</Descriptions.Item>
<Descriptions.Item label={t("jobs.fields.owner")}>
{`${theJob.ownr_fn || ""} ${theJob.ownr_ln || ""} ${
theJob.ownr_co_nm || ""
}`}
<StartChatButton
phone={data.jobs_by_pk.ownr_ph1}
jobid={data.jobs_by_pk.id}
/>
</Descriptions.Item>
<Descriptions.Item label={t("jobs.fields.vehicle")}>
{`${theJob.v_model_yr || ""} ${theJob.v_color || ""} ${
theJob.v_make_desc || ""
} ${theJob.v_model_desc || ""}`}
</Descriptions.Item>
<Descriptions.Item label={t("jobs.fields.clm_total")}>
<CurrencyFormatter>{theJob.clm_total}</CurrencyFormatter>
</Descriptions.Item>
<Descriptions.Item label={t("jobs.fields.actual_in")}>
<DateFormatter>{theJob.actual_in}</DateFormatter>
</Descriptions.Item>
<Descriptions.Item label={t("jobs.fields.scheduled_completion")}>
<DateFormatter>{theJob.scheduled_completion}</DateFormatter>
</Descriptions.Item>
</Descriptions>
<JobDetailCardsPartsComponent
loading={loading}
data={data ? data.jobs_by_pk : null}
/>
<JobDetailCardsNotesComponent
loading={loading}
data={data ? data.jobs_by_pk : null}
/>
<JobDetailCardsDocumentsComponent
loading={loading}
data={data ? data.jobs_by_pk : null}
/>
</div>
)}
</Drawer>
);
}

View File

@@ -57,7 +57,7 @@ export function ScheduleCalendarHeaderGraph({ bodyshop, loadData }) {
fillOpacity={0}
/>
<Radar
name="Current"
name="EOD Load"
dataKey="current"
stroke="dodgerblue"
fill="dodgerblue"

View File

@@ -13,28 +13,24 @@ export const INSERT_NEW_COURTESY_CAR = gql`
`;
export const QUERY_AVAILABLE_CC = gql`
query QUERY_AVAILABLE_CC {
courtesycars(
where: {
serviceenddate: { _is_null: true }
status: { _eq: "courtesycars.status.in" }
}
) {
color
dailycost
damage
fleetnumber
fuel
id
make
model
plate
status
year
dailycost
mileage
}
query QUERY_AVAILABLE_CC($today: date) {
courtesycars(where: {_or: [{serviceenddate: {_is_null: true}}, {serviceenddate: {_gt: $today}}], status: {_eq: "courtesycars.status.in"}}) {
color
dailycost
damage
fleetnumber
fuel
id
make
model
plate
status
year
dailycost
mileage
}
}
`;
export const QUERY_ALL_CC = gql`

View File

@@ -264,6 +264,7 @@ export const QUERY_JOB_COSTING_DETAILS = gql`
rate_matd
actual_in
status
ca_bc_pvrt
joblines(where: { removed: { _eq: false } }) {
id
unq_seq
@@ -327,6 +328,7 @@ export const GET_JOB_BY_PK = gql`
first_name
last_name
}
alt_transport
intakechecklist
csr
loss_desc
@@ -479,6 +481,7 @@ export const GET_JOB_BY_PK = gql`
category
deliverchecklist
voided
ca_bc_pvrt
joblines(where: { jobid: { _eq: $id } }, order_by: { line_no: asc }) {
id
line_no
@@ -554,6 +557,7 @@ export const QUERY_JOB_CARD_DETAILS = gql`
ownr_fn
employee_body
employee_refinish
alt_transport
ownr_ln
ownr_ph1
ownr_ea
@@ -610,7 +614,21 @@ export const QUERY_JOB_CARD_DETAILS = gql`
date_scheduled
date_estimated
employee_body_rel {
id
first_name
last_name
}
employee_refinish_rel {
id
first_name
last_name
}
employee_prep_rel {
id
first_name
last_name
}
notes {
id
text

View File

@@ -702,6 +702,7 @@
"general": {
"actions": {
"add": "Add",
"calculate": "Calculate",
"cancel": "Cancel",
"close": "Close",
"create": "Create",
@@ -935,6 +936,7 @@
"noowner": "No owner associated.",
"novehicle": "No vehicle associated.",
"saving": "Error encountered while saving record.",
"totalscalc": "Error while calculating new job totals.",
"updating": "Error while updating job(s). {{error}}",
"validation": "Please ensure all fields are entered correctly.",
"validationtitle": "Validation Error",
@@ -947,6 +949,7 @@
"adjustment_bottom_line": "Adjustments",
"adjustmenthours": "Adjustment Hours",
"alt_transport": "Alt. Trans.",
"ca_bc_pvrt": "PVRT",
"ca_gst_registrant": "GST Registrant",
"category": "Category",
"ccc": "CC Cleaning",
@@ -1128,6 +1131,10 @@
"audit": "Audit Trail",
"available": "Available",
"availablejobs": "Available Jobs",
"ca_bc_pvrt": {
"days": "Days",
"rate": "PVRT Rate"
},
"cards": {
"customer": "Customer Information",
"damage": "Area of Damage",
@@ -1541,9 +1548,11 @@
"appointment_confirmation": "Appointment Confirmation",
"appointment_reminder": "Appointment Reminder",
"casl_authorization": "CASL Authorization",
"coversheet_portrait": "Coversheet Portrait",
"diagnostic_authorization": "Diagnostic Authorization",
"estimate": "Estimate Only",
"estimate_detail": "Estimate Details",
"filing_coverhseet_portrait": "Filing Coversheet (Portrait)",
"final_invoice": "Final Invoice",
"fippa_authorization": "FIPPA Authorization",
"glass_express_checklist": "Glass Express Checklist",
@@ -1603,14 +1612,14 @@
"alerton": "Add alert to job",
"bodyhours": "B",
"bodypriority": "B/P",
"cycletime": "C/T",
"detailpriority": "D/P",
"employeesearch": "Employee Search",
"jobdetail": "Job Details",
"note": "Production Note",
"paintpriority": "P/P",
"refinishhours": "R",
"sublets": "Sublets"
"sublets": "Sublets",
"touchtime": "T/T"
},
"successes": {
"removed": "Job removed from production."

View File

@@ -702,6 +702,7 @@
"general": {
"actions": {
"add": "",
"calculate": "",
"cancel": "",
"close": "",
"create": "",
@@ -935,6 +936,7 @@
"noowner": "Ningún propietario asociado.",
"novehicle": "No hay vehículo asociado.",
"saving": "Se encontró un error al guardar el registro.",
"totalscalc": "",
"updating": "",
"validation": "Asegúrese de que todos los campos se ingresen correctamente.",
"validationtitle": "Error de validacion",
@@ -947,6 +949,7 @@
"adjustment_bottom_line": "Ajustes",
"adjustmenthours": "",
"alt_transport": "",
"ca_bc_pvrt": "",
"ca_gst_registrant": "",
"category": "",
"ccc": "",
@@ -1128,6 +1131,10 @@
"audit": "",
"available": "",
"availablejobs": "",
"ca_bc_pvrt": {
"days": "",
"rate": ""
},
"cards": {
"customer": "Información al cliente",
"damage": "Área de Daño",
@@ -1541,9 +1548,11 @@
"appointment_confirmation": "",
"appointment_reminder": "",
"casl_authorization": "",
"coversheet_portrait": "",
"diagnostic_authorization": "",
"estimate": "",
"estimate_detail": "",
"filing_coverhseet_portrait": "",
"final_invoice": "",
"fippa_authorization": "",
"glass_express_checklist": "",
@@ -1603,14 +1612,14 @@
"alerton": "",
"bodyhours": "",
"bodypriority": "",
"cycletime": "",
"detailpriority": "",
"employeesearch": "",
"jobdetail": "",
"note": "",
"paintpriority": "",
"refinishhours": "",
"sublets": ""
"sublets": "",
"touchtime": ""
},
"successes": {
"removed": ""

View File

@@ -702,6 +702,7 @@
"general": {
"actions": {
"add": "",
"calculate": "",
"cancel": "",
"close": "",
"create": "",
@@ -935,6 +936,7 @@
"noowner": "Aucun propriétaire associé.",
"novehicle": "Aucun véhicule associé.",
"saving": "Erreur rencontrée lors de la sauvegarde de l'enregistrement.",
"totalscalc": "",
"updating": "",
"validation": "Veuillez vous assurer que tous les champs sont correctement entrés.",
"validationtitle": "Erreur de validation",
@@ -947,6 +949,7 @@
"adjustment_bottom_line": "Ajustements",
"adjustmenthours": "",
"alt_transport": "",
"ca_bc_pvrt": "",
"ca_gst_registrant": "",
"category": "",
"ccc": "",
@@ -1128,6 +1131,10 @@
"audit": "",
"available": "",
"availablejobs": "",
"ca_bc_pvrt": {
"days": "",
"rate": ""
},
"cards": {
"customer": "Informations client",
"damage": "Zone de dommages",
@@ -1541,9 +1548,11 @@
"appointment_confirmation": "",
"appointment_reminder": "",
"casl_authorization": "",
"coversheet_portrait": "",
"diagnostic_authorization": "",
"estimate": "",
"estimate_detail": "",
"filing_coverhseet_portrait": "",
"final_invoice": "",
"fippa_authorization": "",
"glass_express_checklist": "",
@@ -1603,14 +1612,14 @@
"alerton": "",
"bodyhours": "",
"bodypriority": "",
"cycletime": "",
"detailpriority": "",
"employeesearch": "",
"jobdetail": "",
"note": "",
"paintpriority": "",
"refinishhours": "",
"sublets": ""
"sublets": "",
"touchtime": ""
},
"successes": {
"removed": ""

View File

@@ -2,13 +2,12 @@ import { gql } from "@apollo/client";
import { notification } from "antd";
import axios from "axios";
import jsreport from "jsreport-browser-client-dist";
import moment from "moment";
import { auth } from "../firebase/firebase.utils";
import { setEmailOptions } from "../redux/email/email.actions";
import { store } from "../redux/store";
import client from "../utils/GraphQLClient";
import { TemplateList } from "./TemplateConstants";
import moment from "moment";
const server = process.env.REACT_APP_REPORTS_SERVER_URL;
jsreport.serverUrl = server;
@@ -61,46 +60,23 @@ export async function RenderTemplates(
) {
//Query assets that match the template name. Must be in format <<templateName>>.query
let templateAndData = [];
console.log("About to await all promises.");
await Promise.all(
templateObjects.map(async (template) => {
console.log("executing for", template);
let { contextData, useShopSpecificTemplate } = await fetchContextData(
template
);
templateAndData.push({
templateObject: template,
contextData,
useShopSpecificTemplate,
});
})
);
console.log("All promises awaited.", templateAndData);
let rootTemplate = templateAndData[0];
const pdfOps = [];
for (var i = 1; i < templateAndData.length; i++) {
pdfOps.push({
template: {
name: templateAndData[i].useShopSpecificTemplate
? `/${bodyshop.imexshopid}/${templateAndData[i].templateObject.name}`
: `/${templateAndData[i].templateObject.name}`,
...(renderAsHtml ? {} : { recipe: "chrome-pdf" }),
},
data: {
...templateAndData[i].contextData,
...templateAndData[i].templateObject.variables,
...templateAndData[i].templateObject.context,
headerpath: `/${bodyshop.imexshopid}/header.html`,
bodyshop: bodyshop,
offset: moment().utcOffset(),
},
type: "append",
mergeWholeDocument: true,
renderForEveryPage: true,
});
}
let proms = [];
templateObjects.forEach((template) => {
proms.push(
(async () => {
let { contextData, useShopSpecificTemplate } = await fetchContextData(
template
);
templateAndData.push({
templateObject: template,
contextData,
useShopSpecificTemplate,
});
})()
);
});
await Promise.all(proms);
let rootTemplate = templateAndData.shift();
let reportRequest = {
template: {
@@ -108,15 +84,30 @@ export async function RenderTemplates(
? `/${bodyshop.imexshopid}/${rootTemplate.templateObject.name}`
: `/${rootTemplate.templateObject.name}`,
...(renderAsHtml ? {} : { recipe: "chrome-pdf" }),
pdfOperations: pdfOps,
pdfOperations: templateAndData.map((template) => {
return {
template: {
name: template.useShopSpecificTemplate
? `/${bodyshop.imexshopid}/${template.templateObject.name}`
: `/${template.templateObject.name}`,
...(renderAsHtml ? {} : { recipe: "chrome-pdf" }),
},
type: "append",
mergeWholeDocument: true,
renderForEveryPage: true,
};
}),
},
data: {
...rootTemplate.contextData,
...rootTemplate.templateObject.variables,
...rootTemplate.templateObject.context,
...extend(
rootTemplate.contextData,
...templateAndData.map((temp) => temp.contextData)
),
// ...rootTemplate.templateObject.variables,
// ...rootTemplate.templateObject.context,
headerpath: `/${bodyshop.imexshopid}/header.html`,
bodyshop: bodyshop,
offset: moment().utcOffset(),
},
};
@@ -230,3 +221,23 @@ const fetchContextData = async (templateObject) => {
// console.log("Unable to write to new window.", error);
// }
// };
function extend(o1, o2, o3) {
var result = {},
obj;
for (var i = 0; i < arguments.length; i++) {
obj = arguments[i];
for (var key in obj) {
if (Object.prototype.toString.call(obj[key]) === "[object Object]") {
if (typeof result[key] === "undefined") {
result[key] = {};
}
result[key] = extend(result[key], obj[key]);
} else {
result[key] = obj[key];
}
}
}
return result;
}

View File

@@ -6,7 +6,7 @@ export const EmailSettings = {
};
export const TemplateList = (type, context) => {
const { bodyshop } = store.getState().user;
//const { bodyshop } = store.getState().user;
return {
//If there's no type or the type is job, send it back.
@@ -15,81 +15,63 @@ export const TemplateList = (type, context) => {
casl_authorization: {
title: i18n.t("printcenter.jobs.casl_authorization"),
description: "CASL Authorization",
subject: `${i18n.t("printcenter.jobs.casl_authorization")} - ${
context && context.job && context.job.ro_number
}`,
subject: i18n.t("printcenter.jobs.casl_authorization"),
key: "casl_authorization",
disabled: false,
},
diagnostic_authorization: {
title: i18n.t("printcenter.jobs.diagnostic_authorization"),
description: "Diagnostic Authorization",
subject: `${i18n.t(
"printcenter.jobs.diagnostic_authorization"
)} - ${context && context.job && context.job.ro_number}`,
subject: i18n.t("printcenter.jobs.diagnostic_authorization"),
key: "diagnostic_authorization",
disabled: false,
},
job_notes: {
title: i18n.t("printcenter.jobs.job_notes"),
description: "All Jobs Notes",
subject: `${i18n.t("printcenter.jobs.job_notes")} - ${
context && context.job && context.job.ro_number
}`,
subject: i18n.t("printcenter.jobs.job_notes"),
key: "job_notes",
disabled: false,
},
ro_with_description: {
title: i18n.t("printcenter.jobs.ro_with_description"),
description: "All Jobs Notes",
subject: `${i18n.t("printcenter.jobs.ro_with_description")} - ${
context && context.job && context.job.ro_number
}`,
subject: i18n.t("printcenter.jobs.ro_with_description"),
key: "ro_with_description",
disabled: false,
},
window_tag: {
title: i18n.t("printcenter.jobs.window_tag"),
description: "All Jobs Notes",
subject: `${i18n.t("printcenter.jobs.window_tag")} - ${
context && context.job && context.job.ro_number
}`,
subject: i18n.t("printcenter.jobs.window_tag"),
key: "window_tag",
disabled: false,
},
payments_by_job: {
title: i18n.t("printcenter.jobs.payments_by_job"),
description: "All Jobs Notes",
subject: `${i18n.t("printcenter.jobs.payments_by_job")} - ${
context && context.job && context.job.ro_number
}`,
subject: i18n.t("printcenter.jobs.payments_by_job"),
key: "payments_by_job",
disabled: false,
},
appointment_reminder: {
title: i18n.t("printcenter.jobs.appointment_reminder"),
description: "All Jobs Notes",
subject: `${i18n.t("printcenter.jobs.appointment_reminder")} - ${
context && context.job && context.job.ro_number
}`,
subject: i18n.t("printcenter.jobs.appointment_reminder"),
key: "appointment_reminder",
disabled: false,
},
worksheet_by_line_number: {
title: i18n.t("printcenter.jobs.worksheet_by_line_number"),
description: "All Jobs Notes",
subject: `${i18n.t(
"printcenter.jobs.worksheet_by_line_number"
)} - ${context && context.job && context.job.ro_number}`,
subject: i18n.t("printcenter.jobs.worksheet_by_line_number"),
key: "worksheet_by_line_number",
disabled: false,
},
worksheet_sorted_by_operation: {
title: i18n.t("printcenter.jobs.worksheet_sorted_by_operation"),
description: "All Jobs Notes",
subject: `${i18n.t(
"printcenter.jobs.worksheet_sorted_by_operation"
)} - ${context && context.job && context.job.ro_number}`,
subject: i18n.t("printcenter.jobs.worksheet_sorted_by_operation"),
key: "worksheet_sorted_by_operation",
disabled: false,
},
@@ -98,9 +80,9 @@ export const TemplateList = (type, context) => {
"printcenter.jobs.worksheet_sorted_by_operation_no_hours"
),
description: "All Jobs Notes",
subject: `${i18n.t(
subject: i18n.t(
"printcenter.jobs.worksheet_sorted_by_operation_no_hours"
)} - ${context && context.job && context.job.ro_number}`,
),
key: "worksheet_sorted_by_operation_no_hours",
disabled: false,
},
@@ -109,93 +91,89 @@ export const TemplateList = (type, context) => {
"printcenter.jobs.worksheet_sorted_by_operation_part_type"
),
description: "All Jobs Notes",
subject: `${i18n.t(
subject: i18n.t(
"printcenter.jobs.worksheet_sorted_by_operation_part_type"
)} - ${context && context.job && context.job.ro_number}`,
),
key: "worksheet_sorted_by_operation_part_type",
disabled: false,
},
supplement_request: {
title: i18n.t("printcenter.jobs.supplement_request"),
description: "All Jobs Notes",
subject: `${i18n.t("printcenter.jobs.supplement_request")} - ${
context && context.job && context.job.ro_number
}`,
subject: i18n.t("printcenter.jobs.supplement_request"),
key: "supplement_request",
disabled: false,
},
final_invoice: {
title: i18n.t("printcenter.jobs.final_invoice"),
description: "All Jobs Notes",
subject: `${i18n.t("printcenter.jobs.final_invoice")} - ${
context && context.job && context.job.ro_number
}`,
subject: i18n.t("printcenter.jobs.final_invoice"),
key: "final_invoice",
disabled: false,
},
payment_request: {
title: i18n.t("printcenter.jobs.payment_request"),
description: "All Jobs Notes",
subject: `${i18n.t("printcenter.jobs.payment_request")} - ${
context && context.job && context.job.ro_number
}`,
subject: i18n.t("printcenter.jobs.payment_request"),
key: "payment_request",
disabled: false,
},
invoice_total_payable: {
title: i18n.t("printcenter.jobs.invoice_total_payable"),
description: "All Jobs Notes",
subject: `${i18n.t("printcenter.jobs.invoice_total_payable")} - ${
context && context.job && context.job.ro_number
}`,
subject: i18n.t("printcenter.jobs.invoice_total_payable"),
key: "invoice_total_payable",
disabled: false,
},
invoice_customer_payable: {
title: i18n.t("printcenter.jobs.invoice_customer_payable"),
description: "All Jobs Notes",
subject: `${i18n.t(
"printcenter.jobs.invoice_customer_payable"
)} - ${context && context.job && context.job.ro_number}`,
subject: i18n.t("printcenter.jobs.invoice_customer_payable"),
key: "invoice_customer_payable",
disabled: false,
},
parts_order_history: {
title: i18n.t("printcenter.jobs.parts_order_history"),
description: "All Jobs Notes",
subject: `${i18n.t("printcenter.jobs.parts_order_history")} - ${
context && context.job && context.job.ro_number
}`,
subject: i18n.t("printcenter.jobs.parts_order_history"),
key: "parts_order_history",
disabled: false,
},
glass_express_checklist: {
title: i18n.t("printcenter.jobs.glass_express_checklist"),
description: "All Jobs Notes",
subject: `${i18n.t("printcenter.jobs.glass_express_checklist")} - ${
context && context.job && context.job.ro_number
}`,
subject: i18n.t("printcenter.jobs.glass_express_checklist"),
key: "glass_express_checklist",
disabled: false,
},
estimate: {
title: i18n.t("printcenter.jobs.estimate"),
description: "All Jobs Notes",
subject: `${i18n.t("printcenter.jobs.estimate")} - ${
context && context.job && context.job.ro_number
}`,
subject: i18n.t("printcenter.jobs.estimate"),
key: "estimate",
disabled: false,
},
parts_list: {
title: i18n.t("printcenter.jobs.parts_list"),
description: "All Jobs Notes",
subject: `${i18n.t("printcenter.jobs.parts_list")} - ${
context && context.job && context.job.ro_number
}`,
subject: i18n.t("printcenter.jobs.parts_list"),
key: "parts_list",
disabled: false,
},
coversheet_portrait: {
title: i18n.t("printcenter.jobs.coversheet_portrait"),
description: "All Jobs Notes",
subject: i18n.t("printcenter.jobs.coversheet_portrait"),
key: "coversheet_portrait",
disabled: false,
},
filing_coverhseet_portrait: {
title: i18n.t("printcenter.jobs.filing_coverhseet_portrait"),
description: "All Jobs Notes",
subject: i18n.t("printcenter.jobs.filing_coverhseet_portrait"),
key: "filing_coverhseet_portrait",
disabled: false,
},
}
: {}),
...(!type || type === "job_special"
@@ -213,9 +191,9 @@ export const TemplateList = (type, context) => {
appointment_confirmation: {
title: i18n.t("printcenter.appointments.appointment_confirmation"),
description: "Appointment Confirmation",
subject: `${i18n.t(
subject: i18n.t(
"printcenter.appointments.appointment_confirmation"
)} - ${context && context.job && context.job.ro_number}`,
),
key: "appointment_confirmation",
disabled: false,
},
@@ -227,13 +205,12 @@ export const TemplateList = (type, context) => {
title: i18n.t("printcenter.jobs.parts_order"),
description: "Parts Order",
key: "parts_order",
subject: `${bodyshop && bodyshop.shopname} Parts Order ${
(context && context.job && context.job.ro_number) || ""
}`,
subject: i18n.t("printcenter.jobs.parts_order"),
disabled: false,
},
parts_return_slip: {
title: i18n.t("printcenter.jobs.parts_return_slip"),
subject: i18n.t("printcenter.jobs.parts_return_slip"),
description: "Parts Return",
key: "parts_return_slip",
disabled: false,
@@ -245,6 +222,7 @@ export const TemplateList = (type, context) => {
payment_receipt: {
title: i18n.t("printcenter.jobs.payment_receipt"),
description: "Payment Receipt",
subject: i18n.t("printcenter.jobs.payment_receipt"),
key: "payment_receipt",
disabled: false,
},
@@ -256,6 +234,7 @@ export const TemplateList = (type, context) => {
title: i18n.t("printcenter.jobs.csi_invitation"),
description: "CSI invite",
key: "csi_invitation",
subject: i18n.t("printcenter.jobs.csi_invitation"),
disabled: false,
},
}
@@ -265,9 +244,7 @@ export const TemplateList = (type, context) => {
payments_by_date_type: {
title: i18n.t("reportcenter.templates.payments_by_date_type"),
description: "Est Detail",
subject: `${i18n.t(
"reportcenter.templates.payments_by_date_type"
)} - ${context && context.job && context.job.ro_number}`,
subject: i18n.t("reportcenter.templates.payments_by_date_type"),
key: "payments_by_date_type",
disabled: false,
},
@@ -276,9 +253,9 @@ export const TemplateList = (type, context) => {
"reportcenter.templates.purchases_by_date_range_detail"
),
description: "Est Detail",
subject: `${i18n.t(
subject: i18n.t(
"reportcenter.templates.purchases_by_date_range_detail"
)} - ${context && context.job && context.job.ro_number}`,
),
key: "purchases_by_date_range_detail",
disabled: false,
},
@@ -287,27 +264,23 @@ export const TemplateList = (type, context) => {
"reportcenter.templates.purchases_by_date_range_summary"
),
description: "Est Detail",
subject: `${i18n.t(
subject: i18n.t(
"reportcenter.templates.purchases_by_date_range_summary"
)} - ${context && context.job && context.job.ro_number}`,
),
key: "purchases_by_date_range_summary",
disabled: false,
},
schedule: {
title: i18n.t("reportcenter.templates.schedule"),
description: "Est Detail",
subject: `${i18n.t("reportcenter.templates.schedule")} - ${
context && context.job && context.job.ro_number
}`,
subject: i18n.t("reportcenter.templates.schedule"),
key: "schedule",
disabled: false,
},
timetickets: {
title: i18n.t("reportcenter.templates.timetickets"),
description: "Est Detail",
subject: `${i18n.t("reportcenter.templates.timetickets")} - ${
context && context.job && context.job.ro_number
}`,
subject: i18n.t("reportcenter.templates.timetickets"),
key: "timetickets",
disabled: false,
},
@@ -316,9 +289,9 @@ export const TemplateList = (type, context) => {
"reportcenter.templates.purchases_by_vendor_detailed_date_range"
),
description: "Est Detail",
subject: `${i18n.t(
subject: i18n.t(
"reportcenter.templates.purchases_by_vendor_detailed_date_range"
)} - ${context && context.job && context.job.ro_number}`,
),
key: "purchases_by_vendor_detailed_date_range",
idtype: "vendor",
disabled: false,
@@ -328,9 +301,9 @@ export const TemplateList = (type, context) => {
"reportcenter.templates.purchases_by_vendor_summary_date_range"
),
description: "Est Detail",
subject: `${i18n.t(
subject: i18n.t(
"reportcenter.templates.purchases_by_vendor_summary_date_range"
)} - ${context && context.job && context.job.ro_number}`,
),
key: "purchases_by_vendor_summary_date_range",
idtype: "vendor",
disabled: false,
@@ -344,18 +317,18 @@ export const TemplateList = (type, context) => {
"printcenter.courtesycarcontract.courtesy_car_contract"
),
description: "Est Detail",
subject: `${i18n.t(
subject: i18n.t(
"printcenter.courtesycarcontract.courtesy_car_contract"
)} - ${context && context.job && context.job.ro_number}`,
),
key: "courtesy_car_contract",
disabled: false,
},
courtesy_car_terms: {
title: i18n.t("printcenter.courtesycarcontract.courtesy_car_terms"),
description: "Est Detail",
subject: `${i18n.t(
subject: i18n.t(
"printcenter.courtesycarcontract.courtesy_car_terms"
)} - ${context && context.job && context.job.ro_number}`,
),
key: "courtesy_car_terms",
disabled: false,
},
@@ -366,9 +339,7 @@ export const TemplateList = (type, context) => {
inhouse_invoice: {
title: i18n.t("printcenter.bills.inhouse_invoice"),
description: "Est Detail",
subject: `${i18n.t("printcenter.bills.inhouse_invoice")} - ${
context && context.job && context.job.ro_number
}`,
subject: i18n.t("printcenter.bills.inhouse_invoice"),
key: "inhouse_invoice",
disabled: false,
},
@@ -392,18 +363,14 @@ export const TemplateList = (type, context) => {
purchases_by_vendor_detailed: {
title: i18n.t("printcenter.vendors.purchases_by_vendor_detailed"),
description: "Est Detail",
subject: `${i18n.t(
"printcenter.vendors.purchases_by_vendor_detailed"
)} - ${context && context.job && context.job.ro_number}`,
subject: i18n.t("printcenter.vendors.purchases_by_vendor_detailed"),
key: "purchases_by_vendor_detailed",
disabled: false,
},
purchases_by_vendor_summary: {
title: i18n.t("printcenter.vendors.purchases_by_vendor_summary"),
description: "Est Detail",
subject: `${i18n.t(
"printcenter.vendors.purchases_by_vendor_summary"
)} - ${context && context.job && context.job.ro_number}`,
subject: i18n.t("printcenter.vendors.purchases_by_vendor_summary"),
key: "purchases_by_vendor_summary",
disabled: false,
},

View File

@@ -0,0 +1,5 @@
- args:
cascade: false
read_only: false
sql: ALTER TABLE "public"."jobs" DROP COLUMN "ca_bc_pvrt";
type: run_sql

View File

@@ -0,0 +1,5 @@
- args:
cascade: false
read_only: false
sql: ALTER TABLE "public"."jobs" ADD COLUMN "ca_bc_pvrt" numeric NULL;
type: run_sql

View File

@@ -0,0 +1,265 @@
- args:
role: user
table:
name: jobs
schema: public
type: drop_insert_permission
- args:
permission:
check:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
columns:
- actual_completion
- actual_delivery
- actual_in
- adj_g_disc
- adj_strdis
- adj_towdis
- adjustment_bottom_line
- agt_addr1
- agt_addr2
- agt_city
- agt_co_id
- agt_co_nm
- agt_ct_fn
- agt_ct_ln
- agt_ct_ph
- agt_ct_phx
- agt_ctry
- agt_ea
- agt_fax
- agt_faxx
- agt_lic_no
- agt_ph1
- agt_ph1x
- agt_ph2
- agt_ph2x
- agt_st
- agt_zip
- alt_transport
- area_of_damage
- asgn_date
- asgn_no
- asgn_type
- ca_gst_registrant
- cat_no
- category
- cieca_stl
- cieca_ttl
- ciecaid
- class
- clm_addr1
- clm_addr2
- clm_city
- clm_ct_fn
- clm_ct_ln
- clm_ct_ph
- clm_ct_phx
- clm_ctry
- clm_ea
- clm_fax
- clm_faxx
- clm_no
- clm_ofc_id
- clm_ofc_nm
- clm_ph1
- clm_ph1x
- clm_ph2
- clm_ph2x
- clm_st
- clm_title
- clm_total
- clm_zip
- converted
- created_at
- csr
- cust_pr
- date_estimated
- date_exported
- date_invoiced
- date_open
- date_scheduled
- ded_amt
- ded_status
- deliverchecklist
- depreciation_taxes
- driveable
- employee_body
- employee_prep
- employee_refinish
- est_addr1
- est_addr2
- est_city
- est_co_nm
- est_ct_fn
- est_ct_ln
- est_ctry
- est_ea
- est_ph1
- est_st
- est_zip
- federal_tax_rate
- g_bett_amt
- id
- inproduction
- ins_addr1
- ins_addr2
- ins_city
- ins_co_id
- ins_co_nm
- ins_ct_fn
- ins_ct_ln
- ins_ct_ph
- ins_ct_phx
- ins_ctry
- ins_ea
- ins_fax
- ins_faxx
- ins_memo
- ins_ph1
- ins_ph1x
- ins_ph2
- ins_ph2x
- ins_st
- ins_title
- ins_zip
- insd_addr1
- insd_addr2
- insd_city
- insd_co_nm
- insd_ctry
- insd_ea
- insd_fax
- insd_faxx
- insd_fn
- insd_ln
- insd_ph1
- insd_ph1x
- insd_ph2
- insd_ph2x
- insd_st
- insd_title
- insd_zip
- intakechecklist
- invoice_allocation
- invoice_date
- job_totals
- kanbanparent
- kmin
- kmout
- labor_rate_desc
- labor_rate_id
- lbr_adjustments
- local_tax_rate
- loss_cat
- loss_date
- loss_desc
- loss_type
- other_amount_payable
- owner_owing
- ownerid
- ownr_addr1
- ownr_addr2
- ownr_city
- ownr_co_nm
- ownr_ctry
- ownr_ea
- ownr_fax
- ownr_faxx
- ownr_fn
- ownr_ln
- ownr_ph1
- ownr_ph1x
- ownr_ph2
- ownr_ph2x
- ownr_st
- ownr_title
- ownr_zip
- parts_tax_rates
- pay_amt
- pay_chknm
- pay_date
- pay_type
- payee_nms
- plate_no
- plate_st
- po_number
- policy_no
- production_vars
- queued_for_parts
- rate_la1
- rate_la2
- rate_la3
- rate_la4
- rate_laa
- rate_lab
- rate_lad
- rate_lae
- rate_laf
- rate_lag
- rate_lam
- rate_lar
- rate_las
- rate_lau
- rate_ma2s
- rate_ma2t
- rate_ma3s
- rate_mabl
- rate_macs
- rate_mahw
- rate_mapa
- rate_mash
- rate_matd
- referral_source
- regie_number
- ro_number
- scheduled_completion
- scheduled_delivery
- scheduled_in
- selling_dealer
- selling_dealer_contact
- servicing_dealer
- servicing_dealer_contact
- shopid
- special_coverage_policy
- state_tax_rate
- status
- storage_payable
- tax_lbr_rt
- tax_levies_rt
- tax_paint_mat_rt
- tax_predis
- tax_prethr
- tax_pstthr
- tax_registration_number
- tax_shop_mat_rt
- tax_str_rt
- tax_sub_rt
- tax_thramt
- tax_tow_rt
- theft_ind
- tlos_ind
- towin
- towing_payable
- unit_number
- updated_at
- v_color
- v_make_desc
- v_model_desc
- v_model_yr
- v_vin
- vehicleid
- voided
set: {}
role: user
table:
name: jobs
schema: public
type: create_insert_permission

View File

@@ -0,0 +1,266 @@
- args:
role: user
table:
name: jobs
schema: public
type: drop_insert_permission
- args:
permission:
check:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
columns:
- actual_completion
- actual_delivery
- actual_in
- adj_g_disc
- adj_strdis
- adj_towdis
- adjustment_bottom_line
- agt_addr1
- agt_addr2
- agt_city
- agt_co_id
- agt_co_nm
- agt_ct_fn
- agt_ct_ln
- agt_ct_ph
- agt_ct_phx
- agt_ctry
- agt_ea
- agt_fax
- agt_faxx
- agt_lic_no
- agt_ph1
- agt_ph1x
- agt_ph2
- agt_ph2x
- agt_st
- agt_zip
- alt_transport
- area_of_damage
- asgn_date
- asgn_no
- asgn_type
- ca_bc_pvrt
- ca_gst_registrant
- cat_no
- category
- cieca_stl
- cieca_ttl
- ciecaid
- class
- clm_addr1
- clm_addr2
- clm_city
- clm_ct_fn
- clm_ct_ln
- clm_ct_ph
- clm_ct_phx
- clm_ctry
- clm_ea
- clm_fax
- clm_faxx
- clm_no
- clm_ofc_id
- clm_ofc_nm
- clm_ph1
- clm_ph1x
- clm_ph2
- clm_ph2x
- clm_st
- clm_title
- clm_total
- clm_zip
- converted
- created_at
- csr
- cust_pr
- date_estimated
- date_exported
- date_invoiced
- date_open
- date_scheduled
- ded_amt
- ded_status
- deliverchecklist
- depreciation_taxes
- driveable
- employee_body
- employee_prep
- employee_refinish
- est_addr1
- est_addr2
- est_city
- est_co_nm
- est_ct_fn
- est_ct_ln
- est_ctry
- est_ea
- est_ph1
- est_st
- est_zip
- federal_tax_rate
- g_bett_amt
- id
- inproduction
- ins_addr1
- ins_addr2
- ins_city
- ins_co_id
- ins_co_nm
- ins_ct_fn
- ins_ct_ln
- ins_ct_ph
- ins_ct_phx
- ins_ctry
- ins_ea
- ins_fax
- ins_faxx
- ins_memo
- ins_ph1
- ins_ph1x
- ins_ph2
- ins_ph2x
- ins_st
- ins_title
- ins_zip
- insd_addr1
- insd_addr2
- insd_city
- insd_co_nm
- insd_ctry
- insd_ea
- insd_fax
- insd_faxx
- insd_fn
- insd_ln
- insd_ph1
- insd_ph1x
- insd_ph2
- insd_ph2x
- insd_st
- insd_title
- insd_zip
- intakechecklist
- invoice_allocation
- invoice_date
- job_totals
- kanbanparent
- kmin
- kmout
- labor_rate_desc
- labor_rate_id
- lbr_adjustments
- local_tax_rate
- loss_cat
- loss_date
- loss_desc
- loss_type
- other_amount_payable
- owner_owing
- ownerid
- ownr_addr1
- ownr_addr2
- ownr_city
- ownr_co_nm
- ownr_ctry
- ownr_ea
- ownr_fax
- ownr_faxx
- ownr_fn
- ownr_ln
- ownr_ph1
- ownr_ph1x
- ownr_ph2
- ownr_ph2x
- ownr_st
- ownr_title
- ownr_zip
- parts_tax_rates
- pay_amt
- pay_chknm
- pay_date
- pay_type
- payee_nms
- plate_no
- plate_st
- po_number
- policy_no
- production_vars
- queued_for_parts
- rate_la1
- rate_la2
- rate_la3
- rate_la4
- rate_laa
- rate_lab
- rate_lad
- rate_lae
- rate_laf
- rate_lag
- rate_lam
- rate_lar
- rate_las
- rate_lau
- rate_ma2s
- rate_ma2t
- rate_ma3s
- rate_mabl
- rate_macs
- rate_mahw
- rate_mapa
- rate_mash
- rate_matd
- referral_source
- regie_number
- ro_number
- scheduled_completion
- scheduled_delivery
- scheduled_in
- selling_dealer
- selling_dealer_contact
- servicing_dealer
- servicing_dealer_contact
- shopid
- special_coverage_policy
- state_tax_rate
- status
- storage_payable
- tax_lbr_rt
- tax_levies_rt
- tax_paint_mat_rt
- tax_predis
- tax_prethr
- tax_pstthr
- tax_registration_number
- tax_shop_mat_rt
- tax_str_rt
- tax_sub_rt
- tax_thramt
- tax_tow_rt
- theft_ind
- tlos_ind
- towin
- towing_payable
- unit_number
- updated_at
- v_color
- v_make_desc
- v_model_desc
- v_model_yr
- v_vin
- vehicleid
- voided
set: {}
role: user
table:
name: jobs
schema: public
type: create_insert_permission

View File

@@ -0,0 +1,266 @@
- args:
role: user
table:
name: jobs
schema: public
type: drop_select_permission
- args:
permission:
allow_aggregations: true
columns:
- actual_completion
- actual_delivery
- actual_in
- adj_g_disc
- adj_strdis
- adj_towdis
- adjustment_bottom_line
- agt_addr1
- agt_addr2
- agt_city
- agt_co_id
- agt_co_nm
- agt_ct_fn
- agt_ct_ln
- agt_ct_ph
- agt_ct_phx
- agt_ctry
- agt_ea
- agt_fax
- agt_faxx
- agt_lic_no
- agt_ph1
- agt_ph1x
- agt_ph2
- agt_ph2x
- agt_st
- agt_zip
- alt_transport
- area_of_damage
- asgn_date
- asgn_no
- asgn_type
- ca_gst_registrant
- cat_no
- category
- cieca_stl
- cieca_ttl
- ciecaid
- class
- clm_addr1
- clm_addr2
- clm_city
- clm_ct_fn
- clm_ct_ln
- clm_ct_ph
- clm_ct_phx
- clm_ctry
- clm_ea
- clm_fax
- clm_faxx
- clm_no
- clm_ofc_id
- clm_ofc_nm
- clm_ph1
- clm_ph1x
- clm_ph2
- clm_ph2x
- clm_st
- clm_title
- clm_total
- clm_zip
- converted
- created_at
- csr
- cust_pr
- date_estimated
- date_exported
- date_invoiced
- date_open
- date_scheduled
- ded_amt
- ded_status
- deliverchecklist
- depreciation_taxes
- driveable
- employee_body
- employee_prep
- employee_refinish
- est_addr1
- est_addr2
- est_city
- est_co_nm
- est_ct_fn
- est_ct_ln
- est_ctry
- est_ea
- est_ph1
- est_st
- est_zip
- federal_tax_rate
- g_bett_amt
- id
- inproduction
- ins_addr1
- ins_addr2
- ins_city
- ins_co_id
- ins_co_nm
- ins_ct_fn
- ins_ct_ln
- ins_ct_ph
- ins_ct_phx
- ins_ctry
- ins_ea
- ins_fax
- ins_faxx
- ins_memo
- ins_ph1
- ins_ph1x
- ins_ph2
- ins_ph2x
- ins_st
- ins_title
- ins_zip
- insd_addr1
- insd_addr2
- insd_city
- insd_co_nm
- insd_ctry
- insd_ea
- insd_fax
- insd_faxx
- insd_fn
- insd_ln
- insd_ph1
- insd_ph1x
- insd_ph2
- insd_ph2x
- insd_st
- insd_title
- insd_zip
- intakechecklist
- invoice_allocation
- invoice_date
- job_totals
- kanbanparent
- kmin
- kmout
- labor_rate_desc
- labor_rate_id
- lbr_adjustments
- local_tax_rate
- loss_cat
- loss_date
- loss_desc
- loss_type
- other_amount_payable
- owner_owing
- ownerid
- ownr_addr1
- ownr_addr2
- ownr_city
- ownr_co_nm
- ownr_ctry
- ownr_ea
- ownr_fax
- ownr_faxx
- ownr_fn
- ownr_ln
- ownr_ph1
- ownr_ph1x
- ownr_ph2
- ownr_ph2x
- ownr_st
- ownr_title
- ownr_zip
- parts_tax_rates
- pay_amt
- pay_chknm
- pay_date
- pay_type
- payee_nms
- plate_no
- plate_st
- po_number
- policy_no
- production_vars
- queued_for_parts
- rate_la1
- rate_la2
- rate_la3
- rate_la4
- rate_laa
- rate_lab
- rate_lad
- rate_lae
- rate_laf
- rate_lag
- rate_lam
- rate_lar
- rate_las
- rate_lau
- rate_ma2s
- rate_ma2t
- rate_ma3s
- rate_mabl
- rate_macs
- rate_mahw
- rate_mapa
- rate_mash
- rate_matd
- referral_source
- regie_number
- ro_number
- scheduled_completion
- scheduled_delivery
- scheduled_in
- selling_dealer
- selling_dealer_contact
- servicing_dealer
- servicing_dealer_contact
- shopid
- special_coverage_policy
- state_tax_rate
- status
- storage_payable
- tax_lbr_rt
- tax_levies_rt
- tax_paint_mat_rt
- tax_predis
- tax_prethr
- tax_pstthr
- tax_registration_number
- tax_shop_mat_rt
- tax_str_rt
- tax_sub_rt
- tax_thramt
- tax_tow_rt
- theft_ind
- tlos_ind
- towin
- towing_payable
- unit_number
- updated_at
- v_color
- v_make_desc
- v_model_desc
- v_model_yr
- v_vin
- vehicleid
- voided
computed_fields: []
filter:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
role: user
table:
name: jobs
schema: public
type: create_select_permission

View File

@@ -0,0 +1,267 @@
- args:
role: user
table:
name: jobs
schema: public
type: drop_select_permission
- args:
permission:
allow_aggregations: true
columns:
- actual_completion
- actual_delivery
- actual_in
- adj_g_disc
- adj_strdis
- adj_towdis
- adjustment_bottom_line
- agt_addr1
- agt_addr2
- agt_city
- agt_co_id
- agt_co_nm
- agt_ct_fn
- agt_ct_ln
- agt_ct_ph
- agt_ct_phx
- agt_ctry
- agt_ea
- agt_fax
- agt_faxx
- agt_lic_no
- agt_ph1
- agt_ph1x
- agt_ph2
- agt_ph2x
- agt_st
- agt_zip
- alt_transport
- area_of_damage
- asgn_date
- asgn_no
- asgn_type
- ca_bc_pvrt
- ca_gst_registrant
- cat_no
- category
- cieca_stl
- cieca_ttl
- ciecaid
- class
- clm_addr1
- clm_addr2
- clm_city
- clm_ct_fn
- clm_ct_ln
- clm_ct_ph
- clm_ct_phx
- clm_ctry
- clm_ea
- clm_fax
- clm_faxx
- clm_no
- clm_ofc_id
- clm_ofc_nm
- clm_ph1
- clm_ph1x
- clm_ph2
- clm_ph2x
- clm_st
- clm_title
- clm_total
- clm_zip
- converted
- created_at
- csr
- cust_pr
- date_estimated
- date_exported
- date_invoiced
- date_open
- date_scheduled
- ded_amt
- ded_status
- deliverchecklist
- depreciation_taxes
- driveable
- employee_body
- employee_prep
- employee_refinish
- est_addr1
- est_addr2
- est_city
- est_co_nm
- est_ct_fn
- est_ct_ln
- est_ctry
- est_ea
- est_ph1
- est_st
- est_zip
- federal_tax_rate
- g_bett_amt
- id
- inproduction
- ins_addr1
- ins_addr2
- ins_city
- ins_co_id
- ins_co_nm
- ins_ct_fn
- ins_ct_ln
- ins_ct_ph
- ins_ct_phx
- ins_ctry
- ins_ea
- ins_fax
- ins_faxx
- ins_memo
- ins_ph1
- ins_ph1x
- ins_ph2
- ins_ph2x
- ins_st
- ins_title
- ins_zip
- insd_addr1
- insd_addr2
- insd_city
- insd_co_nm
- insd_ctry
- insd_ea
- insd_fax
- insd_faxx
- insd_fn
- insd_ln
- insd_ph1
- insd_ph1x
- insd_ph2
- insd_ph2x
- insd_st
- insd_title
- insd_zip
- intakechecklist
- invoice_allocation
- invoice_date
- job_totals
- kanbanparent
- kmin
- kmout
- labor_rate_desc
- labor_rate_id
- lbr_adjustments
- local_tax_rate
- loss_cat
- loss_date
- loss_desc
- loss_type
- other_amount_payable
- owner_owing
- ownerid
- ownr_addr1
- ownr_addr2
- ownr_city
- ownr_co_nm
- ownr_ctry
- ownr_ea
- ownr_fax
- ownr_faxx
- ownr_fn
- ownr_ln
- ownr_ph1
- ownr_ph1x
- ownr_ph2
- ownr_ph2x
- ownr_st
- ownr_title
- ownr_zip
- parts_tax_rates
- pay_amt
- pay_chknm
- pay_date
- pay_type
- payee_nms
- plate_no
- plate_st
- po_number
- policy_no
- production_vars
- queued_for_parts
- rate_la1
- rate_la2
- rate_la3
- rate_la4
- rate_laa
- rate_lab
- rate_lad
- rate_lae
- rate_laf
- rate_lag
- rate_lam
- rate_lar
- rate_las
- rate_lau
- rate_ma2s
- rate_ma2t
- rate_ma3s
- rate_mabl
- rate_macs
- rate_mahw
- rate_mapa
- rate_mash
- rate_matd
- referral_source
- regie_number
- ro_number
- scheduled_completion
- scheduled_delivery
- scheduled_in
- selling_dealer
- selling_dealer_contact
- servicing_dealer
- servicing_dealer_contact
- shopid
- special_coverage_policy
- state_tax_rate
- status
- storage_payable
- tax_lbr_rt
- tax_levies_rt
- tax_paint_mat_rt
- tax_predis
- tax_prethr
- tax_pstthr
- tax_registration_number
- tax_shop_mat_rt
- tax_str_rt
- tax_sub_rt
- tax_thramt
- tax_tow_rt
- theft_ind
- tlos_ind
- towin
- towing_payable
- unit_number
- updated_at
- v_color
- v_make_desc
- v_model_desc
- v_model_yr
- v_vin
- vehicleid
- voided
computed_fields: []
filter:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
role: user
table:
name: jobs
schema: public
type: create_select_permission

View File

@@ -0,0 +1,265 @@
- args:
role: user
table:
name: jobs
schema: public
type: drop_update_permission
- args:
permission:
columns:
- actual_completion
- actual_delivery
- actual_in
- adj_g_disc
- adj_strdis
- adj_towdis
- adjustment_bottom_line
- agt_addr1
- agt_addr2
- agt_city
- agt_co_id
- agt_co_nm
- agt_ct_fn
- agt_ct_ln
- agt_ct_ph
- agt_ct_phx
- agt_ctry
- agt_ea
- agt_fax
- agt_faxx
- agt_lic_no
- agt_ph1
- agt_ph1x
- agt_ph2
- agt_ph2x
- agt_st
- agt_zip
- alt_transport
- area_of_damage
- asgn_date
- asgn_no
- asgn_type
- ca_gst_registrant
- cat_no
- category
- cieca_stl
- cieca_ttl
- ciecaid
- class
- clm_addr1
- clm_addr2
- clm_city
- clm_ct_fn
- clm_ct_ln
- clm_ct_ph
- clm_ct_phx
- clm_ctry
- clm_ea
- clm_fax
- clm_faxx
- clm_no
- clm_ofc_id
- clm_ofc_nm
- clm_ph1
- clm_ph1x
- clm_ph2
- clm_ph2x
- clm_st
- clm_title
- clm_total
- clm_zip
- converted
- created_at
- csr
- cust_pr
- date_estimated
- date_exported
- date_invoiced
- date_open
- date_scheduled
- ded_amt
- ded_status
- deliverchecklist
- depreciation_taxes
- driveable
- employee_body
- employee_prep
- employee_refinish
- est_addr1
- est_addr2
- est_city
- est_co_nm
- est_ct_fn
- est_ct_ln
- est_ctry
- est_ea
- est_ph1
- est_st
- est_zip
- federal_tax_rate
- g_bett_amt
- id
- inproduction
- ins_addr1
- ins_addr2
- ins_city
- ins_co_id
- ins_co_nm
- ins_ct_fn
- ins_ct_ln
- ins_ct_ph
- ins_ct_phx
- ins_ctry
- ins_ea
- ins_fax
- ins_faxx
- ins_memo
- ins_ph1
- ins_ph1x
- ins_ph2
- ins_ph2x
- ins_st
- ins_title
- ins_zip
- insd_addr1
- insd_addr2
- insd_city
- insd_co_nm
- insd_ctry
- insd_ea
- insd_fax
- insd_faxx
- insd_fn
- insd_ln
- insd_ph1
- insd_ph1x
- insd_ph2
- insd_ph2x
- insd_st
- insd_title
- insd_zip
- intakechecklist
- invoice_allocation
- invoice_date
- job_totals
- kanbanparent
- kmin
- kmout
- labor_rate_desc
- labor_rate_id
- lbr_adjustments
- local_tax_rate
- loss_cat
- loss_date
- loss_desc
- loss_type
- other_amount_payable
- owner_owing
- ownerid
- ownr_addr1
- ownr_addr2
- ownr_city
- ownr_co_nm
- ownr_ctry
- ownr_ea
- ownr_fax
- ownr_faxx
- ownr_fn
- ownr_ln
- ownr_ph1
- ownr_ph1x
- ownr_ph2
- ownr_ph2x
- ownr_st
- ownr_title
- ownr_zip
- parts_tax_rates
- pay_amt
- pay_chknm
- pay_date
- pay_type
- payee_nms
- plate_no
- plate_st
- po_number
- policy_no
- production_vars
- queued_for_parts
- rate_la1
- rate_la2
- rate_la3
- rate_la4
- rate_laa
- rate_lab
- rate_lad
- rate_lae
- rate_laf
- rate_lag
- rate_lam
- rate_lar
- rate_las
- rate_lau
- rate_ma2s
- rate_ma2t
- rate_ma3s
- rate_mabl
- rate_macs
- rate_mahw
- rate_mapa
- rate_mash
- rate_matd
- referral_source
- regie_number
- ro_number
- scheduled_completion
- scheduled_delivery
- scheduled_in
- selling_dealer
- selling_dealer_contact
- servicing_dealer
- servicing_dealer_contact
- shopid
- special_coverage_policy
- state_tax_rate
- status
- storage_payable
- tax_lbr_rt
- tax_levies_rt
- tax_paint_mat_rt
- tax_predis
- tax_prethr
- tax_pstthr
- tax_registration_number
- tax_shop_mat_rt
- tax_str_rt
- tax_sub_rt
- tax_thramt
- tax_tow_rt
- theft_ind
- tlos_ind
- towin
- towing_payable
- unit_number
- updated_at
- v_color
- v_make_desc
- v_model_desc
- v_model_yr
- v_vin
- vehicleid
- voided
filter:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
set: {}
role: user
table:
name: jobs
schema: public
type: create_update_permission

View File

@@ -0,0 +1,266 @@
- args:
role: user
table:
name: jobs
schema: public
type: drop_update_permission
- args:
permission:
columns:
- actual_completion
- actual_delivery
- actual_in
- adj_g_disc
- adj_strdis
- adj_towdis
- adjustment_bottom_line
- agt_addr1
- agt_addr2
- agt_city
- agt_co_id
- agt_co_nm
- agt_ct_fn
- agt_ct_ln
- agt_ct_ph
- agt_ct_phx
- agt_ctry
- agt_ea
- agt_fax
- agt_faxx
- agt_lic_no
- agt_ph1
- agt_ph1x
- agt_ph2
- agt_ph2x
- agt_st
- agt_zip
- alt_transport
- area_of_damage
- asgn_date
- asgn_no
- asgn_type
- ca_bc_pvrt
- ca_gst_registrant
- cat_no
- category
- cieca_stl
- cieca_ttl
- ciecaid
- class
- clm_addr1
- clm_addr2
- clm_city
- clm_ct_fn
- clm_ct_ln
- clm_ct_ph
- clm_ct_phx
- clm_ctry
- clm_ea
- clm_fax
- clm_faxx
- clm_no
- clm_ofc_id
- clm_ofc_nm
- clm_ph1
- clm_ph1x
- clm_ph2
- clm_ph2x
- clm_st
- clm_title
- clm_total
- clm_zip
- converted
- created_at
- csr
- cust_pr
- date_estimated
- date_exported
- date_invoiced
- date_open
- date_scheduled
- ded_amt
- ded_status
- deliverchecklist
- depreciation_taxes
- driveable
- employee_body
- employee_prep
- employee_refinish
- est_addr1
- est_addr2
- est_city
- est_co_nm
- est_ct_fn
- est_ct_ln
- est_ctry
- est_ea
- est_ph1
- est_st
- est_zip
- federal_tax_rate
- g_bett_amt
- id
- inproduction
- ins_addr1
- ins_addr2
- ins_city
- ins_co_id
- ins_co_nm
- ins_ct_fn
- ins_ct_ln
- ins_ct_ph
- ins_ct_phx
- ins_ctry
- ins_ea
- ins_fax
- ins_faxx
- ins_memo
- ins_ph1
- ins_ph1x
- ins_ph2
- ins_ph2x
- ins_st
- ins_title
- ins_zip
- insd_addr1
- insd_addr2
- insd_city
- insd_co_nm
- insd_ctry
- insd_ea
- insd_fax
- insd_faxx
- insd_fn
- insd_ln
- insd_ph1
- insd_ph1x
- insd_ph2
- insd_ph2x
- insd_st
- insd_title
- insd_zip
- intakechecklist
- invoice_allocation
- invoice_date
- job_totals
- kanbanparent
- kmin
- kmout
- labor_rate_desc
- labor_rate_id
- lbr_adjustments
- local_tax_rate
- loss_cat
- loss_date
- loss_desc
- loss_type
- other_amount_payable
- owner_owing
- ownerid
- ownr_addr1
- ownr_addr2
- ownr_city
- ownr_co_nm
- ownr_ctry
- ownr_ea
- ownr_fax
- ownr_faxx
- ownr_fn
- ownr_ln
- ownr_ph1
- ownr_ph1x
- ownr_ph2
- ownr_ph2x
- ownr_st
- ownr_title
- ownr_zip
- parts_tax_rates
- pay_amt
- pay_chknm
- pay_date
- pay_type
- payee_nms
- plate_no
- plate_st
- po_number
- policy_no
- production_vars
- queued_for_parts
- rate_la1
- rate_la2
- rate_la3
- rate_la4
- rate_laa
- rate_lab
- rate_lad
- rate_lae
- rate_laf
- rate_lag
- rate_lam
- rate_lar
- rate_las
- rate_lau
- rate_ma2s
- rate_ma2t
- rate_ma3s
- rate_mabl
- rate_macs
- rate_mahw
- rate_mapa
- rate_mash
- rate_matd
- referral_source
- regie_number
- ro_number
- scheduled_completion
- scheduled_delivery
- scheduled_in
- selling_dealer
- selling_dealer_contact
- servicing_dealer
- servicing_dealer_contact
- shopid
- special_coverage_policy
- state_tax_rate
- status
- storage_payable
- tax_lbr_rt
- tax_levies_rt
- tax_paint_mat_rt
- tax_predis
- tax_prethr
- tax_pstthr
- tax_registration_number
- tax_shop_mat_rt
- tax_str_rt
- tax_sub_rt
- tax_thramt
- tax_tow_rt
- theft_ind
- tlos_ind
- towin
- towing_payable
- unit_number
- updated_at
- v_color
- v_make_desc
- v_model_desc
- v_model_yr
- v_vin
- vehicleid
- voided
filter:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
set: {}
role: user
table:
name: jobs
schema: public
type: create_update_permission

View File

@@ -2253,6 +2253,7 @@ tables:
- asgn_date
- asgn_no
- asgn_type
- ca_bc_pvrt
- ca_gst_registrant
- cat_no
- category
@@ -2498,6 +2499,7 @@ tables:
- asgn_date
- asgn_no
- asgn_type
- ca_bc_pvrt
- ca_gst_registrant
- cat_no
- category
@@ -2753,6 +2755,7 @@ tables:
- asgn_date
- asgn_no
- asgn_type
- ca_bc_pvrt
- ca_gst_registrant
- cat_no
- category

View File

@@ -16,9 +16,6 @@ require("dotenv").config({
),
});
const https = require("https");
const fs = require("fs");
const app = express();
const port = process.env.PORT || 5000;
//const port = 5000;
@@ -96,6 +93,7 @@ app.post(
var job = require("./server/job/job");
app.post("/job/totals", fb.validateFirebaseIdToken, job.totals);
app.post("/job/totalsssu", fb.validateFirebaseIdToken, job.totalsSsu);
//Scheduling
var scheduling = require("./server/scheduling/scheduling-job");

View File

@@ -276,6 +276,20 @@ const generateInvoiceQbxml = (jobs_by_pk, bodyshop) => {
});
}
//Region Specific
const { ca_bc_pvrt } = jobs_by_pk;
if (ca_bc_pvrt) {
InvoiceLineAdd.push({
ItemRef: {
FullName: bodyshop.md_responsibility_centers.taxes.state.accountitem,
},
Desc: "PVRT",
Amount: Dinero({ amount: (ca_bc_pvrt || 0) * 100 }).toFormat(
DineroQbFormat
),
});
}
const invoiceQbxmlObj = {
QBXML: {
QBXMLMsgsRq: {

View File

@@ -84,6 +84,7 @@ query QUERY_JOBS_FOR_RECEIVABLES_EXPORT($ids: [uuid!]!) {
rate_mash
rate_matd
class
ca_bc_pvrt
owner {
accountingid
}
@@ -381,3 +382,190 @@ exports.AUTOHOUSE_QUERY = `query AUTOHOUSE_EXPORT($start: timestamptz) {
}
}
`;
exports.UPDATE_JOB = `
mutation UPDATE_JOB($jobId: uuid!, $job: jobs_set_input!) {
update_jobs(where: { id: { _eq: $jobId } }, _set: $job) {
returning {
id
date_exported
status
alt_transport
ro_number
production_vars
lbr_adjustments
}
}
}
`;
exports.GET_JOB_BY_PK = ` query GET_JOB_BY_PK($id: uuid!) {
jobs_by_pk(id: $id) {
updated_at
alt_transport
intakechecklist
csr
loss_desc
kmin
kmout
referral_source
unit_number
po_number
special_coverage_policy
scheduled_delivery
converted
lbr_adjustments
ro_number
clm_total
inproduction
vehicleid
plate_no
v_vin
v_model_yr
v_model_desc
v_make_desc
v_color
vehicleid
driveable
towin
ins_co_id
policy_no
loss_date
clm_no
area_of_damage
ins_co_nm
ins_addr1
ins_city
ins_ct_ln
ins_ct_fn
ins_ea
ins_ph1
est_co_nm
est_ct_fn
est_ct_ln
est_ph1
est_ea
selling_dealer
servicing_dealer
selling_dealer_contact
servicing_dealer_contact
regie_number
scheduled_completion
id
ded_amt
ded_status
depreciation_taxes
other_amount_payable
towing_payable
storage_payable
adjustment_bottom_line
federal_tax_rate
state_tax_rate
local_tax_rate
tax_tow_rt
tax_str_rt
tax_paint_mat_rt
tax_shop_mat_rt
tax_sub_rt
tax_lbr_rt
tax_levies_rt
parts_tax_rates
job_totals
ownr_fn
ownr_ln
ownr_ea
ownr_addr1
ownr_addr2
ownr_city
ownr_st
ownr_zip
ownr_ctry
ownr_ph1
production_vars
ca_gst_registrant
labor_rate_desc
rate_la1
rate_la2
rate_la3
rate_la4
rate_laa
rate_lab
rate_lad
rate_lae
rate_laf
rate_lag
rate_lam
rate_lar
rate_las
rate_lau
rate_ma2s
rate_ma2t
rate_ma3s
rate_mabl
rate_macs
rate_mahw
rate_mapa
rate_mash
rate_matd
actual_in
federal_tax_rate
local_tax_rate
state_tax_rate
scheduled_completion
scheduled_in
actual_completion
scheduled_delivery
actual_delivery
date_estimated
date_open
date_scheduled
date_invoiced
date_exported
status
owner_owing
tax_registration_number
class
category
deliverchecklist
voided
ca_bc_pvrt
joblines{
id
line_no
unq_seq
line_ind
line_desc
part_type
oem_partno
db_price
act_price
part_qty
mod_lbr_ty
db_hrs
mod_lb_hrs
lbr_op
lbr_amt
op_code_desc
status
notes
location
tax_part
db_ref
manual_line
parts_order_lines {
id
parts_order {
id
order_number
order_date
user_email
vendor {
id
name
}
}
}
}
}
}`;

View File

@@ -1,10 +1,75 @@
const Dinero = require("dinero.js");
const queries = require("../graphql-client/queries");
const GraphQLClient = require("graphql-request").GraphQLClient;
Dinero.defaultCurrency = "USD";
Dinero.globalLocale = "en-CA";
Dinero.globalRoundingMode = "HALF_UP";
exports.default = async function (req, res) {
exports.totalsSsu = async function (req, res) {
const BearerToken = req.headers.authorization;
const { id } = req.body;
const client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, {
headers: {
Authorization: BearerToken,
},
});
try {
const job = await client
.setHeaders({ Authorization: BearerToken })
.request(queries.GET_JOB_BY_PK, {
id: id,
});
const newTotals = await TotalsServerSide(
{ body: { job: job.jobs_by_pk } },
res,
true
);
const result = await client
.setHeaders({ Authorization: BearerToken })
.request(queries.UPDATE_JOB, {
jobId: id,
job: {
clm_total: newTotals.totals.total_repairs.toFormat("0.00"),
owner_owing: newTotals.totals.custPayable.total.toFormat("0.00"),
job_totals: newTotals,
queued_for_parts: true,
},
});
res.status(200);
} catch (error) {
console.log(error);
res.status(503);
}
};
//IMPORTANT*** These two functions MUST be mirrrored.
async function TotalsServerSide(req, res) {
const { job } = req.body;
console.log(
`Calculating Job Totals on the server side for ${job.id} - ${job.ro_number}`
);
try {
let ret = {
parts: CalculatePartsTotals(job.joblines),
rates: CalculateRatesTotals(job),
additional: CalculateAdditional(job),
};
ret.totals = CalculateTaxesTotals(job, ret);
return ret;
} catch (error) {
console.log("error", error);
res.status(400).send(JSON.stringify(error));
}
}
async function Totals(req, res) {
const { job } = req.body;
console.log(`Calculating Job Totals for ${job.id} - ${job.ro_number}`);
try {
@@ -14,12 +79,13 @@ exports.default = async function (req, res) {
additional: CalculateAdditional(job),
};
ret.totals = CalculateTaxesTotals(job, ret);
res.status(200).json(ret);
} catch (error) {
console.log("error", error);
res.status(400).send(JSON.stringify(error));
}
};
}
function CalculateRatesTotals(ratesList, shoprates) {
const jobLines = ratesList.joblines.filter((jl) => !jl.removed);
@@ -226,7 +292,13 @@ function CalculateAdditional(job) {
Dinero({
amount: Math.round((job.storage_payable || 0) * 100),
})
)
.add(
Dinero({
amount: Math.round((job.ca_bc_pvrt || 0) * 100),
})
);
return ret;
}
@@ -234,9 +306,9 @@ function CalculateTaxesTotals(job, otherTotals) {
const subtotal = otherTotals.parts.parts.subtotal
.add(otherTotals.parts.sublets.subtotal)
.add(otherTotals.rates.rates_subtotal)
.add(otherTotals.additional)
.add(Dinero({ amount: (job.towing_payable || 0) * 100 }))
.add(Dinero({ amount: (job.storage_payable || 0) * 100 }));
.add(otherTotals.additional);
// .add(Dinero({ amount: (job.towing_payable || 0) * 100 }))
// .add(Dinero({ amount: (job.storage_payable || 0) * 100 }));
//Potential issue here with Sublet Calculation. Sublets are calculated under labor in Mitchell, but it's done in IO
//Under the parts rates.
@@ -247,7 +319,7 @@ function CalculateTaxesTotals(job, otherTotals) {
job.joblines
.filter((jl) => !jl.removed)
.forEach((val) => {
if (!!!val.tax_part || !!!val.part_type || IsAdditionalCost(val)) {
if (!val.tax_part || !val.part_type || IsAdditionalCost(val)) {
additionalItemsTax = additionalItemsTax.add(
Dinero({ amount: Math.round((val.act_price || 0) * 100) })
.multiply(val.part_qty || 1)
@@ -316,3 +388,5 @@ function CalculateTaxesTotals(job, otherTotals) {
return ret;
}
exports.default = Totals;

View File

@@ -1 +1,2 @@
exports.totals = require("./job-totals").default;
exports.totalsSsu = require("./job-totals").totalsSsu;