IO-733 IO-594 IO-739

This commit is contained in:
Patrick Fic
2021-03-05 19:25:57 +00:00
19 changed files with 3516 additions and 176 deletions

View File

@@ -1,7 +1,39 @@
// craco.config.js
const TerserPlugin = require("terser-webpack-plugin");
const CracoLessPlugin = require("craco-less");
module.exports = {
plugins: [
{
plugin: CracoLessPlugin,
options: {
lessLoaderOptions: {
lessOptions: {
modifyVars: {
...(process.env.NODE_ENV === "development"
? { "@primary-color": "#a51d1d" }
: { "@primary-color": "#1DA57A" }),
// "@primary-color": " #1890ff", // primary color for all components
// "@link-color": "#1890ff", // link color
// "@success-color": "#52c41a", // success state color
// "@warning-color": "#faad14", // warning state color
// "@error-color": "#f5222d", // error state color
// "@font-size-base": "14px", // major text font size
// " @heading-color": "rgba(0, 0, 0, 0.85)", // heading text color
// "@text-color": "rgba(0, 0, 0, 0.65)", // major text color
// "@text-color-secondary": "rgba(0, 0, 0, 0.45)", // secondary text color
// "@disabled-color": "rgba(0, 0, 0, 0.25)", // disable state color
// "@border-radius-base": "2px", // major border radius
// "@border-color-base": "#d9d9d9", // major border color
// "@box-shadow-base":
// "0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 6px 16px 0 rgba(0, 0, 0, 0.08),0 9px 28px 8px rgba(0, 0, 0, 0.05); // major shadow for layers }",
},
javascriptEnabled: true,
},
},
},
},
],
webpack: {
configure: (webpackConfig) => ({
...webpackConfig,

106
client/package-lock.json generated
View File

@@ -1593,9 +1593,9 @@
"integrity": "sha512-wYn6r8zVZyQJ6rQaALBEln5B1pzxb9shV5Ef97kTvn6yVGrqyXVnDqnU24MXnFubR+rZjBY9NWuxX3FB2sTsjg=="
},
"@grpc/grpc-js": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.2.8.tgz",
"integrity": "sha512-9C1xiCbnYe/3OFpSuRqz2JgFSOxv6+SlqFhXgRC1nHfXYbLnXvtmsI/NpaMs6k9ZNyV4gyaOOh5Z4McfegQGew==",
"version": "1.2.9",
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.2.9.tgz",
"integrity": "sha512-hUNM2G8EP/dHN6cLFk8BXV6ae8zR7A0TPXGCERdwUiJv9yb6BL7FrTb73gUrrx4Dje6tUeomH6urSDEDz5mE7g==",
"requires": {
"@types/node": ">=12.12.47",
"google-auth-library": "^6.1.1",
@@ -2526,9 +2526,9 @@
"integrity": "sha512-XExJS3cLqgrmNBIP3bBw6+1oQ1ksGjFh0+oClDKFYpCCqx/hlqwWO5KO/S63fzUo67SxI9dMrF0y5T/Ey7h8Zw=="
},
"@stripe/react-stripe-js": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@stripe/react-stripe-js/-/react-stripe-js-1.3.0.tgz",
"integrity": "sha512-880MjCEEcU4sQNNJxawjFhLrGUbnV/jHbfZsrL7nAUpKZRBtoSPw7DFlEYRt1v0NimtxCkMmCFUSGxRynn990A==",
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/@stripe/react-stripe-js/-/react-stripe-js-1.4.0.tgz",
"integrity": "sha512-Pz5QmG8PgJ3pi8gOWxlngk+ns63p2L1Ds192fn55ykZNRKfGz3G6sfssUVThHn/NAt2Hp1eCEsy/hvlKnXJI6g==",
"requires": {
"prop-types": "^15.7.2"
}
@@ -2697,20 +2697,20 @@
}
},
"@tanem/react-nprogress": {
"version": "3.0.56",
"resolved": "https://registry.npmjs.org/@tanem/react-nprogress/-/react-nprogress-3.0.56.tgz",
"integrity": "sha512-Z7Rf/6da3noFqNKKURsIt5BodHi02YAPI6emYMm1qC0orubO06huDRbXvdsp/vnz0B4BJwd11UVbSfVS+seSLw==",
"version": "3.0.57",
"resolved": "https://registry.npmjs.org/@tanem/react-nprogress/-/react-nprogress-3.0.57.tgz",
"integrity": "sha512-hYNDAENoAQK3LttNs4IfWF4ByLoAaxJ/rxBTXeTR+x4kk5lLdRBqR0rcU6XrX0oyx+mXLqJk5IXterui6usBfg==",
"requires": {
"@babel/runtime": "^7.12.13",
"@babel/runtime": "^7.12.18",
"hoist-non-react-statics": "^3.3.2",
"prop-types": "^15.7.2",
"react-use": "^15.3.8"
}
},
"@tinymce/tinymce-react": {
"version": "3.10.2",
"resolved": "https://registry.npmjs.org/@tinymce/tinymce-react/-/tinymce-react-3.10.2.tgz",
"integrity": "sha512-PcCGYuepfTidkNwSaTyEg5nVRrqQa9KJDBiCrfb7xRCkoNXeYKY4lFhnT84AcBe9BEcJ4HnCXoqCTnjOaF/R2w==",
"version": "3.10.3",
"resolved": "https://registry.npmjs.org/@tinymce/tinymce-react/-/tinymce-react-3.10.3.tgz",
"integrity": "sha512-Rn7dKd7+0IzDLqYAj+GzOzIZPDJ5F/ojviRk0HH7MvKLZWtAj+sBQP5Xv8SFGlxA9B6Cj1Rpv+Zyhuj3lo9p3w==",
"requires": {
"prop-types": "^15.6.2",
"tinymce": "^5.7.0"
@@ -4968,6 +4968,11 @@
}
}
},
"clone": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
"integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18="
},
"clsx": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz",
@@ -5240,6 +5245,14 @@
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
},
"copy-anything": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.3.tgz",
"integrity": "sha512-GK6QUtisv4fNS+XcI7shX0Gx9ORg7QqIznyfho79JTnX1XhLiyZHfftvGiziqzRiEi/Bjhgpi+D2o7HxJFPnDQ==",
"requires": {
"is-what": "^3.12.0"
}
},
"copy-concurrently": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
@@ -5309,6 +5322,15 @@
"yaml": "^1.7.2"
}
},
"craco-less": {
"version": "1.17.1",
"resolved": "https://registry.npmjs.org/craco-less/-/craco-less-1.17.1.tgz",
"integrity": "sha512-T6V1aF3+eQZ22gUigHInX/i+ExPbWrnmdAhtuEXc4mOyhneDifmEzZFseq/BdRy1aUEs9s4z26jTxP+1I6P//g==",
"requires": {
"less": "^3.11.1",
"less-loader": "^6.1.0"
}
},
"create-ecdh": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz",
@@ -7766,9 +7788,9 @@
}
},
"firebase": {
"version": "8.2.9",
"resolved": "https://registry.npmjs.org/firebase/-/firebase-8.2.9.tgz",
"integrity": "sha512-0QNPgKre9OHuBHwXKIs1wW1aPrO0wx1si3JMA46vPOmx/vkpQQD2OCxdZdVUc+y5u9d/yNMvVBR6j85H0O15rA==",
"version": "8.2.10",
"resolved": "https://registry.npmjs.org/firebase/-/firebase-8.2.10.tgz",
"integrity": "sha512-fGDrVWEDbFf4uaRhOMmbLf4CfW3D98GsMsbnvfd/5lPw5wTpUUcVjHyhXxcB+qfu66WeNW5kEKlEKLJmQXTkYw==",
"requires": {
"@firebase/analytics": "0.6.4",
"@firebase/app": "0.6.15",
@@ -8831,6 +8853,12 @@
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg=="
},
"image-size": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
"integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=",
"optional": true
},
"immer": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/immer/-/immer-8.0.1.tgz",
@@ -9228,6 +9256,11 @@
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
},
"is-what": {
"version": "3.14.1",
"resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz",
"integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA=="
},
"is-windows": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
@@ -10982,6 +11015,41 @@
"webpack-sources": "^1.1.0"
}
},
"less": {
"version": "3.13.1",
"resolved": "https://registry.npmjs.org/less/-/less-3.13.1.tgz",
"integrity": "sha512-SwA1aQXGUvp+P5XdZslUOhhLnClSLIjWvJhmd+Vgib5BFIr9lMNlQwmwUNOjXThF/A0x+MCYYPeWEfeWiLRnTw==",
"requires": {
"copy-anything": "^2.0.1",
"errno": "^0.1.1",
"graceful-fs": "^4.1.2",
"image-size": "~0.5.0",
"make-dir": "^2.1.0",
"mime": "^1.4.1",
"native-request": "^1.0.5",
"source-map": "~0.6.0",
"tslib": "^1.10.0"
},
"dependencies": {
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"optional": true
}
}
},
"less-loader": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/less-loader/-/less-loader-6.2.0.tgz",
"integrity": "sha512-Cl5h95/Pz/PWub/tCBgT1oNMFeH1WTD33piG80jn5jr12T4XbxZcjThwNXDQ7AG649WEynuIzO4b0+2Tn9Qolg==",
"requires": {
"clone": "^2.1.2",
"less": "^3.11.3",
"loader-utils": "^2.0.0",
"schema-utils": "^2.7.0"
}
},
"leven": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
@@ -11565,6 +11633,12 @@
"to-regex": "^3.0.1"
}
},
"native-request": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/native-request/-/native-request-1.0.8.tgz",
"integrity": "sha512-vU2JojJVelUGp6jRcLwToPoWGxSx23z/0iX+I77J3Ht17rf2INGjrhOoQnjVo60nQd8wVsgzKkPfRXBiVdD2ag==",
"optional": true
},
"native-url": {
"version": "0.2.6",
"resolved": "https://registry.npmjs.org/native-url/-/native-url-0.2.6.tgz",

View File

@@ -10,16 +10,17 @@
"@lourenci/react-kanban": "^2.1.0",
"@sentry/react": "^6.2.0",
"@sentry/tracing": "^6.2.0",
"@stripe/react-stripe-js": "^1.2.2",
"@stripe/react-stripe-js": "^1.4.0",
"@stripe/stripe-js": "^1.12.1",
"@tanem/react-nprogress": "^3.0.56",
"@tinymce/tinymce-react": "^3.10.2",
"@tanem/react-nprogress": "^3.0.57",
"@tinymce/tinymce-react": "^3.10.3",
"antd": "^4.12.3",
"apollo-link-logger": "^2.0.0",
"axios": "^0.21.1",
"craco-less": "^1.17.1",
"dinero.js": "^1.8.1",
"dotenv": "^8.2.0",
"firebase": "^8.2.9",
"firebase": "^8.2.10",
"graphql": "^15.5.0",
"i18next": "^19.8.9",
"i18next-browser-languagedetector": "^6.0.1",

View File

@@ -1,4 +1,4 @@
import "antd/dist/antd.css";
import React, { lazy, Suspense, useEffect } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";

View File

@@ -1,7 +1,7 @@
import { useApolloClient, useMutation } from "@apollo/client";
import { Button, Form, Modal, notification } from "antd";
import _ from "lodash";
import React, { useEffect, useState } from "react";
import React, { useEffect, useState, useMemo } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
@@ -197,9 +197,28 @@ function BillEnterModalContainer({
if (enterAgain) form.submit();
}, [enterAgain, form]);
const formValues = useMemo(() => {
return {
...billEnterModal.context.bill,
jobid:
(billEnterModal.context.job && billEnterModal.context.job.id) || null,
federal_tax_rate:
(bodyshop.bill_tax_rates && bodyshop.bill_tax_rates.federal_tax_rate) ||
0,
state_tax_rate:
(bodyshop.bill_tax_rates && bodyshop.bill_tax_rates.state_tax_rate) ||
0,
local_tax_rate:
(bodyshop.bill_tax_rates && bodyshop.bill_tax_rates.local_tax_rate) ||
0,
};
}, [billEnterModal, bodyshop]);
useEffect(() => {
if (billEnterModal.visible) form.resetFields();
}, [billEnterModal.visible, form]);
if (billEnterModal.visible) {
form.setFieldsValue(formValues);
}
}, [billEnterModal.visible, form, formValues]);
return (
<Modal
@@ -239,24 +258,7 @@ function BillEnterModalContainer({
onFinishFailed={() => {
setEnterAgain(false);
}}
initialValues={{
...billEnterModal.context.bill,
jobid:
(billEnterModal.context.job && billEnterModal.context.job.id) ||
null,
federal_tax_rate:
(bodyshop.bill_tax_rates &&
bodyshop.bill_tax_rates.federal_tax_rate) ||
0,
state_tax_rate:
(bodyshop.bill_tax_rates &&
bodyshop.bill_tax_rates.state_tax_rate) ||
0,
local_tax_rate:
(bodyshop.bill_tax_rates &&
bodyshop.bill_tax_rates.local_tax_rate) ||
0,
}}
initialValues={formValues}
>
<BillFormContainer
form={form}

View File

@@ -6,6 +6,7 @@ import {
Input,
InputNumber,
Select,
Space,
Switch,
} from "antd";
import React from "react";
@@ -48,6 +49,7 @@ export function BillEnterModalLinesComponent({
<div style={{ display: "flex", alignItems: "center" }}>
<LayoutFormRow style={{ flex: 1 }} grow>
<Form.Item
span={8}
label={t("billlines.fields.jobline")}
key={`${index}joblinename`}
name={[field.name, "joblineid"]}
@@ -154,37 +156,38 @@ export function BillEnterModalLinesComponent({
}}
/>
</Form.Item>
<Form.Item
label={t("billlines.fields.actual_cost")}
key={`${index}actual_cost`}
name={[field.name, "actual_cost"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<CurrencyInput min={0} disabled={disabled} />
</Form.Item>
<Form.Item shouldUpdate>
{() => {
const line = getFieldsValue(["billlines"]).billlines[
index
];
if (!!!line) return null;
const lineDiscount = (
1 -
Math.round(
(line.actual_cost / line.actual_price) * 100
) /
100
).toPrecision(2);
<div>
<Form.Item
label={t("billlines.fields.actual_cost")}
key={`${index}actual_cost`}
name={[field.name, "actual_cost"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<CurrencyInput min={0} disabled={disabled} />
</Form.Item>
<Form.Item shouldUpdate>
{() => {
const line = getFieldsValue(["billlines"])
.billlines[index];
if (!!!line) return null;
const lineDiscount = (
1 -
Math.round(
(line.actual_cost / line.actual_price) * 100
) /
100
).toPrecision(2);
if (lineDiscount - discount === 0) return <div />;
return <WarningOutlined style={{ color: "red" }} />;
}}
</Form.Item>
if (lineDiscount - discount === 0) return <div />;
return <WarningOutlined style={{ color: "red" }} />;
}}
</Form.Item>
</div>
<Form.Item
label={t("billlines.fields.cost_center")}
key={`${index}cost_center`}
@@ -204,30 +207,45 @@ export function BillEnterModalLinesComponent({
))}
</Select>
</Form.Item>
<Space flex>
<Form.Item
label={t("billlines.fields.federal_tax_applicable")}
key={`${index}fedtax`}
initialValue={true}
valuePropName="checked"
name={[field.name, "applicable_taxes", "federal"]}
>
<Switch disabled={disabled} />
</Form.Item>
<Form.Item
label={t("billlines.fields.state_tax_applicable")}
key={`${index}statetax`}
valuePropName="checked"
name={[field.name, "applicable_taxes", "state"]}
>
<Switch disabled={disabled} />
</Form.Item>
<Form.Item
label={t("billlines.fields.local_tax_applicable")}
key={`${index}localtax`}
valuePropName="checked"
name={[field.name, "applicable_taxes", "local"]}
>
<Switch disabled={disabled} />
</Form.Item>
</Space>
<Form.Item
label={t("billlines.fields.federal_tax_applicable")}
key={`${index}fedtax`}
initialValue={true}
valuePropName="checked"
name={[field.name, "applicable_taxes", "federal"]}
label={t("billlines.fields.location")}
key={`${index}location`}
name={[field.name, "location"]}
>
<Switch disabled={disabled} />
</Form.Item>
<Form.Item
label={t("billlines.fields.state_tax_applicable")}
key={`${index}statetax`}
valuePropName="checked"
name={[field.name, "applicable_taxes", "state"]}
>
<Switch disabled={disabled} />
</Form.Item>
<Form.Item
label={t("billlines.fields.local_tax_applicable")}
key={`${index}localtax`}
valuePropName="checked"
name={[field.name, "applicable_taxes", "local"]}
>
<Switch disabled={disabled} />
<Select style={{ width: "10rem" }} disabled={disabled}>
{bodyshop.md_parts_locations.map((loc, idx) => (
<Select.Option key={idx} value={loc}>
{loc}
</Select.Option>
))}
</Select>
</Form.Item>
<Form.Item
label={t("billlines.labels.deductfromlabor")}
@@ -335,19 +353,6 @@ export function BillEnterModalLinesComponent({
return <span />;
}}
</Form.Item>
<Form.Item
label={t("billlines.fields.location")}
key={`${index}location`}
name={[field.name, "location"]}
>
<Select style={{ width: "10rem" }} disabled={disabled}>
{bodyshop.md_parts_locations.map((loc, idx) => (
<Select.Option key={idx} value={loc}>
{loc}
</Select.Option>
))}
</Select>
</Form.Item>
</LayoutFormRow>
<FormListMoveArrows
move={move}

View File

@@ -46,23 +46,17 @@ const BillLineSearchSelect = (
line_desc={item.line_desc}
part_qty={item.part_qty}
>
<Row justify="center" align="middle">
<Col span={12}>{item.line_desc}</Col>
<Col span={8}>
{item.oem_partno ? (
<Tag color="blue">{item.oem_partno}</Tag>
) : null}
</Col>
<Col span={4}>
{item.act_price ? (
<Tag color="green">
<CurrencyFormatter>
{item.act_price || 0}
</CurrencyFormatter>
</Tag>
) : null}
</Col>
</Row>
<div className="imex-flex-row">
<div style={{ flex: 1 }}>{item.line_desc}</div>
{item.oem_partno ? (
<Tag color="blue">{item.oem_partno}</Tag>
) : null}
{item.act_price ? (
<Tag color="green">
<CurrencyFormatter>{item.act_price || 0}</CurrencyFormatter>
</Tag>
) : null}
</div>
</Option>
))
: null}

View File

@@ -1,4 +1,4 @@
import { GET_JOB_LINES_BY_PK } from "../../graphql/jobs-lines.queries";
import { GET_ALL_JOBLINES_BY_PK } from "../../graphql/jobs-lines.queries";
import { gql } from "@apollo/client";
import _ from "lodash";
@@ -8,7 +8,7 @@ export const GetSupplementDelta = async (client, jobId, newLines) => {
const {
data: { joblines: existingLinesFromDb },
} = await client.query({
query: GET_JOB_LINES_BY_PK,
query: GET_ALL_JOBLINES_BY_PK,
variables: { id: jobId },
});
const existingLines = _.cloneDeep(existingLinesFromDb);

View File

@@ -10,6 +10,7 @@ export default function PartnerPingComponent() {
// Create an scoped async function in the hook
async function checkPartnerStatus() {
try {
if (process.env.NODE_ENV === "development") return;
const PartnerResponse = await axios.post("http://localhost:1337/ping/");
const { appver, qbpath } = PartnerResponse.data;
console.log({ appver, qbpath });

View File

@@ -146,7 +146,6 @@ export default function TimeTicketModalComponent({
}
function LaborAllocationContainer({ jobid }) {
console.log("jobid", jobid);
const { loading, data: lineTicketData } = useQuery(GET_LINE_TICKET_BY_PK, {
variables: { id: jobid },
skip: !jobid,

View File

@@ -1,6 +1,6 @@
import { Col, Row, Select, Tag } from "antd";
import React, { useEffect, useState, forwardRef } from "react";
import { HeartOutlined } from "@ant-design/icons";
import { Select, Tag } from "antd";
import React, { forwardRef, useEffect, useState } from "react";
const { Option } = Select;
//To be used as a form element only.
@@ -45,31 +45,22 @@ const VendorSearchSelect = (
name={o.name}
discount={o.discount}
>
<Row>
<Col span={16}>{o.name}</Col>
<Col span={4}>
<HeartOutlined />
</Col>
{o.discount && (
<Col span={4}>
<Tag color="green">{`${o.discount * 100}%`}</Tag>
</Col>
)}
</Row>
<div className="imex-flex-row">
<div style={{ flex: 1 }}>{o.name}</div>
<HeartOutlined />
<Tag color="green">{`${o.discount * 100}%`}</Tag>
</div>
</Option>
))
: null}
{options
? options.map((o) => (
<Option key={o.id} value={o.id} name={o.name} discount={o.discount}>
<Row>
<Col span={20}>{o.name}</Col>
{o.discount && (
<Col span={4}>
<Tag color="green">{`${o.discount * 100}%`}</Tag>
</Col>
)}
</Row>
<div className="imex-flex-row" style={{ width: "100%" }}>
<div style={{ flex: 1 }}>{o.name}</div>
<Tag color="green">{`${o.discount * 100}%`}</Tag>
</div>
</Option>
))
: null}

View File

@@ -1,7 +1,7 @@
import { gql } from "@apollo/client";
export const GET_JOB_LINES_BY_PK = gql`
query GET_JOB_LINES_BY_PK($id: uuid!) {
export const GET_ALL_JOBLINES_BY_PK = gql`
query GET_ALL_JOBLINES_BY_PK($id: uuid!) {
joblines(where: { jobid: { _eq: $id } }, order_by: { line_no: asc }) {
id
line_no
@@ -46,7 +46,7 @@ export const GET_LINE_TICKET_BY_PK = gql`
id
lbr_adjustments
}
joblines(where: { jobid: { _eq: $id } }) {
joblines(where: { jobid: { _eq: $id }, removed: { _eq: false } }) {
id
line_desc
part_type
@@ -126,6 +126,7 @@ export const UPDATE_JOB_LINE = gql`
notes
location
status
removed
}
}
}
@@ -133,7 +134,7 @@ export const UPDATE_JOB_LINE = gql`
export const GET_JOB_LINES_TO_ENTER_BILL = gql`
query GET_JOB_LINES_TO_ENTER_BILL($id: uuid!) {
joblines(where: { jobid: { _eq: $id } }) {
joblines(where: { jobid: { _eq: $id }, removed: { _eq: false } }) {
id
line_desc
part_type

View File

@@ -115,7 +115,6 @@ export const SUBSCRIPTION_JOBS_IN_PRODUCTION = gql`
id
status
ro_number
ownr_fn
ownr_ln
v_model_yr
@@ -157,20 +156,27 @@ export const SUBSCRIPTION_JOBS_IN_PRODUCTION = gql`
first_name
last_name
}
partcount: joblines_aggregate {
partcount: joblines_aggregate(where: { removed: { _eq: false } }) {
nodes {
status
}
}
labhrs: joblines_aggregate(where: { mod_lbr_ty: { _neq: "LAR" } }) {
labhrs: joblines_aggregate(
where: {
_and: [{ mod_lbr_ty: { _neq: "LAR" } }, { removed: { _eq: false } }]
}
) {
aggregate {
sum {
mod_lb_hrs
}
}
}
larhrs: joblines_aggregate(where: { mod_lbr_ty: { _eq: "LAR" } }) {
larhrs: joblines_aggregate(
where: {
_and: [{ mod_lbr_ty: { _eq: "LAR" } }, { removed: { _eq: false } }]
}
) {
aggregate {
sum {
mod_lb_hrs
@@ -196,14 +202,22 @@ export const QUERY_LBR_HRS_BY_PK = gql`
query QUERY_LBR_HRS_BY_PK($id: uuid!) {
jobs_by_pk(id: $id) {
id
labhrs: joblines_aggregate(where: { mod_lbr_ty: { _neq: "LAR" } }) {
labhrs: joblines_aggregate(
where: {
_and: [{ mod_lbr_ty: { _neq: "LAR" } }, { removed: { _eq: false } }]
}
) {
aggregate {
sum {
mod_lb_hrs
}
}
}
larhrs: joblines_aggregate(where: { mod_lbr_ty: { _eq: "LAR" } }) {
larhrs: joblines_aggregate(
where: {
_and: [{ mod_lbr_ty: { _eq: "LAR" } }, { removed: { _eq: false } }]
}
) {
aggregate {
sum {
mod_lb_hrs
@@ -484,7 +498,7 @@ export const GET_JOB_BY_PK = gql`
deliverchecklist
voided
ca_bc_pvrt
joblines(where: { jobid: { _eq: $id } }, order_by: { line_no: asc }) {
joblines(where: { removed: { _eq: false } }, order_by: { line_no: asc }) {
id
line_no
unq_seq
@@ -1072,7 +1086,7 @@ export const QUERY_ALL_JOB_FIELDS = gql`
v_model_yr
v_vin
vehicleid
joblines {
joblines(where: { removed: { _eq: false } }) {
act_price
alt_co_id
alt_overrd
@@ -1136,7 +1150,6 @@ export const QUERY_JOBS_IN_PRODUCTION = gql`
) {
id
ro_number
ownr_co_nm
ownr_fn
ownr_ln
@@ -1144,15 +1157,22 @@ export const QUERY_JOBS_IN_PRODUCTION = gql`
v_make_desc
v_model_desc
scheduled_completion
labhrs: joblines_aggregate(where: { mod_lbr_ty: { _neq: "LAR" } }) {
labhrs: joblines_aggregate(
where: {
_and: [{ mod_lbr_ty: { _neq: "LAR" } }, { removed: { _eq: false } }]
}
) {
aggregate {
sum {
mod_lb_hrs
}
}
}
larhrs: joblines_aggregate(where: { mod_lbr_ty: { _eq: "LAR" } }) {
larhrs: joblines_aggregate(
where: {
_and: [{ mod_lbr_ty: { _eq: "LAR" } }, { removed: { _eq: false } }]
}
) {
aggregate {
sum {
mod_lb_hrs

View File

@@ -16,7 +16,8 @@ import { persistor, store } from "./redux/store";
import * as serviceWorker from "./serviceWorker";
import "./translations/i18n";
import "./utils/CleanAxios";
//import "antd/dist/antd.css";
import "antd/dist/antd.less";
require("dotenv").config();
Dinero.defaultCurrency = "CAD";

View File

@@ -153,8 +153,6 @@ const { Content, Header } = Layout;
const stripePromise = new Promise((resolve, reject) => {
client.query({ query: QUERY_STRIPE_ID }).then((resp) => {
console.log(resp);
resolve(
loadStripe(process.env.REACT_APP_STRIPE_PUBLIC_KEY, {
stripeAccount:

3213
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -41,7 +41,7 @@
"xmlbuilder": "^15.1.1"
},
"devDependencies": {
"concurrently": "^5.3.0",
"concurrently": "^6.0.0",
"eslint": "^7.20.0",
"eslint-plugin-promise": "^4.3.1",
"source-map-explorer": "^2.5.2"

View File

@@ -354,7 +354,7 @@ const StatusMapping = (status, md_ro_statuses) => {
else if (status === default_invoiced || status === default_exported)
return "CLO";
else if (status === default_void) return "CLO";
else if (md_ro_statuses.production_statuses.include(status)) return "IPR";
else if (md_ro_statuses.production_statuses.includes(status)) return "IPR";
else return "UNDEFINED";
// default: return "UNDEFINED"
@@ -362,7 +362,7 @@ const StatusMapping = (status, md_ro_statuses) => {
const GenerateDetailLines = (line, statuses) => {
const ret = {
BackOrdered: line.status === statuses.default_bo ? "Y" : "N",
BackOrdered: line.status === statuses.default_bo ? "1" : "0",
Cost:
line.billlines[0] &&
(line.billlines[0].actual_cost * line.billlines[0].quantity).toFixed(2),

View File

@@ -205,7 +205,7 @@ query QUERY_UPCOMING_APPOINTMENTS($now: timestamptz!, $jobId: uuid!) {
target_touchtime
workingdays
}
jobhrs: joblines_aggregate {
jobhrs: joblines_aggregate(where: { removed: { _eq: false } }) {
aggregate {
sum {
mod_lb_hrs
@@ -219,7 +219,7 @@ query QUERY_UPCOMING_APPOINTMENTS($now: timestamptz!, $jobId: uuid!) {
id
block
job {
joblines_aggregate {
joblines_aggregate(where: { removed: { _eq: false } }) {
aggregate {
sum {
mod_lb_hrs
@@ -231,14 +231,22 @@ query QUERY_UPCOMING_APPOINTMENTS($now: timestamptz!, $jobId: uuid!) {
jobs(where: {inproduction: {_eq: true}}) {
id
scheduled_completion
labhrs: joblines_aggregate(where: {mod_lbr_ty: {_neq: "LAR"}}) {
labhrs: joblines_aggregate(
where: {
_and: [{ mod_lbr_ty: { _neq: "LAR" } }, { removed: { _eq: false } }]
}
) {
aggregate {
sum {
mod_lb_hrs
}
}
}
larhrs: joblines_aggregate(where: {mod_lbr_ty: {_eq: "LAR"}}) {
larhrs: joblines_aggregate(
where: {
_and: [{ mod_lbr_ty: { _eq: "LAR" } }, { removed: { _eq: false } }]
}
) {
aggregate {
sum {
mod_lb_hrs
@@ -532,7 +540,7 @@ exports.GET_JOB_BY_PK = ` query GET_JOB_BY_PK($id: uuid!) {
deliverchecklist
voided
ca_bc_pvrt
joblines{
joblines(where: { removed: { _eq: false } }){
id
line_no
unq_seq