@@ -4509,6 +4509,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>enforce_conversion_csr</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>enforce_referral</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
@@ -42381,6 +42402,27 @@
|
||||
<folder_node>
|
||||
<name>labels</name>
|
||||
<children>
|
||||
<concept_node>
|
||||
<name>atssummary</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>employeevacation</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
|
||||
@@ -9,11 +9,9 @@
|
||||
"@craco/craco": "^6.4.5",
|
||||
"@fingerprintjs/fingerprintjs": "^3.3.3",
|
||||
"@jsreport/browser-client": "^3.1.0",
|
||||
"@sentry/react": "^7.7.0",
|
||||
"@sentry/tracing": "^7.7.0",
|
||||
"@sentry/react": "^7.28.1",
|
||||
"@sentry/tracing": "^7.28.1",
|
||||
"@splitsoftware/splitio-react": "^1.6.0",
|
||||
"@stripe/react-stripe-js": "^1.9.0",
|
||||
"@stripe/stripe-js": "^1.32.0",
|
||||
"@tanem/react-nprogress": "^5.0.8",
|
||||
"antd": "^4.22.3",
|
||||
"apollo-link-logger": "^2.0.0",
|
||||
@@ -119,7 +117,7 @@
|
||||
"react-error-overlay": "6.0.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sentry/webpack-plugin": "^1.19.0",
|
||||
"@sentry/webpack-plugin": "^1.20.0",
|
||||
"@testing-library/cypress": "^8.0.3",
|
||||
"cypress": "^10.3.1",
|
||||
"eslint-plugin-cypress": "^2.12.1",
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
import {
|
||||
PaymentRequestButtonElement,
|
||||
useStripe,
|
||||
} from "@stripe/react-stripe-js";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import React from "react";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { logImEXEvent } from "../../firebase/firebase.utils";
|
||||
@@ -19,49 +15,6 @@ const mapDispatchToProps = (dispatch) => ({
|
||||
});
|
||||
|
||||
function Test({ bodyshop, setEmailOptions }) {
|
||||
const stripe = useStripe();
|
||||
|
||||
const [paymentRequest, setPaymentRequest] = useState(null);
|
||||
useEffect(() => {
|
||||
if (stripe) {
|
||||
const pr = stripe.paymentRequest({
|
||||
country: "CA",
|
||||
displayItems: [{ label: "Deductible", amount: 1099 }],
|
||||
currency: "cad",
|
||||
total: {
|
||||
label: "Demo total",
|
||||
amount: 1099,
|
||||
},
|
||||
requestPayerName: true,
|
||||
requestPayerEmail: true,
|
||||
});
|
||||
|
||||
// Check the availability of the Payment Request API.
|
||||
pr.canMakePayment().then((result) => {
|
||||
if (result) {
|
||||
setPaymentRequest(pr);
|
||||
} else {
|
||||
// var details = {
|
||||
// total: { label: "", amount: { currency: "CAD", value: "0.00" } },
|
||||
// };
|
||||
new PaymentRequest(
|
||||
[{ supportedMethods: ["basic-card"] }],
|
||||
{}
|
||||
// details
|
||||
).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
}, [stripe]);
|
||||
|
||||
if (paymentRequest) {
|
||||
return (
|
||||
<div style={{ height: "300px" }}>
|
||||
<PaymentRequestButtonElement options={{ paymentRequest }} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<button
|
||||
|
||||
@@ -107,11 +107,6 @@ export function AccountingPayablesTableComponent({
|
||||
dataIndex: "transactionid",
|
||||
key: "transactionid",
|
||||
},
|
||||
{
|
||||
title: t("payments.fields.stripeid"),
|
||||
dataIndex: "stripeid",
|
||||
key: "stripeid",
|
||||
},
|
||||
{
|
||||
title: t("payments.fields.created_at"),
|
||||
dataIndex: "created_at",
|
||||
|
||||
@@ -25,8 +25,6 @@ const mapDispatchToProps = (dispatch) => ({
|
||||
dispatch(setModalContext({ context: context, modal: "payment" })),
|
||||
});
|
||||
|
||||
const stripeTestEnv = process.env.REACT_APP_STRIPE_PUBLIC_KEY; //.includes("test");
|
||||
|
||||
export function JobPayments({
|
||||
job,
|
||||
jobRO,
|
||||
@@ -94,23 +92,6 @@ export function JobPayments({
|
||||
state.sortedInfo.columnKey === "transactionid" &&
|
||||
state.sortedInfo.order,
|
||||
},
|
||||
{
|
||||
title: t("payments.fields.stripeid"),
|
||||
dataIndex: "stripeid",
|
||||
key: "stripeid",
|
||||
render: (text, record) =>
|
||||
record.stripeid ? (
|
||||
<a
|
||||
href={
|
||||
stripeTestEnv
|
||||
? `https://dashboard.stripe.com/${bodyshop.stripe_acct_id}/test/payments/${record.stripeid}`
|
||||
: `https://dashboard.stripe.com/${bodyshop.stripe_acct_id}/payments/${record.stripeid}`
|
||||
}
|
||||
>
|
||||
{record.stripeid}
|
||||
</a>
|
||||
) : null,
|
||||
},
|
||||
{
|
||||
title: t("general.labels.actions"),
|
||||
dataIndex: "actions",
|
||||
|
||||
@@ -166,6 +166,16 @@ export default function ScoreboardAddButton({
|
||||
painthrs: 0,
|
||||
}
|
||||
);
|
||||
|
||||
//Add Labor Adjustments
|
||||
v.painthrs = v.painthrs + (job.lbr_adjustments.LAR || 0);
|
||||
v.bodyhrs =
|
||||
v.bodyhrs +
|
||||
Object.keys(job.lbr_adjustments)
|
||||
.filter((key) => key !== "LAR")
|
||||
.reduce((acc, val) => {
|
||||
return acc + job.lbr_adjustments[val];
|
||||
}, 0);
|
||||
form.setFieldsValue({
|
||||
date: new moment(),
|
||||
bodyhrs: Math.round(v.bodyhrs * 10) / 10,
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
Space,
|
||||
Switch,
|
||||
} from "antd";
|
||||
import axios from "axios";
|
||||
import React, { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
@@ -18,7 +19,6 @@ import { insertAuditTrail } from "../../redux/application/application.actions";
|
||||
import { selectJobReadOnly } from "../../redux/application/application.selectors";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
||||
import axios from "axios";
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
//currentUser: selectCurrentUser
|
||||
bodyshop: selectBodyshop,
|
||||
@@ -83,7 +83,11 @@ export function JobsConvertButton({
|
||||
layout="vertical"
|
||||
form={form}
|
||||
onFinish={handleConvert}
|
||||
initialValues={{ driveable: true, towin: false }}
|
||||
initialValues={{
|
||||
driveable: true,
|
||||
towin: false,
|
||||
employee_csr: job.employee_csr,
|
||||
}}
|
||||
>
|
||||
<Form.Item
|
||||
name={["ins_co_nm"]}
|
||||
@@ -151,6 +155,41 @@ export function JobsConvertButton({
|
||||
</Form.Item>
|
||||
</>
|
||||
)}
|
||||
{bodyshop.enforce_conversion_csr && (
|
||||
<Form.Item
|
||||
name={"employee_csr"}
|
||||
label={t("jobs.fields.employee_csr")}
|
||||
rules={[
|
||||
{
|
||||
required: bodyshop.enforce_conversion_csr,
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Select
|
||||
showSearch
|
||||
style={{ width: 200 }}
|
||||
optionFilterProp="children"
|
||||
filterOption={(input, option) =>
|
||||
option.props.children
|
||||
.toLowerCase()
|
||||
.indexOf(input.toLowerCase()) >= 0
|
||||
}
|
||||
>
|
||||
{bodyshop.employees
|
||||
.filter((emp) => emp.active)
|
||||
.map((emp) => (
|
||||
<Select.Option
|
||||
value={emp.id}
|
||||
key={emp.id}
|
||||
name={`${emp.first_name} ${emp.last_name}`}
|
||||
>
|
||||
{`${emp.first_name} ${emp.last_name}`}
|
||||
</Select.Option>
|
||||
))}
|
||||
</Select>
|
||||
</Form.Item>
|
||||
)}
|
||||
<Form.Item
|
||||
label={t("jobs.fields.ca_gst_registrant")}
|
||||
name="ca_gst_registrant"
|
||||
@@ -194,7 +233,14 @@ export function JobsConvertButton({
|
||||
// style={{ display: job.converted ? "none" : "" }}
|
||||
disabled={job.converted || jobRO}
|
||||
loading={loading}
|
||||
onClick={() => setVisible(true)}
|
||||
onClick={() => {
|
||||
setVisible(true);
|
||||
form.setFieldsValue({
|
||||
driveable: true,
|
||||
towin: false,
|
||||
employee_csr: job.employee_csr,
|
||||
});
|
||||
}}
|
||||
>
|
||||
{t("jobs.actions.convert")}
|
||||
</Button>
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import { useTreatments } from "@splitsoftware/splitio-react";
|
||||
import { CardElement } from "@stripe/react-stripe-js";
|
||||
import { Checkbox, Form, Input, Radio, Select } from "antd";
|
||||
import { Form, Input, Radio, Select } from "antd";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import Alert from "../alert/alert.component";
|
||||
import DatePickerFormItem from "../form-date-picker/form-date-picker.component";
|
||||
import CurrencyInput from "../form-items-formatted/currency-form-item.component";
|
||||
import JobSearchSelect from "../job-search-select/job-search-select.component";
|
||||
@@ -19,11 +17,9 @@ const mapStateToProps = createStructuredSelector({
|
||||
|
||||
export function PaymentFormComponent({
|
||||
form,
|
||||
stripeStateArr,
|
||||
bodyshop,
|
||||
disabled,
|
||||
}) {
|
||||
const [stripeState, setStripeState] = stripeStateArr;
|
||||
const { Qb_Multi_Ar } = useTreatments(
|
||||
["Qb_Multi_Ar"],
|
||||
{},
|
||||
@@ -31,9 +27,6 @@ export function PaymentFormComponent({
|
||||
);
|
||||
|
||||
const { t } = useTranslation();
|
||||
const handleStripeChange = (e) => {
|
||||
setStripeState({ error: e.error, cardComplete: e.complete });
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
@@ -150,57 +143,6 @@ export function PaymentFormComponent({
|
||||
</Form.Item>
|
||||
</LayoutFormRow>
|
||||
<LayoutFormRow grow>
|
||||
<div>
|
||||
<Form.Item
|
||||
label={t("payments.labels.electronicpayment")}
|
||||
name="useStripe"
|
||||
valuePropName="checked"
|
||||
>
|
||||
<Checkbox
|
||||
defaultChecked={!!bodyshop.stripe_acct_id}
|
||||
disabled={!!!bodyshop.stripe_acct_id || disabled}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
{!bodyshop.stripe_acct_id ? (
|
||||
<div style={{ fontStyle: "italic" }}>
|
||||
{t("payments.labels.signup")}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<Form.Item shouldUpdate>
|
||||
{() => {
|
||||
if (form.getFieldValue("useStripe"))
|
||||
return (
|
||||
<CardElement
|
||||
options={{
|
||||
style: {
|
||||
base: {
|
||||
color: "#32325d",
|
||||
//fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
|
||||
fontSmoothing: "antialiased",
|
||||
//fontSize: "16px",
|
||||
"::placeholder": {
|
||||
color: "#aab7c4",
|
||||
},
|
||||
},
|
||||
invalid: {
|
||||
color: "#fa755a",
|
||||
iconColor: "#fa755a",
|
||||
},
|
||||
},
|
||||
}}
|
||||
onChange={handleStripeChange}
|
||||
/>
|
||||
);
|
||||
|
||||
return null;
|
||||
}}
|
||||
</Form.Item>
|
||||
{stripeState.error ? (
|
||||
<Alert type="error" message={stripeState.error.message} />
|
||||
) : null}
|
||||
</div>
|
||||
<Form.Item
|
||||
label={t("general.labels.sendby")}
|
||||
name="sendby"
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
import { useApolloClient, useMutation } from "@apollo/client";
|
||||
import { CardElement, useElements, useStripe } from "@stripe/react-stripe-js";
|
||||
import { useMutation } from "@apollo/client";
|
||||
|
||||
import { Button, Form, Modal, notification } from "antd";
|
||||
import axios from "axios";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { logImEXEvent } from "../../firebase/firebase.utils";
|
||||
import { GET_JOB_INFO_FOR_STRIPE } from "../../graphql/jobs.queries";
|
||||
import {
|
||||
INSERT_NEW_PAYMENT,
|
||||
UPDATE_PAYMENT,
|
||||
UPDATE_PAYMENT
|
||||
} from "../../graphql/payments.queries";
|
||||
import { setEmailOptions } from "../../redux/email/email.actions";
|
||||
import { toggleModalVisible } from "../../redux/modals/modals.actions";
|
||||
import { selectPayment } from "../../redux/modals/modals.selectors";
|
||||
import {
|
||||
selectBodyshop,
|
||||
selectCurrentUser,
|
||||
selectCurrentUser
|
||||
} from "../../redux/user/user.selectors";
|
||||
import { GenerateDocument } from "../../utils/RenderTemplate";
|
||||
import { TemplateList } from "../../utils/TemplateConstants";
|
||||
@@ -45,82 +42,23 @@ function PaymentModalContainer({
|
||||
const [enterAgain, setEnterAgain] = useState(false);
|
||||
const [insertPayment] = useMutation(INSERT_NEW_PAYMENT);
|
||||
const [updatePayment] = useMutation(UPDATE_PAYMENT);
|
||||
const client = useApolloClient();
|
||||
const stripe = useStripe();
|
||||
const elements = useElements();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { context, actions, visible } = paymentModal;
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
const stripeStateArr = useState({
|
||||
error: null,
|
||||
cardComplete: false,
|
||||
});
|
||||
const stripeState = stripeStateArr[0];
|
||||
|
||||
const cardValid = !!!stripeState.error && stripeState.cardComplete;
|
||||
|
||||
const handleFinish = async (values) => {
|
||||
const { useStripe, sendby, ...paymentObj } = values;
|
||||
if (useStripe && !cardValid) return;
|
||||
|
||||
if ((useStripe && !stripe) || !elements) {
|
||||
// Stripe.js has not yet loaded.
|
||||
// Make sure to disable form submission until Stripe.js has loaded.
|
||||
return;
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
|
||||
try {
|
||||
let stripePayment;
|
||||
if (useStripe && bodyshop.stripe_acct_id) {
|
||||
logImEXEvent("payment_stripe_attempt");
|
||||
|
||||
const secretKey = await axios.post("/stripe/payment", {
|
||||
amount: Math.round(values.amount * 100),
|
||||
stripe_acct_id: bodyshop.stripe_acct_id,
|
||||
});
|
||||
|
||||
const { data } = await client.query({
|
||||
query: GET_JOB_INFO_FOR_STRIPE,
|
||||
variables: { jobid: values.jobid },
|
||||
});
|
||||
|
||||
stripePayment = await stripe.confirmCardPayment(
|
||||
secretKey.data.clientSecret,
|
||||
{
|
||||
payment_method: {
|
||||
card: elements.getElement(CardElement),
|
||||
billing_details: {
|
||||
name: `${data.jobs_by_pk.ownr_fn || ""} ${
|
||||
data.jobs_by_pk.ownr_ln || ""
|
||||
} ${data.jobs_by_pk.ownr_co_nm || ""}`,
|
||||
email: data.jobs_by_pk.ownr_ea,
|
||||
phone: data.jobs_by_pk.ownr_ph1,
|
||||
},
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (stripePayment.paymentIntent.status === "succeeded") {
|
||||
notification["success"]({ message: t("payments.successes.stripe") });
|
||||
} else {
|
||||
notification["error"]({ message: t("payments.errors.stripe") });
|
||||
throw new Error();
|
||||
}
|
||||
}
|
||||
logImEXEvent("payment_insert");
|
||||
|
||||
if (!context || (context && !context.id)) {
|
||||
const newPayment = await insertPayment({
|
||||
variables: {
|
||||
paymentInput: {
|
||||
...paymentObj,
|
||||
stripeid:
|
||||
stripePayment &&
|
||||
stripePayment.paymentIntent &&
|
||||
stripePayment.paymentIntent.id,
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -236,11 +174,7 @@ function PaymentModalContainer({
|
||||
layout="vertical"
|
||||
initialValues={context || {}}
|
||||
>
|
||||
<PaymentForm
|
||||
form={form}
|
||||
stripeStateArr={stripeStateArr}
|
||||
disabled={context && context.stripeid}
|
||||
/>
|
||||
<PaymentForm form={form} />
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
@@ -250,15 +184,3 @@ export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(PaymentModalContainer);
|
||||
|
||||
// const pr = stripe.paymentRequest({
|
||||
// country: "CA",
|
||||
// currency: "CAD",
|
||||
// total: {
|
||||
// label: "Demo total",
|
||||
// amount: 1099,
|
||||
// },
|
||||
// requestPayerName: true,
|
||||
// requestPayerEmail: true,
|
||||
// });
|
||||
// console.log("handleFinish -> pr", pr);
|
||||
|
||||
@@ -16,8 +16,6 @@ import CaBcEtfTableModalContainer from "../ca-bc-etf-table-modal/ca-bc-etf-table
|
||||
import PrintWrapperComponent from "../print-wrapper/print-wrapper.component";
|
||||
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
|
||||
|
||||
const stripeTestEnv = process.env.REACT_APP_STRIPE_PUBLIC_KEY; //.includes("test");
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
//currentUser: selectCurrentUser
|
||||
bodyshop: selectBodyshop,
|
||||
@@ -125,23 +123,6 @@ export function PaymentsListPaginated({
|
||||
dataIndex: "transactionid",
|
||||
key: "transactionid",
|
||||
},
|
||||
{
|
||||
title: t("payments.fields.stripeid"),
|
||||
dataIndex: "stripeid",
|
||||
key: "stripeid",
|
||||
render: (text, record) =>
|
||||
record.stripeid ? (
|
||||
<a
|
||||
href={
|
||||
stripeTestEnv
|
||||
? `https://dashboard.stripe.com/${bodyshop.stripe_acct_id}/test/payments/${record.stripeid}`
|
||||
: `https://dashboard.stripe.com/${bodyshop.stripe_acct_id}/payments/${record.stripeid}`
|
||||
}
|
||||
>
|
||||
{record.stripeid}
|
||||
</a>
|
||||
) : null,
|
||||
},
|
||||
{
|
||||
title: t("payments.fields.created_at"),
|
||||
dataIndex: "created_at",
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
import { Button, Card, Form, InputNumber, Popover, Radio } from "antd";
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
Form,
|
||||
InputNumber,
|
||||
notification,
|
||||
Popover,
|
||||
Radio,
|
||||
} from "antd";
|
||||
import React, { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
@@ -27,7 +35,6 @@ export function PrintCenterJobsLabels({ bodyshop, jobId }) {
|
||||
const handleOk = (e) => {
|
||||
e.stopPropagation();
|
||||
form.submit();
|
||||
setIsModalVisible(false);
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
@@ -37,18 +44,24 @@ export function PrintCenterJobsLabels({ bodyshop, jobId }) {
|
||||
const handleFinish = async ({ template, ...values }) => {
|
||||
const { sendtype, ...restVals } = values;
|
||||
setLoading(true);
|
||||
await GenerateDocument(
|
||||
{
|
||||
name: TemplateList("job_special")[template].key,
|
||||
variables: { id: jobId },
|
||||
context: restVals,
|
||||
},
|
||||
{},
|
||||
"p",
|
||||
jobId
|
||||
);
|
||||
setLoading(false);
|
||||
setIsModalVisible(false);
|
||||
try {
|
||||
await GenerateDocument(
|
||||
{
|
||||
name: TemplateList("job_special")[template].key,
|
||||
variables: { id: jobId },
|
||||
context: restVals,
|
||||
},
|
||||
{},
|
||||
"p",
|
||||
jobId
|
||||
);
|
||||
setIsModalVisible(false);
|
||||
} catch (error) {
|
||||
notification.open({ type: "error", message: JSON.stringify(error) });
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
form.resetFields();
|
||||
};
|
||||
|
||||
@@ -60,7 +73,15 @@ export function PrintCenterJobsLabels({ bodyshop, jobId }) {
|
||||
layout="vertical"
|
||||
form={form}
|
||||
>
|
||||
<Form.Item required name="template">
|
||||
<Form.Item
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
]}
|
||||
name="template"
|
||||
>
|
||||
<Radio.Group>
|
||||
<Radio.Button value="parts_label_multiple">
|
||||
{t("printcenter.jobs.parts_label_multiple")}
|
||||
@@ -71,14 +92,24 @@ export function PrintCenterJobsLabels({ bodyshop, jobId }) {
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
required
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
]}
|
||||
label={t("printcenter.jobs.labels.position")}
|
||||
name="position"
|
||||
>
|
||||
<InputNumber min={1} precision={0} />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
required
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
]}
|
||||
label={t("printcenter.jobs.labels.count")}
|
||||
name="count"
|
||||
>
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import { Space } from "antd";
|
||||
import React, { useMemo } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { selectScheduleLoad } from "../../redux/application/application.selectors";
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
//currentUser: selectCurrentUser
|
||||
scheduleLoad: selectScheduleLoad,
|
||||
});
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||
});
|
||||
|
||||
export function ScheduleAtsSummary({ scheduleLoad, appointments }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const atsSummary = useMemo(() => {
|
||||
let atsSummary = {};
|
||||
if (!appointments || appointments.length === 0) {
|
||||
return {};
|
||||
}
|
||||
appointments
|
||||
.filter((a) => a.isintake)
|
||||
.forEach((a) => {
|
||||
if (!a.job.alt_transport) return;
|
||||
if (!atsSummary[a.job.alt_transport]) {
|
||||
atsSummary[a.job.alt_transport] = 1;
|
||||
} else {
|
||||
atsSummary[a.job.alt_transport] = atsSummary[a.job.alt_transport] + 1;
|
||||
}
|
||||
});
|
||||
return atsSummary;
|
||||
}, [appointments]);
|
||||
|
||||
if (Object.keys(atsSummary).length > 0)
|
||||
return (
|
||||
<Space wrap>
|
||||
{t("schedule.labels.atssummary")}
|
||||
{Object.keys(atsSummary).map((key) => (
|
||||
<span key={key}>{`${key}: ${atsSummary[key]}`}</span>
|
||||
))}
|
||||
</Space>
|
||||
);
|
||||
|
||||
return null;
|
||||
}
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ScheduleAtsSummary);
|
||||
@@ -3,6 +3,7 @@ import { Button, Card, Checkbox, Col, PageHeader, Row, Space } from "antd";
|
||||
import { t } from "i18next";
|
||||
import React, { useMemo } from "react";
|
||||
import useLocalStorage from "../../utils/useLocalStorage";
|
||||
import ScheduleAtsSummary from "../schedule-ats-summary/schedule-ats-summary.component";
|
||||
import ScheduleCalendarWrapperComponent from "../schedule-calendar-wrapper/scheduler-calendar-wrapper.component";
|
||||
import ScheduleModal from "../schedule-job-modal/schedule-job-modal.container";
|
||||
import ScheduleManualEvent from "../schedule-manual-event/schedule-manual-event.component";
|
||||
@@ -35,6 +36,7 @@ export default function ScheduleCalendarComponent({ data, refetch }) {
|
||||
<PageHeader
|
||||
extra={
|
||||
<Space wrap>
|
||||
<ScheduleAtsSummary appointments={filteredData} />
|
||||
<Checkbox
|
||||
checked={filter?.intake}
|
||||
onChange={(e) => {
|
||||
|
||||
@@ -466,6 +466,13 @@ export default function ShopInfoGeneral({ form }) {
|
||||
>
|
||||
<Switch />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name={["enforce_conversion_csr"]}
|
||||
label={t("bodyshop.fields.enforce_conversion_csr")}
|
||||
valuePropName="checked"
|
||||
>
|
||||
<Switch />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name={["target_touchtime"]}
|
||||
label={t("bodyshop.fields.target_touchtime")}
|
||||
|
||||
@@ -364,6 +364,7 @@ export const QUERY_SCHEDULE_LOAD_DATA = gql`
|
||||
ownr_fn
|
||||
ownr_ln
|
||||
ownr_co_nm
|
||||
alt_transport
|
||||
labhrs: joblines_aggregate(
|
||||
where: { mod_lbr_ty: { _neq: "LAR" }, removed: { _eq: false } }
|
||||
) {
|
||||
|
||||
@@ -111,6 +111,7 @@ export const QUERY_BODYSHOP = gql`
|
||||
localmediaserverhttp
|
||||
localmediaservernetwork
|
||||
localmediatoken
|
||||
enforce_conversion_csr
|
||||
employees {
|
||||
user_email
|
||||
id
|
||||
@@ -220,6 +221,7 @@ export const UPDATE_SHOP = gql`
|
||||
localmediaserverhttp
|
||||
localmediaservernetwork
|
||||
localmediatoken
|
||||
enforce_conversion_csr
|
||||
employees {
|
||||
id
|
||||
first_name
|
||||
|
||||
@@ -501,6 +501,10 @@ export const GET_JOB_BY_PK = gql`
|
||||
first_name
|
||||
last_name
|
||||
}
|
||||
employee_csr
|
||||
employee_prep
|
||||
employee_refinish
|
||||
employee_body
|
||||
alt_transport
|
||||
intakechecklist
|
||||
invoice_final_note
|
||||
@@ -851,6 +855,7 @@ export const QUERY_JOB_CARD_DETAILS = gql`
|
||||
owner_owing
|
||||
special_coverage_policy
|
||||
suspended
|
||||
lbr_adjustments
|
||||
available_jobs {
|
||||
id
|
||||
}
|
||||
@@ -1096,6 +1101,9 @@ export const UPDATE_JOB_ASSIGNMENTS = gql`
|
||||
first_name
|
||||
last_name
|
||||
}
|
||||
employee_csr
|
||||
employee_body
|
||||
employee_prep
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1153,6 +1161,7 @@ export const CONVERT_JOB_TO_RO = gql`
|
||||
$towin: Boolean
|
||||
$referral_source: String
|
||||
$referral_source_extra: String
|
||||
$employee_csr: uuid
|
||||
) {
|
||||
update_jobs(
|
||||
where: { id: { _eq: $jobId } }
|
||||
@@ -1165,6 +1174,7 @@ export const CONVERT_JOB_TO_RO = gql`
|
||||
driveable: $driveable
|
||||
referral_source: $referral_source
|
||||
referral_source_extra: $referral_source_extra
|
||||
employee_csr: $employee_csr
|
||||
}
|
||||
) {
|
||||
returning {
|
||||
@@ -1175,6 +1185,10 @@ export const CONVERT_JOB_TO_RO = gql`
|
||||
ins_co_nm
|
||||
referral_source
|
||||
referral_source_extra
|
||||
employee_csr
|
||||
employee_csr_rel {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1900,6 +1914,7 @@ export const QUERY_JOB_CLOSE_DETAILS = gql`
|
||||
kmin
|
||||
kmout
|
||||
qb_multiple_payers
|
||||
lbr_adjustments
|
||||
joblines(where: { removed: { _eq: false } }, order_by: { line_no: asc }) {
|
||||
id
|
||||
removed
|
||||
|
||||
@@ -14,7 +14,7 @@ import { persistor, store } from "./redux/store";
|
||||
import reportWebVitals from "./reportWebVitals";
|
||||
import "./translations/i18n";
|
||||
import "./utils/CleanAxios";
|
||||
require("dotenv").config();
|
||||
import { BrowserTracing } from "@sentry/tracing";
|
||||
|
||||
// Dinero.defaultCurrency = "CAD";
|
||||
// Dinero.globalLocale = "en-CA";
|
||||
@@ -29,10 +29,18 @@ if (process.env.NODE_ENV !== "development") {
|
||||
"Module specifier, 'zlib' does not start with",
|
||||
],
|
||||
integrations: [
|
||||
// new Integrations.BrowserTracing(),
|
||||
new BrowserTracing(),
|
||||
// new Sentry.Integrations.Breadcrumbs({ console: true }),
|
||||
new Sentry.Replay(),
|
||||
],
|
||||
// This sets the sample rate to be 10%. You may want this to be 100% while
|
||||
// in development and sample at a lower rate in production
|
||||
replaysSessionSampleRate: 0.1,
|
||||
// If the entire session is not sampled, use the below sample rate to sample
|
||||
// sessions when an error occurs.
|
||||
replaysOnErrorSampleRate: 1.0,
|
||||
environment: process.env.NODE_ENV,
|
||||
tracesSampleRate: 0.2,
|
||||
// We recommend adjusting this value in production, or using tracesSampler
|
||||
// for finer control
|
||||
// tracesSampleRate: 0.5,
|
||||
@@ -41,7 +49,7 @@ if (process.env.NODE_ENV !== "development") {
|
||||
|
||||
ReactDOM.render(
|
||||
<Provider store={store}>
|
||||
<BrowserRouter>
|
||||
<BrowserRouter >
|
||||
<PersistGate
|
||||
loading={<LoadingSpinner message="Restoring your settings..." />}
|
||||
persistor={persistor}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { Elements } from "@stripe/react-stripe-js";
|
||||
import { loadStripe } from "@stripe/stripe-js";
|
||||
import { BackTop, Layout } from "antd";
|
||||
import preval from "preval.macro";
|
||||
import React, { lazy, Suspense, useEffect } from "react";
|
||||
@@ -170,18 +168,6 @@ const DmsPayables = lazy(() =>
|
||||
|
||||
const { Content, Footer } = Layout;
|
||||
|
||||
const stripePromise = new Promise((resolve, reject) => {
|
||||
// client.query({ query: QUERY_STRIPE_ID }).then((resp) => {
|
||||
// if (resp.data.bodyshops[0])
|
||||
resolve(
|
||||
loadStripe(process.env.REACT_APP_STRIPE_PUBLIC_KEY, {
|
||||
stripeAccount: "No Stripe Id Resolve",
|
||||
})
|
||||
);
|
||||
// reject();
|
||||
// });
|
||||
});
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
conflict: selectInstanceConflict,
|
||||
bodyshop: selectBodyshop,
|
||||
@@ -207,9 +193,9 @@ export function Manage({ match, conflict, bodyshop }) {
|
||||
<Suspense
|
||||
fallback={<LoadingSpinner message={t("general.labels.loadingapp")} />}
|
||||
>
|
||||
<Elements stripe={stripePromise}>
|
||||
|
||||
<PaymentModalContainer />
|
||||
</Elements>
|
||||
|
||||
<BreadCrumbs />
|
||||
<BillEnterModalContainer />
|
||||
<JobCostingModal />
|
||||
|
||||
@@ -1,81 +1,81 @@
|
||||
import {
|
||||
PaymentRequestButtonElement,
|
||||
useStripe,
|
||||
} from "@stripe/react-stripe-js";
|
||||
import React, { useEffect, useState } from "react";
|
||||
// import {
|
||||
// PaymentRequestButtonElement,
|
||||
// useStripe,
|
||||
// } from "@stripe/react-stripe-js";
|
||||
// import React, { useEffect, useState } from "react";
|
||||
|
||||
export default function MobilePaymentComponent() {
|
||||
const stripe = useStripe();
|
||||
// export default function MobilePaymentComponent() {
|
||||
// const stripe = useStripe();
|
||||
|
||||
const [paymentRequest, setPaymentRequest] = useState(null);
|
||||
useEffect(() => {
|
||||
if (stripe) {
|
||||
const pr = stripe.paymentRequest({
|
||||
country: "CA",
|
||||
displayItems: [{ label: "Deductible", amount: 1 }],
|
||||
currency: "cad",
|
||||
total: {
|
||||
label: "Demo total",
|
||||
amount: 1,
|
||||
},
|
||||
requestPayerName: true,
|
||||
requestPayerEmail: true,
|
||||
});
|
||||
// const [paymentRequest, setPaymentRequest] = useState(null);
|
||||
// useEffect(() => {
|
||||
// if (stripe) {
|
||||
// const pr = stripe.paymentRequest({
|
||||
// country: "CA",
|
||||
// displayItems: [{ label: "Deductible", amount: 1 }],
|
||||
// currency: "cad",
|
||||
// total: {
|
||||
// label: "Demo total",
|
||||
// amount: 1,
|
||||
// },
|
||||
// requestPayerName: true,
|
||||
// requestPayerEmail: true,
|
||||
// });
|
||||
|
||||
// Check the availability of the Payment Request API.
|
||||
pr.canMakePayment().then((result) => {
|
||||
if (result) {
|
||||
setPaymentRequest(pr);
|
||||
} else {
|
||||
// var details = {
|
||||
// total: { label: "", amount: { currency: "CAD", value: "0.00" } },
|
||||
// };
|
||||
// new PaymentRequest(
|
||||
// [{ supportedMethods: ["basic-card"] }],
|
||||
// {}
|
||||
// // details
|
||||
// ).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
}, [stripe]);
|
||||
// // Check the availability of the Payment Request API.
|
||||
// pr.canMakePayment().then((result) => {
|
||||
// if (result) {
|
||||
// setPaymentRequest(pr);
|
||||
// } else {
|
||||
// // var details = {
|
||||
// // total: { label: "", amount: { currency: "CAD", value: "0.00" } },
|
||||
// // };
|
||||
// // new PaymentRequest(
|
||||
// // [{ supportedMethods: ["basic-card"] }],
|
||||
// // {}
|
||||
// // // details
|
||||
// // ).show();
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// }, [stripe]);
|
||||
|
||||
if (paymentRequest) {
|
||||
paymentRequest.on("paymentmethod", async (ev) => {
|
||||
//Call server side to get the client secret
|
||||
// Confirm the PaymentIntent without handling potential next actions (yet).
|
||||
const { error: confirmError } = await stripe.confirmCardPayment(
|
||||
"clientSecret",
|
||||
{ payment_method: ev.paymentMethod.id },
|
||||
{ handleActions: false }
|
||||
);
|
||||
// if (paymentRequest) {
|
||||
// paymentRequest.on("paymentmethod", async (ev) => {
|
||||
// //Call server side to get the client secret
|
||||
// // Confirm the PaymentIntent without handling potential next actions (yet).
|
||||
// const { error: confirmError } = await stripe.confirmCardPayment(
|
||||
// "clientSecret",
|
||||
// { payment_method: ev.paymentMethod.id },
|
||||
// { handleActions: false }
|
||||
// );
|
||||
|
||||
if (confirmError) {
|
||||
// Report to the browser that the payment failed, prompting it to
|
||||
// re-show the payment interface, or show an error message and close
|
||||
// the payment interface.
|
||||
ev.complete("fail");
|
||||
} else {
|
||||
// Report to the browser that the confirmation was successful, prompting
|
||||
// it to close the browser payment method collection interface.
|
||||
ev.complete("success");
|
||||
// Let Stripe.js handle the rest of the payment flow.
|
||||
const {
|
||||
error, //paymentIntent
|
||||
} = await stripe.confirmCardPayment("clientSecret");
|
||||
if (error) {
|
||||
// The payment failed -- ask your customer for a new payment method.
|
||||
} else {
|
||||
// The payment has succeeded.
|
||||
}
|
||||
}
|
||||
});
|
||||
return (
|
||||
<div style={{ height: "300px" }}>
|
||||
<PaymentRequestButtonElement options={{ paymentRequest }} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
// if (confirmError) {
|
||||
// // Report to the browser that the payment failed, prompting it to
|
||||
// // re-show the payment interface, or show an error message and close
|
||||
// // the payment interface.
|
||||
// ev.complete("fail");
|
||||
// } else {
|
||||
// // Report to the browser that the confirmation was successful, prompting
|
||||
// // it to close the browser payment method collection interface.
|
||||
// ev.complete("success");
|
||||
// // Let Stripe.js handle the rest of the payment flow.
|
||||
// const {
|
||||
// error, //paymentIntent
|
||||
// } = await stripe.confirmCardPayment("clientSecret");
|
||||
// if (error) {
|
||||
// // The payment failed -- ask your customer for a new payment method.
|
||||
// } else {
|
||||
// // The payment has succeeded.
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// return (
|
||||
// <div style={{ height: "300px" }}>
|
||||
// <PaymentRequestButtonElement options={{ paymentRequest }} />
|
||||
// </div>
|
||||
// );
|
||||
// }
|
||||
|
||||
return <div></div>;
|
||||
}
|
||||
// return <div></div>;
|
||||
// }
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
import { Elements } from "@stripe/react-stripe-js";
|
||||
import { loadStripe } from "@stripe/stripe-js";
|
||||
import React from "react";
|
||||
import MobilePaymentComponent from "./mobile-payment.component";
|
||||
// import { Elements } from "@stripe/react-stripe-js";
|
||||
// import { loadStripe } from "@stripe/stripe-js";
|
||||
// import React from "react";
|
||||
// import MobilePaymentComponent from "./mobile-payment.component";
|
||||
|
||||
const stripePromise = new Promise((resolve, reject) => {
|
||||
resolve(
|
||||
loadStripe(process.env.REACT_APP_STRIPE_PUBLIC_KEY, {
|
||||
stripeAccount: "acct_1Fa7lFIEahEZW8b4",
|
||||
})
|
||||
);
|
||||
});
|
||||
// const stripePromise = new Promise((resolve, reject) => {
|
||||
// resolve(
|
||||
// loadStripe(process.env.REACT_APP_STRIPE_PUBLIC_KEY, {
|
||||
// stripeAccount: "acct_1Fa7lFIEahEZW8b4",
|
||||
// })
|
||||
// );
|
||||
// });
|
||||
|
||||
export default function MobilePaymentContainer() {
|
||||
return (
|
||||
<div>
|
||||
The mobile payment container.
|
||||
<Elements stripe={stripePromise}>
|
||||
<MobilePaymentComponent />
|
||||
</Elements>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
// export default function MobilePaymentContainer() {
|
||||
// return (
|
||||
// <div>
|
||||
// The mobile payment container.
|
||||
// <Elements stripe={stripePromise}>
|
||||
// <MobilePaymentComponent />
|
||||
// </Elements>
|
||||
// </div>
|
||||
// );
|
||||
// }
|
||||
|
||||
@@ -136,10 +136,6 @@ export function* calculateScheduleLoad({ payload: end }) {
|
||||
}
|
||||
});
|
||||
|
||||
console.log(
|
||||
"🚀 ~ file: application.sagas.js:160 ~ function*calculateScheduleLoad ~ load.productionTotal",
|
||||
load.productionTotal
|
||||
);
|
||||
//Propagate the expected load to each day.
|
||||
const range = Math.round(moment.duration(end.diff(today)).asDays());
|
||||
for (var day = 0; day < range; day++) {
|
||||
@@ -175,6 +171,7 @@ export function* calculateScheduleLoad({ payload: end }) {
|
||||
(load[current].hoursOut || 0);
|
||||
}
|
||||
}
|
||||
|
||||
yield put(setProblemJobs(problemJobs));
|
||||
yield put(scheduleLoadSuccess(load));
|
||||
} catch (error) {
|
||||
|
||||
@@ -279,6 +279,7 @@
|
||||
},
|
||||
"email": "General Shop Email",
|
||||
"enforce_class": "Enforce Class on Conversion?",
|
||||
"enforce_conversion_csr": "Enforce CSR on Conversion?",
|
||||
"enforce_referral": "Enforce Referrals",
|
||||
"federal_tax_id": "Federal Tax ID (GST/HST)",
|
||||
"ignoreblockeddays": "Scoreboard - Ignore Blocked Days",
|
||||
@@ -2500,6 +2501,7 @@
|
||||
},
|
||||
"schedule": {
|
||||
"labels": {
|
||||
"atssummary": "ATS Summary",
|
||||
"employeevacation": "Employee Vacations",
|
||||
"intake": "Intake Events",
|
||||
"manual": "Manual Events",
|
||||
|
||||
@@ -279,6 +279,7 @@
|
||||
},
|
||||
"email": "",
|
||||
"enforce_class": "",
|
||||
"enforce_conversion_csr": "",
|
||||
"enforce_referral": "",
|
||||
"federal_tax_id": "",
|
||||
"ignoreblockeddays": "",
|
||||
@@ -2500,6 +2501,7 @@
|
||||
},
|
||||
"schedule": {
|
||||
"labels": {
|
||||
"atssummary": "",
|
||||
"employeevacation": "",
|
||||
"intake": "",
|
||||
"manual": "",
|
||||
|
||||
@@ -279,6 +279,7 @@
|
||||
},
|
||||
"email": "",
|
||||
"enforce_class": "",
|
||||
"enforce_conversion_csr": "",
|
||||
"enforce_referral": "",
|
||||
"federal_tax_id": "",
|
||||
"ignoreblockeddays": "",
|
||||
@@ -2500,6 +2501,7 @@
|
||||
},
|
||||
"schedule": {
|
||||
"labels": {
|
||||
"atssummary": "",
|
||||
"employeevacation": "",
|
||||
"intake": "",
|
||||
"manual": "",
|
||||
|
||||
116
client/yarn.lock
116
client/yarn.lock
@@ -2178,20 +2178,21 @@
|
||||
estree-walker "^1.0.1"
|
||||
picomatch "^2.2.2"
|
||||
|
||||
"@sentry/browser@7.7.0":
|
||||
version "7.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.7.0.tgz#7810ee98d4969bd0367e29ac0af6c5779db7e6c4"
|
||||
integrity sha512-oyzpWcsjVZTaf14zAL89Ng1DUHlbjN+V8pl8dR9Y9anphbzL5BK9p0fSK4kPIrO4GukK+XrKnLJDPuE/o7WR3g==
|
||||
"@sentry/browser@7.28.1":
|
||||
version "7.28.1"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.28.1.tgz#c8086e26079809aa401a05d9b4a6e4df63a9c965"
|
||||
integrity sha512-N8j93IcrWKWorfJ5D+RSKVAvcR4S5tIcZ/HvFPMrQWnfVa/jtJcrKThdjZYteA0wjmPiy8/D3KA8nB91yulBPA==
|
||||
dependencies:
|
||||
"@sentry/core" "7.7.0"
|
||||
"@sentry/types" "7.7.0"
|
||||
"@sentry/utils" "7.7.0"
|
||||
"@sentry/core" "7.28.1"
|
||||
"@sentry/replay" "7.28.1"
|
||||
"@sentry/types" "7.28.1"
|
||||
"@sentry/utils" "7.28.1"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/cli@^1.74.4":
|
||||
version "1.74.5"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-1.74.5.tgz#4a5c622913087c9ab6f82994da9a7526423779b8"
|
||||
integrity sha512-Ze1ec306ZWHtrxKypOJ8nhtFqkrx2f/6bRH+DcJzEQ3bBePQ0ZnqJTTe4BBHADYBtxFIaUWzCZ6DquLz2Zv/sw==
|
||||
"@sentry/cli@^1.74.6":
|
||||
version "1.74.6"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-1.74.6.tgz#c4f276e52c6f5e8c8d692845a965988068ebc6f5"
|
||||
integrity sha512-pJ7JJgozyjKZSTjOGi86chIngZMLUlYt2HOog+OJn+WGvqEkVymu8m462j1DiXAnex9NspB4zLLNuZ/R6rTQHg==
|
||||
dependencies:
|
||||
https-proxy-agent "^5.0.0"
|
||||
mkdirp "^0.5.5"
|
||||
@@ -2201,65 +2202,65 @@
|
||||
proxy-from-env "^1.1.0"
|
||||
which "^2.0.2"
|
||||
|
||||
"@sentry/core@7.7.0":
|
||||
version "7.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.7.0.tgz#1a2d477897552d179380f7c54c7d81a4e98ea29a"
|
||||
integrity sha512-Z15ACiuiFINFcK4gbMrnejLn4AVjKBPJOWKrrmpIe8mh+Y9diOuswt5mMUABs+jhpZvqht3PBLLGBL0WMsYMYA==
|
||||
"@sentry/core@7.28.1":
|
||||
version "7.28.1"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.28.1.tgz#c712ce17469b18b01606108817be24a99ed2116e"
|
||||
integrity sha512-7wvnuvn/mrAfcugWoCG/3pqDIrUgH5t+HisMJMGw0h9Tc33KqrmqMDCQVvjlrr2pWrw/vuUCFdm8CbUHJ832oQ==
|
||||
dependencies:
|
||||
"@sentry/hub" "7.7.0"
|
||||
"@sentry/types" "7.7.0"
|
||||
"@sentry/utils" "7.7.0"
|
||||
"@sentry/types" "7.28.1"
|
||||
"@sentry/utils" "7.28.1"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/hub@7.7.0":
|
||||
version "7.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-7.7.0.tgz#9ad3471cf5ecaf1a9d3a3a04ca2515ffec9e2c09"
|
||||
integrity sha512-6gydK234+a0nKhBRDdIJ7Dp42CaiW2juTiHegUVDq+482balVzbZyEAmESCmuzKJhx5BhlCElVxs/cci1NjMpg==
|
||||
"@sentry/react@^7.28.1":
|
||||
version "7.28.1"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/react/-/react-7.28.1.tgz#79531b98176765a788cdf7f8f09b8ba713a95cfb"
|
||||
integrity sha512-sFKK7uDREh84GyJcXDNuiQQ5VhLx7XJTOAdELxLv4HEI6BxbBRz0zNRQiKamTRkz9NmL7bZtld5TfbpOo9kijg==
|
||||
dependencies:
|
||||
"@sentry/types" "7.7.0"
|
||||
"@sentry/utils" "7.7.0"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/react@^7.7.0":
|
||||
version "7.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/react/-/react-7.7.0.tgz#a519dd727f863c1abf1a77beac01a3336c856828"
|
||||
integrity sha512-93Khad3YAln6mKU9E15QH09XC1ARIOpNTRpnBl6AGl3bVhSdLExsbKDLa7Rx0mW2j4z/prOC6VEHf5mBvg4mPg==
|
||||
dependencies:
|
||||
"@sentry/browser" "7.7.0"
|
||||
"@sentry/types" "7.7.0"
|
||||
"@sentry/utils" "7.7.0"
|
||||
"@sentry/browser" "7.28.1"
|
||||
"@sentry/types" "7.28.1"
|
||||
"@sentry/utils" "7.28.1"
|
||||
hoist-non-react-statics "^3.3.2"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/tracing@^7.7.0":
|
||||
version "7.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-7.7.0.tgz#67324b755a28e115289755e44a0b8b467a63d0b2"
|
||||
integrity sha512-HNmvTwemuc21q/K6HXsSp9njkne6N1JQ71TB+QGqYU5VtxsVgYSUhhYqV6WcHz7LK4Hj6TvNFoeu69/rO0ysgw==
|
||||
"@sentry/replay@7.28.1":
|
||||
version "7.28.1"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.28.1.tgz#fbdd377923e082423b95e3f128cb9af9451aca70"
|
||||
integrity sha512-Os0PzMjKlwtHwzTU0kfVzGzsi4Vaj3g2arCl4Qnr3b6kYTb9WOFZo/n/v56ss7Z+nZG3K8W5PisoD4MRsRJRig==
|
||||
dependencies:
|
||||
"@sentry/hub" "7.7.0"
|
||||
"@sentry/types" "7.7.0"
|
||||
"@sentry/utils" "7.7.0"
|
||||
"@sentry/core" "7.28.1"
|
||||
"@sentry/types" "7.28.1"
|
||||
"@sentry/utils" "7.28.1"
|
||||
|
||||
"@sentry/tracing@^7.28.1":
|
||||
version "7.28.1"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-7.28.1.tgz#d276e4d17a79190a88112696c73de12c209607a1"
|
||||
integrity sha512-uWspnuz+7FyW8ES5lRaVA7O/YJSzMlSkvBFtgzaoKmdaueokU/sRLwlCsrdgwavG1wpm79df7R1iiSeqhaXDlw==
|
||||
dependencies:
|
||||
"@sentry/core" "7.28.1"
|
||||
"@sentry/types" "7.28.1"
|
||||
"@sentry/utils" "7.28.1"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/types@7.7.0":
|
||||
version "7.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.7.0.tgz#dd6bd3d119d7efea0e85dbaa4b17de1c22b63c7a"
|
||||
integrity sha512-4x8O7uerSGLnYC10krHl9t8h7xXHn5FextqKYbTCXCnx2hC8D+9lz8wcbQAFo0d97wiUYqI8opmEgFVGx7c5hQ==
|
||||
"@sentry/types@7.28.1":
|
||||
version "7.28.1"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.28.1.tgz#9018b4c152b475de9bedd267237393d3c9b1253d"
|
||||
integrity sha512-DvSplMVrVEmOzR2M161V5+B8Up3vR71xMqJOpWTzE9TqtFJRGPtqT/5OBsNJJw1+/j2ssMcnKwbEo9Q2EGeS6g==
|
||||
|
||||
"@sentry/utils@7.7.0":
|
||||
version "7.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.7.0.tgz#013e3097c4268a76de578494c7df999635fb0ad4"
|
||||
integrity sha512-fD+ROSFpeJlK7bEvUT2LOW7QqgjBpXJwVISKZ0P2fuzclRC3KoB2pbZgBM4PXMMTiSzRGWhvfRRjBiBvQJBBJQ==
|
||||
"@sentry/utils@7.28.1":
|
||||
version "7.28.1"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.28.1.tgz#0a7b6aa4b09e91e4d1aded2a8c8dbaf818cee96e"
|
||||
integrity sha512-75/jzLUO9HH09iC9TslNimGbxOP3jgn89P+q7uR+rp2fJfRExHVeKJZQdK0Ij4/SmE7TJ3Uh2r154N0INZEx1g==
|
||||
dependencies:
|
||||
"@sentry/types" "7.7.0"
|
||||
"@sentry/types" "7.28.1"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/webpack-plugin@^1.19.0":
|
||||
version "1.19.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/webpack-plugin/-/webpack-plugin-1.19.0.tgz#2b134318f1552ba7f3e3f9c83c71a202095f7a44"
|
||||
integrity sha512-qSpdgdGMtdzagGveSWgo2b+t8PdPUscuOjbOyWCsJme9jlTFnNk0rX7JEA55OUozikKHM/+vVh08USLBnPboZw==
|
||||
"@sentry/webpack-plugin@^1.20.0":
|
||||
version "1.20.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/webpack-plugin/-/webpack-plugin-1.20.0.tgz#e7add76122708fb6b4ee7951294b521019720e58"
|
||||
integrity sha512-Ssj1mJVFsfU6vMCOM2d+h+KQR7QHSfeIP16t4l20Uq/neqWXZUQ2yvQfe4S3BjdbJXz/X4Rw8Hfy1Sd0ocunYw==
|
||||
dependencies:
|
||||
"@sentry/cli" "^1.74.4"
|
||||
"@sentry/cli" "^1.74.6"
|
||||
webpack-sources "^2.0.0 || ^3.0.0"
|
||||
|
||||
"@sinonjs/commons@^1.7.0":
|
||||
version "1.8.3"
|
||||
@@ -14615,6 +14616,11 @@ webpack-sources@^1.1.0, webpack-sources@^1.3.0, webpack-sources@^1.4.0, webpack-
|
||||
source-list-map "^2.0.0"
|
||||
source-map "~0.6.1"
|
||||
|
||||
"webpack-sources@^2.0.0 || ^3.0.0":
|
||||
version "3.2.3"
|
||||
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde"
|
||||
integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==
|
||||
|
||||
webpack@4.44.2:
|
||||
version "4.44.2"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.44.2.tgz#6bfe2b0af055c8b2d1e90ed2cd9363f841266b72"
|
||||
|
||||
@@ -855,6 +855,7 @@
|
||||
- deliverchecklist
|
||||
- email
|
||||
- enforce_class
|
||||
- enforce_conversion_csr
|
||||
- enforce_referral
|
||||
- entegral_configuration
|
||||
- entegral_id
|
||||
@@ -951,6 +952,7 @@
|
||||
- deliverchecklist
|
||||
- email
|
||||
- enforce_class
|
||||
- enforce_conversion_csr
|
||||
- enforce_referral
|
||||
- federal_tax_id
|
||||
- id
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
-- Could not auto-generate a down migration.
|
||||
-- Please write an appropriate down migration for the SQL below:
|
||||
-- alter table "public"."bodyshops" add column "enforce_conversion_csr" boolean
|
||||
-- null default 'false';
|
||||
@@ -0,0 +1,2 @@
|
||||
alter table "public"."bodyshops" add column "enforce_conversion_csr" boolean
|
||||
null default 'false';
|
||||
@@ -654,9 +654,9 @@ exports.default = function ({
|
||||
if (qbo) {
|
||||
InvoiceLineAdd.push({
|
||||
DetailType: "SalesItemLineDetail",
|
||||
Amount: Dinero({ amount: (payer.amount || 0) * 100 * -1 }).toFormat(
|
||||
DineroQbFormat
|
||||
),
|
||||
Amount: Dinero({
|
||||
amount: Math.round((payer.amount || 0) * 100) * -1,
|
||||
}).toFormat(DineroQbFormat),
|
||||
SalesItemLineDetail: {
|
||||
...(jobs_by_pk.class
|
||||
? { ClassRef: { value: classes[jobs_by_pk.class] } }
|
||||
@@ -687,9 +687,9 @@ exports.default = function ({
|
||||
FullName: responsibilityCenters.qb_multiple_payers?.accountitem,
|
||||
},
|
||||
Desc: `${payer.name} Liability`,
|
||||
Amount: Dinero({ amount: (payer.amount || 0) * 100 * -1 }).toFormat(
|
||||
DineroQbFormat
|
||||
),
|
||||
Amount: Dinero({
|
||||
amount: Math.round((payer.amount || 0) * 100) * -1,
|
||||
}).toFormat(DineroQbFormat),
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user