@@ -132,6 +132,57 @@ jobs:
|
|||||||
to: "s3://rome-online-production/"
|
to: "s3://rome-online-production/"
|
||||||
- jira/notify
|
- jira/notify
|
||||||
|
|
||||||
|
test-rome-hasura-migrate:
|
||||||
|
docker:
|
||||||
|
- image: cimg/node:16.15.0
|
||||||
|
parameters:
|
||||||
|
secret:
|
||||||
|
type: string
|
||||||
|
default: $HASURA_ROME_TEST_SECRET
|
||||||
|
working_directory: ~/repo/hasura
|
||||||
|
steps:
|
||||||
|
- checkout:
|
||||||
|
path: ~/repo
|
||||||
|
- run:
|
||||||
|
name: Execute migration
|
||||||
|
command: |
|
||||||
|
npm install hasura-cli -g
|
||||||
|
echo ${HASURA_TEST_SECRET}
|
||||||
|
hasura migrate apply --endpoint https://db.test.romeonline.io/ --admin-secret << parameters.secret >>
|
||||||
|
hasura metadata apply --endpoint https://db.test.romeonline.io/ --admin-secret << parameters.secret >>
|
||||||
|
hasura metadata reload --endpoint https://db.test.romeonline.io/ --admin-secret << parameters.secret >>
|
||||||
|
|
||||||
|
test-rome-app-build:
|
||||||
|
docker:
|
||||||
|
- image: cimg/node:16.15.0
|
||||||
|
|
||||||
|
working_directory: ~/repo/client
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- checkout:
|
||||||
|
path: ~/repo
|
||||||
|
|
||||||
|
- restore_cache:
|
||||||
|
name: Restore Yarn Package Cache
|
||||||
|
keys:
|
||||||
|
- yarn-packages-{{ checksum "yarn.lock" }}
|
||||||
|
- run:
|
||||||
|
name: Install Dependencies
|
||||||
|
command: yarn install --frozen-lockfile --cache-folder ~/.cache/yarn
|
||||||
|
- save_cache:
|
||||||
|
name: Save Yarn Package Cache
|
||||||
|
key: yarn-packages-{{ checksum "yarn.lock" }}
|
||||||
|
paths:
|
||||||
|
- ~/.cache/yarn
|
||||||
|
|
||||||
|
- run: yarn run build:test
|
||||||
|
|
||||||
|
- aws-s3/sync:
|
||||||
|
from: build
|
||||||
|
to: "s3://rome-online-test/"
|
||||||
|
- jira/notify
|
||||||
|
|
||||||
|
|
||||||
test-hasura-migrate:
|
test-hasura-migrate:
|
||||||
docker:
|
docker:
|
||||||
- image: cimg/node:16.15.0
|
- image: cimg/node:16.15.0
|
||||||
@@ -250,6 +301,15 @@ workflows:
|
|||||||
filters:
|
filters:
|
||||||
branches:
|
branches:
|
||||||
only: test
|
only: test
|
||||||
|
- test-rome-app-build:
|
||||||
|
filters:
|
||||||
|
branches:
|
||||||
|
only: rome/test
|
||||||
|
- test-rome-hasura-migrate:
|
||||||
|
secret: ${HASURA_ROME_TEST_SECRET}
|
||||||
|
filters:
|
||||||
|
branches:
|
||||||
|
only: rome/test
|
||||||
#- admin-app-build:
|
#- admin-app-build:
|
||||||
#filters:
|
#filters:
|
||||||
#branches:
|
#branches:
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<babeledit_project version="1.2" be_version="2.7.1">
|
<babeledit_project be_version="2.7.1" version="1.2">
|
||||||
<!--
|
<!--
|
||||||
|
|
||||||
BabelEdit project file
|
BabelEdit project file
|
||||||
@@ -1009,27 +1009,6 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
<concept_node>
|
|
||||||
<name>smspaymentreminder</name>
|
|
||||||
<definition_loaded>false</definition_loaded>
|
|
||||||
<description></description>
|
|
||||||
<comment></comment>
|
|
||||||
<default_text></default_text>
|
|
||||||
<translations>
|
|
||||||
<translation>
|
|
||||||
<language>en-US</language>
|
|
||||||
<approved>false</approved>
|
|
||||||
</translation>
|
|
||||||
<translation>
|
|
||||||
<language>es-MX</language>
|
|
||||||
<approved>false</approved>
|
|
||||||
</translation>
|
|
||||||
<translation>
|
|
||||||
<language>fr-CA</language>
|
|
||||||
<approved>false</approved>
|
|
||||||
</translation>
|
|
||||||
</translations>
|
|
||||||
</concept_node>
|
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>suggesteddates</name>
|
<name>suggesteddates</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -16312,6 +16291,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>copied</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>copylink</name>
|
<name>copylink</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -16648,6 +16648,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>sendbysms</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>senderrortosupport</name>
|
<name>senderrortosupport</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -19360,6 +19381,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>openingip</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>title</name>
|
<name>title</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -33131,27 +33173,6 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
<concept_node>
|
|
||||||
<name>paymentremindersms</name>
|
|
||||||
<definition_loaded>false</definition_loaded>
|
|
||||||
<description></description>
|
|
||||||
<comment></comment>
|
|
||||||
<default_text></default_text>
|
|
||||||
<translations>
|
|
||||||
<translation>
|
|
||||||
<language>en-US</language>
|
|
||||||
<approved>false</approved>
|
|
||||||
</translation>
|
|
||||||
<translation>
|
|
||||||
<language>es-MX</language>
|
|
||||||
<approved>false</approved>
|
|
||||||
</translation>
|
|
||||||
<translation>
|
|
||||||
<language>fr-CA</language>
|
|
||||||
<approved>false</approved>
|
|
||||||
</translation>
|
|
||||||
</translations>
|
|
||||||
</concept_node>
|
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>phonebook</name>
|
<name>phonebook</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -37601,6 +37622,32 @@
|
|||||||
<folder_node>
|
<folder_node>
|
||||||
<name>payments</name>
|
<name>payments</name>
|
||||||
<children>
|
<children>
|
||||||
|
<folder_node>
|
||||||
|
<name>actions</name>
|
||||||
|
<children>
|
||||||
|
<concept_node>
|
||||||
|
<name>generatepaymentlink</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
|
</children>
|
||||||
|
</folder_node>
|
||||||
<folder_node>
|
<folder_node>
|
||||||
<name>errors</name>
|
<name>errors</name>
|
||||||
<children>
|
<children>
|
||||||
@@ -37646,6 +37693,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>inserting</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
</children>
|
</children>
|
||||||
</folder_node>
|
</folder_node>
|
||||||
<folder_node>
|
<folder_node>
|
||||||
@@ -38118,6 +38186,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>smspaymentreminder</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>title</name>
|
<name>title</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
REACT_APP_GRAPHQL_ENDPOINT=https://db.test.bodyshop.app/v1/graphql
|
REACT_APP_GRAPHQL_ENDPOINT=https://db.test.romeonline.io/v1/graphql
|
||||||
REACT_APP_GRAPHQL_ENDPOINT_WS=wss://db.test.bodyshop.app/v1/graphql
|
REACT_APP_GRAPHQL_ENDPOINT_WS=wss://db.test.romeonline.io/v1/graphql
|
||||||
REACT_APP_GA_CODE=231099835
|
REACT_APP_GA_CODE=231103507
|
||||||
REACT_APP_FIREBASE_CONFIG={ "apiKey":"AIzaSyBw7_GTy7GtQyfkIRPVrWHEGKfcqeyXw0c", "authDomain":"imex-test.firebaseapp.com", "projectId":"imex-test", "storageBucket":"imex-test.appspot.com", "messagingSenderId":"991923618608", "appId":"1:991923618608:web:633437569cdad78299bef5", "measurementId":"G-TW0XLZEH18"}
|
REACT_APP_FIREBASE_CONFIG={ "apiKey": "AIzaSyAuLQR9SV5LsVxjU8wh9hvFLdhcAHU6cxE", "authDomain": "rome-prod-1.firebaseapp.com", "projectId": "rome-prod-1", "storageBucket": "rome-prod-1.appspot.com", "messagingSenderId": "147786367145", "appId": "1:147786367145:web:9d4cba68071c3f29a8a9b8", "measurementId": "G-G8Z9DRHTZS"}
|
||||||
REACT_APP_CLOUDINARY_ENDPOINT_API=https://api.cloudinary.com/v1_1/bodyshop
|
REACT_APP_CLOUDINARY_ENDPOINT_API=https://api.cloudinary.com/v1_1/bodyshop
|
||||||
REACT_APP_CLOUDINARY_ENDPOINT=https://res.cloudinary.com/bodyshop
|
REACT_APP_CLOUDINARY_ENDPOINT=https://res.cloudinary.com/bodyshop
|
||||||
REACT_APP_CLOUDINARY_API_KEY=473322739956866
|
REACT_APP_CLOUDINARY_API_KEY=473322739956866
|
||||||
REACT_APP_CLOUDINARY_THUMB_TRANSFORMATIONS=c_fill,h_250,w_250
|
REACT_APP_CLOUDINARY_THUMB_TRANSFORMATIONS=c_fill,h_250,w_250
|
||||||
REACT_APP_FIREBASE_PUBLIC_VAPID_KEY='BN2GcDPjipR5MTEosO5dT4CfQ3cmrdBIsI4juoOQrRijn_5aRiHlwj1mlq0W145mOusx6xynEKl_tvYJhpCc9lo'
|
REACT_APP_FIREBASE_PUBLIC_VAPID_KEY='BP1B7ZTYpn-KMt6nOxlld6aS8Skt3Q7ZLEqP0hAvGHxG4UojPYiXZ6kPlzZkUC5jH-EcWXomTLtmadAIxurfcHo'
|
||||||
REACT_APP_STRIPE_PUBLIC_KEY=pk_test_51GqB4TJl3nQjrZ0wCQWAxAhlNF8jKe0tipIa6ExBaxwJGitwvFsIZUEua4dUzaMIAuXp4qwYHXx7lgjyQSwP0Pe900vzm38C7g
|
REACT_APP_STRIPE_PUBLIC_KEY=pk_test_51GqB4TJl3nQjrZ0wCQWAxAhlNF8jKe0tipIa6ExBaxwJGitwvFsIZUEua4dUzaMIAuXp4qwYHXx7lgjyQSwP0Pe900vzm38C7g
|
||||||
REACT_APP_AXIOS_BASE_API_URL=https://api.romeonline.io/
|
REACT_APP_AXIOS_BASE_API_URL=https://api.test.romeonline.io/
|
||||||
REACT_APP_REPORTS_SERVER_URL=https://reports.romeonline.io
|
REACT_APP_REPORTS_SERVER_URL=https://reports.test.romeonline.io
|
||||||
REACT_APP_IS_TEST=true
|
REACT_APP_IS_TEST=true
|
||||||
REACT_APP_SPLIT_API=ts615lqgnmk84thn72uk18uu5pgce6e0l4rc
|
REACT_APP_SPLIT_API=ts615lqgnmk84thn72uk18uu5pgce6e0l4rc
|
||||||
@@ -8,18 +8,6 @@
|
|||||||
<meta name="description" content="Rome Online" />
|
<meta name="description" content="Rome Online" />
|
||||||
<!-- <link rel="apple-touch-icon" href="logo192.png" /> -->
|
<!-- <link rel="apple-touch-icon" href="logo192.png" /> -->
|
||||||
<link rel="apple-touch-icon" href="logo192.png" />
|
<link rel="apple-touch-icon" href="logo192.png" />
|
||||||
<script type="text/javascript">
|
|
||||||
window.$crisp = [];
|
|
||||||
window.CRISP_WEBSITE_ID = "36724f62-2eb0-4b29-9cdd-9905fb99913e";
|
|
||||||
(function () {
|
|
||||||
d = document;
|
|
||||||
s = d.createElement("script");
|
|
||||||
s.src = "https://client.crisp.chat/l.js";
|
|
||||||
s.async = 1;
|
|
||||||
d.getElementsByTagName("head")[0].appendChild(s);
|
|
||||||
})();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
!(function () {
|
!(function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|||||||
@@ -320,12 +320,12 @@ function BillEnterModalContainer({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (enterAgain) {
|
if (enterAgain) {
|
||||||
form.resetFields();
|
// form.resetFields();
|
||||||
form.resetFields();
|
|
||||||
form.setFieldsValue({
|
form.setFieldsValue({
|
||||||
...formValues,
|
...formValues,
|
||||||
billlines: [],
|
billlines: [],
|
||||||
});
|
});
|
||||||
|
form.resetFields();
|
||||||
} else {
|
} else {
|
||||||
toggleModalVisible();
|
toggleModalVisible();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,40 @@
|
|||||||
import React, { useCallback, useEffect } from "react";
|
import { DeleteFilled } from "@ant-design/icons";
|
||||||
|
import { useLazyQuery, useMutation } from "@apollo/client";
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Card,
|
||||||
|
Col,
|
||||||
|
Form,
|
||||||
|
Input,
|
||||||
|
Row,
|
||||||
|
Space,
|
||||||
|
Spin,
|
||||||
|
Statistic,
|
||||||
|
notification,
|
||||||
|
} from "antd";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import { Button, Card, Form, Input, InputNumber, Row, Select } from "antd";
|
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { useMutation, useQuery } from "@apollo/client";
|
import React, { useState } from "react";
|
||||||
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
import { useTranslation } from "react-i18next";
|
||||||
import JobSearchSelectComponent from "../job-search-select/job-search-select.component";
|
import { connect } from "react-redux";
|
||||||
import { INSERT_NEW_PAYMENT } from "../../graphql/payments.queries";
|
import { createStructuredSelector } from "reselect";
|
||||||
import {
|
import {
|
||||||
INSERT_PAYMENT_RESPONSE,
|
INSERT_PAYMENT_RESPONSE,
|
||||||
QUERY_RO_AND_OWNER_BY_JOB_PK,
|
QUERY_RO_AND_OWNER_BY_JOB_PKS,
|
||||||
} from "../../graphql/payment_response.queries";
|
} from "../../graphql/payment_response.queries";
|
||||||
import DataLabel from "../data-label/data-label.component";
|
import { INSERT_NEW_PAYMENT } from "../../graphql/payments.queries";
|
||||||
import { insertAuditTrail } from "../../redux/application/application.actions";
|
import { insertAuditTrail } from "../../redux/application/application.actions";
|
||||||
import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
|
||||||
import { connect } from "react-redux";
|
|
||||||
import { toggleModalVisible } from "../../redux/modals/modals.actions";
|
import { toggleModalVisible } from "../../redux/modals/modals.actions";
|
||||||
|
import { selectCardPayment } from "../../redux/modals/modals.selectors";
|
||||||
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
|
import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
||||||
|
import CurrencyFormItemComponent from "../form-items-formatted/currency-form-item.component";
|
||||||
|
import JobSearchSelectComponent from "../job-search-select/job-search-select.component";
|
||||||
|
|
||||||
|
const mapStateToProps = createStructuredSelector({
|
||||||
|
cardPaymentModal: selectCardPayment,
|
||||||
|
bodyshop: selectBodyshop,
|
||||||
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
insertAuditTrail: ({ jobid, operation }) =>
|
insertAuditTrail: ({ jobid, operation }) =>
|
||||||
@@ -25,253 +44,331 @@ const mapDispatchToProps = (dispatch) => ({
|
|||||||
|
|
||||||
const CardPaymentModalComponent = ({
|
const CardPaymentModalComponent = ({
|
||||||
bodyshop,
|
bodyshop,
|
||||||
context,
|
cardPaymentModal,
|
||||||
toggleModalVisible,
|
toggleModalVisible,
|
||||||
insertAuditTrail,
|
insertAuditTrail,
|
||||||
}) => {
|
}) => {
|
||||||
|
const { context } = cardPaymentModal;
|
||||||
|
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const amount = Form.useWatch("amount", form);
|
|
||||||
const payer = Form.useWatch("payer", form);
|
const [loading, setLoading] = useState(false);
|
||||||
const jobid = Form.useWatch("jobid", form);
|
|
||||||
const [insertPayment] = useMutation(INSERT_NEW_PAYMENT);
|
const [insertPayment] = useMutation(INSERT_NEW_PAYMENT);
|
||||||
const [insertPaymentResponse] = useMutation(INSERT_PAYMENT_RESPONSE);
|
const [insertPaymentResponse] = useMutation(INSERT_PAYMENT_RESPONSE);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const { data, refetch } = useQuery(QUERY_RO_AND_OWNER_BY_JOB_PK, {
|
const [, { data, refetch, queryLoading }] = useLazyQuery(
|
||||||
variables: { jobid: context?.jobid ?? "" },
|
QUERY_RO_AND_OWNER_BY_JOB_PKS,
|
||||||
});
|
{
|
||||||
|
variables: { jobids: [context.jobid] },
|
||||||
|
skip: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const nonApproval = useCallback(
|
console.log("🚀 ~ file: card-payment-modal.component..jsx:61 ~ data:", data);
|
||||||
async (response) => {
|
//Initialize the intellipay window.
|
||||||
|
const SetIntellipayCallbackFunctions = () => {
|
||||||
|
console.log("*** Set IntelliPay callback functions.");
|
||||||
|
window.intellipay.runOnClose(() => {
|
||||||
|
//window.intellipay.initialize();
|
||||||
|
});
|
||||||
|
|
||||||
|
window.intellipay.runOnApproval(async function (response) {
|
||||||
|
console.warn("*** Running On Approval Script ***");
|
||||||
|
form.setFieldValue("paymentResponse", response);
|
||||||
|
form.submit();
|
||||||
|
});
|
||||||
|
|
||||||
|
window.intellipay.runOnNonApproval(async function (response) {
|
||||||
// Mutate unsuccessful payment
|
// Mutate unsuccessful payment
|
||||||
|
|
||||||
|
const { payments } = form.getFieldsValue();
|
||||||
|
|
||||||
await insertPaymentResponse({
|
await insertPaymentResponse({
|
||||||
variables: {
|
variables: {
|
||||||
paymentResponse: {
|
paymentResponse: payments.map((payment) => ({
|
||||||
amount: response.amount,
|
amount: payment.amount,
|
||||||
bodyshopid: bodyshop.id,
|
bodyshopid: bodyshop.id,
|
||||||
jobid: jobid || context.jobid,
|
jobid: payment.jobid,
|
||||||
declinereason: response.declinereason,
|
declinereason: response.declinereason,
|
||||||
ext_paymentid: response.paymentid.toString(),
|
ext_paymentid: response.paymentid.toString(),
|
||||||
successful: false,
|
successful: false,
|
||||||
response,
|
response,
|
||||||
},
|
})),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Insert failed payment to audit trail
|
payments.forEach((payment) =>
|
||||||
insertAuditTrail({
|
insertAuditTrail({
|
||||||
jobid: jobid || context?.jobid,
|
jobid: payment.jobid,
|
||||||
operation: AuditTrailMapping.failedpayment(),
|
operation: AuditTrailMapping.failedpayment(),
|
||||||
});
|
})
|
||||||
},
|
);
|
||||||
[bodyshop, context, insertAuditTrail, insertPaymentResponse, jobid]
|
});
|
||||||
);
|
};
|
||||||
|
|
||||||
const initIntellipayFunctions = useCallback(() => {
|
|
||||||
if (window.intellipay !== undefined && typeof jobid !== "undefined") {
|
|
||||||
console.log("intellipay init functions");
|
|
||||||
|
|
||||||
window.intellipay.runOnClose(() => {
|
|
||||||
window.intellipay.initialize();
|
|
||||||
});
|
|
||||||
|
|
||||||
window.intellipay.runOnApproval(async function (response) {
|
|
||||||
form.setFieldValue("paymentResponse", response);
|
|
||||||
form.submit();
|
|
||||||
|
|
||||||
toggleModalVisible();
|
|
||||||
});
|
|
||||||
|
|
||||||
window.intellipay.runOnNonApproval(nonApproval);
|
|
||||||
}
|
|
||||||
}, [form, jobid, nonApproval, toggleModalVisible]);
|
|
||||||
|
|
||||||
const initJobId = useCallback(() => {
|
|
||||||
if (context?.jobid) {
|
|
||||||
form.setFieldValue("jobid", context.jobid);
|
|
||||||
}
|
|
||||||
|
|
||||||
form.setFieldValue("payer", t("payments.labels.customer"));
|
|
||||||
}, [context?.jobid, form, t]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
initJobId();
|
|
||||||
|
|
||||||
axios
|
|
||||||
.post("/intellipay/lightbox_credentials", { bodyshop })
|
|
||||||
.then((response) => {
|
|
||||||
var rg = document.createRange();
|
|
||||||
let node = rg.createContextualFragment(response.data);
|
|
||||||
|
|
||||||
document.documentElement.appendChild(node);
|
|
||||||
window.intellipay.initialize();
|
|
||||||
|
|
||||||
initIntellipayFunctions();
|
|
||||||
});
|
|
||||||
|
|
||||||
function handleEvents(...props) {
|
|
||||||
const operation = props[0].data.operation;
|
|
||||||
|
|
||||||
if (operation === "updateform") {
|
|
||||||
props[0].stopImmediatePropagation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener("message", handleEvents, false);
|
|
||||||
|
|
||||||
return () => window.removeEventListener("message", handleEvents, false);
|
|
||||||
}, [bodyshop, initJobId, initIntellipayFunctions]);
|
|
||||||
|
|
||||||
const handleFinish = async (values) => {
|
const handleFinish = async (values) => {
|
||||||
const paymentResult = await insertPayment({
|
try {
|
||||||
variables: {
|
await insertPayment({
|
||||||
paymentInput: {
|
variables: {
|
||||||
amount: values.amount,
|
paymentInput: values.payments.map((payment) => ({
|
||||||
transactionid: values.paymentResponse.receiptelements.transid,
|
amount: payment.amount,
|
||||||
payer: values.payer,
|
transactionid: (values.paymentResponse.paymentid || "").toString(),
|
||||||
type: values.paymentResponse.cardType,
|
payer: t("payments.labels.customer"),
|
||||||
jobid: values.jobid,
|
type: values.paymentResponse.cardbrand,
|
||||||
date: moment(Date.now()),
|
jobid: payment.jobid,
|
||||||
},
|
date: moment(Date.now()),
|
||||||
},
|
payment_responses: {
|
||||||
update(cache, { data }) {
|
data: [
|
||||||
cache.modify({
|
{
|
||||||
id: cache.identify({ id: jobid, __typename: "jobs" }),
|
amount: payment.amount,
|
||||||
fields: {
|
bodyshopid: bodyshop.id,
|
||||||
payments(payments) {
|
|
||||||
return [...data.insert_payments.returning, ...payments];
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await insertPaymentResponse({
|
jobid: payment.jobid,
|
||||||
variables: {
|
declinereason: values.paymentResponse.declinereason,
|
||||||
paymentResponse: {
|
ext_paymentid: values.paymentResponse.paymentid.toString(),
|
||||||
amount: values.amount,
|
successful: true,
|
||||||
bodyshopid: bodyshop.id,
|
response: values.paymentResponse,
|
||||||
paymentid: paymentResult.data.insert_payments.returning[0].id,
|
},
|
||||||
jobid: values.jobid,
|
],
|
||||||
declinereason: values.paymentResponse.declinereason,
|
},
|
||||||
ext_paymentid: values.paymentResponse.paymentid.toString(),
|
})),
|
||||||
successful: true,
|
|
||||||
response: values.paymentResponse,
|
|
||||||
},
|
},
|
||||||
},
|
refetchQueries: ["GET_JOB_BY_PK"],
|
||||||
});
|
});
|
||||||
|
toggleModalVisible();
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
notification.open({
|
||||||
|
type: "error",
|
||||||
|
message: t("payments.errors.inserting", { error: error.message }),
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleIntelliPayCharge = async () => {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
//Validate
|
||||||
|
try {
|
||||||
|
await form.validateFields();
|
||||||
|
} catch (error) {
|
||||||
|
setLoading(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios.post("/intellipay/lightbox_credentials", {
|
||||||
|
bodyshop,
|
||||||
|
refresh: !!window.intellipay,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (window.intellipay) {
|
||||||
|
// eslint-disable-next-line no-eval
|
||||||
|
eval(response.data);
|
||||||
|
SetIntellipayCallbackFunctions();
|
||||||
|
window.intellipay.autoOpen();
|
||||||
|
} else {
|
||||||
|
var rg = document.createRange();
|
||||||
|
let node = rg.createContextualFragment(response.data);
|
||||||
|
document.documentElement.appendChild(node);
|
||||||
|
SetIntellipayCallbackFunctions();
|
||||||
|
window.intellipay.isAutoOpen = true;
|
||||||
|
window.intellipay.initialize();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
notification.open({
|
||||||
|
type: "error",
|
||||||
|
message: t("job_payments.notifications.error.openingip"),
|
||||||
|
});
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card title="Card Payment">
|
<Card title="Card Payment">
|
||||||
<Form onFinish={handleFinish} form={form}>
|
<Spin spinning={loading}>
|
||||||
<LayoutFormRow grow>
|
<Form
|
||||||
<Form.Item
|
onFinish={handleFinish}
|
||||||
name="jobid"
|
form={form}
|
||||||
label={t("bills.fields.ro_number")}
|
layout="vertical"
|
||||||
rules={[
|
initialValues={{
|
||||||
{
|
payments: context.jobid ? [{ jobid: context.jobid }] : [],
|
||||||
required: true,
|
}}
|
||||||
// message: t("general.validation.required"),
|
>
|
||||||
},
|
<Form.List name={["payments"]}>
|
||||||
]}
|
{(fields, { add, remove, move }) => {
|
||||||
>
|
return (
|
||||||
<JobSearchSelectComponent
|
<div>
|
||||||
disabled={context?.jobid}
|
{fields.map((field, index) => (
|
||||||
notExported={false}
|
<Form.Item key={field.key}>
|
||||||
clm_no
|
<Row gutter={[16, 16]}>
|
||||||
onChange={(e) => {
|
<Col span={16}>
|
||||||
refetch({ jobid: e });
|
<Form.Item
|
||||||
}}
|
key={`${index}jobid`}
|
||||||
/>
|
label={t("jobs.fields.ro_number")}
|
||||||
</Form.Item>
|
name={[field.name, "jobid"]}
|
||||||
</LayoutFormRow>
|
rules={[
|
||||||
|
{
|
||||||
{/* Lighbox Input amount needs to be hidden */}
|
required: true,
|
||||||
<Input
|
//message: t("general.validation.required"),
|
||||||
className="ipayfield"
|
},
|
||||||
data-ipayname="amount"
|
]}
|
||||||
type="hidden"
|
>
|
||||||
value={amount}
|
<JobSearchSelectComponent
|
||||||
hidden
|
notExported={false}
|
||||||
/>
|
clm_no
|
||||||
<Input
|
/>
|
||||||
className="ipayfield"
|
</Form.Item>
|
||||||
data-ipayname="account"
|
</Col>
|
||||||
type="hidden"
|
<Col span={6}>
|
||||||
value={data?.jobs_by_pk.ro_number}
|
<Form.Item
|
||||||
hidden
|
key={`${index}amount`}
|
||||||
/>
|
label={t("payments.fields.amount")}
|
||||||
<Input
|
name={[field.name, "amount"]}
|
||||||
className="ipayfield"
|
rules={[
|
||||||
data-ipayname="email"
|
{
|
||||||
type="hidden"
|
required: true,
|
||||||
value={data?.jobs_by_pk.owner.ownr_ea}
|
//message: t("general.validation.required"),
|
||||||
hidden
|
},
|
||||||
/>
|
]}
|
||||||
{/* Lightbox payment response when it is completed */}
|
>
|
||||||
<Form.Item name="paymentResponse" hidden>
|
<CurrencyFormItemComponent />
|
||||||
<Input type="hidden" value={amount} />
|
</Form.Item>
|
||||||
</Form.Item>
|
</Col>
|
||||||
|
<Col span={2}>
|
||||||
<LayoutFormRow grow>
|
<DeleteFilled
|
||||||
<Form.Item
|
style={{ margin: "1rem" }}
|
||||||
label={t("payments.fields.payer")}
|
onClick={() => {
|
||||||
name="payer"
|
remove(field.name);
|
||||||
rules={[
|
}}
|
||||||
{
|
/>
|
||||||
required: true,
|
</Col>
|
||||||
// message: t("general.validation.required"),
|
</Row>
|
||||||
},
|
</Form.Item>
|
||||||
]}
|
))}
|
||||||
>
|
<Form.Item>
|
||||||
<Select>
|
<Button
|
||||||
<Select.Option value={t("payments.labels.customer")}>
|
type="dashed"
|
||||||
{t("payments.labels.customer")}
|
onClick={() => {
|
||||||
</Select.Option>
|
add();
|
||||||
<Select.Option value={t("payments.labels.insurance")}>
|
}}
|
||||||
{t("payments.labels.insurance")}
|
style={{ width: "100%" }}
|
||||||
</Select.Option>
|
>
|
||||||
</Select>
|
{t("general.actions.add")}
|
||||||
</Form.Item>
|
</Button>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</Form.List>
|
||||||
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label="Amount"
|
shouldUpdate={(prevValues, curValues) =>
|
||||||
name="amount"
|
prevValues.payments?.map((p) => p?.jobid).join() !==
|
||||||
rules={[
|
curValues.payments?.map((p) => p?.jobid).join()
|
||||||
{
|
}
|
||||||
required: true,
|
|
||||||
// message: t("general.validation.required"),
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
>
|
>
|
||||||
<InputNumber />
|
{() => {
|
||||||
|
console.log("Updating the owner info section.");
|
||||||
|
//If all of the job ids have been fileld in, then query and update the IP field.
|
||||||
|
const { payments } = form.getFieldsValue();
|
||||||
|
if (
|
||||||
|
payments?.length > 0 &&
|
||||||
|
payments?.filter((p) => p?.jobid).length === payments?.length
|
||||||
|
) {
|
||||||
|
console.log("**Calling refetch.");
|
||||||
|
refetch({ jobids: payments.map((p) => p.jobid) });
|
||||||
|
}
|
||||||
|
console.log(
|
||||||
|
"Acc info",
|
||||||
|
data,
|
||||||
|
payments && data && data.jobs.length > 0
|
||||||
|
? data.jobs.map((j) => j.ro_number).join(", ")
|
||||||
|
: null
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Input
|
||||||
|
className="ipayfield"
|
||||||
|
data-ipayname="account"
|
||||||
|
//type="hidden"
|
||||||
|
value={
|
||||||
|
payments && data && data.jobs.length > 0
|
||||||
|
? data.jobs.map((j) => j.ro_number).join(", ")
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
hidden
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
className="ipayfield"
|
||||||
|
data-ipayname="email"
|
||||||
|
// type="hidden"
|
||||||
|
value={
|
||||||
|
payments && data && data.jobs.length > 0
|
||||||
|
? data.jobs.filter((j) => j.ownr_ea)[0]?.ownr_ea
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
hidden
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
shouldUpdate={(prevValues, curValues) =>
|
||||||
|
prevValues.payments?.map((p) => p?.amount).join() !==
|
||||||
|
curValues.payments?.map((p) => p?.amount).join()
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{() => {
|
||||||
|
const { payments } = form.getFieldsValue();
|
||||||
|
const totalAmountToCharge = payments?.reduce((acc, val) => {
|
||||||
|
return acc + (val?.amount || 0);
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Space style={{ float: "right" }}>
|
||||||
|
<Statistic
|
||||||
|
title="Amount To Charge"
|
||||||
|
value={totalAmountToCharge}
|
||||||
|
precision={2}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
className="ipayfield"
|
||||||
|
data-ipayname="amount"
|
||||||
|
//type="hidden"
|
||||||
|
value={totalAmountToCharge?.toFixed(2)}
|
||||||
|
hidden
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
// data-ipayname="submit"
|
||||||
|
className="ipayfield"
|
||||||
|
loading={queryLoading || loading}
|
||||||
|
disabled={!(totalAmountToCharge > 0)}
|
||||||
|
onClick={handleIntelliPayCharge}
|
||||||
|
>
|
||||||
|
{t("job_payments.buttons.proceedtopayment")}
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
);
|
||||||
|
}}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Row justify="space-around">
|
{/* Lightbox payment response when it is completed */}
|
||||||
<Button
|
<Form.Item name="paymentResponse" hidden>
|
||||||
type="primary"
|
<Input type="hidden" />
|
||||||
data-ipayname="submit"
|
</Form.Item>
|
||||||
className="ipayfield"
|
</Form>
|
||||||
disabled={!amount || !payer || !jobid}
|
</Spin>
|
||||||
>
|
|
||||||
{t("job_payments.buttons.proceedtopayment")}
|
|
||||||
</Button>
|
|
||||||
{context?.balance && (
|
|
||||||
<DataLabel
|
|
||||||
valueStyle={{
|
|
||||||
color: context?.balance.getAmount() !== 0 ? "red" : "green",
|
|
||||||
}}
|
|
||||||
label={t("payments.labels.balance")}
|
|
||||||
>
|
|
||||||
{context?.balance.toFormat()}
|
|
||||||
</DataLabel>
|
|
||||||
)}
|
|
||||||
</Row>
|
|
||||||
</LayoutFormRow>
|
|
||||||
</Form>
|
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(null, mapDispatchToProps)(CardPaymentModalComponent);
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(CardPaymentModalComponent);
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ function CardPaymentModalContainer({
|
|||||||
toggleModalVisible,
|
toggleModalVisible,
|
||||||
bodyshop,
|
bodyshop,
|
||||||
}) {
|
}) {
|
||||||
const { context, visible } = cardPaymentModal;
|
const { visible } = cardPaymentModal;
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
@@ -35,7 +35,7 @@ function CardPaymentModalContainer({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
visible={visible}
|
open={visible}
|
||||||
onOk={handleOK}
|
onOk={handleOK}
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
footer={[
|
footer={[
|
||||||
@@ -43,10 +43,10 @@ function CardPaymentModalContainer({
|
|||||||
{t("job_payments.buttons.goback")}
|
{t("job_payments.buttons.goback")}
|
||||||
</Button>,
|
</Button>,
|
||||||
]}
|
]}
|
||||||
width="60%"
|
width="80%"
|
||||||
destroyOnClose
|
destroyOnClose
|
||||||
>
|
>
|
||||||
<CardPaymentModalComponent bodyshop={bodyshop} context={context} />
|
<CardPaymentModalComponent />
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,36 +23,40 @@ export default function DashboardScheduledInToday({ data, ...cardProps }) {
|
|||||||
|
|
||||||
const appt = []; // Flatten Data
|
const appt = []; // Flatten Data
|
||||||
data.scheduled_in_today.forEach((item) => {
|
data.scheduled_in_today.forEach((item) => {
|
||||||
var i = {
|
if (item.job) {
|
||||||
canceled: item.canceled,
|
var i = {
|
||||||
id: item.id,
|
canceled: item.canceled,
|
||||||
alt_transport: item.job.alt_transport,
|
id: item.id,
|
||||||
clm_no: item.job.clm_no,
|
alt_transport: item.job.alt_transport,
|
||||||
jobid: item.job.jobid,
|
clm_no: item.job.clm_no,
|
||||||
ins_co_nm: item.job.ins_co_nm,
|
jobid: item.job.jobid,
|
||||||
iouparent: item.job.iouparent,
|
ins_co_nm: item.job.ins_co_nm,
|
||||||
ownerid: item.job.ownerid,
|
iouparent: item.job.iouparent,
|
||||||
ownr_co_nm: item.job.ownr_co_nm,
|
ownerid: item.job.ownerid,
|
||||||
ownr_ea: item.job.ownr_ea,
|
ownr_co_nm: item.job.ownr_co_nm,
|
||||||
ownr_fn: item.job.ownr_fn,
|
ownr_ea: item.job.ownr_ea,
|
||||||
ownr_ln: item.job.ownr_ln,
|
ownr_fn: item.job.ownr_fn,
|
||||||
ownr_ph1: item.job.ownr_ph1,
|
ownr_ln: item.job.ownr_ln,
|
||||||
ownr_ph2: item.job.ownr_ph2,
|
ownr_ph1: item.job.ownr_ph1,
|
||||||
production_vars: item.job.production_vars,
|
ownr_ph2: item.job.ownr_ph2,
|
||||||
ro_number: item.job.ro_number,
|
production_vars: item.job.production_vars,
|
||||||
suspended: item.job.suspended,
|
ro_number: item.job.ro_number,
|
||||||
v_make_desc: item.job.v_make_desc,
|
suspended: item.job.suspended,
|
||||||
v_model_desc: item.job.v_model_desc,
|
v_make_desc: item.job.v_make_desc,
|
||||||
v_model_yr: item.job.v_model_yr,
|
v_model_desc: item.job.v_model_desc,
|
||||||
v_vin: item.job.v_vin,
|
v_model_yr: item.job.v_model_yr,
|
||||||
vehicleid: item.job.vehicleid,
|
v_vin: item.job.v_vin,
|
||||||
note: item.note,
|
vehicleid: item.job.vehicleid,
|
||||||
start: moment(item.start).format("hh:mm a"),
|
note: item.note,
|
||||||
title: item.title,
|
start: moment(item.start).format("hh:mm a"),
|
||||||
};
|
title: item.title,
|
||||||
appt.push(i);
|
};
|
||||||
|
appt.push(i);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
appt.sort(function (a, b) {
|
||||||
|
return new moment(a.start) - new moment(b.start);
|
||||||
});
|
});
|
||||||
appt.sort ( function (a, b) { return new Date(a.start) - new Date(b.start); });
|
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
@@ -182,7 +186,12 @@ export default function DashboardScheduledInToday({ data, ...cardProps }) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card title={t("dashboard.titles.scheduledintoday", {date: moment().startOf("day").format("MM/DD/YYYY")})} {...cardProps}>
|
<Card
|
||||||
|
title={t("dashboard.titles.scheduledintoday", {
|
||||||
|
date: moment().startOf("day").format("MM/DD/YYYY"),
|
||||||
|
})}
|
||||||
|
{...cardProps}
|
||||||
|
>
|
||||||
<div style={{ height: "100%" }}>
|
<div style={{ height: "100%" }}>
|
||||||
<Table
|
<Table
|
||||||
onChange={handleTableChange}
|
onChange={handleTableChange}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export default function DataLabel({
|
|||||||
<div {...props} style={{ display: "flex" }}>
|
<div {...props} style={{ display: "flex" }}>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
flex: 2,
|
// flex: 2,
|
||||||
marginRight: ".2rem",
|
marginRight: ".2rem",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -40,22 +40,22 @@ class ErrorBoundary extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleErrorSubmit = () => {
|
handleErrorSubmit = () => {
|
||||||
window.$crisp.push([
|
// window.$crisp.push([
|
||||||
"do",
|
// "do",
|
||||||
"message:send",
|
// "message:send",
|
||||||
[
|
// [
|
||||||
"text",
|
// "text",
|
||||||
`I hit the following error: \n\n
|
// `I hit the following error: \n\n
|
||||||
${this.state.error.message}\n\n
|
// ${this.state.error.message}\n\n
|
||||||
${this.state.error.stack}\n\n
|
// ${this.state.error.stack}\n\n
|
||||||
URL:${window.location} as ${this.props.currentUser.email} for ${
|
// URL:${window.location} as ${this.props.currentUser.email} for ${
|
||||||
this.props.bodyshop && this.props.bodyshop.name
|
// this.props.bodyshop && this.props.bodyshop.name
|
||||||
}
|
// }
|
||||||
`,
|
// `,
|
||||||
],
|
// ],
|
||||||
]);
|
// ]);
|
||||||
|
|
||||||
window.$crisp.push(["do", "chat:open"]);
|
// window.$crisp.push(["do", "chat:open"]);
|
||||||
// const errorDescription = `**Please add relevant details about what you were doing before you encountered this issue**
|
// const errorDescription = `**Please add relevant details about what you were doing before you encountered this issue**
|
||||||
|
|
||||||
// ----
|
// ----
|
||||||
|
|||||||
@@ -97,6 +97,11 @@ function Header({
|
|||||||
{},
|
{},
|
||||||
bodyshop && bodyshop.imexshopid
|
bodyshop && bodyshop.imexshopid
|
||||||
);
|
);
|
||||||
|
const { ImEXPay } = useTreatments(
|
||||||
|
["ImEXPay"],
|
||||||
|
{},
|
||||||
|
bodyshop && bodyshop.imexshopid
|
||||||
|
);
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
@@ -243,19 +248,20 @@ function Header({
|
|||||||
>
|
>
|
||||||
{t("menus.header.enterpayment")}
|
{t("menus.header.enterpayment")}
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
{/* TODO: Enter Card Payment */}
|
{ImEXPay.treatment === "on" && (
|
||||||
<Menu.Item
|
<Menu.Item
|
||||||
key="entercardpayments"
|
key="entercardpayments"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setCardPaymentContext({
|
setCardPaymentContext({
|
||||||
actions: {},
|
actions: {},
|
||||||
context: null,
|
context: {},
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
icon={<Icon component={FaCreditCard} />}
|
icon={<Icon component={FaCreditCard} />}
|
||||||
>
|
>
|
||||||
{t("menus.header.entercardpayment")}
|
{t("menus.header.entercardpayment")}
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
|
)}
|
||||||
<Menu.Divider key="div5" />
|
<Menu.Divider key="div5" />
|
||||||
<Menu.Item key="timetickets" icon={<FieldTimeOutlined />}>
|
<Menu.Item key="timetickets" icon={<FieldTimeOutlined />}>
|
||||||
<Link to="/manage/timetickets">
|
<Link to="/manage/timetickets">
|
||||||
@@ -383,20 +389,12 @@ function Header({
|
|||||||
<Menu.Item
|
<Menu.Item
|
||||||
key="help"
|
key="help"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
window.open("https://help.imex.online/", "_blank");
|
window.open("https://rometech.com/", "_blank");
|
||||||
}}
|
}}
|
||||||
icon={<Icon component={QuestionCircleFilled} />}
|
icon={<Icon component={QuestionCircleFilled} />}
|
||||||
>
|
>
|
||||||
{t("menus.header.help")}
|
{t("menus.header.help")}
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item
|
|
||||||
key="rescue"
|
|
||||||
onClick={() => {
|
|
||||||
window.open("https://imexrescue.com/", "_blank");
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{t("menus.header.rescueme")}
|
|
||||||
</Menu.Item>
|
|
||||||
<Menu.Item key="shiftclock">
|
<Menu.Item key="shiftclock">
|
||||||
<Link to="/manage/shiftclock">{t("menus.header.shiftclock")}</Link>
|
<Link to="/manage/shiftclock">{t("menus.header.shiftclock")}</Link>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { useTranslation } from "react-i18next";
|
|||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import { SEARCH_VENDOR_AUTOCOMPLETE_WITH_ADDR } from "../../graphql/vendors.queries";
|
import { SEARCH_VENDOR_AUTOCOMPLETE_WITH_ADDR } from "../../graphql/vendors.queries";
|
||||||
|
import { selectTechnician } from "../../redux/tech/tech.selectors";
|
||||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
import { GenerateDocument } from "../../utils/RenderTemplate";
|
import { GenerateDocument } from "../../utils/RenderTemplate";
|
||||||
import { TemplateList } from "../../utils/TemplateConstants";
|
import { TemplateList } from "../../utils/TemplateConstants";
|
||||||
@@ -13,13 +14,14 @@ import VendorSearchSelect from "../vendor-search-select/vendor-search-select.com
|
|||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop,
|
bodyshop: selectBodyshop,
|
||||||
|
technician: selectTechnician,
|
||||||
});
|
});
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||||
});
|
});
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(Jobd3RdPartyModal);
|
export default connect(mapStateToProps, mapDispatchToProps)(Jobd3RdPartyModal);
|
||||||
|
|
||||||
export function Jobd3RdPartyModal({ bodyshop, jobId, job }) {
|
export function Jobd3RdPartyModal({ bodyshop, jobId, job, technician }) {
|
||||||
const [isModalVisible, setIsModalVisible] = useState(false);
|
const [isModalVisible, setIsModalVisible] = useState(false);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
@@ -212,7 +214,9 @@ export function Jobd3RdPartyModal({ bodyshop, jobId, job }) {
|
|||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<Radio.Group>
|
<Radio.Group>
|
||||||
<Radio value={"e"}>{t("parts_orders.labels.email")}</Radio>
|
{!technician ? (
|
||||||
|
<Radio value={"e"}>{t("parts_orders.labels.email")}</Radio>
|
||||||
|
) : null}
|
||||||
<Radio value={"p"}>{t("parts_orders.labels.print")}</Radio>
|
<Radio value={"p"}>{t("parts_orders.labels.print")}</Radio>
|
||||||
</Radio.Group>
|
</Radio.Group>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|||||||
@@ -29,11 +29,11 @@ import { GenerateDocument } from "../../utils/RenderTemplate";
|
|||||||
import { TemplateList } from "../../utils/TemplateConstants";
|
import { TemplateList } from "../../utils/TemplateConstants";
|
||||||
import ChatOpenButton from "../chat-open-button/chat-open-button.component";
|
import ChatOpenButton from "../chat-open-button/chat-open-button.component";
|
||||||
import DataLabel from "../data-label/data-label.component";
|
import DataLabel from "../data-label/data-label.component";
|
||||||
|
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
|
||||||
import ScheduleManualEvent from "../schedule-manual-event/schedule-manual-event.component";
|
import ScheduleManualEvent from "../schedule-manual-event/schedule-manual-event.component";
|
||||||
import ScheduleAtChange from "./job-at-change.component";
|
import ScheduleAtChange from "./job-at-change.component";
|
||||||
import ScheduleEventColor from "./schedule-event.color.component";
|
import ScheduleEventColor from "./schedule-event.color.component";
|
||||||
import ScheduleEventNote from "./schedule-event.note.component";
|
import ScheduleEventNote from "./schedule-event.note.component";
|
||||||
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
|
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop,
|
bodyshop: selectBodyshop,
|
||||||
@@ -208,46 +208,56 @@ export function ScheduleEventComponent({
|
|||||||
<Button>{t("appointments.actions.sendreminder")}</Button>
|
<Button>{t("appointments.actions.sendreminder")}</Button>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
) : null}
|
) : null}
|
||||||
<Popover
|
{event.arrived ? (
|
||||||
trigger="click"
|
|
||||||
disabled={event.arrived}
|
|
||||||
content={
|
|
||||||
<Form
|
|
||||||
layout="vertical"
|
|
||||||
onFinish={({ lost_sale_reason }) => {
|
|
||||||
handleCancel({ id: event.id, lost_sale_reason });
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Form.Item
|
|
||||||
name="lost_sale_reason"
|
|
||||||
label={t("jobs.fields.lost_sale_reason")}
|
|
||||||
rules={[
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
//message: t("general.validation.required"),
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<Select
|
|
||||||
options={bodyshop.md_lost_sale_reasons.map((lsr) => ({
|
|
||||||
label: lsr,
|
|
||||||
value: lsr,
|
|
||||||
}))}
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
|
||||||
<Button htmlType="submit">
|
|
||||||
{t("appointments.actions.cancel")}
|
|
||||||
</Button>
|
|
||||||
</Form>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Button
|
<Button
|
||||||
// onClick={() => handleCancel(event.id)}
|
// onClick={() => handleCancel(event.id)}
|
||||||
disabled={event.arrived}
|
disabled={event.arrived}
|
||||||
>
|
>
|
||||||
{t("appointments.actions.cancel")}
|
{t("appointments.actions.cancel")}
|
||||||
</Button>
|
</Button>
|
||||||
</Popover>
|
) : (
|
||||||
|
<Popover
|
||||||
|
trigger="click"
|
||||||
|
disabled={event.arrived}
|
||||||
|
content={
|
||||||
|
<Form
|
||||||
|
layout="vertical"
|
||||||
|
onFinish={({ lost_sale_reason }) => {
|
||||||
|
handleCancel({ id: event.id, lost_sale_reason });
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Form.Item
|
||||||
|
name="lost_sale_reason"
|
||||||
|
label={t("jobs.fields.lost_sale_reason")}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
//message: t("general.validation.required"),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Select
|
||||||
|
options={bodyshop.md_lost_sale_reasons.map((lsr) => ({
|
||||||
|
label: lsr,
|
||||||
|
value: lsr,
|
||||||
|
}))}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<Button htmlType="submit">
|
||||||
|
{t("appointments.actions.cancel")}
|
||||||
|
</Button>
|
||||||
|
</Form>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
// onClick={() => handleCancel(event.id)}
|
||||||
|
disabled={event.arrived}
|
||||||
|
>
|
||||||
|
{t("appointments.actions.cancel")}
|
||||||
|
</Button>
|
||||||
|
</Popover>
|
||||||
|
)}
|
||||||
|
|
||||||
{event.isintake ? (
|
{event.isintake ? (
|
||||||
<Button
|
<Button
|
||||||
disabled={event.arrived}
|
disabled={event.arrived}
|
||||||
|
|||||||
@@ -86,6 +86,10 @@ export function JobLinesComponent({
|
|||||||
bodyshop.imexshopid
|
bodyshop.imexshopid
|
||||||
);
|
);
|
||||||
const [selectedLines, setSelectedLines] = useState([]);
|
const [selectedLines, setSelectedLines] = useState([]);
|
||||||
|
console.log(
|
||||||
|
"🚀 ~ file: job-lines.component.jsx:89 ~ selectedLines:",
|
||||||
|
selectedLines
|
||||||
|
);
|
||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
sortedInfo: {},
|
sortedInfo: {},
|
||||||
filteredInfo: {},
|
filteredInfo: {},
|
||||||
@@ -114,9 +118,7 @@ export function JobLinesComponent({
|
|||||||
onCell: (record) => ({
|
onCell: (record) => ({
|
||||||
className: record.manual_line && "job-line-manual",
|
className: record.manual_line && "job-line-manual",
|
||||||
style: {
|
style: {
|
||||||
...(record.critical || true
|
...(record.critical ? { boxShadow: " -.5em 0 0 #FFC107" } : {}),
|
||||||
? { boxShadow: " -.5em 0 0 #FFC107" }
|
|
||||||
: {}),
|
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
sortOrder:
|
sortOrder:
|
||||||
@@ -134,7 +136,7 @@ export function JobLinesComponent({
|
|||||||
onCell: (record) => ({
|
onCell: (record) => ({
|
||||||
className: record.manual_line && "job-line-manual",
|
className: record.manual_line && "job-line-manual",
|
||||||
style: {
|
style: {
|
||||||
...(record.parts_dispatch_lines[0]?.accepted_at || true
|
...(record.parts_dispatch_lines[0]?.accepted_at
|
||||||
? { boxShadow: " -.5em 0 0 #FFC107" }
|
? { boxShadow: " -.5em 0 0 #FFC107" }
|
||||||
: {}),
|
: {}),
|
||||||
},
|
},
|
||||||
@@ -426,7 +428,7 @@ export function JobLinesComponent({
|
|||||||
const markedTypes = [e.key];
|
const markedTypes = [e.key];
|
||||||
if (e.key === "PAN") markedTypes.push("PAP");
|
if (e.key === "PAN") markedTypes.push("PAP");
|
||||||
if (e.key === "PAS") markedTypes.push("PASL");
|
if (e.key === "PAS") markedTypes.push("PASL");
|
||||||
setSelectedLines(
|
setSelectedLines((selectedLines) =>
|
||||||
_.uniq([
|
_.uniq([
|
||||||
...selectedLines,
|
...selectedLines,
|
||||||
...jobLines.filter(
|
...jobLines.filter(
|
||||||
@@ -664,8 +666,17 @@ export function JobLinesComponent({
|
|||||||
onSelectAll: (selected, selectedRows, changeRows) => {
|
onSelectAll: (selected, selectedRows, changeRows) => {
|
||||||
setSelectedLines(selectedRows);
|
setSelectedLines(selectedRows);
|
||||||
},
|
},
|
||||||
onSelect: (record, selected, selectedRows, nativeEvent) =>
|
onSelect: (record, selected, selectedRows, nativeEvent) => {
|
||||||
setSelectedLines(selectedRows),
|
if (selected) {
|
||||||
|
setSelectedLines((selectedLines) =>
|
||||||
|
_.uniqBy([...selectedLines, record], "id")
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
setSelectedLines((selectedLines) =>
|
||||||
|
selectedLines.filter((l) => l.id !== record.id)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ export function JoblineBulkAssign({
|
|||||||
hours.toFixed(1)
|
hours.toFixed(1)
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
setSelectedLines([]);
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -1,26 +1,26 @@
|
|||||||
import { Button, Card, Space, Table } from "antd";
|
|
||||||
import { EditFilled } from "@ant-design/icons";
|
import { EditFilled } from "@ant-design/icons";
|
||||||
|
import { Button, Card, Space, Table } from "antd";
|
||||||
import Dinero from "dinero.js";
|
import Dinero from "dinero.js";
|
||||||
import React, { useMemo, useState } from "react";
|
import React, { useMemo, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import { selectJobReadOnly } from "../../redux/application/application.selectors";
|
import { selectJobReadOnly } from "../../redux/application/application.selectors";
|
||||||
|
import {
|
||||||
|
openChatByPhone,
|
||||||
|
setMessage,
|
||||||
|
} from "../../redux/messaging/messaging.actions";
|
||||||
import { setModalContext } from "../../redux/modals/modals.actions";
|
import { setModalContext } from "../../redux/modals/modals.actions";
|
||||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
||||||
import { DateFormatter } from "../../utils/DateFormatter";
|
import { DateFormatter } from "../../utils/DateFormatter";
|
||||||
import { alphaSort, dateSort } from "../../utils/sorters";
|
|
||||||
import { TemplateList } from "../../utils/TemplateConstants";
|
import { TemplateList } from "../../utils/TemplateConstants";
|
||||||
|
import { alphaSort, dateSort } from "../../utils/sorters";
|
||||||
import DataLabel from "../data-label/data-label.component";
|
import DataLabel from "../data-label/data-label.component";
|
||||||
import PrintWrapperComponent from "../print-wrapper/print-wrapper.component";
|
|
||||||
import PaymentExpandedRowComponent from "../payment-expanded-row/payment-expanded-row.component";
|
import PaymentExpandedRowComponent from "../payment-expanded-row/payment-expanded-row.component";
|
||||||
import {
|
import PaymentsGenerateLink from "../payments-generate-link/payments-generate-link.component";
|
||||||
setMessage,
|
import PrintWrapperComponent from "../print-wrapper/print-wrapper.component";
|
||||||
openChatByPhone,
|
import { useTreatments } from "@splitsoftware/splitio-react";
|
||||||
} from "../../redux/messaging/messaging.actions";
|
|
||||||
import { parsePhoneNumber } from "libphonenumber-js";
|
|
||||||
import axios from "axios";
|
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop,
|
bodyshop: selectBodyshop,
|
||||||
@@ -46,12 +46,17 @@ export function JobPayments({
|
|||||||
setCardPaymentContext,
|
setCardPaymentContext,
|
||||||
refetch,
|
refetch,
|
||||||
}) {
|
}) {
|
||||||
|
const { ImEXPay } = useTreatments(
|
||||||
|
["ImEXPay"],
|
||||||
|
{},
|
||||||
|
bodyshop && bodyshop.imexshopid
|
||||||
|
);
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
sortedInfo: {},
|
sortedInfo: {},
|
||||||
filteredInfo: {},
|
filteredInfo: {},
|
||||||
});
|
});
|
||||||
const [generatingURL, setGeneratingtURL] = useState(false);
|
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
@@ -165,39 +170,21 @@ export function JobPayments({
|
|||||||
title={t("payments.labels.title")}
|
title={t("payments.labels.title")}
|
||||||
extra={
|
extra={
|
||||||
<Space wrap>
|
<Space wrap>
|
||||||
<Button
|
{ImEXPay.treatment === "on" && (
|
||||||
disabled={!job.converted}
|
<>
|
||||||
loading={generatingURL}
|
<Button
|
||||||
onClick={async () => {
|
onClick={() =>
|
||||||
const p = parsePhoneNumber(job.ownr_ph1, "CA");
|
setCardPaymentContext({
|
||||||
setGeneratingtURL(true);
|
actions: { refetch },
|
||||||
const response = await axios.post(
|
context: { jobid: job.id, balance },
|
||||||
"/intellipay/generate_payment_url",
|
})
|
||||||
{
|
|
||||||
bodyshop,
|
|
||||||
amount: balance.getAmount(),
|
|
||||||
account: job.ro_number,
|
|
||||||
}
|
}
|
||||||
);
|
>
|
||||||
setGeneratingtURL(false);
|
{t("menus.header.entercardpayment")}
|
||||||
|
</Button>
|
||||||
console.log("SMS", response);
|
<PaymentsGenerateLink job={job} />
|
||||||
|
</>
|
||||||
openChatByPhone({
|
)}
|
||||||
phone_num: p.formatInternational(),
|
|
||||||
jobid: job.id,
|
|
||||||
});
|
|
||||||
setMessage(
|
|
||||||
t("appointments.labels.smspaymentreminder", {
|
|
||||||
shopname: bodyshop.shopname,
|
|
||||||
amount: balance.toFormat(),
|
|
||||||
payment_link: response.data.shorUrl,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{t("menus.header.paymentremindersms")}
|
|
||||||
</Button>
|
|
||||||
<Button
|
<Button
|
||||||
disabled={!job.converted}
|
disabled={!job.converted}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
@@ -209,16 +196,7 @@ export function JobPayments({
|
|||||||
>
|
>
|
||||||
{t("menus.header.enterpayment")}
|
{t("menus.header.enterpayment")}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
|
||||||
onClick={() =>
|
|
||||||
setCardPaymentContext({
|
|
||||||
actions: { refetch },
|
|
||||||
context: { jobid: job.id, balance },
|
|
||||||
})
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{t("menus.header.entercardpayment")}
|
|
||||||
</Button>
|
|
||||||
<DataLabel
|
<DataLabel
|
||||||
valueStyle={{ color: balance.getAmount() !== 0 ? "red" : "green" }}
|
valueStyle={{ color: balance.getAmount() !== 0 ? "red" : "green" }}
|
||||||
label={t("payments.labels.balance")}
|
label={t("payments.labels.balance")}
|
||||||
|
|||||||
@@ -6,8 +6,9 @@ import {
|
|||||||
useQuery,
|
useQuery,
|
||||||
} from "@apollo/client";
|
} from "@apollo/client";
|
||||||
import { useTreatments } from "@splitsoftware/splitio-react";
|
import { useTreatments } from "@splitsoftware/splitio-react";
|
||||||
import { Col, notification, Row } from "antd";
|
import { Col, Row, notification } from "antd";
|
||||||
import Axios from "axios";
|
import Axios from "axios";
|
||||||
|
import _ from "lodash";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import queryString from "query-string";
|
import queryString from "query-string";
|
||||||
import React, { useCallback, useEffect, useState } from "react";
|
import React, { useCallback, useEffect, useState } from "react";
|
||||||
@@ -29,8 +30,8 @@ import {
|
|||||||
selectBodyshop,
|
selectBodyshop,
|
||||||
selectCurrentUser,
|
selectCurrentUser,
|
||||||
} from "../../redux/user/user.selectors";
|
} from "../../redux/user/user.selectors";
|
||||||
import confirmDialog from "../../utils/asyncConfirm";
|
|
||||||
import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
||||||
|
import confirmDialog from "../../utils/asyncConfirm";
|
||||||
import CriticalPartsScan from "../../utils/criticalPartsScan";
|
import CriticalPartsScan from "../../utils/criticalPartsScan";
|
||||||
import AlertComponent from "../alert/alert.component";
|
import AlertComponent from "../alert/alert.component";
|
||||||
import JobsAvailableScan from "../jobs-available-scan/jobs-available-scan.component";
|
import JobsAvailableScan from "../jobs-available-scan/jobs-available-scan.component";
|
||||||
@@ -40,7 +41,6 @@ import OwnerFindModalContainer from "../owner-find-modal/owner-find-modal.contai
|
|||||||
import { GetSupplementDelta } from "./jobs-available-supplement.estlines.util";
|
import { GetSupplementDelta } from "./jobs-available-supplement.estlines.util";
|
||||||
import HeaderFields from "./jobs-available-supplement.headerfields";
|
import HeaderFields from "./jobs-available-supplement.headerfields";
|
||||||
import JobsAvailableTableComponent from "./jobs-available-table.component";
|
import JobsAvailableTableComponent from "./jobs-available-table.component";
|
||||||
import _ from "lodash";
|
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop,
|
bodyshop: selectBodyshop,
|
||||||
@@ -139,6 +139,7 @@ export function JobsAvailableContainer({
|
|||||||
// owner_owing: Dinero(newTotals.totals.custPayable.total).toFormat("0.00"),
|
// owner_owing: Dinero(newTotals.totals.custPayable.total).toFormat("0.00"),
|
||||||
// job_totals: newTotals,
|
// job_totals: newTotals,
|
||||||
date_open: moment(),
|
date_open: moment(),
|
||||||
|
status: bodyshop.md_ro_statuses.default_imported,
|
||||||
notes: {
|
notes: {
|
||||||
data: {
|
data: {
|
||||||
created_by: currentUser.email,
|
created_by: currentUser.email,
|
||||||
@@ -160,6 +161,10 @@ export function JobsAvailableContainer({
|
|||||||
delete newJob.vehicle;
|
delete newJob.vehicle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeof newJob.kmin === "string") {
|
||||||
|
newJob.kmin = null;
|
||||||
|
}
|
||||||
|
|
||||||
insertNewJob({
|
insertNewJob({
|
||||||
variables: {
|
variables: {
|
||||||
job: newJob,
|
job: newJob,
|
||||||
|
|||||||
@@ -4,22 +4,35 @@ import axios from "axios";
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
|
import { useHistory } from "react-router-dom";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import { auth } from "../../firebase/firebase.utils";
|
import { auth, logImEXEvent } from "../../firebase/firebase.utils";
|
||||||
|
import { INSERT_EXPORT_LOG } from "../../graphql/accounting.queries";
|
||||||
import { UPDATE_JOB } from "../../graphql/jobs.queries";
|
import { UPDATE_JOB } from "../../graphql/jobs.queries";
|
||||||
import {
|
import {
|
||||||
selectBodyshop,
|
selectBodyshop,
|
||||||
selectCurrentUser,
|
selectCurrentUser,
|
||||||
} from "../../redux/user/user.selectors";
|
} from "../../redux/user/user.selectors";
|
||||||
import { logImEXEvent } from "../../firebase/firebase.utils";
|
import client from "../../utils/GraphQLClient";
|
||||||
import { INSERT_EXPORT_LOG } from "../../graphql/accounting.queries";
|
|
||||||
import { useHistory } from "react-router-dom";
|
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop,
|
bodyshop: selectBodyshop,
|
||||||
currentUser: selectCurrentUser,
|
currentUser: selectCurrentUser,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function updateJobCache(items) {
|
||||||
|
client.cache.modify({
|
||||||
|
id: "ROOT_QUERY",
|
||||||
|
fields: {
|
||||||
|
jobs(existingJobs = []) {
|
||||||
|
return existingJobs.filter(
|
||||||
|
(jobRef) => jobRef.__ref.includes(items) === false
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function JobsCloseExportButton({
|
export function JobsCloseExportButton({
|
||||||
bodyshop,
|
bodyshop,
|
||||||
currentUser,
|
currentUser,
|
||||||
@@ -101,6 +114,9 @@ export function JobsCloseExportButton({
|
|||||||
|
|
||||||
//Check to see if any of them failed. If they didn't don't execute the update.
|
//Check to see if any of them failed. If they didn't don't execute the update.
|
||||||
const failedTransactions = PartnerResponse.data.filter((r) => !r.success);
|
const failedTransactions = PartnerResponse.data.filter((r) => !r.success);
|
||||||
|
const successfulTransactions = PartnerResponse.data.filter(
|
||||||
|
(r) => r.success
|
||||||
|
);
|
||||||
if (failedTransactions.length > 0) {
|
if (failedTransactions.length > 0) {
|
||||||
//Uh oh. At least one was no good.
|
//Uh oh. At least one was no good.
|
||||||
failedTransactions.forEach((ft) => {
|
failedTransactions.forEach((ft) => {
|
||||||
@@ -159,12 +175,15 @@ export function JobsCloseExportButton({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!jobUpdateResponse.errors) {
|
if (!!!jobUpdateResponse.errors) {
|
||||||
notification.open({
|
notification.open({
|
||||||
type: "success",
|
type: "success",
|
||||||
key: "jobsuccessexport",
|
key: "jobsuccessexport",
|
||||||
message: t("jobs.successes.exported"),
|
message: t("jobs.successes.exported"),
|
||||||
});
|
});
|
||||||
|
updateJobCache(
|
||||||
|
jobUpdateResponse.data.update_jobs.returning.map((job) => job.id)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
notification["error"]({
|
notification["error"]({
|
||||||
message: t("jobs.errors.exporting", {
|
message: t("jobs.errors.exporting", {
|
||||||
@@ -173,13 +192,31 @@ export function JobsCloseExportButton({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo && successfulTransactions.length > 0) {
|
||||||
|
notification.open({
|
||||||
|
type: "success",
|
||||||
|
key: "jobsuccessexport",
|
||||||
|
message: t("jobs.successes.exported"),
|
||||||
|
});
|
||||||
|
updateJobCache([
|
||||||
|
...new Set(
|
||||||
|
successfulTransactions.map(
|
||||||
|
(st) =>
|
||||||
|
st[
|
||||||
|
bodyshop.accountingconfig && bodyshop.accountingconfig.qbo
|
||||||
|
? "jobid"
|
||||||
|
: "id"
|
||||||
|
]
|
||||||
|
)
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
}
|
||||||
if (setSelectedJobs) {
|
if (setSelectedJobs) {
|
||||||
setSelectedJobs((selectedJobs) => {
|
setSelectedJobs((selectedJobs) => {
|
||||||
return selectedJobs.filter((i) => i !== jobId);
|
return selectedJobs.filter((i) => i !== jobId);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo) refetch();
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -143,63 +143,67 @@ export function JobsDetailHeaderActions({
|
|||||||
<Menu.Item
|
<Menu.Item
|
||||||
disabled={job.status !== bodyshop.md_ro_statuses.default_scheduled}
|
disabled={job.status !== bodyshop.md_ro_statuses.default_scheduled}
|
||||||
>
|
>
|
||||||
<Popover
|
{job.status !== bodyshop.md_ro_statuses.default_scheduled ? (
|
||||||
trigger="click"
|
t("menus.jobsactions.cancelallappointments")
|
||||||
disabled={job.status !== bodyshop.md_ro_statuses.default_scheduled}
|
) : (
|
||||||
content={
|
<Popover
|
||||||
<Form
|
trigger="click"
|
||||||
layout="vertical"
|
disabled={job.status !== bodyshop.md_ro_statuses.default_scheduled}
|
||||||
onFinish={async ({ lost_sale_reason }) => {
|
content={
|
||||||
const jobUpdate = await cancelAllAppointments({
|
<Form
|
||||||
variables: {
|
layout="vertical"
|
||||||
jobid: job.id,
|
onFinish={async ({ lost_sale_reason }) => {
|
||||||
job: {
|
const jobUpdate = await cancelAllAppointments({
|
||||||
date_scheduled: null,
|
variables: {
|
||||||
scheduled_in: null,
|
jobid: job.id,
|
||||||
scheduled_completion: null,
|
job: {
|
||||||
lost_sale_reason,
|
date_scheduled: null,
|
||||||
status: bodyshop.md_ro_statuses.default_imported,
|
scheduled_in: null,
|
||||||
|
scheduled_completion: null,
|
||||||
|
lost_sale_reason,
|
||||||
|
status: bodyshop.md_ro_statuses.default_imported,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
|
||||||
});
|
|
||||||
if (!jobUpdate.errors) {
|
|
||||||
notification["success"]({
|
|
||||||
message: t("appointments.successes.canceled"),
|
|
||||||
});
|
});
|
||||||
return;
|
if (!jobUpdate.errors) {
|
||||||
}
|
notification["success"]({
|
||||||
}}
|
message: t("appointments.successes.canceled"),
|
||||||
>
|
});
|
||||||
<Form.Item
|
return;
|
||||||
name="lost_sale_reason"
|
}
|
||||||
label={t("jobs.fields.lost_sale_reason")}
|
}}
|
||||||
rules={[
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
//message: t("general.validation.required"),
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
>
|
>
|
||||||
<Select
|
<Form.Item
|
||||||
options={bodyshop.md_lost_sale_reasons.map((lsr) => ({
|
name="lost_sale_reason"
|
||||||
label: lsr,
|
label={t("jobs.fields.lost_sale_reason")}
|
||||||
value: lsr,
|
rules={[
|
||||||
}))}
|
{
|
||||||
/>
|
required: true,
|
||||||
</Form.Item>
|
//message: t("general.validation.required"),
|
||||||
<Button
|
},
|
||||||
htmlType="submit"
|
]}
|
||||||
disabled={
|
>
|
||||||
job.status !== bodyshop.md_ro_statuses.default_scheduled
|
<Select
|
||||||
}
|
options={bodyshop.md_lost_sale_reasons.map((lsr) => ({
|
||||||
>
|
label: lsr,
|
||||||
{t("appointments.actions.cancel")}
|
value: lsr,
|
||||||
</Button>
|
}))}
|
||||||
</Form>
|
/>
|
||||||
}
|
</Form.Item>
|
||||||
>
|
<Button
|
||||||
{t("menus.jobsactions.cancelallappointments")}
|
htmlType="submit"
|
||||||
</Popover>
|
disabled={
|
||||||
|
job.status !== bodyshop.md_ro_statuses.default_scheduled
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{t("appointments.actions.cancel")}
|
||||||
|
</Button>
|
||||||
|
</Form>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{t("menus.jobsactions.cancelallappointments")}
|
||||||
|
</Popover>
|
||||||
|
)}
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item
|
<Menu.Item
|
||||||
disabled={
|
disabled={
|
||||||
@@ -245,7 +249,12 @@ export function JobsDetailHeaderActions({
|
|||||||
|
|
||||||
setTimeTicketContext({
|
setTimeTicketContext({
|
||||||
actions: {},
|
actions: {},
|
||||||
context: { jobId: job.id },
|
context: {
|
||||||
|
jobId: job.id,
|
||||||
|
created_by: currentUser.displayName
|
||||||
|
? currentUser.email.concat(" | ", currentUser.displayName)
|
||||||
|
: currentUser.email,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -13,12 +13,26 @@ import {
|
|||||||
selectBodyshop,
|
selectBodyshop,
|
||||||
selectCurrentUser,
|
selectCurrentUser,
|
||||||
} from "../../redux/user/user.selectors";
|
} from "../../redux/user/user.selectors";
|
||||||
|
import client from "../../utils/GraphQLClient";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop,
|
bodyshop: selectBodyshop,
|
||||||
currentUser: selectCurrentUser,
|
currentUser: selectCurrentUser,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function updateJobCache(items) {
|
||||||
|
client.cache.modify({
|
||||||
|
id: "ROOT_QUERY",
|
||||||
|
fields: {
|
||||||
|
jobs(existingJobs = []) {
|
||||||
|
return existingJobs.filter(
|
||||||
|
(jobRef) => jobRef.__ref.includes(items) === false
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function JobsExportAllButton({
|
export function JobsExportAllButton({
|
||||||
bodyshop,
|
bodyshop,
|
||||||
currentUser,
|
currentUser,
|
||||||
@@ -96,7 +110,9 @@ export function JobsExportAllButton({
|
|||||||
Object.keys(groupedData).map(async (key) => {
|
Object.keys(groupedData).map(async (key) => {
|
||||||
//Check to see if any of them failed. If they didn't don't execute the update.
|
//Check to see if any of them failed. If they didn't don't execute the update.
|
||||||
const failedTransactions = groupedData[key].filter((r) => !r.success);
|
const failedTransactions = groupedData[key].filter((r) => !r.success);
|
||||||
|
const successfulTransactions = groupedData[key].filter(
|
||||||
|
(r) => r.success
|
||||||
|
);
|
||||||
if (failedTransactions.length > 0) {
|
if (failedTransactions.length > 0) {
|
||||||
//Uh oh. At least one was no good.
|
//Uh oh. At least one was no good.
|
||||||
failedTransactions.forEach((ft) => {
|
failedTransactions.forEach((ft) => {
|
||||||
@@ -155,12 +171,17 @@ export function JobsExportAllButton({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!jobUpdateResponse.errors) {
|
if (!!!jobUpdateResponse.errors) {
|
||||||
notification.open({
|
notification.open({
|
||||||
type: "success",
|
type: "success",
|
||||||
key: "jobsuccessexport",
|
key: "jobsuccessexport",
|
||||||
message: t("jobs.successes.exported"),
|
message: t("jobs.successes.exported"),
|
||||||
});
|
});
|
||||||
|
updateJobCache(
|
||||||
|
jobUpdateResponse.data.update_jobs.returning.map(
|
||||||
|
(job) => job.id
|
||||||
|
)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
notification["error"]({
|
notification["error"]({
|
||||||
message: t("jobs.errors.exporting", {
|
message: t("jobs.errors.exporting", {
|
||||||
@@ -169,14 +190,31 @@ export function JobsExportAllButton({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo && successfulTransactions.length > 0) {
|
||||||
|
notification.open({
|
||||||
|
type: "success",
|
||||||
|
key: "jobsuccessexport",
|
||||||
|
message: t("jobs.successes.exported"),
|
||||||
|
});
|
||||||
|
updateJobCache([
|
||||||
|
...new Set(
|
||||||
|
successfulTransactions.map(
|
||||||
|
(st) =>
|
||||||
|
st[
|
||||||
|
bodyshop.accountingconfig && bodyshop.accountingconfig.qbo
|
||||||
|
? "jobid"
|
||||||
|
: "id"
|
||||||
|
]
|
||||||
|
)
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo) refetch();
|
|
||||||
|
|
||||||
if (!!completedCallback) completedCallback([]);
|
if (!!completedCallback) completedCallback([]);
|
||||||
if (!!loadingCallback) loadingCallback(false);
|
if (!!loadingCallback) loadingCallback(false);
|
||||||
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { Link } from "react-router-dom";
|
|||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
||||||
|
import { alphaSort, statusSort } from "../../utils/sorters";
|
||||||
import OwnerDetailUpdateJobsComponent from "../owner-detail-update-jobs/owner-detail-update-jobs.component";
|
import OwnerDetailUpdateJobsComponent from "../owner-detail-update-jobs/owner-detail-update-jobs.component";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
@@ -15,6 +16,15 @@ const mapStateToProps = createStructuredSelector({
|
|||||||
function OwnerDetailJobsComponent({ bodyshop, owner }) {
|
function OwnerDetailJobsComponent({ bodyshop, owner }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [selectedJobs, setSelectedJobs] = useState([]);
|
const [selectedJobs, setSelectedJobs] = useState([]);
|
||||||
|
const [state, setState] = useState({
|
||||||
|
sortedInfo: {},
|
||||||
|
filteredInfo: { text: "" },
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleTableChange = (pagination, filters, sorter) => {
|
||||||
|
setState({ ...state, filteredInfo: filters, sortedInfo: sorter });
|
||||||
|
};
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: t("jobs.fields.ro_number"),
|
title: t("jobs.fields.ro_number"),
|
||||||
@@ -26,6 +36,9 @@ function OwnerDetailJobsComponent({ bodyshop, owner }) {
|
|||||||
{record.ro_number || t("general.labels.na")}
|
{record.ro_number || t("general.labels.na")}
|
||||||
</Link>
|
</Link>
|
||||||
),
|
),
|
||||||
|
sorter: (a, b) => alphaSort(a.ro_number, b.ro_number),
|
||||||
|
sortOrder:
|
||||||
|
state.sortedInfo.columnKey === "ro_number" && state.sortedInfo.order,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t("jobs.fields.vehicle"),
|
title: t("jobs.fields.vehicle"),
|
||||||
@@ -46,11 +59,17 @@ function OwnerDetailJobsComponent({ bodyshop, owner }) {
|
|||||||
title: t("jobs.fields.clm_no"),
|
title: t("jobs.fields.clm_no"),
|
||||||
dataIndex: "clm_no",
|
dataIndex: "clm_no",
|
||||||
key: "clm_no",
|
key: "clm_no",
|
||||||
|
sorter: (a, b) => alphaSort(a.clm_no, b.clm_no),
|
||||||
|
sortOrder:
|
||||||
|
state.sortedInfo.columnKey === "clm_no" && state.sortedInfo.order,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t("jobs.fields.status"),
|
title: t("jobs.fields.status"),
|
||||||
dataIndex: "status",
|
dataIndex: "status",
|
||||||
key: "status",
|
key: "status",
|
||||||
|
sorter: (a, b) => statusSort(a.status, b.status, bodyshop.md_ro_statuses.statuses),
|
||||||
|
sortOrder:
|
||||||
|
state.sortedInfo.columnKey === "status" && state.sortedInfo.order,
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -60,6 +79,9 @@ function OwnerDetailJobsComponent({ bodyshop, owner }) {
|
|||||||
render: (text, record) => (
|
render: (text, record) => (
|
||||||
<CurrencyFormatter>{record.clm_total}</CurrencyFormatter>
|
<CurrencyFormatter>{record.clm_total}</CurrencyFormatter>
|
||||||
),
|
),
|
||||||
|
sorter: (a, b) => a.clm_total - b.clm_total,
|
||||||
|
sortOrder:
|
||||||
|
state.sortedInfo.columnKey === "clm_total" && state.sortedInfo.order,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -80,6 +102,7 @@ function OwnerDetailJobsComponent({ bodyshop, owner }) {
|
|||||||
scroll={{ x: true }}
|
scroll={{ x: true }}
|
||||||
rowKey="id"
|
rowKey="id"
|
||||||
dataSource={owner.jobs}
|
dataSource={owner.jobs}
|
||||||
|
onChange={handleTableChange}
|
||||||
rowSelection={{
|
rowSelection={{
|
||||||
onSelect: (record, selected, selectedRows) => {
|
onSelect: (record, selected, selectedRows) => {
|
||||||
setSelectedJobs(selectedRows ? selectedRows.map((i) => i.id) : []);
|
setSelectedJobs(selectedRows ? selectedRows.map((i) => i.id) : []);
|
||||||
|
|||||||
@@ -113,6 +113,8 @@ export function PartsOrderListTableComponent({
|
|||||||
id: pol.id,
|
id: pol.id,
|
||||||
line_desc: pol.line_desc,
|
line_desc: pol.line_desc,
|
||||||
quantity: pol.quantity,
|
quantity: pol.quantity,
|
||||||
|
act_price: pol.act_price,
|
||||||
|
oem_partno: pol.oem_partno,
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -79,6 +79,20 @@ export function PartsReceiveModalComponent({ bodyshop, form }) {
|
|||||||
>
|
>
|
||||||
<Input />
|
<Input />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("joblines.fields.oem_partno")}
|
||||||
|
key={`${index}oem_partno`}
|
||||||
|
name={[field.name, "oem_partno"]}
|
||||||
|
>
|
||||||
|
<Input disabled />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("joblines.fields.act_price")}
|
||||||
|
key={`${index}act_price`}
|
||||||
|
name={[field.name, "act_price"]}
|
||||||
|
>
|
||||||
|
<Input disabled />
|
||||||
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("joblines.fields.location")}
|
label={t("joblines.fields.location")}
|
||||||
key={`${index}location`}
|
key={`${index}location`}
|
||||||
|
|||||||
@@ -1,26 +1,39 @@
|
|||||||
import { useMutation } from "@apollo/client";
|
import { useMutation } from "@apollo/client";
|
||||||
import { Button, notification } from "antd";
|
import { Button, notification } from "antd";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
import _ from "lodash";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import { auth } from "../../firebase/firebase.utils";
|
import { auth, logImEXEvent } from "../../firebase/firebase.utils";
|
||||||
|
import { INSERT_EXPORT_LOG } from "../../graphql/accounting.queries";
|
||||||
import { UPDATE_BILLS } from "../../graphql/bills.queries";
|
import { UPDATE_BILLS } from "../../graphql/bills.queries";
|
||||||
import {
|
import {
|
||||||
selectBodyshop,
|
selectBodyshop,
|
||||||
selectCurrentUser,
|
selectCurrentUser,
|
||||||
} from "../../redux/user/user.selectors";
|
} from "../../redux/user/user.selectors";
|
||||||
import { logImEXEvent } from "../../firebase/firebase.utils";
|
import client from "../../utils/GraphQLClient";
|
||||||
import _ from "lodash";
|
|
||||||
import { INSERT_EXPORT_LOG } from "../../graphql/accounting.queries";
|
|
||||||
import { Link } from "react-router-dom";
|
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop,
|
bodyshop: selectBodyshop,
|
||||||
currentUser: selectCurrentUser,
|
currentUser: selectCurrentUser,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function updateBillCache(items) {
|
||||||
|
client.cache.modify({
|
||||||
|
id: "ROOT_QUERY",
|
||||||
|
fields: {
|
||||||
|
bills(existingJobs = []) {
|
||||||
|
return existingJobs.filter(
|
||||||
|
(billRef) => billRef.__ref.includes(items) === false
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function PayableExportAll({
|
export function PayableExportAll({
|
||||||
bodyshop,
|
bodyshop,
|
||||||
currentUser,
|
currentUser,
|
||||||
@@ -97,7 +110,9 @@ export function PayableExportAll({
|
|||||||
proms.push(
|
proms.push(
|
||||||
(async () => {
|
(async () => {
|
||||||
const failedTransactions = groupedData[key].filter((r) => !r.success);
|
const failedTransactions = groupedData[key].filter((r) => !r.success);
|
||||||
|
const successfulTransactions = groupedData[key].filter(
|
||||||
|
(r) => r.success
|
||||||
|
);
|
||||||
if (failedTransactions.length > 0) {
|
if (failedTransactions.length > 0) {
|
||||||
//Uh oh. At least one was no good.
|
//Uh oh. At least one was no good.
|
||||||
failedTransactions.map((ft) =>
|
failedTransactions.map((ft) =>
|
||||||
@@ -143,7 +158,15 @@ export function PayableExportAll({
|
|||||||
|
|
||||||
const billUpdateResponse = await updateBill({
|
const billUpdateResponse = await updateBill({
|
||||||
variables: {
|
variables: {
|
||||||
billIdList: [key],
|
billIdList: successfulTransactions.map(
|
||||||
|
(st) =>
|
||||||
|
st[
|
||||||
|
bodyshop.accountingconfig &&
|
||||||
|
bodyshop.accountingconfig.qbo
|
||||||
|
? "billid"
|
||||||
|
: "id"
|
||||||
|
]
|
||||||
|
),
|
||||||
bill: {
|
bill: {
|
||||||
exported: true,
|
exported: true,
|
||||||
exported_at: new Date(),
|
exported_at: new Date(),
|
||||||
@@ -156,6 +179,11 @@ export function PayableExportAll({
|
|||||||
key: "billsuccessexport",
|
key: "billsuccessexport",
|
||||||
message: t("bills.successes.exported"),
|
message: t("bills.successes.exported"),
|
||||||
});
|
});
|
||||||
|
updateBillCache(
|
||||||
|
billUpdateResponse.data.update_bills.returning.map(
|
||||||
|
(bill) => bill.id
|
||||||
|
)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
notification["error"]({
|
notification["error"]({
|
||||||
message: t("bills.errors.exporting", {
|
message: t("bills.errors.exporting", {
|
||||||
@@ -164,6 +192,26 @@ export function PayableExportAll({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo && successfulTransactions.length > 0) {
|
||||||
|
notification.open({
|
||||||
|
type: "success",
|
||||||
|
key: "billsuccessexport",
|
||||||
|
message: t("bills.successes.exported"),
|
||||||
|
});
|
||||||
|
updateBillCache([
|
||||||
|
...new Set(
|
||||||
|
successfulTransactions.map(
|
||||||
|
(st) =>
|
||||||
|
st[
|
||||||
|
bodyshop.accountingconfig &&
|
||||||
|
bodyshop.accountingconfig.qbo
|
||||||
|
? "billid"
|
||||||
|
: "id"
|
||||||
|
]
|
||||||
|
)
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
);
|
);
|
||||||
@@ -172,8 +220,6 @@ export function PayableExportAll({
|
|||||||
await Promise.all(proms);
|
await Promise.all(proms);
|
||||||
if (!!completedCallback) completedCallback([]);
|
if (!!completedCallback) completedCallback([]);
|
||||||
if (!!loadingCallback) loadingCallback(false);
|
if (!!loadingCallback) loadingCallback(false);
|
||||||
if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo) refetch();
|
|
||||||
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -4,22 +4,35 @@ import axios from "axios";
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import { auth } from "../../firebase/firebase.utils";
|
import { auth, logImEXEvent } from "../../firebase/firebase.utils";
|
||||||
|
import { INSERT_EXPORT_LOG } from "../../graphql/accounting.queries";
|
||||||
import { UPDATE_BILLS } from "../../graphql/bills.queries";
|
import { UPDATE_BILLS } from "../../graphql/bills.queries";
|
||||||
import {
|
import {
|
||||||
selectBodyshop,
|
selectBodyshop,
|
||||||
selectCurrentUser,
|
selectCurrentUser,
|
||||||
} from "../../redux/user/user.selectors";
|
} from "../../redux/user/user.selectors";
|
||||||
import { logImEXEvent } from "../../firebase/firebase.utils";
|
import client from "../../utils/GraphQLClient";
|
||||||
import { INSERT_EXPORT_LOG } from "../../graphql/accounting.queries";
|
|
||||||
import { Link } from "react-router-dom";
|
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop,
|
bodyshop: selectBodyshop,
|
||||||
currentUser: selectCurrentUser,
|
currentUser: selectCurrentUser,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function updateBillCache(items) {
|
||||||
|
client.cache.modify({
|
||||||
|
id: "ROOT_QUERY",
|
||||||
|
fields: {
|
||||||
|
bills(existingJobs = []) {
|
||||||
|
return existingJobs.filter(
|
||||||
|
(billRef) => billRef.__ref.includes(items) === false
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function PayableExportButton({
|
export function PayableExportButton({
|
||||||
bodyshop,
|
bodyshop,
|
||||||
currentUser,
|
currentUser,
|
||||||
@@ -159,6 +172,11 @@ export function PayableExportButton({
|
|||||||
key: "billsuccessexport",
|
key: "billsuccessexport",
|
||||||
message: t("bills.successes.exported"),
|
message: t("bills.successes.exported"),
|
||||||
});
|
});
|
||||||
|
updateBillCache(
|
||||||
|
billUpdateResponse.data.update_bills.returning.map(
|
||||||
|
(bill) => bill.id
|
||||||
|
)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
notification["error"]({
|
notification["error"]({
|
||||||
message: t("bills.errors.exporting", {
|
message: t("bills.errors.exporting", {
|
||||||
@@ -167,7 +185,25 @@ export function PayableExportButton({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo) refetch();
|
if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo && successfulTransactions.length > 0) {
|
||||||
|
notification.open({
|
||||||
|
type: "success",
|
||||||
|
key: "billsuccessexport",
|
||||||
|
message: t("bills.successes.exported"),
|
||||||
|
});
|
||||||
|
updateBillCache([
|
||||||
|
...new Set(
|
||||||
|
successfulTransactions.map(
|
||||||
|
(st) =>
|
||||||
|
st[
|
||||||
|
bodyshop.accountingconfig && bodyshop.accountingconfig.qbo
|
||||||
|
? "billid"
|
||||||
|
: "id"
|
||||||
|
]
|
||||||
|
)
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
if (setSelectedBills) {
|
if (setSelectedBills) {
|
||||||
setSelectedBills((selectedBills) => {
|
setSelectedBills((selectedBills) => {
|
||||||
|
|||||||
@@ -1,15 +1,24 @@
|
|||||||
import React, { useState } from "react";
|
|
||||||
import { useMutation, useQuery } from "@apollo/client";
|
import { useMutation, useQuery } from "@apollo/client";
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Descriptions,
|
||||||
|
InputNumber,
|
||||||
|
Modal,
|
||||||
|
Space,
|
||||||
|
notification,
|
||||||
|
} from "antd";
|
||||||
|
import axios from "axios";
|
||||||
|
import moment from "moment";
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
import {
|
import {
|
||||||
GET_REFUNDABLE_AMOUNT_BY_JOBID,
|
GET_REFUNDABLE_AMOUNT_BY_JOBID,
|
||||||
INSERT_PAYMENT_RESPONSE,
|
INSERT_PAYMENT_RESPONSE,
|
||||||
QUERY_PAYMENT_RESPONSE_BY_PAYMENT_ID,
|
QUERY_PAYMENT_RESPONSE_BY_PAYMENT_ID,
|
||||||
} from "../../graphql/payment_response.queries";
|
} from "../../graphql/payment_response.queries";
|
||||||
import { Button, Descriptions, InputNumber, Modal, notification } from "antd";
|
|
||||||
import moment from "moment";
|
|
||||||
import axios from "axios";
|
|
||||||
import { INSERT_NEW_PAYMENT } from "../../graphql/payments.queries";
|
import { INSERT_NEW_PAYMENT } from "../../graphql/payments.queries";
|
||||||
import { useTranslation } from "react-i18next";
|
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
||||||
|
import { DateTimeFormatter } from "../../utils/DateFormatter";
|
||||||
|
|
||||||
const { confirm } = Modal;
|
const { confirm } = Modal;
|
||||||
|
|
||||||
@@ -137,10 +146,10 @@ const PaymentExpandedRowComponent = ({ record, bodyshop }) => {
|
|||||||
{payment_response?.response?.nameOnCard ?? ""}
|
{payment_response?.response?.nameOnCard ?? ""}
|
||||||
</Descriptions.Item>
|
</Descriptions.Item>
|
||||||
<Descriptions.Item label={t("job_payments.titles.amount")}>
|
<Descriptions.Item label={t("job_payments.titles.amount")}>
|
||||||
{record.amount}
|
<CurrencyFormatter>{record.amount}</CurrencyFormatter>
|
||||||
</Descriptions.Item>
|
</Descriptions.Item>
|
||||||
<Descriptions.Item label={t("job_payments.titles.dateOfPayment")}>
|
<Descriptions.Item label={t("job_payments.titles.dateOfPayment")}>
|
||||||
{moment(record.created_at).format("YYYY-MM-DD HH:mm:ss")}
|
{<DateTimeFormatter>{record.created_at}</DateTimeFormatter>}
|
||||||
</Descriptions.Item>
|
</Descriptions.Item>
|
||||||
<Descriptions.Item label={t("job_payments.titles.transactionid")}>
|
<Descriptions.Item label={t("job_payments.titles.transactionid")}>
|
||||||
{record.transactionid}
|
{record.transactionid}
|
||||||
@@ -151,17 +160,22 @@ const PaymentExpandedRowComponent = ({ record, bodyshop }) => {
|
|||||||
<Descriptions.Item label={t("job_payments.titles.paymenttype")}>
|
<Descriptions.Item label={t("job_payments.titles.paymenttype")}>
|
||||||
{record.type}
|
{record.type}
|
||||||
</Descriptions.Item>
|
</Descriptions.Item>
|
||||||
|
<Descriptions.Item label={t("job_payments.titles.paymentnum")}>
|
||||||
|
{record.paymentnum}
|
||||||
|
</Descriptions.Item>
|
||||||
{payment_response && (
|
{payment_response && (
|
||||||
<Descriptions.Item label={t("job_payments.titles.refundamount")}>
|
<Descriptions.Item label={t("job_payments.titles.refundamount")}>
|
||||||
<InputNumber
|
<Space>
|
||||||
onChange={setRefundAmount}
|
<InputNumber
|
||||||
max={max_refundable_amount}
|
onChange={setRefundAmount}
|
||||||
min={0}
|
max={max_refundable_amount}
|
||||||
/>
|
min={0}
|
||||||
|
/>
|
||||||
|
|
||||||
<Button onClick={() => showConfirm(payment_response)}>
|
<Button onClick={() => showConfirm(payment_response)}>
|
||||||
{t("job_payments.buttons.refundpayment")}
|
{t("job_payments.buttons.refundpayment")}
|
||||||
</Button>
|
</Button>
|
||||||
|
</Space>
|
||||||
</Descriptions.Item>
|
</Descriptions.Item>
|
||||||
)}
|
)}
|
||||||
</Descriptions>
|
</Descriptions>
|
||||||
|
|||||||
@@ -13,12 +13,26 @@ import {
|
|||||||
selectBodyshop,
|
selectBodyshop,
|
||||||
selectCurrentUser,
|
selectCurrentUser,
|
||||||
} from "../../redux/user/user.selectors";
|
} from "../../redux/user/user.selectors";
|
||||||
|
import client from "../../utils/GraphQLClient";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop,
|
bodyshop: selectBodyshop,
|
||||||
currentUser: selectCurrentUser,
|
currentUser: selectCurrentUser,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function updatePaymentCache(items) {
|
||||||
|
client.cache.modify({
|
||||||
|
id: "ROOT_QUERY",
|
||||||
|
fields: {
|
||||||
|
payments(existingJobs = []) {
|
||||||
|
return existingJobs.filter(
|
||||||
|
(paymentRef) => paymentRef.__ref.includes(items) === false
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function PaymentExportButton({
|
export function PaymentExportButton({
|
||||||
bodyshop,
|
bodyshop,
|
||||||
currentUser,
|
currentUser,
|
||||||
@@ -157,6 +171,11 @@ export function PaymentExportButton({
|
|||||||
key: "paymentsuccessexport",
|
key: "paymentsuccessexport",
|
||||||
message: t("payments.successes.exported"),
|
message: t("payments.successes.exported"),
|
||||||
});
|
});
|
||||||
|
updatePaymentCache(
|
||||||
|
paymentUpdateResponse.data.update_payments.returning.map(
|
||||||
|
(payment) => payment.id
|
||||||
|
)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
notification["error"]({
|
notification["error"]({
|
||||||
message: t("payments.errors.exporting", {
|
message: t("payments.errors.exporting", {
|
||||||
@@ -172,7 +191,25 @@ export function PaymentExportButton({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo) refetch();
|
if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo && successfulTransactions.length > 0) {
|
||||||
|
notification.open({
|
||||||
|
type: "success",
|
||||||
|
key: "paymentsuccessexport",
|
||||||
|
message: t("payments.successes.exported"),
|
||||||
|
});
|
||||||
|
updatePaymentCache([
|
||||||
|
...new Set(
|
||||||
|
successfulTransactions.map(
|
||||||
|
(st) =>
|
||||||
|
st[
|
||||||
|
bodyshop.accountingconfig && bodyshop.accountingconfig.qbo
|
||||||
|
? "paymentid"
|
||||||
|
: "id"
|
||||||
|
]
|
||||||
|
)
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
}
|
||||||
if (!!loadingCallback) loadingCallback(false);
|
if (!!loadingCallback) loadingCallback(false);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,11 +13,25 @@ import {
|
|||||||
selectBodyshop,
|
selectBodyshop,
|
||||||
selectCurrentUser,
|
selectCurrentUser,
|
||||||
} from "../../redux/user/user.selectors";
|
} from "../../redux/user/user.selectors";
|
||||||
|
import client from "../../utils/GraphQLClient";
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop,
|
bodyshop: selectBodyshop,
|
||||||
currentUser: selectCurrentUser,
|
currentUser: selectCurrentUser,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function updatePaymentCache(items) {
|
||||||
|
client.cache.modify({
|
||||||
|
id: "ROOT_QUERY",
|
||||||
|
fields: {
|
||||||
|
payments(existingJobs = []) {
|
||||||
|
return existingJobs.filter(
|
||||||
|
(paymentRef) => paymentRef.__ref.includes(items) === false
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function PaymentsExportAllButton({
|
export function PaymentsExportAllButton({
|
||||||
bodyshop,
|
bodyshop,
|
||||||
currentUser,
|
currentUser,
|
||||||
@@ -25,7 +39,7 @@ export function PaymentsExportAllButton({
|
|||||||
disabled,
|
disabled,
|
||||||
loadingCallback,
|
loadingCallback,
|
||||||
completedCallback,
|
completedCallback,
|
||||||
refetch
|
refetch,
|
||||||
}) {
|
}) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [updatePayments] = useMutation(UPDATE_PAYMENTS);
|
const [updatePayments] = useMutation(UPDATE_PAYMENTS);
|
||||||
@@ -84,7 +98,9 @@ export function PaymentsExportAllButton({
|
|||||||
proms.push(
|
proms.push(
|
||||||
(async () => {
|
(async () => {
|
||||||
const failedTransactions = groupedData[key].filter((r) => !r.success);
|
const failedTransactions = groupedData[key].filter((r) => !r.success);
|
||||||
|
const successfulTransactions = groupedData[key].filter(
|
||||||
|
(r) => r.success
|
||||||
|
);
|
||||||
if (failedTransactions.length > 0) {
|
if (failedTransactions.length > 0) {
|
||||||
//Uh oh. At least one was no good.
|
//Uh oh. At least one was no good.
|
||||||
failedTransactions.map((ft) =>
|
failedTransactions.map((ft) =>
|
||||||
@@ -130,7 +146,15 @@ export function PaymentsExportAllButton({
|
|||||||
});
|
});
|
||||||
const paymentUpdateResponse = await updatePayments({
|
const paymentUpdateResponse = await updatePayments({
|
||||||
variables: {
|
variables: {
|
||||||
paymentIdList: [key],
|
paymentIdList: successfulTransactions.map(
|
||||||
|
(st) =>
|
||||||
|
st[
|
||||||
|
bodyshop.accountingconfig &&
|
||||||
|
bodyshop.accountingconfig.qbo
|
||||||
|
? "paymentid"
|
||||||
|
: "id"
|
||||||
|
]
|
||||||
|
),
|
||||||
payment: {
|
payment: {
|
||||||
exportedat: new Date(),
|
exportedat: new Date(),
|
||||||
},
|
},
|
||||||
@@ -142,6 +166,11 @@ export function PaymentsExportAllButton({
|
|||||||
key: "paymentsuccessexport",
|
key: "paymentsuccessexport",
|
||||||
message: t("payments.successes.exported"),
|
message: t("payments.successes.exported"),
|
||||||
});
|
});
|
||||||
|
updatePaymentCache(
|
||||||
|
paymentUpdateResponse.data.update_payments.returning.map(
|
||||||
|
(payment) => payment.id
|
||||||
|
)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
notification["error"]({
|
notification["error"]({
|
||||||
message: t("payments.errors.exporting", {
|
message: t("payments.errors.exporting", {
|
||||||
@@ -150,6 +179,26 @@ export function PaymentsExportAllButton({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo && successfulTransactions.length > 0) {
|
||||||
|
notification.open({
|
||||||
|
type: "success",
|
||||||
|
key: "paymentsuccessexport",
|
||||||
|
message: t("payments.successes.exported"),
|
||||||
|
});
|
||||||
|
updatePaymentCache([
|
||||||
|
...new Set(
|
||||||
|
successfulTransactions.map(
|
||||||
|
(st) =>
|
||||||
|
st[
|
||||||
|
bodyshop.accountingconfig &&
|
||||||
|
bodyshop.accountingconfig.qbo
|
||||||
|
? "paymentid"
|
||||||
|
: "id"
|
||||||
|
]
|
||||||
|
)
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
);
|
);
|
||||||
@@ -157,7 +206,6 @@ export function PaymentsExportAllButton({
|
|||||||
await Promise.all(proms);
|
await Promise.all(proms);
|
||||||
if (!!completedCallback) completedCallback([]);
|
if (!!completedCallback) completedCallback([]);
|
||||||
if (!!loadingCallback) loadingCallback(false);
|
if (!!loadingCallback) loadingCallback(false);
|
||||||
if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo) refetch();
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,156 @@
|
|||||||
|
import { CopyFilled } from "@ant-design/icons";
|
||||||
|
import { Button, Form, Popover, Space, message } from "antd";
|
||||||
|
import axios from "axios";
|
||||||
|
import Dinero from "dinero.js";
|
||||||
|
import { parsePhoneNumber } from "libphonenumber-js";
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import { createStructuredSelector } from "reselect";
|
||||||
|
import {
|
||||||
|
openChatByPhone,
|
||||||
|
setMessage,
|
||||||
|
} from "../../redux/messaging/messaging.actions";
|
||||||
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
|
import CurrencyFormItemComponent from "../form-items-formatted/currency-form-item.component";
|
||||||
|
|
||||||
|
const mapStateToProps = createStructuredSelector({
|
||||||
|
bodyshop: selectBodyshop,
|
||||||
|
});
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
openChatByPhone: (phone) => dispatch(openChatByPhone(phone)),
|
||||||
|
setMessage: (text) => dispatch(setMessage(text)),
|
||||||
|
});
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(PaymentsGenerateLink);
|
||||||
|
|
||||||
|
export function PaymentsGenerateLink({
|
||||||
|
bodyshop,
|
||||||
|
callback,
|
||||||
|
job,
|
||||||
|
openChatByPhone,
|
||||||
|
setMessage,
|
||||||
|
}) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
|
const [visible, setVisible] = useState(false);
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [paymentLink, setPaymentLink] = useState(null);
|
||||||
|
|
||||||
|
const handleFinish = async ({ amount }) => {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
const p = parsePhoneNumber(job.ownr_ph1, "CA");
|
||||||
|
setLoading(true);
|
||||||
|
const response = await axios.post("/intellipay/generate_payment_url", {
|
||||||
|
bodyshop,
|
||||||
|
amount: amount,
|
||||||
|
account: job.ro_number,
|
||||||
|
invoice: job.id,
|
||||||
|
});
|
||||||
|
setLoading(false);
|
||||||
|
setPaymentLink(response.data.shorUrl);
|
||||||
|
|
||||||
|
openChatByPhone({
|
||||||
|
phone_num: p.formatInternational(),
|
||||||
|
jobid: job.id,
|
||||||
|
});
|
||||||
|
setMessage(
|
||||||
|
t("payments.labels.smspaymentreminder", {
|
||||||
|
shopname: bodyshop.shopname,
|
||||||
|
amount: amount,
|
||||||
|
payment_link: response.data.shorUrl,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
//Add in confirmation & errors.
|
||||||
|
if (callback) callback();
|
||||||
|
|
||||||
|
// setVisible(false);
|
||||||
|
setLoading(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const popContent = (
|
||||||
|
<div>
|
||||||
|
<Form onFinish={handleFinish} layout="vertical" form={form}>
|
||||||
|
<Form.Item
|
||||||
|
label={t("payments.fields.amount")}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
//message: t("general.validation.required"),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
name="amount"
|
||||||
|
>
|
||||||
|
<CurrencyFormItemComponent />
|
||||||
|
</Form.Item>
|
||||||
|
{paymentLink && (
|
||||||
|
<Space direction="vertical">
|
||||||
|
<Space
|
||||||
|
style={{ cursor: "pointer" }}
|
||||||
|
onClick={() => {
|
||||||
|
navigator.clipboard.writeText(paymentLink);
|
||||||
|
message.success(t("general.actions.copied"));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
onClick={() => {
|
||||||
|
//Copy the link.
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{paymentLink}
|
||||||
|
</div>{" "}
|
||||||
|
<CopyFilled />
|
||||||
|
</Space>
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
const p = parsePhoneNumber(job.ownr_ph1, "CA");
|
||||||
|
openChatByPhone({
|
||||||
|
phone_num: p.formatInternational(),
|
||||||
|
jobid: job.id,
|
||||||
|
});
|
||||||
|
setMessage(
|
||||||
|
t("payments.labels.smspaymentreminder", {
|
||||||
|
shopname: bodyshop.shopname,
|
||||||
|
amount: Dinero({
|
||||||
|
amount: Math.round(form.getFieldValue("amount") * 100),
|
||||||
|
}).toFormat(),
|
||||||
|
payment_link: paymentLink,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t("general.actions.sendbysms")}
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
)}
|
||||||
|
</Form>
|
||||||
|
<Space>
|
||||||
|
<Button type="primary" onClick={() => form.submit()}>
|
||||||
|
{t("general.actions.submit")}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
form.resetFields();
|
||||||
|
setPaymentLink(null);
|
||||||
|
setVisible(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t("general.actions.cancel")}
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Popover content={popContent} visible={visible}>
|
||||||
|
<Button onClick={() => setVisible(true)} loading={loading}>
|
||||||
|
{t("payments.actions.generatepaymentlink")}
|
||||||
|
</Button>
|
||||||
|
</Popover>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -5,11 +5,13 @@ import { connect } from "react-redux";
|
|||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import { setEmailOptions } from "../../redux/email/email.actions";
|
import { setEmailOptions } from "../../redux/email/email.actions";
|
||||||
import { selectPrintCenter } from "../../redux/modals/modals.selectors";
|
import { selectPrintCenter } from "../../redux/modals/modals.selectors";
|
||||||
|
import { selectTechnician } from "../../redux/tech/tech.selectors";
|
||||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
import { GenerateDocument } from "../../utils/RenderTemplate";
|
import { GenerateDocument } from "../../utils/RenderTemplate";
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
printCenterModal: selectPrintCenter,
|
printCenterModal: selectPrintCenter,
|
||||||
bodyshop: selectBodyshop,
|
bodyshop: selectBodyshop,
|
||||||
|
technician: selectTechnician,
|
||||||
});
|
});
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
setEmailOptions: (e) => dispatch(setEmailOptions(e)),
|
setEmailOptions: (e) => dispatch(setEmailOptions(e)),
|
||||||
@@ -22,6 +24,7 @@ export function PrintCenterItemComponent({
|
|||||||
id,
|
id,
|
||||||
bodyshop,
|
bodyshop,
|
||||||
disabled,
|
disabled,
|
||||||
|
technician,
|
||||||
}) {
|
}) {
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const { context } = printCenterModal;
|
const { context } = printCenterModal;
|
||||||
@@ -44,19 +47,24 @@ export function PrintCenterItemComponent({
|
|||||||
<Space wrap>
|
<Space wrap>
|
||||||
{item.title}
|
{item.title}
|
||||||
<PrinterOutlined onClick={renderToNewWindow} />
|
<PrinterOutlined onClick={renderToNewWindow} />
|
||||||
<MailOutlined
|
{!technician ? (
|
||||||
onClick={() => {
|
<MailOutlined
|
||||||
GenerateDocument(
|
onClick={() => {
|
||||||
{
|
GenerateDocument(
|
||||||
name: item.key,
|
{
|
||||||
variables: { id: id },
|
name: item.key,
|
||||||
},
|
variables: { id: id },
|
||||||
{ to: context.job && context.job.ownr_ea, subject: item.subject },
|
},
|
||||||
"e",
|
{
|
||||||
id
|
to: context.job && context.job.ownr_ea,
|
||||||
);
|
subject: item.subject,
|
||||||
}}
|
},
|
||||||
/>
|
"e",
|
||||||
|
id
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
{loading && <Spin />}
|
{loading && <Spin />}
|
||||||
</Space>
|
</Space>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { useTreatments } from "@splitsoftware/splitio-react";
|
||||||
import { Card, Col, Input, Row, Space, Typography } from "antd";
|
import { Card, Col, Input, Row, Space, Typography } from "antd";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
@@ -23,8 +24,13 @@ export function PrintCenterJobsComponent({ printCenterModal, bodyshop }) {
|
|||||||
const { id: jobId, job } = printCenterModal.context;
|
const { id: jobId, job } = printCenterModal.context;
|
||||||
const tempList = TemplateList("job", {});
|
const tempList = TemplateList("job", {});
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const { Enhanced_Payroll } = useTreatments(
|
||||||
|
["Enhanced_Payroll"],
|
||||||
|
{},
|
||||||
|
bodyshop.imexshopid
|
||||||
|
);
|
||||||
|
|
||||||
const JobsReportsList =
|
const Templates =
|
||||||
bodyshop.cdk_dealerid === null && bodyshop.pbs_serialnumber === null
|
bodyshop.cdk_dealerid === null && bodyshop.pbs_serialnumber === null
|
||||||
? Object.keys(tempList)
|
? Object.keys(tempList)
|
||||||
.map((key) => {
|
.map((key) => {
|
||||||
@@ -51,7 +57,26 @@ export function PrintCenterJobsComponent({ printCenterModal, bodyshop }) {
|
|||||||
bodyshop.region_config.includes(Object.keys(temp.regions)) ===
|
bodyshop.region_config.includes(Object.keys(temp.regions)) ===
|
||||||
true)
|
true)
|
||||||
);
|
);
|
||||||
|
const JobsReportsList =
|
||||||
|
Enhanced_Payroll.treatment === "on"
|
||||||
|
? Object.keys(Templates)
|
||||||
|
.map((key) => {
|
||||||
|
return Templates[key];
|
||||||
|
})
|
||||||
|
.filter(
|
||||||
|
(temp) =>
|
||||||
|
temp.enhanced_payroll === undefined ||
|
||||||
|
temp.enhanced_payroll === true
|
||||||
|
)
|
||||||
|
: Object.keys(Templates)
|
||||||
|
.map((key) => {
|
||||||
|
return Templates[key];
|
||||||
|
})
|
||||||
|
.filter(
|
||||||
|
(temp) =>
|
||||||
|
temp.enhanced_payroll === undefined ||
|
||||||
|
temp.enhanced_payroll === false
|
||||||
|
);
|
||||||
const filteredJobsReportsList =
|
const filteredJobsReportsList =
|
||||||
search !== ""
|
search !== ""
|
||||||
? JobsReportsList.filter((r) =>
|
? JobsReportsList.filter((r) =>
|
||||||
|
|||||||
@@ -1,31 +1,33 @@
|
|||||||
|
import { PrinterFilled } from "@ant-design/icons";
|
||||||
import { useQuery } from "@apollo/client";
|
import { useQuery } from "@apollo/client";
|
||||||
import { Descriptions, Drawer, Space, PageHeader, Button } from "antd";
|
import { Button, Descriptions, Drawer, PageHeader, Space } from "antd";
|
||||||
import queryString from "query-string";
|
import queryString from "query-string";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { connect } from "react-redux";
|
||||||
import { useHistory, useLocation } from "react-router-dom";
|
import { useHistory, useLocation } from "react-router-dom";
|
||||||
|
import { createStructuredSelector } from "reselect";
|
||||||
import { QUERY_JOB_CARD_DETAILS } from "../../graphql/jobs.queries";
|
import { QUERY_JOB_CARD_DETAILS } from "../../graphql/jobs.queries";
|
||||||
|
import { setModalContext } from "../../redux/modals/modals.actions";
|
||||||
|
import { selectTechnician } from "../../redux/tech/tech.selectors";
|
||||||
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
||||||
import { DateFormatter } from "../../utils/DateFormatter";
|
import { DateFormatter } from "../../utils/DateFormatter";
|
||||||
import AlertComponent from "../alert/alert.component";
|
import AlertComponent from "../alert/alert.component";
|
||||||
import StartChatButton from "../chat-open-button/chat-open-button.component";
|
import StartChatButton from "../chat-open-button/chat-open-button.component";
|
||||||
|
import JobAtChange from "../job-at-change/job-at-change.component";
|
||||||
import JobDetailCardsDocumentsComponent from "../job-detail-cards/job-detail-cards.documents.component";
|
import JobDetailCardsDocumentsComponent from "../job-detail-cards/job-detail-cards.documents.component";
|
||||||
import JobDetailCardsNotesComponent from "../job-detail-cards/job-detail-cards.notes.component";
|
import JobDetailCardsNotesComponent from "../job-detail-cards/job-detail-cards.notes.component";
|
||||||
import JobDetailCardsPartsComponent from "../job-detail-cards/job-detail-cards.parts.component";
|
import JobDetailCardsPartsComponent from "../job-detail-cards/job-detail-cards.parts.component";
|
||||||
import JobEmployeeAssignments from "../job-employee-assignments/job-employee-assignments.container";
|
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 JobAtChange from "../job-at-change/job-at-change.component";
|
|
||||||
import { PrinterFilled } from "@ant-design/icons";
|
|
||||||
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
|
|
||||||
import { connect } from "react-redux";
|
|
||||||
import { createStructuredSelector } from "reselect";
|
|
||||||
import { setModalContext } from "../../redux/modals/modals.actions";
|
|
||||||
import ScoreboardAddButton from "../job-scoreboard-add-button/job-scoreboard-add-button.component";
|
import ScoreboardAddButton from "../job-scoreboard-add-button/job-scoreboard-add-button.component";
|
||||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component";
|
||||||
|
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
|
||||||
|
import ProductionRemoveButton from "../production-remove-button/production-remove-button.component";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop,
|
bodyshop: selectBodyshop,
|
||||||
|
technician: selectTechnician,
|
||||||
});
|
});
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
setPrintCenterContext: (context) =>
|
setPrintCenterContext: (context) =>
|
||||||
@@ -40,6 +42,7 @@ export function ProductionListDetail({
|
|||||||
bodyshop,
|
bodyshop,
|
||||||
jobs,
|
jobs,
|
||||||
setPrintCenterContext,
|
setPrintCenterContext,
|
||||||
|
technician,
|
||||||
}) {
|
}) {
|
||||||
const search = queryString.parse(useLocation().search);
|
const search = queryString.parse(useLocation().search);
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
@@ -66,7 +69,9 @@ export function ProductionListDetail({
|
|||||||
title={theJob.ro_number}
|
title={theJob.ro_number}
|
||||||
extra={
|
extra={
|
||||||
<Space wrap>
|
<Space wrap>
|
||||||
<ProductionRemoveButton jobId={theJob.id} />{" "}
|
{!technician ? (
|
||||||
|
<ProductionRemoveButton jobId={theJob.id} />
|
||||||
|
) : null}
|
||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setPrintCenterContext({
|
setPrintCenterContext({
|
||||||
@@ -82,7 +87,9 @@ export function ProductionListDetail({
|
|||||||
<PrinterFilled />
|
<PrinterFilled />
|
||||||
{t("jobs.actions.printCenter")}
|
{t("jobs.actions.printCenter")}
|
||||||
</Button>
|
</Button>
|
||||||
<ScoreboardAddButton job={data ? data.jobs_by_pk : {}} />
|
{!technician ? (
|
||||||
|
<ScoreboardAddButton job={data ? data.jobs_by_pk : {}} />
|
||||||
|
) : null}
|
||||||
</Space>
|
</Space>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { useLazyQuery } from "@apollo/client";
|
import { useLazyQuery } from "@apollo/client";
|
||||||
|
import { useTreatments } from "@splitsoftware/splitio-react";
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Card,
|
Card,
|
||||||
@@ -19,6 +20,7 @@ import { createStructuredSelector } from "reselect";
|
|||||||
import { QUERY_ACTIVE_EMPLOYEES } from "../../graphql/employees.queries";
|
import { QUERY_ACTIVE_EMPLOYEES } from "../../graphql/employees.queries";
|
||||||
import { QUERY_ALL_VENDORS } from "../../graphql/vendors.queries";
|
import { QUERY_ALL_VENDORS } from "../../graphql/vendors.queries";
|
||||||
import { selectReportCenter } from "../../redux/modals/modals.selectors";
|
import { selectReportCenter } from "../../redux/modals/modals.selectors";
|
||||||
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
import DatePIckerRanges from "../../utils/DatePickerRanges";
|
import DatePIckerRanges from "../../utils/DatePickerRanges";
|
||||||
import { GenerateDocument } from "../../utils/RenderTemplate";
|
import { GenerateDocument } from "../../utils/RenderTemplate";
|
||||||
import { TemplateList } from "../../utils/TemplateConstants";
|
import { TemplateList } from "../../utils/TemplateConstants";
|
||||||
@@ -27,6 +29,7 @@ import VendorSearchSelect from "../vendor-search-select/vendor-search-select.com
|
|||||||
import "./report-center-modal.styles.scss";
|
import "./report-center-modal.styles.scss";
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
reportCenterModal: selectReportCenter,
|
reportCenterModal: selectReportCenter,
|
||||||
|
bodyshop: selectBodyshop,
|
||||||
});
|
});
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||||
@@ -36,16 +39,38 @@ export default connect(
|
|||||||
mapDispatchToProps
|
mapDispatchToProps
|
||||||
)(ReportCenterModalComponent);
|
)(ReportCenterModalComponent);
|
||||||
|
|
||||||
export function ReportCenterModalComponent({ reportCenterModal }) {
|
export function ReportCenterModalComponent({ reportCenterModal, bodyshop }) {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [search, setSearch] = useState("");
|
const [search, setSearch] = useState("");
|
||||||
|
const { Enhanced_Payroll } = useTreatments(
|
||||||
|
["Enhanced_Payroll"],
|
||||||
|
{},
|
||||||
|
bodyshop.imexshopid
|
||||||
|
);
|
||||||
|
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const Templates = TemplateList("report_center");
|
const Templates = TemplateList("report_center");
|
||||||
const ReportsList = Object.keys(Templates).map((key) => {
|
const ReportsList =
|
||||||
return Templates[key];
|
Enhanced_Payroll.treatment === "on"
|
||||||
});
|
? Object.keys(Templates)
|
||||||
|
.map((key) => {
|
||||||
|
return Templates[key];
|
||||||
|
})
|
||||||
|
.filter(
|
||||||
|
(temp) =>
|
||||||
|
temp.enhanced_payroll === undefined ||
|
||||||
|
temp.enhanced_payroll === true
|
||||||
|
)
|
||||||
|
: Object.keys(Templates)
|
||||||
|
.map((key) => {
|
||||||
|
return Templates[key];
|
||||||
|
})
|
||||||
|
.filter(
|
||||||
|
(temp) =>
|
||||||
|
temp.enhanced_payroll === undefined ||
|
||||||
|
temp.enhanced_payroll === false
|
||||||
|
);
|
||||||
const { visible } = reportCenterModal;
|
const { visible } = reportCenterModal;
|
||||||
|
|
||||||
const [callVendorQuery, { data: vendorData, called: vendorCalled }] =
|
const [callVendorQuery, { data: vendorData, called: vendorCalled }] =
|
||||||
|
|||||||
@@ -59,11 +59,12 @@ export function ScheduleManualEvent({ bodyshop, event }) {
|
|||||||
refetchQueries: ["QUERY_ALL_ACTIVE_APPOINTMENTS"],
|
refetchQueries: ["QUERY_ALL_ACTIVE_APPOINTMENTS"],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
form.resetFields();
|
||||||
|
setVisibility(false);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
setVisibility(false);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -293,12 +293,6 @@ export function ShopInfoGeneral({ form, bodyshop }) {
|
|||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("bodyshop.fields.federal_tax_id")}
|
label={t("bodyshop.fields.federal_tax_id")}
|
||||||
name="federal_tax_id"
|
name="federal_tax_id"
|
||||||
rules={[
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
//message: t("general.validation.required"),
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
>
|
>
|
||||||
<Input />
|
<Input />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { useMutation } from "@apollo/client";
|
|||||||
import { Button, Card, Form, notification, Space } from "antd";
|
import { Button, Card, Form, notification, Space } from "antd";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
|
import momenttz from "moment-timezone";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
@@ -51,14 +52,20 @@ export function TechClockInContainer({
|
|||||||
const handleFinish = async (values) => {
|
const handleFinish = async (values) => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const theTime = (await axios.post("/utils/time")).data;
|
const theTime = (await axios.post("/utils/time")).data;
|
||||||
|
|
||||||
const result = await insertTimeTicket({
|
const result = await insertTimeTicket({
|
||||||
variables: {
|
variables: {
|
||||||
timeTicketInput: [
|
timeTicketInput: [
|
||||||
{
|
{
|
||||||
bodyshopid: bodyshop.id,
|
bodyshopid: bodyshop.id,
|
||||||
employeeid: technician.id,
|
employeeid: technician.id,
|
||||||
date: moment(theTime).format("YYYY-MM-DD"),
|
date:
|
||||||
|
typeof bodyshop.timezone === "string"
|
||||||
|
? momenttz.tz(theTime, bodyshop.timezone).format("YYYY-MM-DD")
|
||||||
|
: typeof bodyshop.timezone === "number"
|
||||||
|
? moment(theTime)
|
||||||
|
.format("YYYY-MM-DD")
|
||||||
|
.utcOffset(bodyshop.timezone)
|
||||||
|
: moment(theTime).format("YYYY-MM-DD"),
|
||||||
clockon: moment(theTime),
|
clockon: moment(theTime),
|
||||||
jobid: values.jobid,
|
jobid: values.jobid,
|
||||||
cost_center: values.cost_center,
|
cost_center: values.cost_center,
|
||||||
@@ -130,7 +137,7 @@ export function TechClockInContainer({
|
|||||||
>
|
>
|
||||||
{t("timetickets.actions.enter")}
|
{t("timetickets.actions.enter")}
|
||||||
</Button>
|
</Button>
|
||||||
<TechJobPrintTickets />
|
<TechJobPrintTickets attendacePrint={false} />
|
||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
onClick={() => form.submit()}
|
onClick={() => form.submit()}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Button, Card, DatePicker, Form, Popover, Space } from "antd";
|
import { Button, Card, DatePicker, Form, Popover, Radio, Space } from "antd";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
@@ -21,12 +21,13 @@ export default connect(
|
|||||||
mapDispatchToProps
|
mapDispatchToProps
|
||||||
)(TechJobPrintTickets);
|
)(TechJobPrintTickets);
|
||||||
|
|
||||||
export function TechJobPrintTickets({ technician, event }) {
|
export function TechJobPrintTickets({ technician, event, attendacePrint }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [visibility, setVisibility] = useState(false);
|
const [visibility, setVisibility] = useState(false);
|
||||||
|
const Templates = TemplateList("report_center");
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (visibility && event) {
|
if (visibility && event) {
|
||||||
@@ -44,7 +45,10 @@ export function TechJobPrintTickets({ technician, event }) {
|
|||||||
try {
|
try {
|
||||||
await GenerateDocument(
|
await GenerateDocument(
|
||||||
{
|
{
|
||||||
name: TemplateList().timetickets_employee.key,
|
name:
|
||||||
|
attendacePrint === true
|
||||||
|
? Templates.attendance_employee.key
|
||||||
|
: Templates.timetickets_employee.key,
|
||||||
variables: {
|
variables: {
|
||||||
...(start
|
...(start
|
||||||
? { start: moment(start).startOf("day").format("YYYY-MM-DD") }
|
? { start: moment(start).startOf("day").format("YYYY-MM-DD") }
|
||||||
@@ -60,9 +64,12 @@ export function TechJobPrintTickets({ technician, event }) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
to: technician.email,
|
to: technician.email,
|
||||||
subject: TemplateList().timetickets_employee.subject,
|
subject:
|
||||||
|
attendacePrint === true
|
||||||
|
? Templates.attendance_employee.subject
|
||||||
|
: Templates.timetickets_employee.subject,
|
||||||
},
|
},
|
||||||
"p"
|
values.sendby // === "email" ? "e" : "p"
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
@@ -92,10 +99,25 @@ export function TechJobPrintTickets({ technician, event }) {
|
|||||||
format={"MM/DD/YYYY"}
|
format={"MM/DD/YYYY"}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item dependencies={["dates"]}>
|
||||||
|
{() => {
|
||||||
|
return (
|
||||||
|
<Form.Item
|
||||||
|
label={t("general.labels.sendby")}
|
||||||
|
name="sendby"
|
||||||
|
initialValue="p"
|
||||||
|
>
|
||||||
|
<Radio.Group>
|
||||||
|
<Radio value="e">{t("general.labels.email")}</Radio>
|
||||||
|
<Radio value="p">{t("general.labels.print")}</Radio>
|
||||||
|
</Radio.Group>
|
||||||
|
</Form.Item>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</Form.Item>
|
||||||
<Space wrap>
|
<Space wrap>
|
||||||
<Button type="primary" onClick={() => form.submit()}>
|
<Button type="primary" onClick={() => form.submit()}>
|
||||||
{t("general.actions.print")}
|
{t("reportcenter.actions.generate")}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@@ -118,7 +140,7 @@ export function TechJobPrintTickets({ technician, event }) {
|
|||||||
return (
|
return (
|
||||||
<Popover content={overlay} visible={visibility}>
|
<Popover content={overlay} visible={visibility}>
|
||||||
<Button loading={loading} onClick={handleClick}>
|
<Button loading={loading} onClick={handleClick}>
|
||||||
{t("general.actions.print")}
|
{t("general.labels.reports")}
|
||||||
</Button>
|
</Button>
|
||||||
</Popover>
|
</Popover>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ export function TimeTicketModalContainer({
|
|||||||
if (!!changedFields.cost_center && !!EmployeeAutoCompleteData) {
|
if (!!changedFields.cost_center && !!EmployeeAutoCompleteData) {
|
||||||
form.setFieldsValue({
|
form.setFieldsValue({
|
||||||
ciecacode:
|
ciecacode:
|
||||||
bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber || Enhanced_Payroll.treatments === 'on'
|
bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber || Enhanced_Payroll.treatment === 'on'
|
||||||
? changedFields.cost_center
|
? changedFields.cost_center
|
||||||
: Object.keys(
|
: Object.keys(
|
||||||
bodyshop.md_responsibility_centers.defaults.costs
|
bodyshop.md_responsibility_centers.defaults.costs
|
||||||
|
|||||||
@@ -4,48 +4,67 @@ import { useTranslation } from "react-i18next";
|
|||||||
import { DateTimeFormatter } from "../../utils/DateFormatter";
|
import { DateTimeFormatter } from "../../utils/DateFormatter";
|
||||||
import DataLabel from "../data-label/data-label.component";
|
import DataLabel from "../data-label/data-label.component";
|
||||||
import TechClockOffButton from "../tech-job-clock-out-button/tech-job-clock-out-button.component";
|
import TechClockOffButton from "../tech-job-clock-out-button/tech-job-clock-out-button.component";
|
||||||
|
import TechJobPrintTickets from "../tech-job-print-tickets/tech-job-print-tickets.component";
|
||||||
|
|
||||||
export default function TimeTicketShiftActive({ timetickets, refetch }) {
|
export default function TimeTicketShiftActive({
|
||||||
|
timetickets,
|
||||||
|
refetch,
|
||||||
|
isTechConsole,
|
||||||
|
}) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{timetickets.length > 0 ? (
|
{timetickets.length > 0 ? (
|
||||||
<div>
|
<div
|
||||||
<Typography.Title level={2}>
|
style={{
|
||||||
{t("timetickets.labels.shiftalreadyclockedon")}
|
display: "flex",
|
||||||
</Typography.Title>
|
justifyContent: "space-between",
|
||||||
<List
|
flexDirection: "column",
|
||||||
grid={{
|
height: "100%",
|
||||||
gutter: 32,
|
}}
|
||||||
xs: 1,
|
>
|
||||||
sm: 2,
|
<div style={{ display: "flex", justifyContent: "space-between" }}>
|
||||||
md: 3,
|
<Typography.Title level={2}>
|
||||||
lg: 4,
|
{t("timetickets.labels.shiftalreadyclockedon")}
|
||||||
xl: 5,
|
</Typography.Title>
|
||||||
xxl: 6,
|
{isTechConsole ? (
|
||||||
}}
|
<TechJobPrintTickets attendacePrint={true} />
|
||||||
dataSource={timetickets || []}
|
) : null}
|
||||||
renderItem={(ticket) => (
|
</div>
|
||||||
<List.Item>
|
<div style={{ flexGrow: 1 }}>
|
||||||
<Card
|
<List
|
||||||
title={t(ticket.memo)}
|
grid={{
|
||||||
actions={[
|
gutter: 32,
|
||||||
<TechClockOffButton
|
xs: 1,
|
||||||
jobId={ticket.jobid}
|
sm: 2,
|
||||||
timeTicketId={ticket.id}
|
md: 3,
|
||||||
completedCallback={refetch}
|
lg: 4,
|
||||||
isShiftTicket
|
xl: 5,
|
||||||
/>,
|
xxl: 6,
|
||||||
]}
|
}}
|
||||||
>
|
dataSource={timetickets || []}
|
||||||
<DataLabel label={t("timetickets.fields.clockon")}>
|
renderItem={(ticket) => (
|
||||||
<DateTimeFormatter>{ticket.clockon}</DateTimeFormatter>
|
<List.Item>
|
||||||
</DataLabel>
|
<Card
|
||||||
</Card>
|
title={t(ticket.memo)}
|
||||||
</List.Item>
|
actions={[
|
||||||
)}
|
<TechClockOffButton
|
||||||
></List>
|
jobId={ticket.jobid}
|
||||||
|
timeTicketId={ticket.id}
|
||||||
|
completedCallback={refetch}
|
||||||
|
isShiftTicket
|
||||||
|
/>,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<DataLabel label={t("timetickets.fields.clockon")}>
|
||||||
|
<DateTimeFormatter>{ticket.clockon}</DateTimeFormatter>
|
||||||
|
</DataLabel>
|
||||||
|
</Card>
|
||||||
|
</List.Item>
|
||||||
|
)}
|
||||||
|
></List>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { useMutation } from "@apollo/client";
|
import { useMutation } from "@apollo/client";
|
||||||
import { Button, Form, notification } from "antd";
|
import { Button, Form, Space, notification } from "antd";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
|
import momenttz from "moment-timezone";
|
||||||
import React, { useMemo, useState } from "react";
|
import React, { useMemo, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
@@ -12,6 +13,7 @@ import {
|
|||||||
selectBodyshop,
|
selectBodyshop,
|
||||||
selectCurrentUser,
|
selectCurrentUser,
|
||||||
} from "../../redux/user/user.selectors";
|
} from "../../redux/user/user.selectors";
|
||||||
|
import TechJobPrintTickets from "../tech-job-print-tickets/tech-job-print-tickets.component";
|
||||||
import TimeTicektShiftComponent from "./time-ticket-shift-form.component";
|
import TimeTicektShiftComponent from "./time-ticket-shift-form.component";
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
currentUser: selectCurrentUser,
|
currentUser: selectCurrentUser,
|
||||||
@@ -29,6 +31,10 @@ export function TimeTicektShiftContainer({
|
|||||||
isTechConsole,
|
isTechConsole,
|
||||||
checkIfAlreadyClocked,
|
checkIfAlreadyClocked,
|
||||||
}) {
|
}) {
|
||||||
|
console.log(
|
||||||
|
"🚀 ~ file: time-ticket-shift-form.container.jsx:28 ~ technician:",
|
||||||
|
technician
|
||||||
|
);
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [insertTimeTicket] = useMutation(INSERT_NEW_TIME_TICKET);
|
const [insertTimeTicket] = useMutation(INSERT_NEW_TIME_TICKET);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@@ -63,7 +69,14 @@ export function TimeTicektShiftContainer({
|
|||||||
employeeid: isTechConsole ? technician.id : employeeId,
|
employeeid: isTechConsole ? technician.id : employeeId,
|
||||||
cost_center: "timetickets.labels.shift",
|
cost_center: "timetickets.labels.shift",
|
||||||
clockon: theTime,
|
clockon: theTime,
|
||||||
date: theTime,
|
date:
|
||||||
|
typeof bodyshop.timezone === "string"
|
||||||
|
? momenttz.tz(theTime, bodyshop.timezone).format("YYYY-MM-DD")
|
||||||
|
: typeof bodyshop.timezone === "number"
|
||||||
|
? moment(theTime)
|
||||||
|
.utcOffset(bodyshop.timezone)
|
||||||
|
.format("YYYY-MM-DD")
|
||||||
|
: moment(theTime).format("YYYY-MM-DD"),
|
||||||
memo: values.memo,
|
memo: values.memo,
|
||||||
created_by: isTechConsole
|
created_by: isTechConsole
|
||||||
? currentUser.email.concat(
|
? currentUser.email.concat(
|
||||||
@@ -113,9 +126,14 @@ export function TimeTicektShiftContainer({
|
|||||||
initialValues={{ cost_center: t("timetickets.labels.shift") }}
|
initialValues={{ cost_center: t("timetickets.labels.shift") }}
|
||||||
>
|
>
|
||||||
<TimeTicektShiftComponent form={form} />
|
<TimeTicektShiftComponent form={form} />
|
||||||
<Button htmlType="submit" loading={loading}>
|
<Space wrap>
|
||||||
{t("timetickets.actions.clockin")}
|
<Button htmlType="submit" loading={loading} type="primary">
|
||||||
</Button>
|
{t("timetickets.actions.clockin")}
|
||||||
|
</Button>
|
||||||
|
{isTechConsole === true ? (
|
||||||
|
<TechJobPrintTickets attendacePrint={true} />
|
||||||
|
) : null}
|
||||||
|
</Space>
|
||||||
</Form>
|
</Form>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ export function TimeTicketShiftContainer({
|
|||||||
<TimeTicketShiftActive
|
<TimeTicketShiftActive
|
||||||
timetickets={data ? data.timetickets : []}
|
timetickets={data ? data.timetickets : []}
|
||||||
refetch={refetch}
|
refetch={refetch}
|
||||||
|
isTechConsole={isTechConsole}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<TimeTicketShiftFormContainer
|
<TimeTicketShiftFormContainer
|
||||||
|
|||||||
@@ -6,8 +6,9 @@ import { Link } from "react-router-dom";
|
|||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
||||||
import VehicleDetailUpdateJobsComponent from "../vehicle-detail-update-jobs/vehicle-detail-update-jobs.component";
|
import { alphaSort, statusSort } from "../../utils/sorters";
|
||||||
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
|
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
|
||||||
|
import VehicleDetailUpdateJobsComponent from "../vehicle-detail-update-jobs/vehicle-detail-update-jobs.component";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop,
|
bodyshop: selectBodyshop,
|
||||||
@@ -16,6 +17,14 @@ const mapStateToProps = createStructuredSelector({
|
|||||||
export function VehicleDetailJobsComponent({ vehicle, bodyshop }) {
|
export function VehicleDetailJobsComponent({ vehicle, bodyshop }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [selectedJobs, setSelectedJobs] = useState([]);
|
const [selectedJobs, setSelectedJobs] = useState([]);
|
||||||
|
const [state, setState] = useState({
|
||||||
|
sortedInfo: {},
|
||||||
|
filteredInfo: { text: "" },
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleTableChange = (pagination, filters, sorter) => {
|
||||||
|
setState({ ...state, filteredInfo: filters, sortedInfo: sorter });
|
||||||
|
};
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
@@ -28,6 +37,9 @@ export function VehicleDetailJobsComponent({ vehicle, bodyshop }) {
|
|||||||
{record.ro_number || t("general.labels.na")}
|
{record.ro_number || t("general.labels.na")}
|
||||||
</Link>
|
</Link>
|
||||||
),
|
),
|
||||||
|
sorter: (a, b) => alphaSort(a.ro_number, b.ro_number),
|
||||||
|
sortOrder:
|
||||||
|
state.sortedInfo.columnKey === "ro_number" && state.sortedInfo.order,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t("jobs.fields.owner"),
|
title: t("jobs.fields.owner"),
|
||||||
@@ -43,11 +55,17 @@ export function VehicleDetailJobsComponent({ vehicle, bodyshop }) {
|
|||||||
title: t("jobs.fields.clm_no"),
|
title: t("jobs.fields.clm_no"),
|
||||||
dataIndex: "clm_no",
|
dataIndex: "clm_no",
|
||||||
key: "clm_no",
|
key: "clm_no",
|
||||||
|
sorter: (a, b) => alphaSort(a.clm_no, b.clm_no),
|
||||||
|
sortOrder:
|
||||||
|
state.sortedInfo.columnKey === "clm_no" && state.sortedInfo.order,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t("jobs.fields.status"),
|
title: t("jobs.fields.status"),
|
||||||
dataIndex: "status",
|
dataIndex: "status",
|
||||||
key: "status",
|
key: "status",
|
||||||
|
sorter: (a, b) => statusSort(a.status, b.status, bodyshop.md_ro_statuses.statuses),
|
||||||
|
sortOrder:
|
||||||
|
state.sortedInfo.columnKey === "status" && state.sortedInfo.order,
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -57,6 +75,9 @@ export function VehicleDetailJobsComponent({ vehicle, bodyshop }) {
|
|||||||
render: (text, record) => (
|
render: (text, record) => (
|
||||||
<CurrencyFormatter>{record.clm_total}</CurrencyFormatter>
|
<CurrencyFormatter>{record.clm_total}</CurrencyFormatter>
|
||||||
),
|
),
|
||||||
|
sorter: (a, b) => a.clm_total - b.clm_total,
|
||||||
|
sortOrder:
|
||||||
|
state.sortedInfo.columnKey === "clm_total" && state.sortedInfo.order,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -76,6 +97,7 @@ export function VehicleDetailJobsComponent({ vehicle, bodyshop }) {
|
|||||||
rowKey="id"
|
rowKey="id"
|
||||||
scroll={{ x: true }}
|
scroll={{ x: true }}
|
||||||
dataSource={vehicle.jobs}
|
dataSource={vehicle.jobs}
|
||||||
|
onChange={handleTableChange}
|
||||||
rowSelection={{
|
rowSelection={{
|
||||||
onSelect: (record, selected, selectedRows) => {
|
onSelect: (record, selected, selectedRows) => {
|
||||||
setSelectedJobs(selectedRows ? selectedRows.map((i) => i.id) : []);
|
setSelectedJobs(selectedRows ? selectedRows.map((i) => i.id) : []);
|
||||||
|
|||||||
@@ -574,7 +574,6 @@ export const GET_JOB_BY_PK = gql`
|
|||||||
est_co_nm
|
est_co_nm
|
||||||
est_ct_fn
|
est_ct_fn
|
||||||
est_ct_ln
|
est_ct_ln
|
||||||
|
|
||||||
est_ph1
|
est_ph1
|
||||||
est_ea
|
est_ea
|
||||||
selling_dealer
|
selling_dealer
|
||||||
@@ -756,8 +755,8 @@ export const GET_JOB_BY_PK = gql`
|
|||||||
jobid
|
jobid
|
||||||
amount
|
amount
|
||||||
payer
|
payer
|
||||||
|
paymentnum
|
||||||
created_at
|
created_at
|
||||||
stripeid
|
|
||||||
transactionid
|
transactionid
|
||||||
memo
|
memo
|
||||||
date
|
date
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ export const QUERY_OWNER_BY_ID = gql`
|
|||||||
preferred_contact
|
preferred_contact
|
||||||
note
|
note
|
||||||
tax_number
|
tax_number
|
||||||
jobs {
|
jobs(order_by: { date_open: desc }) {
|
||||||
id
|
id
|
||||||
ro_number
|
ro_number
|
||||||
clm_no
|
clm_no
|
||||||
|
|||||||
@@ -28,16 +28,14 @@ export const QUERY_PAYMENT_RESPONSE_BY_PAYMENT_ID = gql`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const QUERY_RO_AND_OWNER_BY_JOB_PK = gql`
|
export const QUERY_RO_AND_OWNER_BY_JOB_PKS = gql`
|
||||||
query QUERY_RO_AND_OWNER_BY_JOB_PK($jobid: uuid!) {
|
query QUERY_RO_AND_OWNER_BY_JOB_PKS($jobids: [uuid!]!) {
|
||||||
jobs_by_pk(id: $jobid) {
|
jobs(where: { id: { _in: $jobids } }) {
|
||||||
ro_number
|
ro_number
|
||||||
owner {
|
ownr_fn
|
||||||
ownr_fn
|
ownr_ln
|
||||||
ownr_ln
|
ownr_ea
|
||||||
ownr_ea
|
ownr_zip
|
||||||
ownr_zip
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -5,6 +5,15 @@ export const INSERT_NEW_PAYMENT = gql`
|
|||||||
insert_payments(objects: $paymentInput) {
|
insert_payments(objects: $paymentInput) {
|
||||||
returning {
|
returning {
|
||||||
id
|
id
|
||||||
|
jobid
|
||||||
|
amount
|
||||||
|
payer
|
||||||
|
created_at
|
||||||
|
transactionid
|
||||||
|
memo
|
||||||
|
date
|
||||||
|
type
|
||||||
|
exportedat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,11 +28,10 @@ export const QUERY_VEHICLE_BY_ID = gql`
|
|||||||
updated_at
|
updated_at
|
||||||
trim_color
|
trim_color
|
||||||
notes
|
notes
|
||||||
jobs {
|
jobs(order_by: { date_open: desc }) {
|
||||||
id
|
id
|
||||||
ro_number
|
ro_number
|
||||||
ownr_fn
|
ownr_fn
|
||||||
|
|
||||||
ownr_ln
|
ownr_ln
|
||||||
owner {
|
owner {
|
||||||
id
|
id
|
||||||
|
|||||||
@@ -1,23 +1,26 @@
|
|||||||
import { BackTop, Layout } from "antd";
|
import { BackTop, Layout } from "antd";
|
||||||
import React, { lazy, Suspense, useEffect } from "react";
|
import React, { Suspense, lazy, useEffect } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { Redirect, Route, Switch } from "react-router-dom";
|
import { Redirect, Route, Switch } from "react-router-dom";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import ErrorBoundary from "../../components/error-boundary/error-boundary.component";
|
import ErrorBoundary from "../../components/error-boundary/error-boundary.component";
|
||||||
|
|
||||||
|
import FeatureWrapper from "../../components/feature-wrapper/feature-wrapper.component";
|
||||||
import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component";
|
import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component";
|
||||||
import TechHeader from "../../components/tech-header/tech-header.component";
|
import TechHeader from "../../components/tech-header/tech-header.component";
|
||||||
import TechSider from "../../components/tech-sider/tech-sider.component";
|
|
||||||
import { selectTechnician } from "../../redux/tech/tech.selectors";
|
|
||||||
import FeatureWrapper from "../../components/feature-wrapper/feature-wrapper.component";
|
|
||||||
import "./tech.page.styles.scss";
|
|
||||||
import TechLookupJobsDrawer from "../../components/tech-lookup-jobs-drawer/tech-lookup-jobs-drawer.component";
|
import TechLookupJobsDrawer from "../../components/tech-lookup-jobs-drawer/tech-lookup-jobs-drawer.component";
|
||||||
|
import TechSider from "../../components/tech-sider/tech-sider.component";
|
||||||
import UpdateAlert from "../../components/update-alert/update-alert.component";
|
import UpdateAlert from "../../components/update-alert/update-alert.component";
|
||||||
|
import { selectTechnician } from "../../redux/tech/tech.selectors";
|
||||||
|
import "./tech.page.styles.scss";
|
||||||
|
import "./tech.page.styles.scss";
|
||||||
const TimeTicketModalContainer = lazy(() =>
|
const TimeTicketModalContainer = lazy(() =>
|
||||||
import("../../components/time-ticket-modal/time-ticket-modal.container")
|
import("../../components/time-ticket-modal/time-ticket-modal.container")
|
||||||
);
|
);
|
||||||
|
const EmailOverlayContainer = lazy(() =>
|
||||||
|
import("../../components/email-overlay/email-overlay.container.jsx")
|
||||||
|
);
|
||||||
const PrintCenterModalContainer = lazy(() =>
|
const PrintCenterModalContainer = lazy(() =>
|
||||||
import("../../components/print-center-modal/print-center-modal.container")
|
import("../../components/print-center-modal/print-center-modal.container")
|
||||||
);
|
);
|
||||||
@@ -44,7 +47,8 @@ const TimeTicketModalTask = lazy(() =>
|
|||||||
);
|
);
|
||||||
const TechAssignedProdJobs = lazy(() =>
|
const TechAssignedProdJobs = lazy(() =>
|
||||||
import("../tech-assigned-prod-jobs/tech-assigned-prod-jobs.component")
|
import("../tech-assigned-prod-jobs/tech-assigned-prod-jobs.component")
|
||||||
);const TechDispatchedParts = lazy(() =>
|
);
|
||||||
|
const TechDispatchedParts = lazy(() =>
|
||||||
import("../tech-dispatched-parts/tech-dispatched-parts.page")
|
import("../tech-dispatched-parts/tech-dispatched-parts.page")
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -81,6 +85,7 @@ export function TechPage({ technician, match }) {
|
|||||||
>
|
>
|
||||||
<FeatureWrapper featureName="tech-console">
|
<FeatureWrapper featureName="tech-console">
|
||||||
<TimeTicketModalContainer />
|
<TimeTicketModalContainer />
|
||||||
|
<EmailOverlayContainer />
|
||||||
<PrintCenterModalContainer />
|
<PrintCenterModalContainer />
|
||||||
<TimeTicketModalTask />
|
<TimeTicketModalTask />
|
||||||
<Switch>
|
<Switch>
|
||||||
|
|||||||
@@ -197,6 +197,14 @@ export function* signInSuccessSaga({ payload }) {
|
|||||||
LogRocket.identify(payload.email);
|
LogRocket.identify(payload.email);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// window.$crisp.push([
|
||||||
|
// "set",
|
||||||
|
// "user:nickname",
|
||||||
|
// [payload.displayName || payload.email],
|
||||||
|
// ]);
|
||||||
|
|
||||||
|
// window.$crisp.push(["set", "session:segments", [["rome-user"]]]);
|
||||||
|
|
||||||
Sentry.setUser({
|
Sentry.setUser({
|
||||||
email: payload.email,
|
email: payload.email,
|
||||||
username: payload.displayName || payload.email,
|
username: payload.displayName || payload.email,
|
||||||
@@ -280,6 +288,10 @@ export function* SetAuthLevelFromShopDetails({ payload }) {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
try {
|
try {
|
||||||
|
// window.$crisp.push(["set", "user:company", [payload.shopname]]);
|
||||||
|
// if (authRecord[0] && authRecord[0].user.validemail) {
|
||||||
|
// window.$crisp.push(["set", "user:email", [authRecord[0].user.email]]);
|
||||||
|
// }
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Couldnt find $crisp.");
|
console.error("Couldnt find $crisp.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -495,7 +495,7 @@
|
|||||||
"lam": "Mechanical",
|
"lam": "Mechanical",
|
||||||
"lar": "Refinish",
|
"lar": "Refinish",
|
||||||
"las": "Structural",
|
"las": "Structural",
|
||||||
"lau": "Detail",
|
"lau": "User Defined",
|
||||||
"local_tax": "Local Tax",
|
"local_tax": "Local Tax",
|
||||||
"mapa": "Paint Materials",
|
"mapa": "Paint Materials",
|
||||||
"mash": "Shop Materials",
|
"mash": "Shop Materials",
|
||||||
@@ -614,6 +614,7 @@
|
|||||||
"laborrates": "Labor Rates",
|
"laborrates": "Labor Rates",
|
||||||
"licensing": "Licensing",
|
"licensing": "Licensing",
|
||||||
"md_tasks_presets": "Tasks Presets",
|
"md_tasks_presets": "Tasks Presets",
|
||||||
|
"md_parts_scan": "Parts Scan Rules",
|
||||||
"md_to_emails": "Preset To Emails",
|
"md_to_emails": "Preset To Emails",
|
||||||
"md_to_emails_emails": "Emails",
|
"md_to_emails_emails": "Emails",
|
||||||
"messagingpresets": "Messaging Presets",
|
"messagingpresets": "Messaging Presets",
|
||||||
@@ -1019,6 +1020,7 @@
|
|||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
"clear": "Clear",
|
"clear": "Clear",
|
||||||
"close": "Close",
|
"close": "Close",
|
||||||
|
"copied": "Copied!",
|
||||||
"copylink": "Copy Link",
|
"copylink": "Copy Link",
|
||||||
"create": "Create",
|
"create": "Create",
|
||||||
"delete": "Delete",
|
"delete": "Delete",
|
||||||
@@ -1035,6 +1037,7 @@
|
|||||||
"saveandnew": "Save and New",
|
"saveandnew": "Save and New",
|
||||||
"selectall": "Select All",
|
"selectall": "Select All",
|
||||||
"send": "Send",
|
"send": "Send",
|
||||||
|
"sendbysms": "Send by SMS",
|
||||||
"senderrortosupport": "Send Error to Support",
|
"senderrortosupport": "Send Error to Support",
|
||||||
"submit": "Submit",
|
"submit": "Submit",
|
||||||
"tryagain": "Try Again",
|
"tryagain": "Try Again",
|
||||||
@@ -1096,6 +1099,7 @@
|
|||||||
"passwordsdonotmatch": "The passwords you have entered do not match.",
|
"passwordsdonotmatch": "The passwords you have entered do not match.",
|
||||||
"print": "Print",
|
"print": "Print",
|
||||||
"refresh": "Refresh",
|
"refresh": "Refresh",
|
||||||
|
"reports": "Reports",
|
||||||
"required": "Required",
|
"required": "Required",
|
||||||
"saturday": "Saturday",
|
"saturday": "Saturday",
|
||||||
"search": "Search...",
|
"search": "Search...",
|
||||||
@@ -1195,24 +1199,26 @@
|
|||||||
},
|
},
|
||||||
"job_payments": {
|
"job_payments": {
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"goback": "Cancel",
|
"goback": "Go Back",
|
||||||
"proceedtopayment": "Proceed to Payment",
|
"proceedtopayment": "Proceed to Payment",
|
||||||
"refundpayment": "Refund Payment"
|
"refundpayment": "Refund Payment"
|
||||||
},
|
},
|
||||||
"notifications": {
|
"notifications": {
|
||||||
"error": {
|
"error": {
|
||||||
"description": "Please try again. Make sure the refund amount does not exceeds the payment amount.",
|
"description": "Please try again. Make sure the refund amount does not exceeds the payment amount.",
|
||||||
"title": "Error Refunding Payment"
|
"openingip": "Error connecting to IntelliPay service.",
|
||||||
|
"title": "Error placing refund"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"titles": {
|
"titles": {
|
||||||
"amount": "Amount",
|
"amount": "Amount",
|
||||||
"dateOfPayment": "Date",
|
"dateOfPayment": "Date of Payment",
|
||||||
"descriptions": "Description",
|
"descriptions": "Payment Details",
|
||||||
"payer": "Payer",
|
"payer": "Payer",
|
||||||
"payername": "Payer Name",
|
"payername": "Payer Name",
|
||||||
"paymentid": "Payment ID",
|
"paymentid": "Payment Reference ID",
|
||||||
"paymenttype": "Type",
|
"paymentnum": "Payment Number",
|
||||||
|
"paymenttype": "Payment Type",
|
||||||
"refundamount": "Refund Amount",
|
"refundamount": "Refund Amount",
|
||||||
"transactionid": "Transaction ID"
|
"transactionid": "Transaction ID"
|
||||||
}
|
}
|
||||||
@@ -1933,7 +1939,7 @@
|
|||||||
"customers": "Customers",
|
"customers": "Customers",
|
||||||
"dashboard": "Dashboard",
|
"dashboard": "Dashboard",
|
||||||
"enterbills": "Enter Bills",
|
"enterbills": "Enter Bills",
|
||||||
"entercardpayment": "Enter Card Payments",
|
"entercardpayment": "New Card Charge",
|
||||||
"enterpayment": "Enter Payments",
|
"enterpayment": "Enter Payments",
|
||||||
"entertimeticket": "Enter Time Tickets",
|
"entertimeticket": "Enter Time Tickets",
|
||||||
"export": "Export",
|
"export": "Export",
|
||||||
@@ -1945,7 +1951,6 @@
|
|||||||
"newjob": "Create New Job",
|
"newjob": "Create New Job",
|
||||||
"owners": "Owners",
|
"owners": "Owners",
|
||||||
"parts-queue": "Parts Queue",
|
"parts-queue": "Parts Queue",
|
||||||
"paymentremindersms": "Send Payment Reminder via SMS",
|
|
||||||
"phonebook": "Phonebook",
|
"phonebook": "Phonebook",
|
||||||
"productionboard": "Production Board - Visual",
|
"productionboard": "Production Board - Visual",
|
||||||
"productionlist": "Production Board - List",
|
"productionlist": "Production Board - List",
|
||||||
@@ -2231,9 +2236,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"payments": {
|
"payments": {
|
||||||
|
"actions": {
|
||||||
|
"generatepaymentlink": "Generate Payment Link"
|
||||||
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"exporting": "Error exporting payment(s). {{error}}",
|
"exporting": "Error exporting payment(s). {{error}}",
|
||||||
"exporting-partner": "Error exporting to partner. Please check the partner interaction log for more errors."
|
"exporting-partner": "Error exporting to partner. Please check the partner interaction log for more errors.",
|
||||||
|
"inserting": "Error inserting payment. {{error}}"
|
||||||
},
|
},
|
||||||
"fields": {
|
"fields": {
|
||||||
"amount": "Amount",
|
"amount": "Amount",
|
||||||
@@ -2260,6 +2269,7 @@
|
|||||||
"markforreexport": "Mark for Re-export",
|
"markforreexport": "Mark for Re-export",
|
||||||
"new": "New Payment",
|
"new": "New Payment",
|
||||||
"signup": "Please contact support to sign up for electronic payments.",
|
"signup": "Please contact support to sign up for electronic payments.",
|
||||||
|
"smspaymentreminder": "This is {{shopname}} reminding you about your balance of {{amount}}. To pay, click the following link {{payment_link}}.",
|
||||||
"title": "Payments",
|
"title": "Payments",
|
||||||
"totalpayments": "Total Payments"
|
"totalpayments": "Total Payments"
|
||||||
},
|
},
|
||||||
@@ -2343,6 +2353,7 @@
|
|||||||
"appointment_confirmation": "Appointment Confirmation",
|
"appointment_confirmation": "Appointment Confirmation",
|
||||||
"appointment_reminder": "Appointment Reminder",
|
"appointment_reminder": "Appointment Reminder",
|
||||||
"casl_authorization": "CASL Authorization",
|
"casl_authorization": "CASL Authorization",
|
||||||
|
"committed_timetickets_ro": "Committed Time Tickets",
|
||||||
"coversheet_landscape": "Coversheet (Landscape)",
|
"coversheet_landscape": "Coversheet (Landscape)",
|
||||||
"coversheet_portrait": "Coversheet Portrait",
|
"coversheet_portrait": "Coversheet Portrait",
|
||||||
"csi_invitation": "CSI Invitation",
|
"csi_invitation": "CSI Invitation",
|
||||||
@@ -2380,6 +2391,7 @@
|
|||||||
"mpi_final_acct_sheet": "MPI - Final Accounting Sheet (Direct Repair)",
|
"mpi_final_acct_sheet": "MPI - Final Accounting Sheet (Direct Repair)",
|
||||||
"mpi_final_repair_acct_sheet": "MPI - Final Accounting Sheet",
|
"mpi_final_repair_acct_sheet": "MPI - Final Accounting Sheet",
|
||||||
"paint_grid": "Paint Grid",
|
"paint_grid": "Paint Grid",
|
||||||
|
"parts_dispatch": "Parts Dispatch",
|
||||||
"parts_invoice_label_single": "Parts Label Single",
|
"parts_invoice_label_single": "Parts Label Single",
|
||||||
"parts_label_multiple": "Parts Label - Multi",
|
"parts_label_multiple": "Parts Label - Multi",
|
||||||
"parts_label_single": "Parts Label - Single",
|
"parts_label_single": "Parts Label - Single",
|
||||||
@@ -2414,7 +2426,8 @@
|
|||||||
"worksheet_sorted_by_operation": "Worksheet by Operation",
|
"worksheet_sorted_by_operation": "Worksheet by Operation",
|
||||||
"worksheet_sorted_by_operation_no_hours": "Worksheet by Operation (No Hours)",
|
"worksheet_sorted_by_operation_no_hours": "Worksheet by Operation (No Hours)",
|
||||||
"worksheet_sorted_by_operation_part_type": "Worksheet by Operation & Part Type",
|
"worksheet_sorted_by_operation_part_type": "Worksheet by Operation & Part Type",
|
||||||
"worksheet_sorted_by_operation_type": "Worksheet by Operation Type"
|
"worksheet_sorted_by_operation_type": "Worksheet by Operation Type",
|
||||||
|
"worksheet_sorted_by_team": "Worksheet by Team"
|
||||||
},
|
},
|
||||||
"labels": {
|
"labels": {
|
||||||
"groups": {
|
"groups": {
|
||||||
@@ -2441,6 +2454,7 @@
|
|||||||
"subjects": {
|
"subjects": {
|
||||||
"jobs": {
|
"jobs": {
|
||||||
"individual_job_note": "Job Note RO: {{ro_number}}",
|
"individual_job_note": "Job Note RO: {{ro_number}}",
|
||||||
|
"parts_dispatch": "Parts Dispatch RO: {{ro_number}}",
|
||||||
"parts_order": "Parts Order PO: {{ro_number}} - {{name}}",
|
"parts_order": "Parts Order PO: {{ro_number}} - {{name}}",
|
||||||
"parts_return_slip": "Parts Return PO: {{ro_number}} - {{name}}",
|
"parts_return_slip": "Parts Return PO: {{ro_number}} - {{name}}",
|
||||||
"sublet_order": "Sublet Order PO: {{ro_number}} - {{name}}"
|
"sublet_order": "Sublet Order PO: {{ro_number}} - {{name}}"
|
||||||
@@ -2561,6 +2575,9 @@
|
|||||||
"attendance_detail": "Attendance (All Employees)",
|
"attendance_detail": "Attendance (All Employees)",
|
||||||
"attendance_employee": "Employee Attendance",
|
"attendance_employee": "Employee Attendance",
|
||||||
"attendance_summary": "Attendance Summary (All Employees)",
|
"attendance_summary": "Attendance Summary (All Employees)",
|
||||||
|
"committed_timetickets": "Committed Time Tickets",
|
||||||
|
"committed_timetickets_employee": "Committed Employee Time Tickets",
|
||||||
|
"committed_timetickets_summary": "Committed Time Tickets Summary",
|
||||||
"credits_not_received_date": "Credits not Received by Date",
|
"credits_not_received_date": "Credits not Received by Date",
|
||||||
"credits_not_received_date_vendorid": "Credits not Received by Vendor",
|
"credits_not_received_date_vendorid": "Credits not Received by Vendor",
|
||||||
"csi": "CSI Responses",
|
"csi": "CSI Responses",
|
||||||
@@ -2659,6 +2676,7 @@
|
|||||||
"timetickets_summary": "Time Tickets Summary",
|
"timetickets_summary": "Time Tickets Summary",
|
||||||
"unclaimed_hrs": "Unflagged Hours",
|
"unclaimed_hrs": "Unflagged Hours",
|
||||||
"void_ros": "Void ROs",
|
"void_ros": "Void ROs",
|
||||||
|
"work_in_progress_committed_labour": "Work in Progress - Committed Labor",
|
||||||
"work_in_progress_jobs": "Work in Progress - Jobs",
|
"work_in_progress_jobs": "Work in Progress - Jobs",
|
||||||
"work_in_progress_labour": "Work in Progress - Labor",
|
"work_in_progress_labour": "Work in Progress - Labor",
|
||||||
"work_in_progress_payables": "Work in Progress - Payables"
|
"work_in_progress_payables": "Work in Progress - Payables"
|
||||||
@@ -2765,6 +2783,7 @@
|
|||||||
"clockoff": "Clock Off",
|
"clockoff": "Clock Off",
|
||||||
"clockon": "Clocked In",
|
"clockon": "Clocked In",
|
||||||
"committed": "Committed",
|
"committed": "Committed",
|
||||||
|
"committed_at": "Committed At",
|
||||||
"cost_center": "Cost Center",
|
"cost_center": "Cost Center",
|
||||||
"created_by": "Created By",
|
"created_by": "Created By",
|
||||||
"date": "Ticket Date",
|
"date": "Ticket Date",
|
||||||
|
|||||||
@@ -63,7 +63,6 @@
|
|||||||
"scheduledfor": "Cita programada para:",
|
"scheduledfor": "Cita programada para:",
|
||||||
"severalerrorsfound": "",
|
"severalerrorsfound": "",
|
||||||
"smartscheduling": "",
|
"smartscheduling": "",
|
||||||
"smspaymentreminder": "",
|
|
||||||
"suggesteddates": ""
|
"suggesteddates": ""
|
||||||
},
|
},
|
||||||
"successes": {
|
"successes": {
|
||||||
@@ -613,6 +612,7 @@
|
|||||||
"jobstatuses": "",
|
"jobstatuses": "",
|
||||||
"laborrates": "",
|
"laborrates": "",
|
||||||
"licensing": "",
|
"licensing": "",
|
||||||
|
"md_parts_scan": "",
|
||||||
"md_tasks_presets": "",
|
"md_tasks_presets": "",
|
||||||
"md_to_emails": "",
|
"md_to_emails": "",
|
||||||
"md_to_emails_emails": "",
|
"md_to_emails_emails": "",
|
||||||
@@ -1019,6 +1019,7 @@
|
|||||||
"cancel": "",
|
"cancel": "",
|
||||||
"clear": "",
|
"clear": "",
|
||||||
"close": "",
|
"close": "",
|
||||||
|
"copied": "",
|
||||||
"copylink": "",
|
"copylink": "",
|
||||||
"create": "",
|
"create": "",
|
||||||
"delete": "Borrar",
|
"delete": "Borrar",
|
||||||
@@ -1035,6 +1036,7 @@
|
|||||||
"saveandnew": "",
|
"saveandnew": "",
|
||||||
"selectall": "",
|
"selectall": "",
|
||||||
"send": "",
|
"send": "",
|
||||||
|
"sendbysms": "",
|
||||||
"senderrortosupport": "",
|
"senderrortosupport": "",
|
||||||
"submit": "",
|
"submit": "",
|
||||||
"tryagain": "",
|
"tryagain": "",
|
||||||
@@ -1096,6 +1098,7 @@
|
|||||||
"passwordsdonotmatch": "",
|
"passwordsdonotmatch": "",
|
||||||
"print": "",
|
"print": "",
|
||||||
"refresh": "",
|
"refresh": "",
|
||||||
|
"reports": "",
|
||||||
"required": "",
|
"required": "",
|
||||||
"saturday": "",
|
"saturday": "",
|
||||||
"search": "Buscar...",
|
"search": "Buscar...",
|
||||||
@@ -1202,6 +1205,7 @@
|
|||||||
"notifications": {
|
"notifications": {
|
||||||
"error": {
|
"error": {
|
||||||
"description": "",
|
"description": "",
|
||||||
|
"openingip": "",
|
||||||
"title": ""
|
"title": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1212,6 +1216,7 @@
|
|||||||
"payer": "",
|
"payer": "",
|
||||||
"payername": "",
|
"payername": "",
|
||||||
"paymentid": "",
|
"paymentid": "",
|
||||||
|
"paymentnum": "",
|
||||||
"paymenttype": "",
|
"paymenttype": "",
|
||||||
"refundamount": "",
|
"refundamount": "",
|
||||||
"transactionid": ""
|
"transactionid": ""
|
||||||
@@ -1945,7 +1950,6 @@
|
|||||||
"newjob": "",
|
"newjob": "",
|
||||||
"owners": "propietarios",
|
"owners": "propietarios",
|
||||||
"parts-queue": "",
|
"parts-queue": "",
|
||||||
"paymentremindersms": "",
|
|
||||||
"phonebook": "",
|
"phonebook": "",
|
||||||
"productionboard": "",
|
"productionboard": "",
|
||||||
"productionlist": "",
|
"productionlist": "",
|
||||||
@@ -2231,9 +2235,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"payments": {
|
"payments": {
|
||||||
|
"actions": {
|
||||||
|
"generatepaymentlink": ""
|
||||||
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"exporting": "",
|
"exporting": "",
|
||||||
"exporting-partner": ""
|
"exporting-partner": "",
|
||||||
|
"inserting": ""
|
||||||
},
|
},
|
||||||
"fields": {
|
"fields": {
|
||||||
"amount": "",
|
"amount": "",
|
||||||
@@ -2260,6 +2268,7 @@
|
|||||||
"markforreexport": "",
|
"markforreexport": "",
|
||||||
"new": "",
|
"new": "",
|
||||||
"signup": "",
|
"signup": "",
|
||||||
|
"smspaymentreminder": "",
|
||||||
"title": "",
|
"title": "",
|
||||||
"totalpayments": ""
|
"totalpayments": ""
|
||||||
},
|
},
|
||||||
@@ -2343,6 +2352,7 @@
|
|||||||
"appointment_confirmation": "",
|
"appointment_confirmation": "",
|
||||||
"appointment_reminder": "",
|
"appointment_reminder": "",
|
||||||
"casl_authorization": "",
|
"casl_authorization": "",
|
||||||
|
"committed_timetickets_ro": "",
|
||||||
"coversheet_landscape": "",
|
"coversheet_landscape": "",
|
||||||
"coversheet_portrait": "",
|
"coversheet_portrait": "",
|
||||||
"csi_invitation": "",
|
"csi_invitation": "",
|
||||||
@@ -2380,6 +2390,7 @@
|
|||||||
"mpi_final_acct_sheet": "",
|
"mpi_final_acct_sheet": "",
|
||||||
"mpi_final_repair_acct_sheet": "",
|
"mpi_final_repair_acct_sheet": "",
|
||||||
"paint_grid": "",
|
"paint_grid": "",
|
||||||
|
"parts_dispatch": "",
|
||||||
"parts_invoice_label_single": "",
|
"parts_invoice_label_single": "",
|
||||||
"parts_label_multiple": "",
|
"parts_label_multiple": "",
|
||||||
"parts_label_single": "",
|
"parts_label_single": "",
|
||||||
@@ -2414,7 +2425,8 @@
|
|||||||
"worksheet_sorted_by_operation": "",
|
"worksheet_sorted_by_operation": "",
|
||||||
"worksheet_sorted_by_operation_no_hours": "",
|
"worksheet_sorted_by_operation_no_hours": "",
|
||||||
"worksheet_sorted_by_operation_part_type": "",
|
"worksheet_sorted_by_operation_part_type": "",
|
||||||
"worksheet_sorted_by_operation_type": ""
|
"worksheet_sorted_by_operation_type": "",
|
||||||
|
"worksheet_sorted_by_team": ""
|
||||||
},
|
},
|
||||||
"labels": {
|
"labels": {
|
||||||
"groups": {
|
"groups": {
|
||||||
@@ -2441,6 +2453,7 @@
|
|||||||
"subjects": {
|
"subjects": {
|
||||||
"jobs": {
|
"jobs": {
|
||||||
"individual_job_note": "",
|
"individual_job_note": "",
|
||||||
|
"parts_dispatch": "",
|
||||||
"parts_order": "",
|
"parts_order": "",
|
||||||
"parts_return_slip": "",
|
"parts_return_slip": "",
|
||||||
"sublet_order": ""
|
"sublet_order": ""
|
||||||
@@ -2561,6 +2574,9 @@
|
|||||||
"attendance_detail": "",
|
"attendance_detail": "",
|
||||||
"attendance_employee": "",
|
"attendance_employee": "",
|
||||||
"attendance_summary": "",
|
"attendance_summary": "",
|
||||||
|
"committed_timetickets": "",
|
||||||
|
"committed_timetickets_employee": "",
|
||||||
|
"committed_timetickets_summary": "",
|
||||||
"credits_not_received_date": "",
|
"credits_not_received_date": "",
|
||||||
"credits_not_received_date_vendorid": "",
|
"credits_not_received_date_vendorid": "",
|
||||||
"csi": "",
|
"csi": "",
|
||||||
@@ -2659,6 +2675,7 @@
|
|||||||
"timetickets_summary": "",
|
"timetickets_summary": "",
|
||||||
"unclaimed_hrs": "",
|
"unclaimed_hrs": "",
|
||||||
"void_ros": "",
|
"void_ros": "",
|
||||||
|
"work_in_progress_committed_labour": "",
|
||||||
"work_in_progress_jobs": "",
|
"work_in_progress_jobs": "",
|
||||||
"work_in_progress_labour": "",
|
"work_in_progress_labour": "",
|
||||||
"work_in_progress_payables": ""
|
"work_in_progress_payables": ""
|
||||||
@@ -2765,6 +2782,7 @@
|
|||||||
"clockoff": "",
|
"clockoff": "",
|
||||||
"clockon": "",
|
"clockon": "",
|
||||||
"committed": "",
|
"committed": "",
|
||||||
|
"committed_at": "",
|
||||||
"cost_center": "",
|
"cost_center": "",
|
||||||
"created_by": "",
|
"created_by": "",
|
||||||
"date": "",
|
"date": "",
|
||||||
|
|||||||
@@ -63,7 +63,6 @@
|
|||||||
"scheduledfor": "Rendez-vous prévu pour:",
|
"scheduledfor": "Rendez-vous prévu pour:",
|
||||||
"severalerrorsfound": "",
|
"severalerrorsfound": "",
|
||||||
"smartscheduling": "",
|
"smartscheduling": "",
|
||||||
"smspaymentreminder": "",
|
|
||||||
"suggesteddates": ""
|
"suggesteddates": ""
|
||||||
},
|
},
|
||||||
"successes": {
|
"successes": {
|
||||||
@@ -613,6 +612,7 @@
|
|||||||
"jobstatuses": "",
|
"jobstatuses": "",
|
||||||
"laborrates": "",
|
"laborrates": "",
|
||||||
"licensing": "",
|
"licensing": "",
|
||||||
|
"md_parts_scan": "",
|
||||||
"md_tasks_presets": "",
|
"md_tasks_presets": "",
|
||||||
"md_to_emails": "",
|
"md_to_emails": "",
|
||||||
"md_to_emails_emails": "",
|
"md_to_emails_emails": "",
|
||||||
@@ -1019,6 +1019,7 @@
|
|||||||
"cancel": "",
|
"cancel": "",
|
||||||
"clear": "",
|
"clear": "",
|
||||||
"close": "",
|
"close": "",
|
||||||
|
"copied": "",
|
||||||
"copylink": "",
|
"copylink": "",
|
||||||
"create": "",
|
"create": "",
|
||||||
"delete": "Effacer",
|
"delete": "Effacer",
|
||||||
@@ -1035,6 +1036,7 @@
|
|||||||
"saveandnew": "",
|
"saveandnew": "",
|
||||||
"selectall": "",
|
"selectall": "",
|
||||||
"send": "",
|
"send": "",
|
||||||
|
"sendbysms": "",
|
||||||
"senderrortosupport": "",
|
"senderrortosupport": "",
|
||||||
"submit": "",
|
"submit": "",
|
||||||
"tryagain": "",
|
"tryagain": "",
|
||||||
@@ -1096,6 +1098,7 @@
|
|||||||
"passwordsdonotmatch": "",
|
"passwordsdonotmatch": "",
|
||||||
"print": "",
|
"print": "",
|
||||||
"refresh": "",
|
"refresh": "",
|
||||||
|
"reports": "",
|
||||||
"required": "",
|
"required": "",
|
||||||
"saturday": "",
|
"saturday": "",
|
||||||
"search": "Chercher...",
|
"search": "Chercher...",
|
||||||
@@ -1202,6 +1205,7 @@
|
|||||||
"notifications": {
|
"notifications": {
|
||||||
"error": {
|
"error": {
|
||||||
"description": "",
|
"description": "",
|
||||||
|
"openingip": "",
|
||||||
"title": ""
|
"title": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1212,6 +1216,7 @@
|
|||||||
"payer": "",
|
"payer": "",
|
||||||
"payername": "",
|
"payername": "",
|
||||||
"paymentid": "",
|
"paymentid": "",
|
||||||
|
"paymentnum": "",
|
||||||
"paymenttype": "",
|
"paymenttype": "",
|
||||||
"refundamount": "",
|
"refundamount": "",
|
||||||
"transactionid": ""
|
"transactionid": ""
|
||||||
@@ -1945,7 +1950,6 @@
|
|||||||
"newjob": "",
|
"newjob": "",
|
||||||
"owners": "Propriétaires",
|
"owners": "Propriétaires",
|
||||||
"parts-queue": "",
|
"parts-queue": "",
|
||||||
"paymentremindersms": "",
|
|
||||||
"phonebook": "",
|
"phonebook": "",
|
||||||
"productionboard": "",
|
"productionboard": "",
|
||||||
"productionlist": "",
|
"productionlist": "",
|
||||||
@@ -2231,9 +2235,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"payments": {
|
"payments": {
|
||||||
|
"actions": {
|
||||||
|
"generatepaymentlink": ""
|
||||||
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"exporting": "",
|
"exporting": "",
|
||||||
"exporting-partner": ""
|
"exporting-partner": "",
|
||||||
|
"inserting": ""
|
||||||
},
|
},
|
||||||
"fields": {
|
"fields": {
|
||||||
"amount": "",
|
"amount": "",
|
||||||
@@ -2260,6 +2268,7 @@
|
|||||||
"markforreexport": "",
|
"markforreexport": "",
|
||||||
"new": "",
|
"new": "",
|
||||||
"signup": "",
|
"signup": "",
|
||||||
|
"smspaymentreminder": "",
|
||||||
"title": "",
|
"title": "",
|
||||||
"totalpayments": ""
|
"totalpayments": ""
|
||||||
},
|
},
|
||||||
@@ -2343,6 +2352,7 @@
|
|||||||
"appointment_confirmation": "",
|
"appointment_confirmation": "",
|
||||||
"appointment_reminder": "",
|
"appointment_reminder": "",
|
||||||
"casl_authorization": "",
|
"casl_authorization": "",
|
||||||
|
"committed_timetickets_ro": "",
|
||||||
"coversheet_landscape": "",
|
"coversheet_landscape": "",
|
||||||
"coversheet_portrait": "",
|
"coversheet_portrait": "",
|
||||||
"csi_invitation": "",
|
"csi_invitation": "",
|
||||||
@@ -2380,6 +2390,7 @@
|
|||||||
"mpi_final_acct_sheet": "",
|
"mpi_final_acct_sheet": "",
|
||||||
"mpi_final_repair_acct_sheet": "",
|
"mpi_final_repair_acct_sheet": "",
|
||||||
"paint_grid": "",
|
"paint_grid": "",
|
||||||
|
"parts_dispatch": "",
|
||||||
"parts_invoice_label_single": "",
|
"parts_invoice_label_single": "",
|
||||||
"parts_label_multiple": "",
|
"parts_label_multiple": "",
|
||||||
"parts_label_single": "",
|
"parts_label_single": "",
|
||||||
@@ -2414,7 +2425,8 @@
|
|||||||
"worksheet_sorted_by_operation": "",
|
"worksheet_sorted_by_operation": "",
|
||||||
"worksheet_sorted_by_operation_no_hours": "",
|
"worksheet_sorted_by_operation_no_hours": "",
|
||||||
"worksheet_sorted_by_operation_part_type": "",
|
"worksheet_sorted_by_operation_part_type": "",
|
||||||
"worksheet_sorted_by_operation_type": ""
|
"worksheet_sorted_by_operation_type": "",
|
||||||
|
"worksheet_sorted_by_team": ""
|
||||||
},
|
},
|
||||||
"labels": {
|
"labels": {
|
||||||
"groups": {
|
"groups": {
|
||||||
@@ -2441,6 +2453,7 @@
|
|||||||
"subjects": {
|
"subjects": {
|
||||||
"jobs": {
|
"jobs": {
|
||||||
"individual_job_note": "",
|
"individual_job_note": "",
|
||||||
|
"parts_dispatch": "",
|
||||||
"parts_order": "",
|
"parts_order": "",
|
||||||
"parts_return_slip": "",
|
"parts_return_slip": "",
|
||||||
"sublet_order": ""
|
"sublet_order": ""
|
||||||
@@ -2561,6 +2574,9 @@
|
|||||||
"attendance_detail": "",
|
"attendance_detail": "",
|
||||||
"attendance_employee": "",
|
"attendance_employee": "",
|
||||||
"attendance_summary": "",
|
"attendance_summary": "",
|
||||||
|
"committed_timetickets": "",
|
||||||
|
"committed_timetickets_employee": "",
|
||||||
|
"committed_timetickets_summary": "",
|
||||||
"credits_not_received_date": "",
|
"credits_not_received_date": "",
|
||||||
"credits_not_received_date_vendorid": "",
|
"credits_not_received_date_vendorid": "",
|
||||||
"csi": "",
|
"csi": "",
|
||||||
@@ -2659,6 +2675,7 @@
|
|||||||
"timetickets_summary": "",
|
"timetickets_summary": "",
|
||||||
"unclaimed_hrs": "",
|
"unclaimed_hrs": "",
|
||||||
"void_ros": "",
|
"void_ros": "",
|
||||||
|
"work_in_progress_committed_labour": "",
|
||||||
"work_in_progress_jobs": "",
|
"work_in_progress_jobs": "",
|
||||||
"work_in_progress_labour": "",
|
"work_in_progress_labour": "",
|
||||||
"work_in_progress_payables": ""
|
"work_in_progress_payables": ""
|
||||||
@@ -2765,6 +2782,7 @@
|
|||||||
"clockoff": "",
|
"clockoff": "",
|
||||||
"clockon": "",
|
"clockon": "",
|
||||||
"committed": "",
|
"committed": "",
|
||||||
|
"committed_at": "",
|
||||||
"cost_center": "",
|
"cost_center": "",
|
||||||
"created_by": "",
|
"created_by": "",
|
||||||
"date": "",
|
"date": "",
|
||||||
|
|||||||
@@ -189,6 +189,16 @@ export const TemplateList = (type, context) => {
|
|||||||
key: "worksheet_by_line_number",
|
key: "worksheet_by_line_number",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
group: "worksheet",
|
group: "worksheet",
|
||||||
|
enhanced_payroll: false,
|
||||||
|
},
|
||||||
|
worksheet_by_line_number_enhanced: {
|
||||||
|
title: i18n.t("printcenter.jobs.worksheet_by_line_number"),
|
||||||
|
description: "",
|
||||||
|
subject: i18n.t("printcenter.jobs.worksheet_by_line_number"),
|
||||||
|
key: "worksheet_by_line_number_enhanced",
|
||||||
|
disabled: false,
|
||||||
|
group: "worksheet",
|
||||||
|
enhanced_payroll: true,
|
||||||
},
|
},
|
||||||
worksheet_sorted_by_operation_type: {
|
worksheet_sorted_by_operation_type: {
|
||||||
title: i18n.t(
|
title: i18n.t(
|
||||||
@@ -201,6 +211,20 @@ export const TemplateList = (type, context) => {
|
|||||||
key: "worksheet_sorted_by_operation_type",
|
key: "worksheet_sorted_by_operation_type",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
group: "worksheet",
|
group: "worksheet",
|
||||||
|
enhanced_payroll: false,
|
||||||
|
},
|
||||||
|
worksheet_sorted_by_operation_type_enhanced: {
|
||||||
|
title: i18n.t(
|
||||||
|
"printcenter.jobs.worksheet_sorted_by_operation_type"
|
||||||
|
),
|
||||||
|
description: "",
|
||||||
|
subject: i18n.t(
|
||||||
|
"printcenter.jobs.worksheet_sorted_by_operation_type"
|
||||||
|
),
|
||||||
|
key: "worksheet_sorted_by_operation_type_enhanced",
|
||||||
|
disabled: false,
|
||||||
|
group: "worksheet",
|
||||||
|
enhanced_payroll: true,
|
||||||
},
|
},
|
||||||
worksheet_sorted_by_operation: {
|
worksheet_sorted_by_operation: {
|
||||||
title: i18n.t("printcenter.jobs.worksheet_sorted_by_operation"),
|
title: i18n.t("printcenter.jobs.worksheet_sorted_by_operation"),
|
||||||
@@ -209,6 +233,16 @@ export const TemplateList = (type, context) => {
|
|||||||
key: "worksheet_sorted_by_operation",
|
key: "worksheet_sorted_by_operation",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
group: "worksheet",
|
group: "worksheet",
|
||||||
|
enhanced_payroll: false,
|
||||||
|
},
|
||||||
|
worksheet_sorted_by_operation_enhanced: {
|
||||||
|
title: i18n.t("printcenter.jobs.worksheet_sorted_by_operation"),
|
||||||
|
description: "",
|
||||||
|
subject: i18n.t("printcenter.jobs.worksheet_sorted_by_operation"),
|
||||||
|
key: "worksheet_sorted_by_operation_enhanced",
|
||||||
|
disabled: false,
|
||||||
|
group: "worksheet",
|
||||||
|
enhanced_payroll: true,
|
||||||
},
|
},
|
||||||
worksheet_sorted_by_operation_no_hours: {
|
worksheet_sorted_by_operation_no_hours: {
|
||||||
title: i18n.t(
|
title: i18n.t(
|
||||||
@@ -221,6 +255,20 @@ export const TemplateList = (type, context) => {
|
|||||||
key: "worksheet_sorted_by_operation_no_hours",
|
key: "worksheet_sorted_by_operation_no_hours",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
group: "worksheet",
|
group: "worksheet",
|
||||||
|
enhanced_payroll: false,
|
||||||
|
},
|
||||||
|
worksheet_sorted_by_operation_no_hours_enhanced: {
|
||||||
|
title: i18n.t(
|
||||||
|
"printcenter.jobs.worksheet_sorted_by_operation_no_hours"
|
||||||
|
),
|
||||||
|
description: "",
|
||||||
|
subject: i18n.t(
|
||||||
|
"printcenter.jobs.worksheet_sorted_by_operation_no_hours"
|
||||||
|
),
|
||||||
|
key: "worksheet_sorted_by_operation_no_hours_enhanced",
|
||||||
|
disabled: false,
|
||||||
|
group: "worksheet",
|
||||||
|
enhanced_payroll: true,
|
||||||
},
|
},
|
||||||
worksheet_sorted_by_operation_part_type: {
|
worksheet_sorted_by_operation_part_type: {
|
||||||
title: i18n.t(
|
title: i18n.t(
|
||||||
@@ -233,6 +281,20 @@ export const TemplateList = (type, context) => {
|
|||||||
key: "worksheet_sorted_by_operation_part_type",
|
key: "worksheet_sorted_by_operation_part_type",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
group: "worksheet",
|
group: "worksheet",
|
||||||
|
enhanced_payroll: false,
|
||||||
|
},
|
||||||
|
worksheet_sorted_by_operation_part_type_enhanced: {
|
||||||
|
title: i18n.t(
|
||||||
|
"printcenter.jobs.worksheet_sorted_by_operation_part_type"
|
||||||
|
),
|
||||||
|
description: "",
|
||||||
|
subject: i18n.t(
|
||||||
|
"printcenter.jobs.worksheet_sorted_by_operation_part_type"
|
||||||
|
),
|
||||||
|
key: "worksheet_sorted_by_operation_part_type_enhanced",
|
||||||
|
disabled: false,
|
||||||
|
group: "worksheet",
|
||||||
|
enhanced_payroll: true,
|
||||||
},
|
},
|
||||||
payments_by_job: {
|
payments_by_job: {
|
||||||
title: i18n.t("printcenter.jobs.payments_by_job"),
|
title: i18n.t("printcenter.jobs.payments_by_job"),
|
||||||
@@ -514,6 +576,24 @@ export const TemplateList = (type, context) => {
|
|||||||
group: "financial",
|
group: "financial",
|
||||||
dms: true,
|
dms: true,
|
||||||
},
|
},
|
||||||
|
worksheet_sorted_by_team: {
|
||||||
|
title: i18n.t("printcenter.jobs.worksheet_sorted_by_team"),
|
||||||
|
description: "",
|
||||||
|
subject: i18n.t("printcenter.jobs.worksheet_sorted_by_team"),
|
||||||
|
key: "worksheet_sorted_by_team",
|
||||||
|
disabled: false,
|
||||||
|
group: "worksheet",
|
||||||
|
enhanced_payroll: true,
|
||||||
|
},
|
||||||
|
committed_timetickets_ro: {
|
||||||
|
title: i18n.t("printcenter.jobs.committed_timetickets_ro"),
|
||||||
|
description: "",
|
||||||
|
subject: i18n.t("printcenter.jobs.committed_timetickets_ro"),
|
||||||
|
key: "committed_timetickets_ro",
|
||||||
|
disabled: false,
|
||||||
|
group: "financial",
|
||||||
|
enhanced_payroll: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
: {}),
|
: {}),
|
||||||
...(!type || type === "job_special"
|
...(!type || type === "job_special"
|
||||||
@@ -1144,6 +1224,10 @@ export const TemplateList = (type, context) => {
|
|||||||
key: "timetickets_employee",
|
key: "timetickets_employee",
|
||||||
idtype: "employee",
|
idtype: "employee",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
|
rangeFilter: {
|
||||||
|
object: i18n.t("reportcenter.labels.objects.timetickets"),
|
||||||
|
field: i18n.t("timetickets.fields.date"),
|
||||||
|
},
|
||||||
group: "payroll",
|
group: "payroll",
|
||||||
},
|
},
|
||||||
attendance_detail: {
|
attendance_detail: {
|
||||||
@@ -1582,6 +1666,24 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
group: "jobs",
|
group: "jobs",
|
||||||
},
|
},
|
||||||
|
work_in_progress_committed_labour: {
|
||||||
|
title: i18n.t(
|
||||||
|
"reportcenter.templates.work_in_progress_committed_labour"
|
||||||
|
),
|
||||||
|
description: "",
|
||||||
|
subject: i18n.t(
|
||||||
|
"reportcenter.templates.work_in_progress_committed_labour"
|
||||||
|
),
|
||||||
|
key: "work_in_progress_committed_labour",
|
||||||
|
//idtype: "vendor",
|
||||||
|
disabled: false,
|
||||||
|
rangeFilter: {
|
||||||
|
object: i18n.t("reportcenter.labels.objects.jobs"),
|
||||||
|
field: i18n.t("jobs.fields.date_open"),
|
||||||
|
},
|
||||||
|
group: "jobs",
|
||||||
|
enhanced_payroll: true,
|
||||||
|
},
|
||||||
work_in_progress_payables: {
|
work_in_progress_payables: {
|
||||||
title: i18n.t("reportcenter.templates.work_in_progress_payables"),
|
title: i18n.t("reportcenter.templates.work_in_progress_payables"),
|
||||||
description: "",
|
description: "",
|
||||||
@@ -1938,6 +2040,52 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
group: "jobs",
|
group: "jobs",
|
||||||
},
|
},
|
||||||
|
committed_timetickets: {
|
||||||
|
title: i18n.t("reportcenter.templates.committed_timetickets"),
|
||||||
|
subject: i18n.t("reportcenter.templates.committed_timetickets"),
|
||||||
|
key: "committed_timetickets",
|
||||||
|
disabled: false,
|
||||||
|
rangeFilter: {
|
||||||
|
object: i18n.t("reportcenter.labels.objects.timetickets"),
|
||||||
|
field: i18n.t("timetickets.fields.committed_at"),
|
||||||
|
},
|
||||||
|
group: "payroll",
|
||||||
|
enhanced_payroll: true,
|
||||||
|
},
|
||||||
|
committed_timetickets_employee: {
|
||||||
|
title: i18n.t(
|
||||||
|
"reportcenter.templates.committed_timetickets_employee"
|
||||||
|
),
|
||||||
|
subject: i18n.t(
|
||||||
|
"reportcenter.templates.committed_timetickets_employee"
|
||||||
|
),
|
||||||
|
key: "committed_timetickets_employee",
|
||||||
|
idtype: "employee",
|
||||||
|
disabled: false,
|
||||||
|
rangeFilter: {
|
||||||
|
object: i18n.t("reportcenter.labels.objects.timetickets"),
|
||||||
|
field: i18n.t("timetickets.fields.committed_at"),
|
||||||
|
},
|
||||||
|
group: "payroll",
|
||||||
|
enhanced_payroll: true,
|
||||||
|
},
|
||||||
|
committed_timetickets_summary: {
|
||||||
|
title: i18n.t(
|
||||||
|
"reportcenter.templates.committed_timetickets_summary"
|
||||||
|
),
|
||||||
|
subject: i18n.t(
|
||||||
|
"reportcenter.templates.committed_timetickets_summary"
|
||||||
|
),
|
||||||
|
key: "committed_timetickets_summary",
|
||||||
|
//idtype: "vendor",
|
||||||
|
disabled: false,
|
||||||
|
rangeFilter: {
|
||||||
|
object: i18n.t("reportcenter.labels.objects.timetickets"),
|
||||||
|
field: i18n.t("timetickets.fields.committed_at"),
|
||||||
|
},
|
||||||
|
group: "payroll",
|
||||||
|
enhanced_payroll: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
: {}),
|
: {}),
|
||||||
...(!type || type === "courtesycarcontract"
|
...(!type || type === "courtesycarcontract"
|
||||||
|
|||||||
@@ -3273,6 +3273,8 @@
|
|||||||
- ca_gst_registrant
|
- ca_gst_registrant
|
||||||
- cat_no
|
- cat_no
|
||||||
- category
|
- category
|
||||||
|
- cieca_pfl
|
||||||
|
- cieca_pft
|
||||||
- cieca_stl
|
- cieca_stl
|
||||||
- cieca_ttl
|
- cieca_ttl
|
||||||
- ciecaid
|
- ciecaid
|
||||||
@@ -3314,6 +3316,7 @@
|
|||||||
- date_repairstarted
|
- date_repairstarted
|
||||||
- date_scheduled
|
- date_scheduled
|
||||||
- date_towin
|
- date_towin
|
||||||
|
- date_void
|
||||||
- ded_amt
|
- ded_amt
|
||||||
- ded_note
|
- ded_note
|
||||||
- ded_status
|
- ded_status
|
||||||
@@ -3495,7 +3498,6 @@
|
|||||||
- v_model_yr
|
- v_model_yr
|
||||||
- v_vin
|
- v_vin
|
||||||
- vehicleid
|
- vehicleid
|
||||||
- date_void
|
|
||||||
- voided
|
- voided
|
||||||
select_permissions:
|
select_permissions:
|
||||||
- role: user
|
- role: user
|
||||||
@@ -3539,6 +3541,8 @@
|
|||||||
- ca_gst_registrant
|
- ca_gst_registrant
|
||||||
- cat_no
|
- cat_no
|
||||||
- category
|
- category
|
||||||
|
- cieca_pfl
|
||||||
|
- cieca_pft
|
||||||
- cieca_stl
|
- cieca_stl
|
||||||
- cieca_ttl
|
- cieca_ttl
|
||||||
- ciecaid
|
- ciecaid
|
||||||
@@ -3580,6 +3584,7 @@
|
|||||||
- date_repairstarted
|
- date_repairstarted
|
||||||
- date_scheduled
|
- date_scheduled
|
||||||
- date_towin
|
- date_towin
|
||||||
|
- date_void
|
||||||
- ded_amt
|
- ded_amt
|
||||||
- ded_note
|
- ded_note
|
||||||
- ded_status
|
- ded_status
|
||||||
@@ -3762,7 +3767,6 @@
|
|||||||
- v_model_yr
|
- v_model_yr
|
||||||
- v_vin
|
- v_vin
|
||||||
- vehicleid
|
- vehicleid
|
||||||
- date_void
|
|
||||||
- voided
|
- voided
|
||||||
filter:
|
filter:
|
||||||
bodyshop:
|
bodyshop:
|
||||||
@@ -3816,6 +3820,8 @@
|
|||||||
- ca_gst_registrant
|
- ca_gst_registrant
|
||||||
- cat_no
|
- cat_no
|
||||||
- category
|
- category
|
||||||
|
- cieca_pfl
|
||||||
|
- cieca_pft
|
||||||
- cieca_stl
|
- cieca_stl
|
||||||
- cieca_ttl
|
- cieca_ttl
|
||||||
- ciecaid
|
- ciecaid
|
||||||
@@ -3857,6 +3863,7 @@
|
|||||||
- date_repairstarted
|
- date_repairstarted
|
||||||
- date_scheduled
|
- date_scheduled
|
||||||
- date_towin
|
- date_towin
|
||||||
|
- date_void
|
||||||
- ded_amt
|
- ded_amt
|
||||||
- ded_note
|
- ded_note
|
||||||
- ded_status
|
- ded_status
|
||||||
@@ -4039,7 +4046,6 @@
|
|||||||
- v_model_yr
|
- v_model_yr
|
||||||
- v_vin
|
- v_vin
|
||||||
- vehicleid
|
- vehicleid
|
||||||
- date_void
|
|
||||||
- voided
|
- voided
|
||||||
filter:
|
filter:
|
||||||
bodyshop:
|
bodyshop:
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- Could not auto-generate a down migration.
|
||||||
|
-- Please write an appropriate down migration for the SQL below:
|
||||||
|
-- alter table "public"."jobs" add column "cieca_pfl" jsonb
|
||||||
|
-- null default jsonb_build_object();
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
alter table "public"."jobs" add column "cieca_pfl" jsonb
|
||||||
|
null default jsonb_build_object();
|
||||||
@@ -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 "claimscorpid" text
|
||||||
|
-- null;
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
alter table "public"."bodyshops" add column "claimscorpid" text
|
||||||
|
null;
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- Could not auto-generate a down migration.
|
||||||
|
-- Please write an appropriate down migration for the SQL below:
|
||||||
|
-- alter table "public"."jobs" add column "cieca_pft" jsonb
|
||||||
|
-- null default jsonb_build_object();
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
alter table "public"."jobs" add column "cieca_pft" jsonb
|
||||||
|
null default jsonb_build_object();
|
||||||
@@ -20,7 +20,7 @@ require("dotenv").config({
|
|||||||
|
|
||||||
async function RunTheTest() {
|
async function RunTheTest() {
|
||||||
const bodyshopids = ["6c63a820-542c-497e-8c82-0cc38fb2bbca"];
|
const bodyshopids = ["6c63a820-542c-497e-8c82-0cc38fb2bbca"];
|
||||||
const bearerToken = `Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Ijk3OWVkMTU1OTdhYjM1Zjc4MjljZTc0NDMwN2I3OTNiN2ViZWIyZjAiLCJ0eXAiOiJKV1QifQ.eyJodHRwczovL2hhc3VyYS5pby9qd3QvY2xhaW1zIjp7IngtaGFzdXJhLWRlZmF1bHQtcm9sZSI6InVzZXIiLCJ4LWhhc3VyYS1hbGxvd2VkLXJvbGVzIjpbInVzZXIiXSwieC1oYXN1cmEtdXNlci1pZCI6InQ2WW0xTkRsQ0RPUFpyM0Y5Ymd1V0g0TGhTWDIifSwiaXNzIjoiaHR0cHM6Ly9zZWN1cmV0b2tlbi5nb29nbGUuY29tL3JvbWUtcHJvZC0xIiwiYXVkIjoicm9tZS1wcm9kLTEiLCJhdXRoX3RpbWUiOjE2NzkzNDc4NzAsInVzZXJfaWQiOiJ0NlltMU5EbENET1BacjNGOWJndVdINExoU1gyIiwic3ViIjoidDZZbTFORGxDRE9QWnIzRjliZ3VXSDRMaFNYMiIsImlhdCI6MTY3OTk1NDk3MiwiZXhwIjoxNjc5OTU4NTcyLCJlbWFpbCI6InBhdHJpY2tAcm9tZS5kZXYiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsImZpcmViYXNlIjp7ImlkZW50aXRpZXMiOnsiZW1haWwiOlsicGF0cmlja0Byb21lLmRldiJdfSwic2lnbl9pbl9wcm92aWRlciI6InBhc3N3b3JkIn19.Dnq_xo5tffFf-LK0qD_iieUa_UYe4cJqOxcuJnRGH0aqirMMeQLRR4B_Z3pOsD3T20ML3qZMQNUKx-Ivz1mfyK_aA7_4GKtHRKOpIrAyssw_l5aXuCAEmC8iLQHDGvKi7Vp8LsTMPKqjJSjtaW2zuFqcIGrqncWkBMYSnCKjCFsKjryp35hQiIynAN1W0ajgjmFZHCy7hG1h4wFtLKNXEAGxWA0tE7m7ZZBZk3W7J3nMbYiMuGZfw0y2yYeILQGw3UW6sb9B2Jx2bAR3x-GWhPzQHNZEPolE-andm900cFgdph1z7eBE5P2udc2rp8JsAPdUdovt8ZImhCUeE5wD6g`;
|
const bearerToken = `Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImM2MGI5ZGUwODBmZmFmYmZjMTgzMzllY2Q0NGFjNzdmN2ZhNGU4ZDMiLCJ0eXAiOiJKV1QifQ.eyJuYW1lIjoiUm9tZSBEZXZlbG9wbWVudCIsImh0dHBzOi8vaGFzdXJhLmlvL2p3dC9jbGFpbXMiOnsieC1oYXN1cmEtZGVmYXVsdC1yb2xlIjoiYWRtaW4iLCJ4LWhhc3VyYS1hbGxvd2VkLXJvbGVzIjpbImFkbWluIl0sIngtaGFzdXJhLXVzZXItaWQiOiJ0NlltMU5EbENET1BacjNGOWJndVdINExoU1gyIn0sImlvYWRtaW4iOnRydWUsImlzcyI6Imh0dHBzOi8vc2VjdXJldG9rZW4uZ29vZ2xlLmNvbS9yb21lLXByb2QtMSIsImF1ZCI6InJvbWUtcHJvZC0xIiwiYXV0aF90aW1lIjoxNjkyODk5ODE2LCJ1c2VyX2lkIjoidDZZbTFORGxDRE9QWnIzRjliZ3VXSDRMaFNYMiIsInN1YiI6InQ2WW0xTkRsQ0RPUFpyM0Y5Ymd1V0g0TGhTWDIiLCJpYXQiOjE2OTMyNTA1NjIsImV4cCI6MTY5MzI1NDE2MiwiZW1haWwiOiJwYXRyaWNrQHJvbWUuZGV2IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJmaXJlYmFzZSI6eyJpZGVudGl0aWVzIjp7ImVtYWlsIjpbInBhdHJpY2tAcm9tZS5kZXYiXX0sInNpZ25faW5fcHJvdmlkZXIiOiJwYXNzd29yZCJ9fQ.POr8U2pP4XtTJEDRJ_BveRkCs92CIfDDdfU24OYe_aZh6LFPN0bQukNHXrLt3gaD30SUcg5mgmI2VUphgmwviMEGY-zizPC9o6GUKEEppZWQXfrfTyJNa1VKKH9h5zZPPFFW8UJRMi131pCc0ev26GS8Do-FJAgwHLJd6Jp2RbbqiCIeafNMhQCEoXohOk-VArNe7tPAb6-IjxqGVyNqvVyIo6niSXYvmgNjyF1WnnIw0CsnPoJlc5kVMtRdYeshJI7V117MOlUwZicF62vsm32eCunjn3qhN5XsujI7gy9us3vzwhdR1lxISZCLhLOXEYHPL373HJh7I_KN1C3NuA`;
|
||||||
const { jobs } = await client.request(
|
const { jobs } = await client.request(
|
||||||
gql`
|
gql`
|
||||||
query GET_JOBS($bodyshopids: [uuid!]!) {
|
query GET_JOBS($bodyshopids: [uuid!]!) {
|
||||||
|
|||||||
11095
package-lock.json
generated
11095
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -17,6 +17,7 @@
|
|||||||
"start": "node server.js"
|
"start": "node server.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@aws-sdk/client-secrets-manager": "^3.388.0",
|
||||||
"@aws-sdk/credential-provider-node": "^3.319.0",
|
"@aws-sdk/credential-provider-node": "^3.319.0",
|
||||||
"@opensearch-project/opensearch": "^2.2.1",
|
"@opensearch-project/opensearch": "^2.2.1",
|
||||||
"aws-sdk": "^2.1326.0",
|
"aws-sdk": "^2.1326.0",
|
||||||
|
|||||||
16
server.js
16
server.js
@@ -44,13 +44,13 @@ const io = new Server(server, {
|
|||||||
});
|
});
|
||||||
exports.io = io;
|
exports.io = io;
|
||||||
require("./server/web-sockets/web-socket");
|
require("./server/web-sockets/web-socket");
|
||||||
|
// app.set('trust proxy', true)
|
||||||
//app.use(fb.validateFirebaseIdToken);
|
// app.use(fb.validateFirebaseIdToken);
|
||||||
app.use(compression());
|
app.use(compression());
|
||||||
app.use(cookieParser());
|
app.use(cookieParser());
|
||||||
app.use(bodyParser.json({ limit: "50mb" }));
|
app.use(bodyParser.json({ limit: "50mb" }));
|
||||||
app.use(bodyParser.urlencoded({ limit: "50mb", extended: true }));
|
app.use(bodyParser.urlencoded({ limit: "50mb", extended: true }));
|
||||||
//app.use(enforce.HTTPS({ trustProtoHeader: true }));
|
// app.use(enforce.HTTPS({ trustProtoHeader: true }));
|
||||||
app.use(
|
app.use(
|
||||||
cors({ credentials: true, exposedHeaders: ["set-cookie"] })
|
cors({ credentials: true, exposedHeaders: ["set-cookie"] })
|
||||||
// cors({
|
// cors({
|
||||||
@@ -73,10 +73,17 @@ app.get("/test", async function (req, res) {
|
|||||||
const commit = require("child_process").execSync(
|
const commit = require("child_process").execSync(
|
||||||
"git rev-parse --short HEAD"
|
"git rev-parse --short HEAD"
|
||||||
);
|
);
|
||||||
|
// console.log(app.get('trust proxy'));
|
||||||
|
// console.log("remoteAddress", req.socket.remoteAddress);
|
||||||
|
// console.log("X-Forwarded-For", req.header('x-forwarded-for'));
|
||||||
logger.log("test-api-status", "DEBUG", "api", { commit });
|
logger.log("test-api-status", "DEBUG", "api", { commit });
|
||||||
|
// sendEmail.sendServerEmail({
|
||||||
|
// subject: `API Check - ${process.env.NODE_ENV}`,
|
||||||
|
// text: `Server API check has come in. Remote IP: ${req.socket.remoteAddress}, X-Forwarded-For: ${req.header('x-forwarded-for')}`,
|
||||||
|
// });
|
||||||
sendEmail.sendServerEmail({
|
sendEmail.sendServerEmail({
|
||||||
subject: `API Check - ${process.env.NODE_ENV}`,
|
subject: `API Check - ${process.env.NODE_ENV}`,
|
||||||
text: `Server API check has come in. `,
|
text: `Server API check has come in.`,
|
||||||
});
|
});
|
||||||
res.status(200).send(`OK - ${commit}`);
|
res.status(200).send(`OK - ${commit}`);
|
||||||
});
|
});
|
||||||
@@ -222,6 +229,7 @@ app.post("/qbo/payments", fb.validateFirebaseIdToken, qbo.payments);
|
|||||||
|
|
||||||
var data = require("./server/data/data");
|
var data = require("./server/data/data");
|
||||||
app.post("/data/ah", data.autohouse);
|
app.post("/data/ah", data.autohouse);
|
||||||
|
app.post("/data/cc", data.claimscorp);
|
||||||
app.post("/record-handler/arms", data.arms);
|
app.post("/record-handler/arms", data.arms);
|
||||||
|
|
||||||
var taskHandler = require("./server/tasks/tasks");
|
var taskHandler = require("./server/tasks/tasks");
|
||||||
|
|||||||
@@ -643,6 +643,7 @@ async function InsertAccountPostingData(socket) {
|
|||||||
|
|
||||||
wips.push(item);
|
wips.push(item);
|
||||||
});
|
});
|
||||||
|
socket.transWips = wips;
|
||||||
|
|
||||||
const { data: AccountPostingChange } = await axios.post(
|
const { data: AccountPostingChange } = await axios.post(
|
||||||
PBS_ENDPOINTS.AccountingPostingChange,
|
PBS_ENDPOINTS.AccountingPostingChange,
|
||||||
@@ -697,6 +698,7 @@ async function MarkJobExported(socket, jobid) {
|
|||||||
jobid: jobid,
|
jobid: jobid,
|
||||||
successful: true,
|
successful: true,
|
||||||
useremail: socket.user.email,
|
useremail: socket.user.email,
|
||||||
|
metadata: socket.transWips,
|
||||||
},
|
},
|
||||||
bill: {
|
bill: {
|
||||||
exported: true,
|
exported: true,
|
||||||
|
|||||||
@@ -8,8 +8,7 @@ require("dotenv").config({
|
|||||||
|
|
||||||
function urlBuilder(realmId, object, query = null) {
|
function urlBuilder(realmId, object, query = null) {
|
||||||
return `https://${
|
return `https://${
|
||||||
//process.env.NODE_ENV === "production" ? "" :
|
process.env.NODE_ENV === "production" ? "" : "sandbox-"
|
||||||
"sandbox-"
|
|
||||||
}quickbooks.api.intuit.com/v3/company/${realmId}/${object}${
|
}quickbooks.api.intuit.com/v3/company/${realmId}/${object}${
|
||||||
query ? `?query=${encodeURIComponent(query)}` : ""
|
query ? `?query=${encodeURIComponent(query)}` : ""
|
||||||
}`;
|
}`;
|
||||||
|
|||||||
847
server/data/claimscorp.js
Normal file
847
server/data/claimscorp.js
Normal file
@@ -0,0 +1,847 @@
|
|||||||
|
const path = require("path");
|
||||||
|
const queries = require("../graphql-client/queries");
|
||||||
|
const Dinero = require("dinero.js");
|
||||||
|
const moment = require("moment-timezone");
|
||||||
|
var builder = require("xmlbuilder2");
|
||||||
|
const _ = require("lodash");
|
||||||
|
const logger = require("../utils/logger");
|
||||||
|
const fs = require("fs");
|
||||||
|
require("dotenv").config({
|
||||||
|
path: path.resolve(
|
||||||
|
process.cwd(),
|
||||||
|
`.env.${process.env.NODE_ENV || "development"}`
|
||||||
|
),
|
||||||
|
});
|
||||||
|
let Client = require("ssh2-sftp-client");
|
||||||
|
|
||||||
|
const client = require("../graphql-client/graphql-client").client;
|
||||||
|
const { sendServerEmail } = require("../email/sendemail");
|
||||||
|
const CCDineroFormat = "0,0.00";
|
||||||
|
const AhDateFormat = "MMDDYYYY";
|
||||||
|
|
||||||
|
const repairOpCodes = ["OP4", "OP9", "OP10"];
|
||||||
|
const replaceOpCodes = ["OP2", "OP5", "OP11", "OP12"];
|
||||||
|
|
||||||
|
const ftpSetup = {
|
||||||
|
host: process.env.CLAIMSCORP_HOST,
|
||||||
|
port: process.env.CLAIMSCORP_PORT,
|
||||||
|
username: process.env.CLAIMSCORP_USER,
|
||||||
|
password: process.env.CLAIMSCORP_PASSWORD,
|
||||||
|
debug: (message, ...data) => logger.log(message, "DEBUG", "api", null, data),
|
||||||
|
algorithms: {
|
||||||
|
serverHostKey: ["ssh-rsa", "ssh-dss"],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.default = async (req, res) => {
|
||||||
|
//Query for the List of Bodyshop Clients.
|
||||||
|
logger.log("claimscorp-start", "DEBUG", "api", null, null);
|
||||||
|
const { bodyshops } = await client.request(queries.GET_CLAIMSCORP_SHOPS);
|
||||||
|
|
||||||
|
const specificShopIds = req.body.bodyshopIds; // ['uuid]
|
||||||
|
const { start, end, skipUpload } = req.body; //YYYY-MM-DD
|
||||||
|
if (req.headers["x-imex-auth"] !== process.env.AUTOHOUSE_AUTH_TOKEN) {
|
||||||
|
res.sendStatus(401);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const allxmlsToUpload = [];
|
||||||
|
const allErrors = [];
|
||||||
|
try {
|
||||||
|
for (const bodyshop of specificShopIds
|
||||||
|
? bodyshops.filter((b) => specificShopIds.includes(b.id))
|
||||||
|
: bodyshops) {
|
||||||
|
logger.log("claimscorp-start-shop-extract", "DEBUG", "api", bodyshop.id, {
|
||||||
|
shopname: bodyshop.shopname,
|
||||||
|
});
|
||||||
|
const erroredJobs = [];
|
||||||
|
try {
|
||||||
|
const { jobs, bodyshops_by_pk } = await client.request(
|
||||||
|
queries.CLAIMSCORP_QUERY,
|
||||||
|
{
|
||||||
|
bodyshopid: bodyshop.id,
|
||||||
|
start: start
|
||||||
|
? moment(start).startOf("day")
|
||||||
|
: moment().subtract(5, "days").startOf("day"),
|
||||||
|
...(end && { end: moment(end).startOf("day") }),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const claimsCorpObject = {
|
||||||
|
ClaimsCorpExport: {
|
||||||
|
ShopID: bodyshops_by_pk.claimscorpid,
|
||||||
|
ShopName: bodyshops_by_pk.shopname,
|
||||||
|
RO: jobs.map((j) =>
|
||||||
|
CreateRepairOrderTag(
|
||||||
|
{ ...j, bodyshop: bodyshops_by_pk },
|
||||||
|
function ({ job, error }) {
|
||||||
|
erroredJobs.push({ job: job, error: error.toString() });
|
||||||
|
}
|
||||||
|
)
|
||||||
|
),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (erroredJobs.length > 0) {
|
||||||
|
logger.log("claimscorp-failed-jobs", "ERROR", "api", bodyshop.id, {
|
||||||
|
count: erroredJobs.length,
|
||||||
|
jobs: JSON.stringify(erroredJobs.map((j) => j.job.ro_number)),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var ret = builder
|
||||||
|
.create(
|
||||||
|
{
|
||||||
|
// version: "1.0",
|
||||||
|
// encoding: "UTF-8",
|
||||||
|
//keepNullNodes: true,
|
||||||
|
},
|
||||||
|
claimsCorpObject
|
||||||
|
)
|
||||||
|
.end({ allowEmptyTags: true });
|
||||||
|
|
||||||
|
allxmlsToUpload.push({
|
||||||
|
count: claimsCorpObject.ClaimsCorpExport.RO.length,
|
||||||
|
xml: ret,
|
||||||
|
filename: `${bodyshop.claimscorpid}-MIS-${moment().format(
|
||||||
|
"YYYYMMDDTHHMMss"
|
||||||
|
)}.xml`,
|
||||||
|
});
|
||||||
|
|
||||||
|
logger.log("claimscorp-end-shop-extract", "DEBUG", "api", bodyshop.id, {
|
||||||
|
shopname: bodyshop.shopname,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
//Error at the shop level.
|
||||||
|
logger.log("claimscorp-error-shop", "ERROR", "api", bodyshop.id, {
|
||||||
|
...error,
|
||||||
|
});
|
||||||
|
|
||||||
|
allErrors.push({
|
||||||
|
bodyshopid: bodyshop.id,
|
||||||
|
imexshopid: bodyshop.imexshopid,
|
||||||
|
claimscorpid: bodyshop.claimscorpid,
|
||||||
|
fatal: true,
|
||||||
|
errors: [error.toString()],
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
allErrors.push({
|
||||||
|
bodyshopid: bodyshop.id,
|
||||||
|
imexshopid: bodyshop.imexshopid,
|
||||||
|
claimscorpid: bodyshop.claimscorpid,
|
||||||
|
errors: erroredJobs.map((ej) => ({
|
||||||
|
ro_number: ej.job?.ro_number,
|
||||||
|
jobid: ej.job?.id,
|
||||||
|
error: ej.error,
|
||||||
|
})),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skipUpload) {
|
||||||
|
for (const xmlObj of allxmlsToUpload) {
|
||||||
|
fs.writeFileSync(`./logs/${xmlObj.filename}`, xmlObj.xml);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json(allxmlsToUpload);
|
||||||
|
sendServerEmail({
|
||||||
|
subject: `ClaimsCorp Report ${moment().format("MM-DD-YY")}`,
|
||||||
|
text: `Errors: ${allErrors.map((e) => JSON.stringify(e, null, 2))}
|
||||||
|
Uploaded: ${JSON.stringify(
|
||||||
|
allxmlsToUpload.map((x) => ({ filename: x.filename, count: x.count })),
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
)}
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let sftp = new Client();
|
||||||
|
sftp.on("error", (errors) =>
|
||||||
|
logger.log("claimscorp-sftp-error", "ERROR", "api", null, {
|
||||||
|
...errors,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
//Connect to the FTP and upload all.
|
||||||
|
|
||||||
|
await sftp.connect(ftpSetup);
|
||||||
|
|
||||||
|
for (const xmlObj of allxmlsToUpload) {
|
||||||
|
logger.log("claimscorp-sftp-upload", "DEBUG", "api", null, {
|
||||||
|
filename: xmlObj.filename,
|
||||||
|
});
|
||||||
|
|
||||||
|
const uploadResult = await sftp.put(
|
||||||
|
Buffer.from(xmlObj.xml),
|
||||||
|
`/${xmlObj.filename}`
|
||||||
|
);
|
||||||
|
logger.log("claimscorp-sftp-upload-result", "DEBUG", "api", null, {
|
||||||
|
uploadResult,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//***TODO Change filing naming when creating the cron job. IM_ShopInternalName_DDMMYYYY_HHMMSS.xml
|
||||||
|
} catch (error) {
|
||||||
|
logger.log("claimscorp-sftp-error", "ERROR", "api", null, {
|
||||||
|
...error,
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
sftp.end();
|
||||||
|
}
|
||||||
|
sendServerEmail({
|
||||||
|
subject: `ClaimsCorp Report ${moment().format("MM-DD-YY")}`,
|
||||||
|
text: `Errors: ${allErrors.map((e) => JSON.stringify(e, null, 2))}
|
||||||
|
Uploaded: ${JSON.stringify(
|
||||||
|
allxmlsToUpload.map((x) => ({ filename: x.filename, count: x.count })),
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
)}
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
res.sendStatus(200);
|
||||||
|
} catch (error) {
|
||||||
|
res.status(200).json(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const CreateRepairOrderTag = (job, errorCallback) => {
|
||||||
|
//Level 2
|
||||||
|
|
||||||
|
if (!job.job_totals) {
|
||||||
|
errorCallback({
|
||||||
|
jobid: job.id,
|
||||||
|
job: job,
|
||||||
|
ro_number: job.ro_number,
|
||||||
|
error: { toString: () => "No job totals for RO." },
|
||||||
|
});
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const repairCosts = CreateCosts(job);
|
||||||
|
|
||||||
|
//Calculate detail only lines.
|
||||||
|
const detailAdjustments = job.joblines
|
||||||
|
.filter((jl) => jl.ah_detail_line && jl.mod_lbr_ty)
|
||||||
|
.reduce(
|
||||||
|
(acc, val) => {
|
||||||
|
return {
|
||||||
|
hours: acc.hours + val.mod_lb_hrs,
|
||||||
|
amount: acc.amount.add(
|
||||||
|
Dinero({
|
||||||
|
amount: Math.round(
|
||||||
|
(job.job_totals.rates[val.mod_lbr_ty.toLowerCase()].rate || 0) *
|
||||||
|
val.mod_lb_hrs *
|
||||||
|
100
|
||||||
|
),
|
||||||
|
})
|
||||||
|
),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
{ hours: 0, amount: Dinero() }
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const ret = {
|
||||||
|
RONumber: job.ro_number,
|
||||||
|
Customer: {
|
||||||
|
CustomerZip: (job.ownr_zip && job.ownr_zip.substring(0, 3)) || "",
|
||||||
|
CustomerState: job.ownr_st || "",
|
||||||
|
},
|
||||||
|
Vehicle: {
|
||||||
|
Year: job.v_model_yr
|
||||||
|
? parseInt(job.v_model_yr.match(/\d/g))
|
||||||
|
? parseInt(job.v_model_yr.match(/\d/g).join(""), 10)
|
||||||
|
: ""
|
||||||
|
: "",
|
||||||
|
Make: job.v_make_desc || "",
|
||||||
|
Model: job.v_model_desc || "",
|
||||||
|
BodyStyle: (job.vehicle && job.vehicle.v_bstyle) || "",
|
||||||
|
Color: job.v_color || "",
|
||||||
|
VIN: job.v_vin || "",
|
||||||
|
},
|
||||||
|
Carrier: {
|
||||||
|
InsuranceCo: job.ins_co_nm || "",
|
||||||
|
CompanyName: job.ins_co_nm || "",
|
||||||
|
},
|
||||||
|
Claim: job.clm_no || "",
|
||||||
|
Contacts: {
|
||||||
|
PC: job.employee_csr_rel
|
||||||
|
? `${
|
||||||
|
job.employee_csr_rel.last_name
|
||||||
|
? job.employee_csr_rel.last_name
|
||||||
|
: ""
|
||||||
|
}${job.employee_csr_rel.last_name ? ", " : ""}${
|
||||||
|
job.employee_csr_rel.first_name
|
||||||
|
? job.employee_csr_rel.first_name
|
||||||
|
: ""
|
||||||
|
}`
|
||||||
|
: "",
|
||||||
|
Phone1: "",
|
||||||
|
Phone2: "",
|
||||||
|
EstimatorName: `${job.est_ct_ln ? job.est_ct_ln : ""}${
|
||||||
|
job.est_ct_ln ? ", " : ""
|
||||||
|
}${job.est_ct_fn ? job.est_ct_fn : ""}`,
|
||||||
|
BodyTechnician: job.employee_body_rel
|
||||||
|
? `${
|
||||||
|
job.employee_body_rel.last_name
|
||||||
|
? job.employee_body_rel.last_name
|
||||||
|
: ""
|
||||||
|
}${job.employee_body_rel.last_name ? ", " : ""}${
|
||||||
|
job.employee_body_rel.first_name
|
||||||
|
? job.employee_body_rel.first_name
|
||||||
|
: ""
|
||||||
|
}`
|
||||||
|
: "",
|
||||||
|
PaintTechnician: job.employee_refinish_rel
|
||||||
|
? `${
|
||||||
|
job.employee_refinish_rel.last_name
|
||||||
|
? job.employee_refinish_rel.last_name
|
||||||
|
: ""
|
||||||
|
}${job.employee_refinish_rel.last_name ? ", " : ""}${
|
||||||
|
job.employee_refinish_rel.first_name
|
||||||
|
? job.employee_refinish_rel.first_name
|
||||||
|
: ""
|
||||||
|
}`
|
||||||
|
: "",
|
||||||
|
},
|
||||||
|
Dates: {
|
||||||
|
DateCreated:
|
||||||
|
(job.date_estimated &&
|
||||||
|
moment(job.date_estimated).format(AhDateFormat)) ||
|
||||||
|
"",
|
||||||
|
DateofLoss:
|
||||||
|
(job.loss_date && moment(job.loss_date).format(AhDateFormat)) || "",
|
||||||
|
DateFNOL: "",
|
||||||
|
DateContact: "",
|
||||||
|
DateEstimated:
|
||||||
|
(job.date_estimated &&
|
||||||
|
moment(job.date_estimated).format(AhDateFormat)) ||
|
||||||
|
"",
|
||||||
|
DateScheduled:
|
||||||
|
(job.scheduled_in &&
|
||||||
|
moment(job.scheduled_in)
|
||||||
|
.tz(job.bodyshop.timezone)
|
||||||
|
.format(AhDateFormat)) ||
|
||||||
|
"",
|
||||||
|
DateArrived:
|
||||||
|
(job.actual_in &&
|
||||||
|
moment(job.actual_in)
|
||||||
|
.tz(job.bodyshop.timezone)
|
||||||
|
.format(AhDateFormat)) ||
|
||||||
|
"",
|
||||||
|
DateFirstPartsOrdered:
|
||||||
|
(job.parts_orders &&
|
||||||
|
job.parts_orders[0] &&
|
||||||
|
moment(job.parts_orders[0].created_at)
|
||||||
|
.tz(job.bodyshop.timezone)
|
||||||
|
.format(AhDateFormat)) ||
|
||||||
|
"",
|
||||||
|
StartDate: job.date_repairstarted
|
||||||
|
? (job.date_repairstarted &&
|
||||||
|
moment(job.date_repairstarted)
|
||||||
|
.tz(job.bodyshop.timezone)
|
||||||
|
.format(AhDateFormat)) ||
|
||||||
|
""
|
||||||
|
: (job.date_repairstarted &&
|
||||||
|
moment(job.actual_in)
|
||||||
|
.tz(job.bodyshop.timezone)
|
||||||
|
.format(AhDateFormat)) ||
|
||||||
|
"",
|
||||||
|
BodyStart: "",
|
||||||
|
BodyEnd: "",
|
||||||
|
FrameStart: "",
|
||||||
|
FrameEnd: "",
|
||||||
|
PrepStart: "",
|
||||||
|
PrepEnd: "",
|
||||||
|
SprayStart: "",
|
||||||
|
SprayEnd: "",
|
||||||
|
DateReady:
|
||||||
|
(job.actual_completion &&
|
||||||
|
moment(job.actual_completion)
|
||||||
|
.tz(job.bodyshop.timezone)
|
||||||
|
.format(AhDateFormat)) ||
|
||||||
|
"",
|
||||||
|
DateScheduledDelivery:
|
||||||
|
(job.scheduled_delivery &&
|
||||||
|
moment(job.scheduled_delivery)
|
||||||
|
.tz(job.bodyshop.timezone)
|
||||||
|
.format(AhDateFormat)) ||
|
||||||
|
"",
|
||||||
|
DateDelivered:
|
||||||
|
(job.actual_delivery &&
|
||||||
|
moment(job.actual_delivery)
|
||||||
|
.tz(job.bodyshop.timezone)
|
||||||
|
.format(AhDateFormat)) ||
|
||||||
|
"",
|
||||||
|
DateClosed:
|
||||||
|
(job.date_invoiced &&
|
||||||
|
moment(job.date_invoiced)
|
||||||
|
.tz(job.bodyshop.timezone)
|
||||||
|
.format(AhDateFormat)) ||
|
||||||
|
"",
|
||||||
|
BilledDate: "",
|
||||||
|
PaidInFullDate: "",
|
||||||
|
RoStatus: job.tlos_ind
|
||||||
|
? "TOT"
|
||||||
|
: StatusMapping(job.status, job.bodyshop.md_ro_statuses),
|
||||||
|
},
|
||||||
|
Sales: {
|
||||||
|
Body: Dinero(job.job_totals.rates.lab.total)
|
||||||
|
.add(Dinero(job.job_totals.rates.laa.total))
|
||||||
|
.add(Dinero(job.job_totals.rates.lad.total))
|
||||||
|
.add(Dinero(job.job_totals.rates.las.total))
|
||||||
|
.toFormat(CCDineroFormat),
|
||||||
|
Refinish: Dinero(job.job_totals.rates.lar.total).toFormat(
|
||||||
|
CCDineroFormat
|
||||||
|
),
|
||||||
|
Prep: Dinero().toFormat(CCDineroFormat),
|
||||||
|
Frame: Dinero(job.job_totals.rates.laf.total).toFormat(CCDineroFormat),
|
||||||
|
Mechanical: Dinero(job.job_totals.rates.lam.total).toFormat(
|
||||||
|
CCDineroFormat
|
||||||
|
),
|
||||||
|
Glass: Dinero(job.job_totals.rates.lag.total).toFormat(CCDineroFormat),
|
||||||
|
Elec: Dinero(job.job_totals.rates.lae.total).toFormat(CCDineroFormat),
|
||||||
|
Detail: detailAdjustments.amount.toFormat(CCDineroFormat),
|
||||||
|
Reassem: Dinero().toFormat(CCDineroFormat),
|
||||||
|
OtherLabor: Dinero(job.job_totals.rates.la1.total)
|
||||||
|
.add(Dinero(job.job_totals.rates.la2.total))
|
||||||
|
.add(Dinero(job.job_totals.rates.la3.total))
|
||||||
|
.add(Dinero(job.job_totals.rates.la4.total))
|
||||||
|
.add(Dinero(job.job_totals.rates.lau.total))
|
||||||
|
.subtract(detailAdjustments.amount)
|
||||||
|
.toFormat(CCDineroFormat),
|
||||||
|
BMatl: Dinero(job.job_totals.rates.mash.total).toFormat(CCDineroFormat),
|
||||||
|
PMatl: Dinero(job.job_totals.rates.mapa.total).toFormat(CCDineroFormat),
|
||||||
|
OEM: Dinero(
|
||||||
|
job.job_totals.parts.parts.list.PAN &&
|
||||||
|
job.job_totals.parts.parts.list.PAN.total
|
||||||
|
)
|
||||||
|
.add(
|
||||||
|
Dinero(
|
||||||
|
job.job_totals.parts.parts.list.PAP &&
|
||||||
|
job.job_totals.parts.parts.list.PAP.total
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.toFormat(CCDineroFormat),
|
||||||
|
LKQ: Dinero(
|
||||||
|
job.job_totals.parts.parts.list.PAL &&
|
||||||
|
job.job_totals.parts.parts.list.PAL.total
|
||||||
|
).toFormat(CCDineroFormat),
|
||||||
|
AM: Dinero(
|
||||||
|
job.job_totals.parts.parts.list.PAA &&
|
||||||
|
job.job_totals.parts.parts.list.PAA.total
|
||||||
|
).toFormat(CCDineroFormat),
|
||||||
|
MechParts: Dinero().toFormat(CCDineroFormat),
|
||||||
|
OtherParts: Dinero(
|
||||||
|
job.job_totals.parts.parts.list.PAO &&
|
||||||
|
job.job_totals.parts.parts.list.PAO.total
|
||||||
|
).toFormat(CCDineroFormat),
|
||||||
|
OtherSales: Dinero(job.job_totals.additional.storage).toFormat(
|
||||||
|
CCDineroFormat
|
||||||
|
),
|
||||||
|
Sublet: Dinero(job.job_totals.parts.sublets.total).toFormat(
|
||||||
|
CCDineroFormat
|
||||||
|
),
|
||||||
|
Towing: Dinero(job.job_totals.additional.towing).toFormat(
|
||||||
|
CCDineroFormat
|
||||||
|
),
|
||||||
|
Rental:
|
||||||
|
job.job_totals.additional.additionalCostItems.includes(
|
||||||
|
"ATS Amount"
|
||||||
|
) === true
|
||||||
|
? Dinero(
|
||||||
|
job.job_totals.additional.additionalCostItems[
|
||||||
|
job.job_totals.additional.additionalCostItems.indexOf(
|
||||||
|
"ATS Amount"
|
||||||
|
)
|
||||||
|
].total
|
||||||
|
).toFormat(CCDineroFormat)
|
||||||
|
: Dinero().toFormat(CCDineroFormat),
|
||||||
|
HazWaste: Dinero().toFormat(CCDineroFormat),
|
||||||
|
Discounts: Dinero(job.job_totals.additional.adjustments).toFormat(
|
||||||
|
CCDineroFormat
|
||||||
|
),
|
||||||
|
Tax: Dinero(job.job_totals.totals.local_tax)
|
||||||
|
.add(Dinero(job.job_totals.totals.state_tax))
|
||||||
|
.add(Dinero(job.job_totals.totals.federal_tax))
|
||||||
|
.add(Dinero(job.job_totals.additional.pvrt))
|
||||||
|
.toFormat(CCDineroFormat),
|
||||||
|
NetSaleTotal: Dinero(job.job_totals.totals.subtotal).toFormat(
|
||||||
|
CCDineroFormat
|
||||||
|
),
|
||||||
|
SaleTotal: Dinero(job.job_totals.totals.total_repairs).toFormat(
|
||||||
|
CCDineroFormat
|
||||||
|
),
|
||||||
|
},
|
||||||
|
SaleHours: {
|
||||||
|
Body: job.job_totals.rates.lab.hours.toFixed(2),
|
||||||
|
BodyRepairHours: job.joblines
|
||||||
|
.filter((line) => repairOpCodes.includes(line.lbr_op))
|
||||||
|
.reduce((acc, val) => acc + val.mod_lb_hrs, 0)
|
||||||
|
.toFixed(2),
|
||||||
|
BodyReplaceHours: job.joblines
|
||||||
|
.filter((line) => replaceOpCodes.includes(line.lbr_op))
|
||||||
|
.reduce((acc, val) => acc + val.mod_lb_hrs, 0)
|
||||||
|
.toFixed(2),
|
||||||
|
Paint: job.job_totals.rates.lar.hours.toFixed(2),
|
||||||
|
Prep: "0.00",
|
||||||
|
FrameHours: job.job_totals.rates.laf.hours.toFixed(2),
|
||||||
|
MechanicalHours: job.job_totals.rates.lam.hours.toFixed(2),
|
||||||
|
GlassHours: job.job_totals.rates.lag.hours.toFixed(2),
|
||||||
|
ElectricalHours: job.job_totals.rates.lae.hours.toFixed(2),
|
||||||
|
DetailHours: detailAdjustments.hours,
|
||||||
|
Reassem: "0.00",
|
||||||
|
Other: (
|
||||||
|
job.job_totals.rates.la1.hours +
|
||||||
|
job.job_totals.rates.la2.hours +
|
||||||
|
job.job_totals.rates.la3.hours +
|
||||||
|
job.job_totals.rates.la4.hours +
|
||||||
|
job.job_totals.rates.lau.hours -
|
||||||
|
detailAdjustments.hours
|
||||||
|
).toFixed(2),
|
||||||
|
TotalHours: job.joblines
|
||||||
|
.reduce((acc, val) => acc + val.mod_lb_hrs, 0)
|
||||||
|
.toFixed(2),
|
||||||
|
},
|
||||||
|
Costs: {
|
||||||
|
Body: repairCosts.BodyLaborTotalCost.toFormat(CCDineroFormat),
|
||||||
|
Paint: repairCosts.RefinishLaborTotalCost.toFormat(CCDineroFormat),
|
||||||
|
Prep: Dinero().toFormat(CCDineroFormat),
|
||||||
|
Frame: Dinero(job.job_totals.rates.laf.total).toFormat(CCDineroFormat),
|
||||||
|
Mech: repairCosts.MechanicalLaborTotalCost.toFormat(CCDineroFormat),
|
||||||
|
Glass: repairCosts.GlassLaborTotalCost.toFormat(CCDineroFormat),
|
||||||
|
Elec: repairCosts.ElectricalLaborTotalCost.toFormat(CCDineroFormat),
|
||||||
|
Detail: Dinero().toFormat(CCDineroFormat),
|
||||||
|
Reassem: Dinero().toFormat(CCDineroFormat),
|
||||||
|
OtherLabor: repairCosts.LaborMiscTotalCost.toFormat(CCDineroFormat),
|
||||||
|
Bmatl: repairCosts.BMTotalCost.toFormat(CCDineroFormat),
|
||||||
|
Pmatl: repairCosts.PMTotalCost.toFormat(CCDineroFormat),
|
||||||
|
OEM: repairCosts.PartsOemCost.toFormat(CCDineroFormat),
|
||||||
|
LKQ: repairCosts.PartsRecycledCost.toFormat(CCDineroFormat),
|
||||||
|
AM: repairCosts.PartsAMCost.toFormat(CCDineroFormat),
|
||||||
|
MechParts: Dinero().toFormat(CCDineroFormat),
|
||||||
|
OtherParts: Dinero().toFormat(CCDineroFormat), //Check Synergy
|
||||||
|
OtherCosts: repairCosts.PartsOtherCost.toFormat(CCDineroFormat),
|
||||||
|
Sublet: repairCosts.SubletTotalCost.toFormat(CCDineroFormat),
|
||||||
|
Towing: repairCosts.TowingTotalCost.toFormat(CCDineroFormat),
|
||||||
|
Storage: repairCosts.StorageTotalCost.toFormat(CCDineroFormat),
|
||||||
|
Rental: Dinero().toFormat(CCDineroFormat),
|
||||||
|
HazWaste: Dinero().toFormat(CCDineroFormat),
|
||||||
|
CostTotal: repairCosts.TotalCost.toFormat(CCDineroFormat),
|
||||||
|
},
|
||||||
|
CostHours: {
|
||||||
|
Body: repairCosts.BodyLaborTotalHrs.toFixed(2),
|
||||||
|
Paint: repairCosts.RefinishLaborTotalHrs.toFixed(2),
|
||||||
|
Prep: "0.00",
|
||||||
|
Frame: repairCosts.FrameLaborTotalHrs.toFixed(2),
|
||||||
|
Mech: repairCosts.MechanicalLaborTotalHrs.toFixed(2),
|
||||||
|
Glass: repairCosts.GlassLaborTotalHrs.toFixed(2),
|
||||||
|
Elec: repairCosts.ElectricalLaborTotalHrs.toFixed(2),
|
||||||
|
Detail: "0.00",
|
||||||
|
Other: repairCosts.LaborMiscTotalHrs.toFixed(2),
|
||||||
|
CostTotalHours: repairCosts.TotalHrs.toFixed(2),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return ret;
|
||||||
|
} catch (error) {
|
||||||
|
logger.log("claimscorp-job-calculate-error", "ERROR", "api", null, {
|
||||||
|
error,
|
||||||
|
});
|
||||||
|
|
||||||
|
errorCallback({ jobid: job.id, ro_number: job.ro_number, error });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const CreateCosts = (job) => {
|
||||||
|
//Create a mapping based on AH Requirements
|
||||||
|
|
||||||
|
//For DMS, the keys in the object below are the CIECA part types.
|
||||||
|
const billTotalsByCostCenters = job.bills.reduce((bill_acc, bill_val) => {
|
||||||
|
//At the bill level.
|
||||||
|
bill_val.billlines.map((line_val) => {
|
||||||
|
//At the bill line level.
|
||||||
|
|
||||||
|
if (!bill_acc[line_val.cost_center])
|
||||||
|
bill_acc[line_val.cost_center] = Dinero();
|
||||||
|
|
||||||
|
bill_acc[line_val.cost_center] = bill_acc[line_val.cost_center].add(
|
||||||
|
Dinero({
|
||||||
|
amount: Math.round((line_val.actual_cost || 0) * 100),
|
||||||
|
})
|
||||||
|
.multiply(line_val.quantity)
|
||||||
|
.multiply(bill_val.is_credit_memo ? -1 : 1)
|
||||||
|
);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
return bill_acc;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
//If the hourly rates for job costing are set, add them in.
|
||||||
|
if (
|
||||||
|
job.bodyshop.jc_hourly_rates &&
|
||||||
|
(job.bodyshop.jc_hourly_rates.mapa ||
|
||||||
|
typeof job.bodyshop.jc_hourly_rates.mapa === "number" ||
|
||||||
|
isNaN(job.bodyshop.jc_hourly_rates.mapa) === false)
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
!billTotalsByCostCenters[
|
||||||
|
job.bodyshop.md_responsibility_centers.defaults.costs.MAPA
|
||||||
|
]
|
||||||
|
)
|
||||||
|
billTotalsByCostCenters[
|
||||||
|
job.bodyshop.md_responsibility_centers.defaults.costs.MAPA
|
||||||
|
] = Dinero();
|
||||||
|
if (job.bodyshop.use_paint_scale_data === true) {
|
||||||
|
if (job.mixdata.length > 0) {
|
||||||
|
billTotalsByCostCenters[
|
||||||
|
job.bodyshop.md_responsibility_centers.defaults.costs.MAPA
|
||||||
|
] = Dinero({
|
||||||
|
amount: Math.round(
|
||||||
|
((job.mixdata[0] && job.mixdata[0].totalliquidcost) || 0) * 100
|
||||||
|
),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
billTotalsByCostCenters[
|
||||||
|
job.bodyshop.md_responsibility_centers.defaults.costs.MAPA
|
||||||
|
] = billTotalsByCostCenters[
|
||||||
|
job.bodyshop.md_responsibility_centers.defaults.costs.MAPA
|
||||||
|
].add(
|
||||||
|
Dinero({
|
||||||
|
amount: Math.round(
|
||||||
|
(job.bodyshop.jc_hourly_rates &&
|
||||||
|
job.bodyshop.jc_hourly_rates.mapa * 100) ||
|
||||||
|
0
|
||||||
|
),
|
||||||
|
}).multiply(job.job_totals.rates.mapa.hours)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
billTotalsByCostCenters[
|
||||||
|
job.bodyshop.md_responsibility_centers.defaults.costs.MAPA
|
||||||
|
] = billTotalsByCostCenters[
|
||||||
|
job.bodyshop.md_responsibility_centers.defaults.costs.MAPA
|
||||||
|
].add(
|
||||||
|
Dinero({
|
||||||
|
amount: Math.round(
|
||||||
|
(job.bodyshop.jc_hourly_rates &&
|
||||||
|
job.bodyshop.jc_hourly_rates.mapa * 100) ||
|
||||||
|
0
|
||||||
|
),
|
||||||
|
}).multiply(job.job_totals.rates.mapa.hours)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (job.bodyshop.jc_hourly_rates && job.bodyshop.jc_hourly_rates.mash) {
|
||||||
|
if (
|
||||||
|
!billTotalsByCostCenters[
|
||||||
|
job.bodyshop.md_responsibility_centers.defaults.costs.MASH
|
||||||
|
]
|
||||||
|
)
|
||||||
|
billTotalsByCostCenters[
|
||||||
|
job.bodyshop.md_responsibility_centers.defaults.costs.MASH
|
||||||
|
] = Dinero();
|
||||||
|
billTotalsByCostCenters[
|
||||||
|
job.bodyshop.md_responsibility_centers.defaults.costs.MASH
|
||||||
|
] = billTotalsByCostCenters[
|
||||||
|
job.bodyshop.md_responsibility_centers.defaults.costs.MASH
|
||||||
|
].add(
|
||||||
|
Dinero({
|
||||||
|
amount: Math.round(
|
||||||
|
(job.bodyshop.jc_hourly_rates &&
|
||||||
|
job.bodyshop.jc_hourly_rates.mash * 100) ||
|
||||||
|
0
|
||||||
|
),
|
||||||
|
}).multiply(job.job_totals.rates.mash.hours)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
//Uses CIECA Labor types.
|
||||||
|
const ticketTotalsByCostCenter = job.timetickets.reduce(
|
||||||
|
(ticket_acc, ticket_val) => {
|
||||||
|
//At the invoice level.
|
||||||
|
if (!ticket_acc[ticket_val.cost_center])
|
||||||
|
ticket_acc[ticket_val.cost_center] = Dinero();
|
||||||
|
|
||||||
|
ticket_acc[ticket_val.cost_center] = ticket_acc[
|
||||||
|
ticket_val.cost_center
|
||||||
|
].add(
|
||||||
|
Dinero({
|
||||||
|
amount: Math.round((ticket_val.rate || 0) * 100),
|
||||||
|
}).multiply(
|
||||||
|
(ticket_val.flat_rate
|
||||||
|
? ticket_val.productivehrs
|
||||||
|
: ticket_val.actualhrs) || 0
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return ticket_acc;
|
||||||
|
},
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
const ticketHrsByCostCenter = job.timetickets.reduce(
|
||||||
|
(ticket_acc, ticket_val) => {
|
||||||
|
//At the invoice level.
|
||||||
|
if (!ticket_acc[ticket_val.cost_center])
|
||||||
|
ticket_acc[ticket_val.cost_center] = 0;
|
||||||
|
|
||||||
|
ticket_acc[ticket_val.cost_center] =
|
||||||
|
ticket_acc[ticket_val.cost_center] +
|
||||||
|
(ticket_val.flat_rate
|
||||||
|
? ticket_val.productivehrs
|
||||||
|
: ticket_val.actualhrs) || 0;
|
||||||
|
|
||||||
|
return ticket_acc;
|
||||||
|
},
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
//CIECA STANDARD MAPPING OBJECT.
|
||||||
|
|
||||||
|
const ciecaObj = {
|
||||||
|
ATS: "ATS",
|
||||||
|
LA1: "LA1",
|
||||||
|
LA2: "LA2",
|
||||||
|
LA3: "LA3",
|
||||||
|
LA4: "LA4",
|
||||||
|
LAA: "LAA",
|
||||||
|
LAB: "LAB",
|
||||||
|
LAD: "LAD",
|
||||||
|
LAE: "LAE",
|
||||||
|
LAF: "LAF",
|
||||||
|
LAG: "LAG",
|
||||||
|
LAM: "LAM",
|
||||||
|
LAR: "LAR",
|
||||||
|
LAS: "LAS",
|
||||||
|
LAU: "LAU",
|
||||||
|
PAA: "PAA",
|
||||||
|
PAC: "PAC",
|
||||||
|
PAG: "PAG",
|
||||||
|
PAL: "PAL",
|
||||||
|
PAM: "PAM",
|
||||||
|
PAN: "PAN",
|
||||||
|
PAO: "PAO",
|
||||||
|
PAP: "PAP",
|
||||||
|
PAR: "PAR",
|
||||||
|
PAS: "PAS",
|
||||||
|
TOW: "TOW",
|
||||||
|
MAPA: "MAPA",
|
||||||
|
MASH: "MASH",
|
||||||
|
PASL: "PASL",
|
||||||
|
};
|
||||||
|
const defaultCosts =
|
||||||
|
job.bodyshop.cdk_dealerid || job.bodyshop.pbs_serialnumber
|
||||||
|
? ciecaObj
|
||||||
|
: job.bodyshop.md_responsibility_centers.defaults.costs;
|
||||||
|
|
||||||
|
return {
|
||||||
|
PartsTotalCost: Object.keys(billTotalsByCostCenters).reduce((acc, key) => {
|
||||||
|
if (
|
||||||
|
key !== defaultCosts.PAS &&
|
||||||
|
key !== defaultCosts.PASL &&
|
||||||
|
key !== defaultCosts.MAPA &&
|
||||||
|
key !== defaultCosts.MASH &&
|
||||||
|
key !== defaultCosts.TOW
|
||||||
|
)
|
||||||
|
return acc.add(billTotalsByCostCenters[key]);
|
||||||
|
return acc;
|
||||||
|
}, Dinero()),
|
||||||
|
PartsOemCost: (billTotalsByCostCenters[defaultCosts.PAN] || Dinero()).add(
|
||||||
|
billTotalsByCostCenters[defaultCosts.PAP] || Dinero()
|
||||||
|
),
|
||||||
|
PartsAMCost: billTotalsByCostCenters[defaultCosts.PAA] || Dinero(),
|
||||||
|
PartsReconditionedCost:
|
||||||
|
billTotalsByCostCenters[defaultCosts.PAM] || Dinero(),
|
||||||
|
PartsRecycledCost: billTotalsByCostCenters[defaultCosts.PAL] || Dinero(),
|
||||||
|
PartsOtherCost: billTotalsByCostCenters[defaultCosts.PAO] || Dinero(),
|
||||||
|
SubletTotalCost:
|
||||||
|
billTotalsByCostCenters[defaultCosts.PAS] ||
|
||||||
|
Dinero(billTotalsByCostCenters[defaultCosts.PASL] || Dinero()),
|
||||||
|
BodyLaborTotalCost: ticketTotalsByCostCenter[defaultCosts.LAB] || Dinero(),
|
||||||
|
BodyLaborTotalHrs: ticketHrsByCostCenter[defaultCosts.LAB] || 0,
|
||||||
|
RefinishLaborTotalCost:
|
||||||
|
ticketTotalsByCostCenter[defaultCosts.LAR] || Dinero(),
|
||||||
|
RefinishLaborTotalHrs: ticketHrsByCostCenter[defaultCosts.LAR] || 0,
|
||||||
|
MechanicalLaborTotalCost:
|
||||||
|
ticketTotalsByCostCenter[defaultCosts.LAM] || Dinero(),
|
||||||
|
MechanicalLaborTotalHrs: ticketHrsByCostCenter[defaultCosts.LAM] || 0,
|
||||||
|
StructuralLaborTotalCost:
|
||||||
|
ticketTotalsByCostCenter[defaultCosts.LAS] || Dinero(),
|
||||||
|
StructuralLaborTotalHrs: ticketHrsByCostCenter[defaultCosts.LAS] || 0,
|
||||||
|
ElectricalLaborTotalCost:
|
||||||
|
ticketTotalsByCostCenter[defaultCosts.LAE] || Dinero(),
|
||||||
|
ElectricalLaborTotalHrs: ticketHrsByCostCenter[defaultCosts.LAE] || 0,
|
||||||
|
FrameLaborTotalCost: ticketTotalsByCostCenter[defaultCosts.LAF] || Dinero(),
|
||||||
|
FrameLaborTotalHrs: ticketHrsByCostCenter[defaultCosts.LAF] || 0,
|
||||||
|
GlassLaborTotalCost: ticketTotalsByCostCenter[defaultCosts.LAG] || Dinero(),
|
||||||
|
GlassLaborTotalHrs: ticketHrsByCostCenter[defaultCosts.LAG] || 0,
|
||||||
|
DetailLaborTotalCost: Dinero(),
|
||||||
|
// ticketTotalsByCostCenter[defaultCosts.LAD] || Dinero(),
|
||||||
|
LaborMiscTotalCost: (ticketTotalsByCostCenter[defaultCosts.LA1] || Dinero())
|
||||||
|
.add(ticketTotalsByCostCenter[defaultCosts.LA2] || Dinero())
|
||||||
|
.add(ticketTotalsByCostCenter[defaultCosts.LA2] || Dinero())
|
||||||
|
.add(ticketTotalsByCostCenter[defaultCosts.LA3] || Dinero())
|
||||||
|
.add(ticketTotalsByCostCenter[defaultCosts.LA4] || Dinero())
|
||||||
|
.add(ticketTotalsByCostCenter[defaultCosts.LAU] || Dinero()),
|
||||||
|
LaborMiscTotalHrs:
|
||||||
|
(ticketHrsByCostCenter[defaultCosts.LA1] || 0) +
|
||||||
|
(ticketHrsByCostCenter[defaultCosts.LA2] || 0) +
|
||||||
|
(ticketHrsByCostCenter[defaultCosts.LA3] || 0) +
|
||||||
|
(ticketHrsByCostCenter[defaultCosts.LA4] || 0) +
|
||||||
|
(ticketHrsByCostCenter[defaultCosts.LAU] || 0),
|
||||||
|
PMTotalCost: billTotalsByCostCenters[defaultCosts.MAPA] || Dinero(),
|
||||||
|
BMTotalCost: billTotalsByCostCenters[defaultCosts.MASH] || Dinero(),
|
||||||
|
MiscTotalCost: billTotalsByCostCenters[defaultCosts.PAO] || Dinero(),
|
||||||
|
TowingTotalCost: billTotalsByCostCenters[defaultCosts.TOW] || Dinero(),
|
||||||
|
StorageTotalCost: Dinero(),
|
||||||
|
DetailTotal: Dinero(),
|
||||||
|
DetailTotalCost: Dinero(),
|
||||||
|
SalesTaxTotalCost: Dinero(),
|
||||||
|
LabourTotalCost: Object.keys(ticketTotalsByCostCenter).reduce(
|
||||||
|
(acc, key) => {
|
||||||
|
return acc.add(ticketTotalsByCostCenter[key]);
|
||||||
|
},
|
||||||
|
Dinero()
|
||||||
|
),
|
||||||
|
TotalCost: Object.keys(billTotalsByCostCenters).reduce((acc, key) => {
|
||||||
|
return acc.add(billTotalsByCostCenters[key]);
|
||||||
|
}, Dinero()),
|
||||||
|
TotalHrs: job.timetickets.reduce((acc, ticket_val) => {
|
||||||
|
return (
|
||||||
|
acc +
|
||||||
|
(ticket_val.flat_rate
|
||||||
|
? ticket_val.productivehrs
|
||||||
|
: ticket_val.actualhrs) || 0
|
||||||
|
);
|
||||||
|
}, 0),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const StatusMapping = (status, md_ro_statuses) => {
|
||||||
|
//Possible return statuses CLO, CAN, OPN
|
||||||
|
const {
|
||||||
|
default_imported,
|
||||||
|
default_open,
|
||||||
|
default_scheduled,
|
||||||
|
default_arrived,
|
||||||
|
default_completed,
|
||||||
|
default_delivered,
|
||||||
|
default_invoiced,
|
||||||
|
default_exported,
|
||||||
|
default_void,
|
||||||
|
} = md_ro_statuses;
|
||||||
|
|
||||||
|
if (
|
||||||
|
status === default_open ||
|
||||||
|
status === default_imported ||
|
||||||
|
status === default_scheduled ||
|
||||||
|
status === default_arrived ||
|
||||||
|
status === default_completed ||
|
||||||
|
status === default_delivered ||
|
||||||
|
md_ro_statuses.production_statuses.includes(status)
|
||||||
|
)
|
||||||
|
return "OPN";
|
||||||
|
else if (status === default_invoiced || status === default_exported)
|
||||||
|
return "CLO";
|
||||||
|
else if (status === default_void) return "CAN";
|
||||||
|
else return "UNDEFINED";
|
||||||
|
};
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
exports.autohouse = require("./autohouse").default;
|
exports.autohouse = require("./autohouse").default;
|
||||||
exports.arms = require("./arms").default;
|
exports.claimscorp = require("./claimscorp").default;
|
||||||
|
exports.arms = require("./arms").default;
|
||||||
@@ -841,6 +841,179 @@ exports.AUTOHOUSE_QUERY = `query AUTOHOUSE_EXPORT($start: timestamptz, $bodyshop
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports.CLAIMSCORP_QUERY = `query CLAIMSCORP_EXPORT($start: timestamptz, $bodyshopid: uuid!, $end: timestamptz) {
|
||||||
|
bodyshops_by_pk(id: $bodyshopid){
|
||||||
|
id
|
||||||
|
shopname
|
||||||
|
address1
|
||||||
|
city
|
||||||
|
state
|
||||||
|
zip_post
|
||||||
|
country
|
||||||
|
phone
|
||||||
|
md_ro_statuses
|
||||||
|
md_order_statuses
|
||||||
|
claimscorpid
|
||||||
|
md_responsibility_centers
|
||||||
|
jc_hourly_rates
|
||||||
|
cdk_dealerid
|
||||||
|
pbs_serialnumber
|
||||||
|
use_paint_scale_data
|
||||||
|
timezone
|
||||||
|
}
|
||||||
|
jobs(where: {_and: [{converted: {_eq: true}}, {updated_at: {_gt: $start}}, {updated_at: {_lte: $end}}, {shopid: {_eq: $bodyshopid}}]}) {
|
||||||
|
id
|
||||||
|
created_at
|
||||||
|
ro_number
|
||||||
|
status
|
||||||
|
est_ct_fn
|
||||||
|
est_ct_ln
|
||||||
|
ownr_st
|
||||||
|
ownr_zip
|
||||||
|
tlos_ind
|
||||||
|
v_color
|
||||||
|
v_model_yr
|
||||||
|
v_model_desc
|
||||||
|
v_make_desc
|
||||||
|
v_vin
|
||||||
|
vehicle {
|
||||||
|
v_bstyle
|
||||||
|
}
|
||||||
|
ins_co_nm
|
||||||
|
clm_no
|
||||||
|
loss_date
|
||||||
|
asgn_date
|
||||||
|
date_estimated
|
||||||
|
date_open
|
||||||
|
scheduled_in
|
||||||
|
actual_in
|
||||||
|
scheduled_completion
|
||||||
|
actual_completion
|
||||||
|
scheduled_delivery
|
||||||
|
actual_delivery
|
||||||
|
date_invoiced
|
||||||
|
date_exported
|
||||||
|
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_matd
|
||||||
|
rate_mapa
|
||||||
|
rate_mash
|
||||||
|
job_totals
|
||||||
|
parts_tax_rates
|
||||||
|
date_repairstarted
|
||||||
|
joblines(where: {removed: {_eq: false}}) {
|
||||||
|
id
|
||||||
|
line_no
|
||||||
|
line_ind
|
||||||
|
status
|
||||||
|
line_ind
|
||||||
|
db_price
|
||||||
|
act_price
|
||||||
|
mod_lb_hrs
|
||||||
|
mod_lbr_ty
|
||||||
|
line_desc
|
||||||
|
prt_dsmk_m
|
||||||
|
prt_dsmk_p
|
||||||
|
part_qty
|
||||||
|
part_type
|
||||||
|
oem_partno
|
||||||
|
lbr_op
|
||||||
|
profitcenter_part
|
||||||
|
profitcenter_labor
|
||||||
|
ah_detail_line
|
||||||
|
parts_order_lines(order_by: {parts_order: {order_date: desc_nulls_last}} limit: 1){
|
||||||
|
parts_order{
|
||||||
|
id
|
||||||
|
order_date
|
||||||
|
}
|
||||||
|
}
|
||||||
|
billlines(order_by: {bill: {date: desc_nulls_last}} limit: 1) {
|
||||||
|
actual_cost
|
||||||
|
actual_price
|
||||||
|
quantity
|
||||||
|
bill {
|
||||||
|
vendor {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
invoice_number
|
||||||
|
date
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bills {
|
||||||
|
id
|
||||||
|
federal_tax_rate
|
||||||
|
local_tax_rate
|
||||||
|
state_tax_rate
|
||||||
|
is_credit_memo
|
||||||
|
billlines {
|
||||||
|
actual_cost
|
||||||
|
cost_center
|
||||||
|
id
|
||||||
|
quantity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
employee_body_rel {
|
||||||
|
first_name
|
||||||
|
last_name
|
||||||
|
employee_number
|
||||||
|
id
|
||||||
|
}
|
||||||
|
employee_csr_rel {
|
||||||
|
first_name
|
||||||
|
last_name
|
||||||
|
employee_number
|
||||||
|
id
|
||||||
|
}
|
||||||
|
employee_prep_rel {
|
||||||
|
first_name
|
||||||
|
last_name
|
||||||
|
employee_number
|
||||||
|
id
|
||||||
|
}
|
||||||
|
employee_refinish_rel {
|
||||||
|
first_name
|
||||||
|
last_name
|
||||||
|
employee_number
|
||||||
|
id
|
||||||
|
}
|
||||||
|
parts_orders(limit: 1, order_by: {created_at: desc}) {
|
||||||
|
created_at
|
||||||
|
}
|
||||||
|
timetickets {
|
||||||
|
id
|
||||||
|
rate
|
||||||
|
cost_center
|
||||||
|
actualhrs
|
||||||
|
productivehrs
|
||||||
|
flat_rate
|
||||||
|
}
|
||||||
|
mixdata(limit: 1, order_by: {updated_at: desc}) {
|
||||||
|
jobid
|
||||||
|
totalliquidcost
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
exports.ENTEGRAL_EXPORT = `
|
exports.ENTEGRAL_EXPORT = `
|
||||||
query ENTEGRAL_EXPORT($bodyshopid: uuid!) {
|
query ENTEGRAL_EXPORT($bodyshopid: uuid!) {
|
||||||
jobs(where: {_and: [{converted: {_eq: true}}, {shopid: {_eq: $bodyshopid}}]}) {
|
jobs(where: {_and: [{converted: {_eq: true}}, {shopid: {_eq: $bodyshopid}}]}) {
|
||||||
@@ -992,7 +1165,9 @@ exports.GET_JOB_BY_PK = `query GET_JOB_BY_PK($id: uuid!) {
|
|||||||
ins_ph1
|
ins_ph1
|
||||||
est_co_nm
|
est_co_nm
|
||||||
est_ct_fn
|
est_ct_fn
|
||||||
|
shopid
|
||||||
est_ct_ln
|
est_ct_ln
|
||||||
|
cieca_pfl
|
||||||
vehicle{
|
vehicle{
|
||||||
id
|
id
|
||||||
notes
|
notes
|
||||||
@@ -1389,6 +1564,27 @@ exports.GET_AUTOHOUSE_SHOPS = `query GET_AUTOHOUSE_SHOPS {
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports.GET_CLAIMSCORP_SHOPS = `query GET_CLAIMSCORP_SHOPS {
|
||||||
|
bodyshops(where: {claimscorpid: {_is_null: false}}){
|
||||||
|
id
|
||||||
|
shopname
|
||||||
|
address1
|
||||||
|
city
|
||||||
|
state
|
||||||
|
zip_post
|
||||||
|
country
|
||||||
|
phone
|
||||||
|
md_ro_statuses
|
||||||
|
md_order_statuses
|
||||||
|
claimscorpid
|
||||||
|
md_responsibility_centers
|
||||||
|
jc_hourly_rates
|
||||||
|
imexshopid
|
||||||
|
timezone
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
exports.GET_ENTEGRAL_SHOPS = `query GET_AUTOHOUSE_SHOPS {
|
exports.GET_ENTEGRAL_SHOPS = `query GET_AUTOHOUSE_SHOPS {
|
||||||
bodyshops(where: {entegral_id: {_is_null: false}}){
|
bodyshops(where: {entegral_id: {_is_null: false}}){
|
||||||
id
|
id
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ const queries = require("../graphql-client/queries");
|
|||||||
const Dinero = require("dinero.js");
|
const Dinero = require("dinero.js");
|
||||||
const qs = require("query-string");
|
const qs = require("query-string");
|
||||||
const axios = require("axios");
|
const axios = require("axios");
|
||||||
|
const moment = require("moment");
|
||||||
|
const logger = require("../utils/logger");
|
||||||
|
|
||||||
require("dotenv").config({
|
require("dotenv").config({
|
||||||
path: path.resolve(
|
path: path.resolve(
|
||||||
process.cwd(),
|
process.cwd(),
|
||||||
@@ -12,7 +15,15 @@ require("dotenv").config({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const domain = process.env.NODE_ENV ? "secure" : "test";
|
const domain = process.env.NODE_ENV ? "secure" : "test";
|
||||||
const SecretsManager = require("./aws-secrets-manager");
|
|
||||||
|
const {
|
||||||
|
SecretsManagerClient,
|
||||||
|
GetSecretValueCommand,
|
||||||
|
} = require("@aws-sdk/client-secrets-manager");
|
||||||
|
|
||||||
|
const client = new SecretsManagerClient({
|
||||||
|
region: "ca-central-1",
|
||||||
|
});
|
||||||
|
|
||||||
const gqlClient = require("../graphql-client/graphql-client").client;
|
const gqlClient = require("../graphql-client/graphql-client").client;
|
||||||
|
|
||||||
@@ -20,38 +31,55 @@ const getShopCredentials = async (bodyshop) => {
|
|||||||
// Development only
|
// Development only
|
||||||
if (process.env.NODE_ENV === undefined) {
|
if (process.env.NODE_ENV === undefined) {
|
||||||
return {
|
return {
|
||||||
merchantkey: process.env.DEV_INTELLIPAY_MERCHANTKEY,
|
merchantkey: process.env.INTELLIPAY_MERCHANTKEY,
|
||||||
apikey: process.env.DEV_INTELLIPAY_APIKEY,
|
apikey: process.env.INTELLIPAY_APIKEY,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Production code
|
// Production code
|
||||||
if (bodyshop?.imexshopid) {
|
if (bodyshop?.imexshopid) {
|
||||||
const secret = await SecretsManager.getSecret(
|
try {
|
||||||
`intellipay-credentials-${bodyshop.imexshopid}`,
|
const secret = await client.send(
|
||||||
process.env.REGION
|
new GetSecretValueCommand({
|
||||||
);
|
SecretId: `intellipay-credentials-${bodyshop.imexshopid}`,
|
||||||
|
VersionStage: "AWSCURRENT", // VersionStage defaults to AWSCURRENT if unspecified
|
||||||
return JSON.parse(secret);
|
})
|
||||||
|
);
|
||||||
|
return JSON.parse(secret.SecretString);
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
error: error.message,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.lightbox_credentials = async (req, res) => {
|
exports.lightbox_credentials = async (req, res) => {
|
||||||
|
logger.log(
|
||||||
|
"intellipay-lightbox-credentials",
|
||||||
|
"DEBUG",
|
||||||
|
req.user?.email,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
const shopCredentials = await getShopCredentials(req.body.bodyshop);
|
const shopCredentials = await getShopCredentials(req.body.bodyshop);
|
||||||
|
|
||||||
|
if (shopCredentials.error) {
|
||||||
|
res.json(shopCredentials);
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const options = {
|
const options = {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "content-type": "application/x-www-form-urlencoded" },
|
headers: { "content-type": "application/x-www-form-urlencoded" },
|
||||||
//TODO: Move these to environment variables/database.
|
|
||||||
data: qs.stringify({
|
data: qs.stringify({
|
||||||
...shopCredentials,
|
...shopCredentials,
|
||||||
operatingenv:
|
operatingenv: "businessattended",
|
||||||
process.env.NODE_ENV === undefined
|
|
||||||
? process.env.NODE_ENV
|
|
||||||
: "businessattended",
|
|
||||||
}),
|
}),
|
||||||
url: `https://${domain}.cpteller.com/api/custapi.cfc?method=autoterminal`,
|
url: `https://${domain}.cpteller.com/api/custapi.cfc?method=autoterminal${
|
||||||
|
req.body.refresh ? "_refresh" : ""
|
||||||
|
}`, //autoterminal_refresh
|
||||||
};
|
};
|
||||||
|
|
||||||
const response = await axios(options);
|
const response = await axios(options);
|
||||||
@@ -59,11 +87,20 @@ exports.lightbox_credentials = async (req, res) => {
|
|||||||
res.send(response.data);
|
res.send(response.data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
logger.log(
|
||||||
|
"intellipay-lightbox-credentials-error",
|
||||||
|
"ERROR",
|
||||||
|
req.user?.email,
|
||||||
|
null,
|
||||||
|
{ error: JSON.stringify(error) }
|
||||||
|
);
|
||||||
res.json({ error });
|
res.json({ error });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.payment_refund = async (req, res) => {
|
exports.payment_refund = async (req, res) => {
|
||||||
|
logger.log("intellipay-refund", "DEBUG", req.user?.email, null, null);
|
||||||
|
|
||||||
const shopCredentials = await getShopCredentials(req.body.bodyshop);
|
const shopCredentials = await getShopCredentials(req.body.bodyshop);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -85,11 +122,15 @@ exports.payment_refund = async (req, res) => {
|
|||||||
res.send(response.data);
|
res.send(response.data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
logger.log("intellipay-refund-error", "ERROR", req.user?.email, null, {
|
||||||
|
error: JSON.stringify(error),
|
||||||
|
});
|
||||||
res.json({ error });
|
res.json({ error });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.generate_payment_url = async (req, res) => {
|
exports.generate_payment_url = async (req, res) => {
|
||||||
|
logger.log("intellipay-payment-url", "DEBUG", req.user?.email, null, null);
|
||||||
const shopCredentials = await getShopCredentials(req.body.bodyshop);
|
const shopCredentials = await getShopCredentials(req.body.bodyshop);
|
||||||
try {
|
try {
|
||||||
const options = {
|
const options = {
|
||||||
@@ -100,6 +141,7 @@ exports.generate_payment_url = async (req, res) => {
|
|||||||
...shopCredentials,
|
...shopCredentials,
|
||||||
...req.body,
|
...req.body,
|
||||||
createshorturl: true,
|
createshorturl: true,
|
||||||
|
//The postback URL is set at the CP teller global terminal settings page.
|
||||||
}),
|
}),
|
||||||
url: `https://${domain}.cpteller.com/api/custapi.cfc?method=generate_lightbox_url`,
|
url: `https://${domain}.cpteller.com/api/custapi.cfc?method=generate_lightbox_url`,
|
||||||
};
|
};
|
||||||
@@ -109,76 +151,58 @@ exports.generate_payment_url = async (req, res) => {
|
|||||||
res.send(response.data);
|
res.send(response.data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
logger.log("intellipay-payment-url-error", "ERROR", req.user?.email, null, {
|
||||||
|
error: JSON.stringify(error),
|
||||||
|
});
|
||||||
res.json({ error });
|
res.json({ error });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.postback = async (req, res) => {
|
exports.postback = async (req, res) => {
|
||||||
console.log("postback as", req.body);
|
logger.log("intellipay-postback", "ERROR", req.user?.email, null, req.body);
|
||||||
|
|
||||||
const { body: values } = req;
|
const { body: values } = req;
|
||||||
|
|
||||||
|
if (!values.invoice) {
|
||||||
|
res.sendStatus(200);
|
||||||
|
return;
|
||||||
|
}
|
||||||
// TODO query job by account name
|
// TODO query job by account name
|
||||||
const job = await gqlClient.request(queries.GET_JOB_BY_RO_NUMBER, {
|
const job = await gqlClient.request(queries.GET_JOB_BY_PK, {
|
||||||
ro_number: values.account,
|
id: values.invoice,
|
||||||
});
|
});
|
||||||
// TODO add mutation to database
|
// TODO add mutation to database
|
||||||
|
|
||||||
const paymentResult = await gqlClient.request(queries.INSERT_NEW_PAYMENT, {
|
try {
|
||||||
paymentInput: {
|
const paymentResult = await gqlClient.request(queries.INSERT_NEW_PAYMENT, {
|
||||||
amount: values.total,
|
paymentInput: {
|
||||||
transactionid: `C00 ${values.authcode}`,
|
amount: values.total,
|
||||||
payer: "Customer",
|
transactionid: `C00 ${values.authcode}`,
|
||||||
type: values.cardtype,
|
payer: "Customer",
|
||||||
jobid: job.jobs[0].id,
|
type: values.cardtype,
|
||||||
date: moment(Date.now()),
|
jobid: values.invoice,
|
||||||
},
|
date: moment(Date.now()),
|
||||||
});
|
},
|
||||||
|
});
|
||||||
|
|
||||||
await gqlClient.request(queries.INSERT_PAYMENT_RESPONSE, {
|
await gqlClient.request(queries.INSERT_PAYMENT_RESPONSE, {
|
||||||
paymentResponse: {
|
paymentResponse: {
|
||||||
amount: values.total,
|
amount: values.total,
|
||||||
bodyshopid: job.jobs[0].bodyshop.id,
|
bodyshopid: job.jobs_by_pk.shopid,
|
||||||
paymentid: paymentResult.id,
|
paymentid: paymentResult.id,
|
||||||
jobid: job.jobs[0].id,
|
jobid: values.invoice,
|
||||||
declinereason: "Approved",
|
declinereason: "Approved",
|
||||||
ext_paymentid: values.paymentid,
|
ext_paymentid: values.paymentid,
|
||||||
successful: true,
|
successful: true,
|
||||||
response: values,
|
response: values,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
res.send({ message: "Postback Successful" });
|
res.send({ message: "Postback Successful" });
|
||||||
|
} catch (error) {
|
||||||
|
logger.log("intellipay-postback-error", "ERROR", req.user?.email, null, {
|
||||||
|
error: JSON.stringify(error),
|
||||||
|
body: req.body,
|
||||||
|
});
|
||||||
|
res.status(400).json({ succesful: false, error: error.message });
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
`{
|
|
||||||
ipaddress: '136.158.34.242',
|
|
||||||
firstname: 'JC',
|
|
||||||
notes: '',
|
|
||||||
city: '',
|
|
||||||
fee: ' 0.00',
|
|
||||||
origin: 'OneLink',
|
|
||||||
total: '5061.36',
|
|
||||||
avsdata: 'N',
|
|
||||||
arglist: '""',
|
|
||||||
state: ' ',
|
|
||||||
cardtype: 'Visa',
|
|
||||||
department: '',
|
|
||||||
email: '',
|
|
||||||
timestamp: "{ts '2023-03-23 09:52:23'}",
|
|
||||||
op: 'Kh6Pa6AT9keg',
|
|
||||||
amount: '5061.36',
|
|
||||||
method: 'CARD',
|
|
||||||
address2: '',
|
|
||||||
address1: '',
|
|
||||||
lastname: 'Tolentino',
|
|
||||||
zipcode: '1742 ',
|
|
||||||
authcode: '367885',
|
|
||||||
phone: '',
|
|
||||||
merchantid: '7114',
|
|
||||||
paymentid: '24205435',
|
|
||||||
customerid: '19610104',
|
|
||||||
comment: '',
|
|
||||||
invoice: '',
|
|
||||||
account: 'QBD241'
|
|
||||||
}`;
|
|
||||||
|
|||||||
@@ -389,7 +389,7 @@ async function CalculateRatesTotals({ job, client }) {
|
|||||||
lbr_op: "OP11",
|
lbr_op: "OP11",
|
||||||
lbr_amt: 0,
|
lbr_amt: 0,
|
||||||
op_code_desc: "REMOVE / REPLACE",
|
op_code_desc: "REMOVE / REPLACE",
|
||||||
tax_part: true,
|
tax_part: hasMahwLine.tax_amt > 0 ? true : false,
|
||||||
db_ref: null,
|
db_ref: null,
|
||||||
manual_line: true,
|
manual_line: true,
|
||||||
jobid: job.id,
|
jobid: job.id,
|
||||||
@@ -399,6 +399,26 @@ async function CalculateRatesTotals({ job, client }) {
|
|||||||
lineInput: [newMahwLine],
|
lineInput: [newMahwLine],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Materials Scrubbing as required by CCC.
|
||||||
|
let matTotalLine = job.cieca_stl.data.find((l) => l.ttl_typecd === "MAT");
|
||||||
|
let shopMatLine = job.cieca_stl.data.find((l) => l.ttl_typecd === "MASH");
|
||||||
|
|
||||||
|
if (matTotalLine && shopMatLine) {
|
||||||
|
//Check to see if theyre different
|
||||||
|
let calcMapaAmount = Dinero({
|
||||||
|
amount: Math.round(
|
||||||
|
(matTotalLine?.ttl_amt - shopMatLine?.ttl_amt - stlMahw?.ttl_amt) * 100
|
||||||
|
),
|
||||||
|
});
|
||||||
|
let mapaDifference = calcMapaAmount.subtract(ret.mapa.total);
|
||||||
|
if (mapaDifference.getAmount() > 0) {
|
||||||
|
//fix it.
|
||||||
|
ret.mapa.total = calcMapaAmount;
|
||||||
|
//Add the difference to the subt total as well.
|
||||||
|
subtotal = subtotal.add(mapaDifference);
|
||||||
|
}
|
||||||
|
}
|
||||||
ret.subtotal = subtotal;
|
ret.subtotal = subtotal;
|
||||||
ret.rates_subtotal = rates_subtotal;
|
ret.rates_subtotal = rates_subtotal;
|
||||||
|
|
||||||
@@ -690,7 +710,7 @@ function CalculateAdditional(job) {
|
|||||||
.reduce((acc, val) => {
|
.reduce((acc, val) => {
|
||||||
const lineValue = Dinero({
|
const lineValue = Dinero({
|
||||||
amount: Math.round((val.act_price || 0) * 100),
|
amount: Math.round((val.act_price || 0) * 100),
|
||||||
}).multiply(val.part_qty || 1);
|
}).multiply(val.part_qty);
|
||||||
|
|
||||||
if (val.db_ref === "936004") {
|
if (val.db_ref === "936004") {
|
||||||
//Shipping line IO-1921.
|
//Shipping line IO-1921.
|
||||||
@@ -796,9 +816,43 @@ function CalculateTaxesTotals(job, otherTotals) {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
console.log(statePartsTax.toFormat(), val.line_desc);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let laborTaxTotal = Dinero();
|
||||||
|
|
||||||
|
if (Object.keys(job.cieca_pfl).length > 0) {
|
||||||
|
//Do it by labor type
|
||||||
|
const types = [
|
||||||
|
"la1",
|
||||||
|
"la2",
|
||||||
|
"la3",
|
||||||
|
"la4",
|
||||||
|
"lau",
|
||||||
|
"laa",
|
||||||
|
"lab",
|
||||||
|
"lad",
|
||||||
|
"lae",
|
||||||
|
"laf",
|
||||||
|
"lag",
|
||||||
|
"lam",
|
||||||
|
"lar",
|
||||||
|
"las",
|
||||||
|
];
|
||||||
|
types.forEach((type) => {
|
||||||
|
laborTaxTotal = laborTaxTotal.add(
|
||||||
|
otherTotals.rates[type].total.percentage(
|
||||||
|
job.cieca_pfl[type.toUpperCase()]
|
||||||
|
? job.cieca_pfl[type.toUpperCase()].lbr_taxp
|
||||||
|
: (job.tax_lbr_rt || 0) * 100
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
//We don't have it, just add in how it was before.
|
||||||
|
laborTaxTotal = otherTotals.rates.subtotal.percentage(
|
||||||
|
(job.tax_lbr_rt || 0) * 100
|
||||||
|
); // THis is currently using the lbr tax rate from PFH not PFL.
|
||||||
|
}
|
||||||
let ret = {
|
let ret = {
|
||||||
subtotal: subtotal,
|
subtotal: subtotal,
|
||||||
federal_tax: subtotal
|
federal_tax: subtotal
|
||||||
@@ -810,9 +864,7 @@ function CalculateTaxesTotals(job, otherTotals) {
|
|||||||
),
|
),
|
||||||
statePartsTax,
|
statePartsTax,
|
||||||
state_tax: statePartsTax
|
state_tax: statePartsTax
|
||||||
.add(
|
.add(laborTaxTotal)
|
||||||
otherTotals.rates.subtotal.percentage((job.tax_lbr_rt || 0) * 100) // THis is currently using the lbr tax rate from PFH not PFL.
|
|
||||||
)
|
|
||||||
.add(
|
.add(
|
||||||
otherTotals.additional.adjustments.percentage(
|
otherTotals.additional.adjustments.percentage(
|
||||||
(job.tax_lbr_rt || 0) * 100
|
(job.tax_lbr_rt || 0) * 100
|
||||||
@@ -835,7 +887,7 @@ function CalculateTaxesTotals(job, otherTotals) {
|
|||||||
.add(
|
.add(
|
||||||
otherTotals.rates.mash.hasMashLine === false //If parts and materials were not added as lines, we must calculate the taxes on them.
|
otherTotals.rates.mash.hasMashLine === false //If parts and materials were not added as lines, we must calculate the taxes on them.
|
||||||
? otherTotals.rates.mash.total.percentage(
|
? otherTotals.rates.mash.total.percentage(
|
||||||
(job.tax_paint_mat_rt || 0) * 100
|
(job.tax_shop_mat_rt || 0) * 100
|
||||||
)
|
)
|
||||||
: Dinero()
|
: Dinero()
|
||||||
),
|
),
|
||||||
@@ -882,18 +934,15 @@ function DiscountNotAlreadyCounted(jobline, joblines) {
|
|||||||
(jobline.prt_dsmk_m / (jobline.act_price - jobline.prt_dsmk_m)) * 100
|
(jobline.prt_dsmk_m / (jobline.act_price - jobline.prt_dsmk_m)) * 100
|
||||||
) === Math.abs(jobline.prt_dsmk_p)
|
) === Math.abs(jobline.prt_dsmk_p)
|
||||||
) {
|
) {
|
||||||
console.log(jobline.line_desc, "Already had the discount counted.");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check it against the database price too? If it's an OE part.
|
//Check it against the database price too? If it's an OE part.
|
||||||
console.log(jobline.db_price - jobline.act_price);
|
|
||||||
if (
|
if (
|
||||||
Math.abs(jobline.db_price - jobline.act_price) -
|
Math.abs(jobline.db_price - jobline.act_price) -
|
||||||
Math.abs(jobline.prt_dsmk_m) <
|
Math.abs(jobline.prt_dsmk_m) <
|
||||||
0.01
|
0.01
|
||||||
) {
|
) {
|
||||||
console.log(jobline.line_desc, "Already had the discount counted.");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
703
yarn.lock
703
yarn.lock
@@ -2,6 +2,15 @@
|
|||||||
# yarn lockfile v1
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
|
"@aws-crypto/crc32@3.0.0":
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@aws-crypto/crc32/-/crc32-3.0.0.tgz#07300eca214409c33e3ff769cd5697b57fdd38fa"
|
||||||
|
integrity sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==
|
||||||
|
dependencies:
|
||||||
|
"@aws-crypto/util" "^3.0.0"
|
||||||
|
"@aws-sdk/types" "^3.222.0"
|
||||||
|
tslib "^1.11.1"
|
||||||
|
|
||||||
"@aws-crypto/ie11-detection@^3.0.0":
|
"@aws-crypto/ie11-detection@^3.0.0":
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@aws-crypto/ie11-detection/-/ie11-detection-3.0.0.tgz#640ae66b4ec3395cee6a8e94ebcd9f80c24cd688"
|
resolved "https://registry.yarnpkg.com/@aws-crypto/ie11-detection/-/ie11-detection-3.0.0.tgz#640ae66b4ec3395cee6a8e94ebcd9f80c24cd688"
|
||||||
@@ -56,6 +65,49 @@
|
|||||||
"@aws-sdk/types" "3.310.0"
|
"@aws-sdk/types" "3.310.0"
|
||||||
tslib "^2.5.0"
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@aws-sdk/client-secrets-manager@^3.388.0":
|
||||||
|
version "3.388.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.388.0.tgz#284429ebc9376a167c3197075a848ea00b49bea9"
|
||||||
|
integrity sha512-XOf7FXz2Xn6tbykx/79rDLWysMLX5hQNciuCdbaHhKiflyTSYFNOpe5NQoq7jTzA64NW4dUxJUNwsBdo5M/i3g==
|
||||||
|
dependencies:
|
||||||
|
"@aws-crypto/sha256-browser" "3.0.0"
|
||||||
|
"@aws-crypto/sha256-js" "3.0.0"
|
||||||
|
"@aws-sdk/client-sts" "3.388.0"
|
||||||
|
"@aws-sdk/credential-provider-node" "3.388.0"
|
||||||
|
"@aws-sdk/middleware-host-header" "3.387.0"
|
||||||
|
"@aws-sdk/middleware-logger" "3.387.0"
|
||||||
|
"@aws-sdk/middleware-recursion-detection" "3.387.0"
|
||||||
|
"@aws-sdk/middleware-signing" "3.387.0"
|
||||||
|
"@aws-sdk/middleware-user-agent" "3.387.0"
|
||||||
|
"@aws-sdk/types" "3.387.0"
|
||||||
|
"@aws-sdk/util-endpoints" "3.387.0"
|
||||||
|
"@aws-sdk/util-user-agent-browser" "3.387.0"
|
||||||
|
"@aws-sdk/util-user-agent-node" "3.387.0"
|
||||||
|
"@smithy/config-resolver" "^2.0.2"
|
||||||
|
"@smithy/fetch-http-handler" "^2.0.2"
|
||||||
|
"@smithy/hash-node" "^2.0.2"
|
||||||
|
"@smithy/invalid-dependency" "^2.0.2"
|
||||||
|
"@smithy/middleware-content-length" "^2.0.2"
|
||||||
|
"@smithy/middleware-endpoint" "^2.0.2"
|
||||||
|
"@smithy/middleware-retry" "^2.0.2"
|
||||||
|
"@smithy/middleware-serde" "^2.0.2"
|
||||||
|
"@smithy/middleware-stack" "^2.0.0"
|
||||||
|
"@smithy/node-config-provider" "^2.0.2"
|
||||||
|
"@smithy/node-http-handler" "^2.0.2"
|
||||||
|
"@smithy/protocol-http" "^2.0.2"
|
||||||
|
"@smithy/smithy-client" "^2.0.2"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
"@smithy/url-parser" "^2.0.2"
|
||||||
|
"@smithy/util-base64" "^2.0.0"
|
||||||
|
"@smithy/util-body-length-browser" "^2.0.0"
|
||||||
|
"@smithy/util-body-length-node" "^2.0.0"
|
||||||
|
"@smithy/util-defaults-mode-browser" "^2.0.2"
|
||||||
|
"@smithy/util-defaults-mode-node" "^2.0.2"
|
||||||
|
"@smithy/util-retry" "^2.0.0"
|
||||||
|
"@smithy/util-utf8" "^2.0.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
uuid "^8.3.2"
|
||||||
|
|
||||||
"@aws-sdk/client-sso-oidc@3.319.0":
|
"@aws-sdk/client-sso-oidc@3.319.0":
|
||||||
version "3.319.0"
|
version "3.319.0"
|
||||||
resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.319.0.tgz#d9c1045ac3e1c55b719590f2a47e825a803fd6ed"
|
resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.319.0.tgz#d9c1045ac3e1c55b719590f2a47e825a803fd6ed"
|
||||||
@@ -132,6 +184,88 @@
|
|||||||
"@aws-sdk/util-utf8" "3.310.0"
|
"@aws-sdk/util-utf8" "3.310.0"
|
||||||
tslib "^2.5.0"
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@aws-sdk/client-sso@3.387.0":
|
||||||
|
version "3.387.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.387.0.tgz#d2182c09ad8d75a1a8896c2765e6f8729118660f"
|
||||||
|
integrity sha512-E7uKSvbA0XMKSN5KLInf52hmMpe9/OKo6N9OPffGXdn3fNEQlvyQq3meUkqG7Is0ldgsQMz5EUBNtNybXzr3tQ==
|
||||||
|
dependencies:
|
||||||
|
"@aws-crypto/sha256-browser" "3.0.0"
|
||||||
|
"@aws-crypto/sha256-js" "3.0.0"
|
||||||
|
"@aws-sdk/middleware-host-header" "3.387.0"
|
||||||
|
"@aws-sdk/middleware-logger" "3.387.0"
|
||||||
|
"@aws-sdk/middleware-recursion-detection" "3.387.0"
|
||||||
|
"@aws-sdk/middleware-user-agent" "3.387.0"
|
||||||
|
"@aws-sdk/types" "3.387.0"
|
||||||
|
"@aws-sdk/util-endpoints" "3.387.0"
|
||||||
|
"@aws-sdk/util-user-agent-browser" "3.387.0"
|
||||||
|
"@aws-sdk/util-user-agent-node" "3.387.0"
|
||||||
|
"@smithy/config-resolver" "^2.0.2"
|
||||||
|
"@smithy/fetch-http-handler" "^2.0.2"
|
||||||
|
"@smithy/hash-node" "^2.0.2"
|
||||||
|
"@smithy/invalid-dependency" "^2.0.2"
|
||||||
|
"@smithy/middleware-content-length" "^2.0.2"
|
||||||
|
"@smithy/middleware-endpoint" "^2.0.2"
|
||||||
|
"@smithy/middleware-retry" "^2.0.2"
|
||||||
|
"@smithy/middleware-serde" "^2.0.2"
|
||||||
|
"@smithy/middleware-stack" "^2.0.0"
|
||||||
|
"@smithy/node-config-provider" "^2.0.2"
|
||||||
|
"@smithy/node-http-handler" "^2.0.2"
|
||||||
|
"@smithy/protocol-http" "^2.0.2"
|
||||||
|
"@smithy/smithy-client" "^2.0.2"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
"@smithy/url-parser" "^2.0.2"
|
||||||
|
"@smithy/util-base64" "^2.0.0"
|
||||||
|
"@smithy/util-body-length-browser" "^2.0.0"
|
||||||
|
"@smithy/util-body-length-node" "^2.0.0"
|
||||||
|
"@smithy/util-defaults-mode-browser" "^2.0.2"
|
||||||
|
"@smithy/util-defaults-mode-node" "^2.0.2"
|
||||||
|
"@smithy/util-retry" "^2.0.0"
|
||||||
|
"@smithy/util-utf8" "^2.0.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@aws-sdk/client-sts@3.388.0":
|
||||||
|
version "3.388.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@aws-sdk/client-sts/-/client-sts-3.388.0.tgz#df4363f89de34bd02533056fc335ec8e785f788c"
|
||||||
|
integrity sha512-y9FAcAYHT8O6T/jqhgsIQUb4gLiSTKD3xtzudDvjmFi8gl0oRIY1npbeckSiK6k07VQugm2s64I0nDnDxtWsBg==
|
||||||
|
dependencies:
|
||||||
|
"@aws-crypto/sha256-browser" "3.0.0"
|
||||||
|
"@aws-crypto/sha256-js" "3.0.0"
|
||||||
|
"@aws-sdk/credential-provider-node" "3.388.0"
|
||||||
|
"@aws-sdk/middleware-host-header" "3.387.0"
|
||||||
|
"@aws-sdk/middleware-logger" "3.387.0"
|
||||||
|
"@aws-sdk/middleware-recursion-detection" "3.387.0"
|
||||||
|
"@aws-sdk/middleware-sdk-sts" "3.387.0"
|
||||||
|
"@aws-sdk/middleware-signing" "3.387.0"
|
||||||
|
"@aws-sdk/middleware-user-agent" "3.387.0"
|
||||||
|
"@aws-sdk/types" "3.387.0"
|
||||||
|
"@aws-sdk/util-endpoints" "3.387.0"
|
||||||
|
"@aws-sdk/util-user-agent-browser" "3.387.0"
|
||||||
|
"@aws-sdk/util-user-agent-node" "3.387.0"
|
||||||
|
"@smithy/config-resolver" "^2.0.2"
|
||||||
|
"@smithy/fetch-http-handler" "^2.0.2"
|
||||||
|
"@smithy/hash-node" "^2.0.2"
|
||||||
|
"@smithy/invalid-dependency" "^2.0.2"
|
||||||
|
"@smithy/middleware-content-length" "^2.0.2"
|
||||||
|
"@smithy/middleware-endpoint" "^2.0.2"
|
||||||
|
"@smithy/middleware-retry" "^2.0.2"
|
||||||
|
"@smithy/middleware-serde" "^2.0.2"
|
||||||
|
"@smithy/middleware-stack" "^2.0.0"
|
||||||
|
"@smithy/node-config-provider" "^2.0.2"
|
||||||
|
"@smithy/node-http-handler" "^2.0.2"
|
||||||
|
"@smithy/protocol-http" "^2.0.2"
|
||||||
|
"@smithy/smithy-client" "^2.0.2"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
"@smithy/url-parser" "^2.0.2"
|
||||||
|
"@smithy/util-base64" "^2.0.0"
|
||||||
|
"@smithy/util-body-length-browser" "^2.0.0"
|
||||||
|
"@smithy/util-body-length-node" "^2.0.0"
|
||||||
|
"@smithy/util-defaults-mode-browser" "^2.0.2"
|
||||||
|
"@smithy/util-defaults-mode-node" "^2.0.2"
|
||||||
|
"@smithy/util-retry" "^2.0.0"
|
||||||
|
"@smithy/util-utf8" "^2.0.0"
|
||||||
|
fast-xml-parser "4.2.5"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
"@aws-sdk/config-resolver@3.310.0":
|
"@aws-sdk/config-resolver@3.310.0":
|
||||||
version "3.310.0"
|
version "3.310.0"
|
||||||
resolved "https://registry.yarnpkg.com/@aws-sdk/config-resolver/-/config-resolver-3.310.0.tgz#c02dce96546d5cd25551bc89907b27224e16ca7f"
|
resolved "https://registry.yarnpkg.com/@aws-sdk/config-resolver/-/config-resolver-3.310.0.tgz#c02dce96546d5cd25551bc89907b27224e16ca7f"
|
||||||
@@ -151,6 +285,16 @@
|
|||||||
"@aws-sdk/types" "3.310.0"
|
"@aws-sdk/types" "3.310.0"
|
||||||
tslib "^2.5.0"
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@aws-sdk/credential-provider-env@3.387.0":
|
||||||
|
version "3.387.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.387.0.tgz#7323eada10228c0157195a922d10638cd65c293c"
|
||||||
|
integrity sha512-PVqNk7XPIYe5CMYNvELkcALtkl/pIM8/uPtqEtTg+mgnZBeL4fAmgXZiZMahQo1DxP5t/JaK384f6JG+A0qDjA==
|
||||||
|
dependencies:
|
||||||
|
"@aws-sdk/types" "3.387.0"
|
||||||
|
"@smithy/property-provider" "^2.0.0"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
"@aws-sdk/credential-provider-imds@3.310.0":
|
"@aws-sdk/credential-provider-imds@3.310.0":
|
||||||
version "3.310.0"
|
version "3.310.0"
|
||||||
resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-imds/-/credential-provider-imds-3.310.0.tgz#d8fb1223fee7e289a81e28177fe55dedf4d2745e"
|
resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-imds/-/credential-provider-imds-3.310.0.tgz#d8fb1223fee7e289a81e28177fe55dedf4d2745e"
|
||||||
@@ -177,6 +321,39 @@
|
|||||||
"@aws-sdk/types" "3.310.0"
|
"@aws-sdk/types" "3.310.0"
|
||||||
tslib "^2.5.0"
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@aws-sdk/credential-provider-ini@3.388.0":
|
||||||
|
version "3.388.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.388.0.tgz#284b6dd2da4f3f8f53b2fa1838085148a478b936"
|
||||||
|
integrity sha512-3dg3A8AiZ5vXkSAYyyI3V/AW3Eo6KQJyE/glA+Nr2M0oAjT4z3vHhS3pf2B+hfKGZBTuKKgxusrrhrQABd/Diw==
|
||||||
|
dependencies:
|
||||||
|
"@aws-sdk/credential-provider-env" "3.387.0"
|
||||||
|
"@aws-sdk/credential-provider-process" "3.387.0"
|
||||||
|
"@aws-sdk/credential-provider-sso" "3.388.0"
|
||||||
|
"@aws-sdk/credential-provider-web-identity" "3.387.0"
|
||||||
|
"@aws-sdk/types" "3.387.0"
|
||||||
|
"@smithy/credential-provider-imds" "^2.0.0"
|
||||||
|
"@smithy/property-provider" "^2.0.0"
|
||||||
|
"@smithy/shared-ini-file-loader" "^2.0.0"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@aws-sdk/credential-provider-node@3.388.0":
|
||||||
|
version "3.388.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.388.0.tgz#4c1599e2fdd94cff61f1d5568cade8e595cf4da2"
|
||||||
|
integrity sha512-BqWAkIG08gj/wevpesaZhAjALjfUNVjseHQRk+DNUoHIfyibW7Ahf3q/GIPs11dA2o8ECwR9/fo68Sq+sK799A==
|
||||||
|
dependencies:
|
||||||
|
"@aws-sdk/credential-provider-env" "3.387.0"
|
||||||
|
"@aws-sdk/credential-provider-ini" "3.388.0"
|
||||||
|
"@aws-sdk/credential-provider-process" "3.387.0"
|
||||||
|
"@aws-sdk/credential-provider-sso" "3.388.0"
|
||||||
|
"@aws-sdk/credential-provider-web-identity" "3.387.0"
|
||||||
|
"@aws-sdk/types" "3.387.0"
|
||||||
|
"@smithy/credential-provider-imds" "^2.0.0"
|
||||||
|
"@smithy/property-provider" "^2.0.0"
|
||||||
|
"@smithy/shared-ini-file-loader" "^2.0.0"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
"@aws-sdk/credential-provider-node@^3.319.0":
|
"@aws-sdk/credential-provider-node@^3.319.0":
|
||||||
version "3.319.0"
|
version "3.319.0"
|
||||||
resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.319.0.tgz#51c8cd9d676d5b3ef80e88282fc1925946b1aaaf"
|
resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.319.0.tgz#51c8cd9d676d5b3ef80e88282fc1925946b1aaaf"
|
||||||
@@ -203,6 +380,17 @@
|
|||||||
"@aws-sdk/types" "3.310.0"
|
"@aws-sdk/types" "3.310.0"
|
||||||
tslib "^2.5.0"
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@aws-sdk/credential-provider-process@3.387.0":
|
||||||
|
version "3.387.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.387.0.tgz#114acfbcf9bd289e549fb3fd48acc1a71d7c75b7"
|
||||||
|
integrity sha512-tQScLHmDlqkQN+mqw4s3cxepEUeHYDhFl5eH+J8puvPqWjXMYpCEdY79SAtWs6SZd4CWiZ0VLeYU6xQBZengbQ==
|
||||||
|
dependencies:
|
||||||
|
"@aws-sdk/types" "3.387.0"
|
||||||
|
"@smithy/property-provider" "^2.0.0"
|
||||||
|
"@smithy/shared-ini-file-loader" "^2.0.0"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
"@aws-sdk/credential-provider-sso@3.319.0":
|
"@aws-sdk/credential-provider-sso@3.319.0":
|
||||||
version "3.319.0"
|
version "3.319.0"
|
||||||
resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.319.0.tgz#c7bbea82e28bfbbafdb7d729239464c7ae38f7d0"
|
resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.319.0.tgz#c7bbea82e28bfbbafdb7d729239464c7ae38f7d0"
|
||||||
@@ -215,6 +403,19 @@
|
|||||||
"@aws-sdk/types" "3.310.0"
|
"@aws-sdk/types" "3.310.0"
|
||||||
tslib "^2.5.0"
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@aws-sdk/credential-provider-sso@3.388.0":
|
||||||
|
version "3.388.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.388.0.tgz#39868ebd160d24348287c8a8e57908f6a5d86046"
|
||||||
|
integrity sha512-RH02+rntaO0UhnSBr42n+7q8HOztc+Dets/hh6cWovf3Yi9s9ghLgYLN9FXpSosfot3XkmT/HOCa+CphAmGN9A==
|
||||||
|
dependencies:
|
||||||
|
"@aws-sdk/client-sso" "3.387.0"
|
||||||
|
"@aws-sdk/token-providers" "3.388.0"
|
||||||
|
"@aws-sdk/types" "3.387.0"
|
||||||
|
"@smithy/property-provider" "^2.0.0"
|
||||||
|
"@smithy/shared-ini-file-loader" "^2.0.0"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
"@aws-sdk/credential-provider-web-identity@3.310.0":
|
"@aws-sdk/credential-provider-web-identity@3.310.0":
|
||||||
version "3.310.0"
|
version "3.310.0"
|
||||||
resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.310.0.tgz#c9fa09b0068027e58d31178e3fa06bf4e9ae9d36"
|
resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.310.0.tgz#c9fa09b0068027e58d31178e3fa06bf4e9ae9d36"
|
||||||
@@ -224,6 +425,16 @@
|
|||||||
"@aws-sdk/types" "3.310.0"
|
"@aws-sdk/types" "3.310.0"
|
||||||
tslib "^2.5.0"
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@aws-sdk/credential-provider-web-identity@3.387.0":
|
||||||
|
version "3.387.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.387.0.tgz#f15431ce00dbfe4f937b4afc706254759a096396"
|
||||||
|
integrity sha512-6ueMPl+J3KWv6ZaAWF4Z138QCuBVFZRVAgwbtP3BNqWrrs4Q6TPksOQJ79lRDMpv0EUoyVl04B6lldNlhN8RdA==
|
||||||
|
dependencies:
|
||||||
|
"@aws-sdk/types" "3.387.0"
|
||||||
|
"@smithy/property-provider" "^2.0.0"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
"@aws-sdk/fetch-http-handler@3.310.0":
|
"@aws-sdk/fetch-http-handler@3.310.0":
|
||||||
version "3.310.0"
|
version "3.310.0"
|
||||||
resolved "https://registry.yarnpkg.com/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.310.0.tgz#f31006b7b3103683d72e177cd27d80354f7a37c4"
|
resolved "https://registry.yarnpkg.com/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.310.0.tgz#f31006b7b3103683d72e177cd27d80354f7a37c4"
|
||||||
@@ -289,6 +500,16 @@
|
|||||||
"@aws-sdk/types" "3.310.0"
|
"@aws-sdk/types" "3.310.0"
|
||||||
tslib "^2.5.0"
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@aws-sdk/middleware-host-header@3.387.0":
|
||||||
|
version "3.387.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-host-header/-/middleware-host-header-3.387.0.tgz#17c4948b83bb42ed04bdc2346fce4e4f980691e5"
|
||||||
|
integrity sha512-EWm9PXSr8dSp7hnRth1U7OfelXQp9dLf1yS1kUL+UhppYDJpjhdP7ql3NI4xJKw8e76sP2FuJYEuzWnJHuWoyQ==
|
||||||
|
dependencies:
|
||||||
|
"@aws-sdk/types" "3.387.0"
|
||||||
|
"@smithy/protocol-http" "^2.0.2"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
"@aws-sdk/middleware-logger@3.310.0":
|
"@aws-sdk/middleware-logger@3.310.0":
|
||||||
version "3.310.0"
|
version "3.310.0"
|
||||||
resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-logger/-/middleware-logger-3.310.0.tgz#8cc6381f49ef867cae1364b8517f939629e4dd9d"
|
resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-logger/-/middleware-logger-3.310.0.tgz#8cc6381f49ef867cae1364b8517f939629e4dd9d"
|
||||||
@@ -297,6 +518,15 @@
|
|||||||
"@aws-sdk/types" "3.310.0"
|
"@aws-sdk/types" "3.310.0"
|
||||||
tslib "^2.5.0"
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@aws-sdk/middleware-logger@3.387.0":
|
||||||
|
version "3.387.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-logger/-/middleware-logger-3.387.0.tgz#bbc05eb087989d6addecc58f1baeb39334851e6e"
|
||||||
|
integrity sha512-FjAvJr1XyaInT81RxUwgifnbXoFJrRBFc64XeFJgFanGIQCWLYxRrK2HV9eBpao/AycbmuoHgLd/f0sa4hZFoQ==
|
||||||
|
dependencies:
|
||||||
|
"@aws-sdk/types" "3.387.0"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
"@aws-sdk/middleware-recursion-detection@3.310.0":
|
"@aws-sdk/middleware-recursion-detection@3.310.0":
|
||||||
version "3.310.0"
|
version "3.310.0"
|
||||||
resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.310.0.tgz#020c986ed8da751bd613fd84c8c8a805c89e0952"
|
resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.310.0.tgz#020c986ed8da751bd613fd84c8c8a805c89e0952"
|
||||||
@@ -306,6 +536,16 @@
|
|||||||
"@aws-sdk/types" "3.310.0"
|
"@aws-sdk/types" "3.310.0"
|
||||||
tslib "^2.5.0"
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@aws-sdk/middleware-recursion-detection@3.387.0":
|
||||||
|
version "3.387.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.387.0.tgz#34beba7dc436dcf13065f5ad99cc239f2f6175b9"
|
||||||
|
integrity sha512-ZF45T785ru8OwvYZw6awD9Z76OwSMM1eZzj2eY+FDz1cHfkpLjxEiti2iIH1FxbyK7n9ZqDUx29lVlCv238YyQ==
|
||||||
|
dependencies:
|
||||||
|
"@aws-sdk/types" "3.387.0"
|
||||||
|
"@smithy/protocol-http" "^2.0.2"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
"@aws-sdk/middleware-retry@3.310.0":
|
"@aws-sdk/middleware-retry@3.310.0":
|
||||||
version "3.310.0"
|
version "3.310.0"
|
||||||
resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-retry/-/middleware-retry-3.310.0.tgz#12e95e962875d44af4acbdebe02db337a1ad5c35"
|
resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-retry/-/middleware-retry-3.310.0.tgz#12e95e962875d44af4acbdebe02db337a1ad5c35"
|
||||||
@@ -319,6 +559,16 @@
|
|||||||
tslib "^2.5.0"
|
tslib "^2.5.0"
|
||||||
uuid "^8.3.2"
|
uuid "^8.3.2"
|
||||||
|
|
||||||
|
"@aws-sdk/middleware-sdk-sts@3.387.0":
|
||||||
|
version "3.387.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.387.0.tgz#6bd1e4eb17acc7387fa4231da52378ef77e10b1b"
|
||||||
|
integrity sha512-7ZzRKOJ4V/JDQmKz9z+FjZqw59mrMATEMLR6ff0H0JHMX0Uk5IX8TQB058ss+ar14qeJ4UcteYzCqHNI0O1BHw==
|
||||||
|
dependencies:
|
||||||
|
"@aws-sdk/middleware-signing" "3.387.0"
|
||||||
|
"@aws-sdk/types" "3.387.0"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
"@aws-sdk/middleware-serde@3.310.0":
|
"@aws-sdk/middleware-serde@3.310.0":
|
||||||
version "3.310.0"
|
version "3.310.0"
|
||||||
resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-serde/-/middleware-serde-3.310.0.tgz#e334031b66a1a155375ec901478b26570fbe1783"
|
resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-serde/-/middleware-serde-3.310.0.tgz#e334031b66a1a155375ec901478b26570fbe1783"
|
||||||
@@ -327,6 +577,19 @@
|
|||||||
"@aws-sdk/types" "3.310.0"
|
"@aws-sdk/types" "3.310.0"
|
||||||
tslib "^2.5.0"
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@aws-sdk/middleware-signing@3.387.0":
|
||||||
|
version "3.387.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-signing/-/middleware-signing-3.387.0.tgz#74bf5a9cf35239b5745a384a9d8f6f92afbd8328"
|
||||||
|
integrity sha512-oJXlE0MES8gxNLo137PPNNiOICQGOaETTvq3kBSJgb/gtEAxQajMIlaNT7s1wsjOAruFHt4975nCXuY4lpx7GQ==
|
||||||
|
dependencies:
|
||||||
|
"@aws-sdk/types" "3.387.0"
|
||||||
|
"@smithy/property-provider" "^2.0.0"
|
||||||
|
"@smithy/protocol-http" "^2.0.2"
|
||||||
|
"@smithy/signature-v4" "^2.0.0"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
"@smithy/util-middleware" "^2.0.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
"@aws-sdk/middleware-stack@3.310.0":
|
"@aws-sdk/middleware-stack@3.310.0":
|
||||||
version "3.310.0"
|
version "3.310.0"
|
||||||
resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-stack/-/middleware-stack-3.310.0.tgz#06c83963998fbdc83e99b67a7a138529312a6224"
|
resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-stack/-/middleware-stack-3.310.0.tgz#06c83963998fbdc83e99b67a7a138529312a6224"
|
||||||
@@ -344,6 +607,17 @@
|
|||||||
"@aws-sdk/util-endpoints" "3.319.0"
|
"@aws-sdk/util-endpoints" "3.319.0"
|
||||||
tslib "^2.5.0"
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@aws-sdk/middleware-user-agent@3.387.0":
|
||||||
|
version "3.387.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.387.0.tgz#aa5f9eb4f3cb4d6e0df879d8d84ccaf4f8baf8e5"
|
||||||
|
integrity sha512-hTfFTwDtp86xS98BKa+RFuLfcvGftxwzrbZeisZV8hdb4ZhvNXjSxnvM3vetW0GUEnY9xHPSGyp2ERRTinPKFQ==
|
||||||
|
dependencies:
|
||||||
|
"@aws-sdk/types" "3.387.0"
|
||||||
|
"@aws-sdk/util-endpoints" "3.387.0"
|
||||||
|
"@smithy/protocol-http" "^2.0.2"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
"@aws-sdk/node-config-provider@3.310.0":
|
"@aws-sdk/node-config-provider@3.310.0":
|
||||||
version "3.310.0"
|
version "3.310.0"
|
||||||
resolved "https://registry.yarnpkg.com/@aws-sdk/node-config-provider/-/node-config-provider-3.310.0.tgz#ba8fb41af2db0316291ba9002267627553ec65ac"
|
resolved "https://registry.yarnpkg.com/@aws-sdk/node-config-provider/-/node-config-provider-3.310.0.tgz#ba8fb41af2db0316291ba9002267627553ec65ac"
|
||||||
@@ -431,6 +705,47 @@
|
|||||||
"@aws-sdk/types" "3.310.0"
|
"@aws-sdk/types" "3.310.0"
|
||||||
tslib "^2.5.0"
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@aws-sdk/token-providers@3.388.0":
|
||||||
|
version "3.388.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.388.0.tgz#50000f5ca32b58614542a6e25918bc32585535cb"
|
||||||
|
integrity sha512-2lo1gFJl624kfjo/YdU6zW+k6dEwhoqjNkDNbOZEFgS1KDofHe9GX8W4/ReKb0Ggho5/EcjzZ53/1CjkzUq4tA==
|
||||||
|
dependencies:
|
||||||
|
"@aws-crypto/sha256-browser" "3.0.0"
|
||||||
|
"@aws-crypto/sha256-js" "3.0.0"
|
||||||
|
"@aws-sdk/middleware-host-header" "3.387.0"
|
||||||
|
"@aws-sdk/middleware-logger" "3.387.0"
|
||||||
|
"@aws-sdk/middleware-recursion-detection" "3.387.0"
|
||||||
|
"@aws-sdk/middleware-user-agent" "3.387.0"
|
||||||
|
"@aws-sdk/types" "3.387.0"
|
||||||
|
"@aws-sdk/util-endpoints" "3.387.0"
|
||||||
|
"@aws-sdk/util-user-agent-browser" "3.387.0"
|
||||||
|
"@aws-sdk/util-user-agent-node" "3.387.0"
|
||||||
|
"@smithy/config-resolver" "^2.0.2"
|
||||||
|
"@smithy/fetch-http-handler" "^2.0.2"
|
||||||
|
"@smithy/hash-node" "^2.0.2"
|
||||||
|
"@smithy/invalid-dependency" "^2.0.2"
|
||||||
|
"@smithy/middleware-content-length" "^2.0.2"
|
||||||
|
"@smithy/middleware-endpoint" "^2.0.2"
|
||||||
|
"@smithy/middleware-retry" "^2.0.2"
|
||||||
|
"@smithy/middleware-serde" "^2.0.2"
|
||||||
|
"@smithy/middleware-stack" "^2.0.0"
|
||||||
|
"@smithy/node-config-provider" "^2.0.2"
|
||||||
|
"@smithy/node-http-handler" "^2.0.2"
|
||||||
|
"@smithy/property-provider" "^2.0.0"
|
||||||
|
"@smithy/protocol-http" "^2.0.2"
|
||||||
|
"@smithy/shared-ini-file-loader" "^2.0.0"
|
||||||
|
"@smithy/smithy-client" "^2.0.2"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
"@smithy/url-parser" "^2.0.2"
|
||||||
|
"@smithy/util-base64" "^2.0.0"
|
||||||
|
"@smithy/util-body-length-browser" "^2.0.0"
|
||||||
|
"@smithy/util-body-length-node" "^2.0.0"
|
||||||
|
"@smithy/util-defaults-mode-browser" "^2.0.2"
|
||||||
|
"@smithy/util-defaults-mode-node" "^2.0.2"
|
||||||
|
"@smithy/util-retry" "^2.0.0"
|
||||||
|
"@smithy/util-utf8" "^2.0.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
"@aws-sdk/types@3.310.0", "@aws-sdk/types@^3.222.0":
|
"@aws-sdk/types@3.310.0", "@aws-sdk/types@^3.222.0":
|
||||||
version "3.310.0"
|
version "3.310.0"
|
||||||
resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.310.0.tgz#b83a0580feb38b58417abb8b4ed3eae1a0cb7bc1"
|
resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.310.0.tgz#b83a0580feb38b58417abb8b4ed3eae1a0cb7bc1"
|
||||||
@@ -438,6 +753,14 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
tslib "^2.5.0"
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@aws-sdk/types@3.387.0":
|
||||||
|
version "3.387.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.387.0.tgz#15a968344956b2587dbab1224718d72329e050f4"
|
||||||
|
integrity sha512-YTjFabNwjTF+6yl88f0/tWff018qmmgMmjlw45s6sdVKueWxdxV68U7gepNLF2nhaQPZa6FDOBoA51NaviVs0Q==
|
||||||
|
dependencies:
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
"@aws-sdk/url-parser@3.310.0":
|
"@aws-sdk/url-parser@3.310.0":
|
||||||
version "3.310.0"
|
version "3.310.0"
|
||||||
resolved "https://registry.yarnpkg.com/@aws-sdk/url-parser/-/url-parser-3.310.0.tgz#928c9eac2e3d74c3c5db4c6e364a1de00185dcaa"
|
resolved "https://registry.yarnpkg.com/@aws-sdk/url-parser/-/url-parser-3.310.0.tgz#928c9eac2e3d74c3c5db4c6e364a1de00185dcaa"
|
||||||
@@ -514,6 +837,14 @@
|
|||||||
"@aws-sdk/types" "3.310.0"
|
"@aws-sdk/types" "3.310.0"
|
||||||
tslib "^2.5.0"
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@aws-sdk/util-endpoints@3.387.0":
|
||||||
|
version "3.387.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@aws-sdk/util-endpoints/-/util-endpoints-3.387.0.tgz#86d7611527ce916c39dfc02641b8be6e0ad8f1f4"
|
||||||
|
integrity sha512-g7kvuCXehGXHHBw9PkSQdwVyDFmNUZLmfrRmqMyrMDG9QLQrxr4pyWcSaYgTE16yUzhQQOR+QSey+BL6W9/N6g==
|
||||||
|
dependencies:
|
||||||
|
"@aws-sdk/types" "3.387.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
"@aws-sdk/util-locate-window@^3.0.0":
|
"@aws-sdk/util-locate-window@^3.0.0":
|
||||||
version "3.310.0"
|
version "3.310.0"
|
||||||
resolved "https://registry.yarnpkg.com/@aws-sdk/util-locate-window/-/util-locate-window-3.310.0.tgz#b071baf050301adee89051032bd4139bba32cc40"
|
resolved "https://registry.yarnpkg.com/@aws-sdk/util-locate-window/-/util-locate-window-3.310.0.tgz#b071baf050301adee89051032bd4139bba32cc40"
|
||||||
@@ -552,6 +883,16 @@
|
|||||||
bowser "^2.11.0"
|
bowser "^2.11.0"
|
||||||
tslib "^2.5.0"
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@aws-sdk/util-user-agent-browser@3.387.0":
|
||||||
|
version "3.387.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.387.0.tgz#a59409a168a73a3ce08c0ac831593f864490078e"
|
||||||
|
integrity sha512-lpgSVvDqx+JjHZCTYs/yQSS7J71dPlJeAlvxc7bmx5m+vfwKe07HAnIs+929DngS0QbAp/VaXbTiMFsInLkO4Q==
|
||||||
|
dependencies:
|
||||||
|
"@aws-sdk/types" "3.387.0"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
bowser "^2.11.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
"@aws-sdk/util-user-agent-node@3.310.0":
|
"@aws-sdk/util-user-agent-node@3.310.0":
|
||||||
version "3.310.0"
|
version "3.310.0"
|
||||||
resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.310.0.tgz#ebefbedc5a4759adc958885741628ec0de1ab197"
|
resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.310.0.tgz#ebefbedc5a4759adc958885741628ec0de1ab197"
|
||||||
@@ -561,6 +902,16 @@
|
|||||||
"@aws-sdk/types" "3.310.0"
|
"@aws-sdk/types" "3.310.0"
|
||||||
tslib "^2.5.0"
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@aws-sdk/util-user-agent-node@3.387.0":
|
||||||
|
version "3.387.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.387.0.tgz#54ae2e17fb3738c018891bdb67ab4e4cce219e6f"
|
||||||
|
integrity sha512-r9OVkcWpRYatjLhJacuHFgvO2T5s/Nu5DDbScMrkUD8b4aGIIqsrdZji0vZy9FCjsUFQMM92t9nt4SejrGjChA==
|
||||||
|
dependencies:
|
||||||
|
"@aws-sdk/types" "3.387.0"
|
||||||
|
"@smithy/node-config-provider" "^2.0.2"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
"@aws-sdk/util-utf8-browser@^3.0.0":
|
"@aws-sdk/util-utf8-browser@^3.0.0":
|
||||||
version "3.259.0"
|
version "3.259.0"
|
||||||
resolved "https://registry.yarnpkg.com/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz#3275a6f5eb334f96ca76635b961d3c50259fd9ff"
|
resolved "https://registry.yarnpkg.com/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz#3275a6f5eb334f96ca76635b961d3c50259fd9ff"
|
||||||
@@ -841,6 +1192,346 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570"
|
resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570"
|
||||||
integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==
|
integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==
|
||||||
|
|
||||||
|
"@smithy/abort-controller@^2.0.2":
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/abort-controller/-/abort-controller-2.0.2.tgz#e2188247a1723b58d60b0803f3ba24b76a714413"
|
||||||
|
integrity sha512-ln5Cob0mksym62sLr7NiPOSqJ0jKao4qjfcNLDdgINM1lQI12hXrZBlKdPHbXJqpKhKiECDgonMoqCM8bigq4g==
|
||||||
|
dependencies:
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/config-resolver@^2.0.2":
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/config-resolver/-/config-resolver-2.0.2.tgz#64496d2f2f9f1482d2e982d3dc057dccc4ba97db"
|
||||||
|
integrity sha512-0kdsqBL6BdmSbdU6YaDkodVBMua5MuQQluC3nocJ7OJ6PnOuM7i2FEQHE46LBadLqT+CimlDSM+6j91uHNL1ng==
|
||||||
|
dependencies:
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
"@smithy/util-config-provider" "^2.0.0"
|
||||||
|
"@smithy/util-middleware" "^2.0.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/credential-provider-imds@^2.0.0", "@smithy/credential-provider-imds@^2.0.2":
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/credential-provider-imds/-/credential-provider-imds-2.0.2.tgz#9096ff1a2ceb235497a62d469ac70086b96022ad"
|
||||||
|
integrity sha512-mbWFYEZ00LBRDk3WvcXViwpdpkJQcfrM3seuKzFxZnF6wIBLMwrcWcsj+OUC/1L+86m8aQY9imXMAaQsAoGxow==
|
||||||
|
dependencies:
|
||||||
|
"@smithy/node-config-provider" "^2.0.2"
|
||||||
|
"@smithy/property-provider" "^2.0.2"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
"@smithy/url-parser" "^2.0.2"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/eventstream-codec@^2.0.2":
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/eventstream-codec/-/eventstream-codec-2.0.2.tgz#9d81c8d081ac28ba098d98b06cbb39955af1e09b"
|
||||||
|
integrity sha512-PQZiKx7fMnNwx4zxcUCm82VjnqK6wV4MEHSmMy3taj5dKfXV782IjRGyaDT+8TsmNqVdZIkve5zLRAzh+7kOhA==
|
||||||
|
dependencies:
|
||||||
|
"@aws-crypto/crc32" "3.0.0"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
"@smithy/util-hex-encoding" "^2.0.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/fetch-http-handler@^2.0.2":
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/fetch-http-handler/-/fetch-http-handler-2.0.2.tgz#dcc0e9d365efd8feef4a54dd96a264735a1446b7"
|
||||||
|
integrity sha512-Wo2m1RaiXNSLF4J3D62LpdSoj/YYb+6tn0H8is1tSrzr7eXAdiYVBc0wIa23N0wT4zmN0iG/yNY6gTCDQ6799A==
|
||||||
|
dependencies:
|
||||||
|
"@smithy/protocol-http" "^2.0.2"
|
||||||
|
"@smithy/querystring-builder" "^2.0.2"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
"@smithy/util-base64" "^2.0.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/hash-node@^2.0.2":
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/hash-node/-/hash-node-2.0.2.tgz#e968a3e7ab7072bd12297063e3770ae6d9249dee"
|
||||||
|
integrity sha512-JKDzZ1YVR7JzOBaJoWy3ToJCE86OQE6D4kOBvvVsu93a3lcF9kv6KYTKBYEWAjwOn/CpK4NH7mKB01OQ8H+aiA==
|
||||||
|
dependencies:
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
"@smithy/util-buffer-from" "^2.0.0"
|
||||||
|
"@smithy/util-utf8" "^2.0.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/invalid-dependency@^2.0.2":
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/invalid-dependency/-/invalid-dependency-2.0.2.tgz#1f7b6a860395e9f11fcdbdf3ac22fb95ce863c69"
|
||||||
|
integrity sha512-inQZQ5gCO3WRWuXpsc1YJ4KBjsvj2qsoU32yTIKznBWTCQe/D5Dp+sSaysqBqxe0VTZ+8nFEHdUMWUX2BxQThw==
|
||||||
|
dependencies:
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/is-array-buffer@^2.0.0":
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/is-array-buffer/-/is-array-buffer-2.0.0.tgz#8fa9b8040651e7ba0b2f6106e636a91354ff7d34"
|
||||||
|
integrity sha512-z3PjFjMyZNI98JFRJi/U0nGoLWMSJlDjAW4QUX2WNZLas5C0CmVV6LJ01JI0k90l7FvpmixjWxPFmENSClQ7ug==
|
||||||
|
dependencies:
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/middleware-content-length@^2.0.2":
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/middleware-content-length/-/middleware-content-length-2.0.2.tgz#6167e8ca52cb5f2b06d3c76fa445080c45baaf25"
|
||||||
|
integrity sha512-FmHlNfuvYgDZE3fIx0G3rD/wLXfAmBYE4mVc/w6d7RllA7TygPzq2pfHL1iCMzWkWTdoAVnt3h4aavAZnhaxEQ==
|
||||||
|
dependencies:
|
||||||
|
"@smithy/protocol-http" "^2.0.2"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/middleware-endpoint@^2.0.2":
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/middleware-endpoint/-/middleware-endpoint-2.0.2.tgz#29f4c8ae799ffb0891f96148eb754f8d0a41a97c"
|
||||||
|
integrity sha512-ropE7/c+g22QeluZ+By/B/WvVep0UFreX+IeRMGIO7EbOUPgqtJRXpbJFdG6JKB1uC+CdaJLn4MnZnVBpcyjuA==
|
||||||
|
dependencies:
|
||||||
|
"@smithy/middleware-serde" "^2.0.2"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
"@smithy/url-parser" "^2.0.2"
|
||||||
|
"@smithy/util-middleware" "^2.0.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/middleware-retry@^2.0.2":
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/middleware-retry/-/middleware-retry-2.0.2.tgz#0d6feb551a5d546c720106435d2a4e7878fd8ea2"
|
||||||
|
integrity sha512-wtBUXqtZVriiXppYaFkUrybAPhFVX7vebnW/yVPliLMWMcguOMS58qhOYPZe3t9Wki2+mASfyu+kO3An8lAg2A==
|
||||||
|
dependencies:
|
||||||
|
"@smithy/protocol-http" "^2.0.2"
|
||||||
|
"@smithy/service-error-classification" "^2.0.0"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
"@smithy/util-middleware" "^2.0.0"
|
||||||
|
"@smithy/util-retry" "^2.0.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
uuid "^8.3.2"
|
||||||
|
|
||||||
|
"@smithy/middleware-serde@^2.0.2":
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/middleware-serde/-/middleware-serde-2.0.2.tgz#a59f74e981be8b76ef18e272d525e24e3974dc82"
|
||||||
|
integrity sha512-Kw9xLdlueIaivUWslKB67WZ/cCUg3QnzYVIA3t5KfgsseEEuU4UxXw8NSTvIt71gqQloY+Um8ugS+idgxrWWnw==
|
||||||
|
dependencies:
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/middleware-stack@^2.0.0":
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/middleware-stack/-/middleware-stack-2.0.0.tgz#cd9f442c2788b1ef0ea6b32236d80c76b3c342e9"
|
||||||
|
integrity sha512-31XC1xNF65nlbc16yuh3wwTudmqs6qy4EseQUGF8A/p2m/5wdd/cnXJqpniy/XvXVwkHPz/GwV36HqzHtIKATQ==
|
||||||
|
dependencies:
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/node-config-provider@^2.0.2":
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/node-config-provider/-/node-config-provider-2.0.2.tgz#a15f125f7011ff82610297d899826b7ef7889867"
|
||||||
|
integrity sha512-9wVJccASfuCctNWrzR0zrDkf0ox3HCHGEhFlWL2LBoghUYuK28pVRBbG69wvnkhlHnB8dDZHagxH+Nq9dm7eWw==
|
||||||
|
dependencies:
|
||||||
|
"@smithy/property-provider" "^2.0.2"
|
||||||
|
"@smithy/shared-ini-file-loader" "^2.0.2"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/node-http-handler@^2.0.2":
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/node-http-handler/-/node-http-handler-2.0.2.tgz#3c4d43352f5412cdb23ca075327ac997f5b03df2"
|
||||||
|
integrity sha512-lpZjmtmyZqSAtMPsbrLhb7XoAQ2kAHeuLY/csW6I2k+QyFvOk7cZeQsqEngWmZ9SJaeYiDCBINxAIM61i5WGLw==
|
||||||
|
dependencies:
|
||||||
|
"@smithy/abort-controller" "^2.0.2"
|
||||||
|
"@smithy/protocol-http" "^2.0.2"
|
||||||
|
"@smithy/querystring-builder" "^2.0.2"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/property-provider@^2.0.0", "@smithy/property-provider@^2.0.2":
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/property-provider/-/property-provider-2.0.2.tgz#abe091d1e7dc5b617e3418b63eaed11363c96f21"
|
||||||
|
integrity sha512-DfaZ8cO+d/mgnMzIllcXcU4OYP+omiOl2LYdn/fTGpw/EAQSVzscYV2muV3sDDnuPYQ/r014hUqIxnF+pzh+SQ==
|
||||||
|
dependencies:
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/protocol-http@^2.0.2":
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/protocol-http/-/protocol-http-2.0.2.tgz#ec3d45a650cb5554b6aba1c38768f51fc9cf79b5"
|
||||||
|
integrity sha512-qWu8g1FUy+m36KpO1sREJSF7BaLmjw9AqOuwxLVVSdYz+nUQjc9tFAZ9LB6jJXKdsZFSjfkjHJBbhD78QdE7Rw==
|
||||||
|
dependencies:
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/querystring-builder@^2.0.2":
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/querystring-builder/-/querystring-builder-2.0.2.tgz#67a1bb503037c4666b5df56ad4b9e10bc525f568"
|
||||||
|
integrity sha512-H99LOMWEssfwqkOoTs4Y12UiZ7CTGQSX5Nrx5UkYgRbUEpC1GnnaprHiYrqclC58/xr4K76aNchdPyioxewMzA==
|
||||||
|
dependencies:
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
"@smithy/util-uri-escape" "^2.0.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/querystring-parser@^2.0.2":
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/querystring-parser/-/querystring-parser-2.0.2.tgz#d6b2562e7ae29282b144939e5fd439b17bdf61dd"
|
||||||
|
integrity sha512-L4VtKQ8O4/aWPQJbiFymbhAmxdfLnEaROh/Vs0OstJ7jtOZeBl2QJmuWY2V7hjt64W7V+tEn2sv6vVvnxkm/xQ==
|
||||||
|
dependencies:
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/service-error-classification@^2.0.0":
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/service-error-classification/-/service-error-classification-2.0.0.tgz#bbce07c9c529d9333d40db881fd4a1795dd84892"
|
||||||
|
integrity sha512-2z5Nafy1O0cTf69wKyNjGW/sNVMiqDnb4jgwfMG8ye8KnFJ5qmJpDccwIbJNhXIfbsxTg9SEec2oe1cexhMJvw==
|
||||||
|
|
||||||
|
"@smithy/shared-ini-file-loader@^2.0.0", "@smithy/shared-ini-file-loader@^2.0.2":
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-2.0.2.tgz#49b9bf384ece821352f50c8f6cb989edc77d2dbf"
|
||||||
|
integrity sha512-2VkNOM/82u4vatVdK5nfusgGIlvR48Fkq6me17Oc+V1iyxfR/1x0pG6LzW0br1qlGtzBYFZKmDyviBRcPVFTVw==
|
||||||
|
dependencies:
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/signature-v4@^2.0.0":
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/signature-v4/-/signature-v4-2.0.2.tgz#c1ec6d9485a72039060e9a8fe2c02e0afb9d7764"
|
||||||
|
integrity sha512-YMooDEw/UmGxcXY4qWnSXkbPFsRloluSvyXVT678YPDN/K2AS1GzKfRsvSU7fbccOB4WF8MHZf2UqcRGEltE3Q==
|
||||||
|
dependencies:
|
||||||
|
"@smithy/eventstream-codec" "^2.0.2"
|
||||||
|
"@smithy/is-array-buffer" "^2.0.0"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
"@smithy/util-hex-encoding" "^2.0.0"
|
||||||
|
"@smithy/util-middleware" "^2.0.0"
|
||||||
|
"@smithy/util-uri-escape" "^2.0.0"
|
||||||
|
"@smithy/util-utf8" "^2.0.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/smithy-client@^2.0.2":
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/smithy-client/-/smithy-client-2.0.2.tgz#3364bfb4afa73d57712b95cb9319f7c8324a104e"
|
||||||
|
integrity sha512-mDfokI8WwLU5C0gcQ4ww/zJI/WLGSh2+vdIA42JRnjfYUjJNH/rKfX9YOnn2eBOxl3loATERVUqkHmKe+P8s2Q==
|
||||||
|
dependencies:
|
||||||
|
"@smithy/middleware-stack" "^2.0.0"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
"@smithy/util-stream" "^2.0.2"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/types@^2.1.0":
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/types/-/types-2.1.0.tgz#67fd47c25bbb0fd818951891bf7bcf19a8ee2fe6"
|
||||||
|
integrity sha512-KLsCsqxX0j2l99iP8s0f7LBlcsp7a7ceXGn0LPYPyVOsqmIKvSaPQajq0YevlL4T9Bm+DtcyXfBTbtBcLX1I7A==
|
||||||
|
dependencies:
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/url-parser@^2.0.2":
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/url-parser/-/url-parser-2.0.2.tgz#af50bd62298b209b1a16c80912a03460b7cb8994"
|
||||||
|
integrity sha512-X1mHCzrSVDlhVy7d3S7Vq+dTfYzwh4n7xGHhyJumu77nJqIss0lazVug85Pwo0DKIoO314wAOvMnBxNYDa+7wA==
|
||||||
|
dependencies:
|
||||||
|
"@smithy/querystring-parser" "^2.0.2"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/util-base64@^2.0.0":
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/util-base64/-/util-base64-2.0.0.tgz#1beeabfb155471d1d41c8d0603be1351f883c444"
|
||||||
|
integrity sha512-Zb1E4xx+m5Lud8bbeYi5FkcMJMnn+1WUnJF3qD7rAdXpaL7UjkFQLdmW5fHadoKbdHpwH9vSR8EyTJFHJs++tA==
|
||||||
|
dependencies:
|
||||||
|
"@smithy/util-buffer-from" "^2.0.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/util-body-length-browser@^2.0.0":
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/util-body-length-browser/-/util-body-length-browser-2.0.0.tgz#5447853003b4c73da3bc5f3c5e82c21d592d1650"
|
||||||
|
integrity sha512-JdDuS4ircJt+FDnaQj88TzZY3+njZ6O+D3uakS32f2VNnDo3vyEuNdBOh/oFd8Df1zSZOuH1HEChk2AOYDezZg==
|
||||||
|
dependencies:
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/util-body-length-node@^2.0.0":
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/util-body-length-node/-/util-body-length-node-2.0.0.tgz#4870b71cb9ded0123d984898ce952ce56896bc53"
|
||||||
|
integrity sha512-ZV7Z/WHTMxHJe/xL/56qZwSUcl63/5aaPAGjkfynJm4poILjdD4GmFI+V+YWabh2WJIjwTKZ5PNsuvPQKt93Mg==
|
||||||
|
dependencies:
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/util-buffer-from@^2.0.0":
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/util-buffer-from/-/util-buffer-from-2.0.0.tgz#7eb75d72288b6b3001bc5f75b48b711513091deb"
|
||||||
|
integrity sha512-/YNnLoHsR+4W4Vf2wL5lGv0ksg8Bmk3GEGxn2vEQt52AQaPSCuaO5PM5VM7lP1K9qHRKHwrPGktqVoAHKWHxzw==
|
||||||
|
dependencies:
|
||||||
|
"@smithy/is-array-buffer" "^2.0.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/util-config-provider@^2.0.0":
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/util-config-provider/-/util-config-provider-2.0.0.tgz#4dd6a793605559d94267312fd06d0f58784b4c38"
|
||||||
|
integrity sha512-xCQ6UapcIWKxXHEU4Mcs2s7LcFQRiU3XEluM2WcCjjBtQkUN71Tb+ydGmJFPxMUrW/GWMgQEEGipLym4XG0jZg==
|
||||||
|
dependencies:
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/util-defaults-mode-browser@^2.0.2":
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.0.2.tgz#fb3ad350573ddea0ff7222adc98e9ecc4155b0d3"
|
||||||
|
integrity sha512-c2tMMjb624XLuzmlRoZpnFOkejVxcgw3WQKdmgdGZYZapcLzXyC0H9JhnXMjQCt30GqLTlsILRNVBYwFRbw/4Q==
|
||||||
|
dependencies:
|
||||||
|
"@smithy/property-provider" "^2.0.2"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
bowser "^2.11.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/util-defaults-mode-node@^2.0.2":
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.0.2.tgz#2e16e3eb57427c76604c255c38d9e1eacd385d7e"
|
||||||
|
integrity sha512-gt7m5LLqUtEKldJLyc14DE4kb85vxwomvt9AfEMEvWM4VwfWS1kGJqiStZFb5KNqnQPXw8vvpgLTi8NrWAOXqg==
|
||||||
|
dependencies:
|
||||||
|
"@smithy/config-resolver" "^2.0.2"
|
||||||
|
"@smithy/credential-provider-imds" "^2.0.2"
|
||||||
|
"@smithy/node-config-provider" "^2.0.2"
|
||||||
|
"@smithy/property-provider" "^2.0.2"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/util-hex-encoding@^2.0.0":
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/util-hex-encoding/-/util-hex-encoding-2.0.0.tgz#0aa3515acd2b005c6d55675e377080a7c513b59e"
|
||||||
|
integrity sha512-c5xY+NUnFqG6d7HFh1IFfrm3mGl29lC+vF+geHv4ToiuJCBmIfzx6IeHLg+OgRdPFKDXIw6pvi+p3CsscaMcMA==
|
||||||
|
dependencies:
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/util-middleware@^2.0.0":
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/util-middleware/-/util-middleware-2.0.0.tgz#706681d4a1686544a2275f68266304233f372c99"
|
||||||
|
integrity sha512-eCWX4ECuDHn1wuyyDdGdUWnT4OGyIzV0LN1xRttBFMPI9Ff/4heSHVxneyiMtOB//zpXWCha1/SWHJOZstG7kA==
|
||||||
|
dependencies:
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/util-retry@^2.0.0":
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/util-retry/-/util-retry-2.0.0.tgz#7ac5d5f12383a9d9b2a43f9ff25f3866c8727c24"
|
||||||
|
integrity sha512-/dvJ8afrElasuiiIttRJeoS2sy8YXpksQwiM/TcepqdRVp7u4ejd9C4IQURHNjlfPUT7Y6lCDSa2zQJbdHhVTg==
|
||||||
|
dependencies:
|
||||||
|
"@smithy/service-error-classification" "^2.0.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/util-stream@^2.0.2":
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/util-stream/-/util-stream-2.0.2.tgz#cb4f3c4eca4253f77a780fd861630ed02d67b220"
|
||||||
|
integrity sha512-Mg9IJcKIu4YKlbzvpp1KLvh4JZLdcPgpxk+LICuDwzZCfxe47R9enVK8dNEiuyiIGK2ExbfvzCVT8IBru62vZw==
|
||||||
|
dependencies:
|
||||||
|
"@smithy/fetch-http-handler" "^2.0.2"
|
||||||
|
"@smithy/node-http-handler" "^2.0.2"
|
||||||
|
"@smithy/types" "^2.1.0"
|
||||||
|
"@smithy/util-base64" "^2.0.0"
|
||||||
|
"@smithy/util-buffer-from" "^2.0.0"
|
||||||
|
"@smithy/util-hex-encoding" "^2.0.0"
|
||||||
|
"@smithy/util-utf8" "^2.0.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/util-uri-escape@^2.0.0":
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/util-uri-escape/-/util-uri-escape-2.0.0.tgz#19955b1a0f517a87ae77ac729e0e411963dfda95"
|
||||||
|
integrity sha512-ebkxsqinSdEooQduuk9CbKcI+wheijxEb3utGXkCoYQkJnwTnLbH1JXGimJtUkQwNQbsbuYwG2+aFVyZf5TLaw==
|
||||||
|
dependencies:
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
|
"@smithy/util-utf8@^2.0.0":
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@smithy/util-utf8/-/util-utf8-2.0.0.tgz#b4da87566ea7757435e153799df9da717262ad42"
|
||||||
|
integrity sha512-rctU1VkziY84n5OXe3bPNpKR001ZCME2JCaBBFgtiM2hfKbHFudc/BkMuPab8hRbLd0j3vbnBTTZ1igBf0wgiQ==
|
||||||
|
dependencies:
|
||||||
|
"@smithy/util-buffer-from" "^2.0.0"
|
||||||
|
tslib "^2.5.0"
|
||||||
|
|
||||||
"@socket.io/component-emitter@~3.1.0":
|
"@socket.io/component-emitter@~3.1.0":
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz#96116f2a912e0c02817345b3c10751069920d553"
|
resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz#96116f2a912e0c02817345b3c10751069920d553"
|
||||||
@@ -2136,6 +2827,13 @@ fast-text-encoding@^1.0.0, fast-text-encoding@^1.0.3:
|
|||||||
resolved "https://registry.yarnpkg.com/fast-text-encoding/-/fast-text-encoding-1.0.6.tgz#0aa25f7f638222e3396d72bf936afcf1d42d6867"
|
resolved "https://registry.yarnpkg.com/fast-text-encoding/-/fast-text-encoding-1.0.6.tgz#0aa25f7f638222e3396d72bf936afcf1d42d6867"
|
||||||
integrity sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w==
|
integrity sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w==
|
||||||
|
|
||||||
|
fast-xml-parser@4.2.5:
|
||||||
|
version "4.2.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.2.5.tgz#a6747a09296a6cb34f2ae634019bf1738f3b421f"
|
||||||
|
integrity sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==
|
||||||
|
dependencies:
|
||||||
|
strnum "^1.0.5"
|
||||||
|
|
||||||
faye-websocket@0.11.4:
|
faye-websocket@0.11.4:
|
||||||
version "0.11.4"
|
version "0.11.4"
|
||||||
resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da"
|
resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da"
|
||||||
@@ -4187,6 +4885,11 @@ stripe@^9.15.0:
|
|||||||
"@types/node" ">=8.1.0"
|
"@types/node" ">=8.1.0"
|
||||||
qs "^6.10.3"
|
qs "^6.10.3"
|
||||||
|
|
||||||
|
strnum@^1.0.5:
|
||||||
|
version "1.0.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.0.5.tgz#5c4e829fe15ad4ff0d20c3db5ac97b73c9b072db"
|
||||||
|
integrity sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==
|
||||||
|
|
||||||
stubs@^3.0.0:
|
stubs@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/stubs/-/stubs-3.0.0.tgz#e8d2ba1fa9c90570303c030b6900f7d5f89abe5b"
|
resolved "https://registry.yarnpkg.com/stubs/-/stubs-3.0.0.tgz#e8d2ba1fa9c90570303c030b6900f7d5f89abe5b"
|
||||||
|
|||||||
Reference in New Issue
Block a user