Merged in release/AIO/2024-04-26 (pull request #1440)
Release/AIO/2024 04 26
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,14 +1,12 @@
|
||||
import { DeleteFilled } from "@ant-design/icons";
|
||||
import { useLazyQuery, useMutation } from "@apollo/client";
|
||||
import { Button, Card, Col, Form, Input, notification, Row, Space, Spin, Statistic } from "antd";
|
||||
import { Button, Card, Col, Form, Input, Row, Space, Spin, Statistic, notification } from "antd";
|
||||
import axios from "axios";
|
||||
import dayjs from "../../utils/day";
|
||||
import React, { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { INSERT_PAYMENT_RESPONSE, QUERY_RO_AND_OWNER_BY_JOB_PKS } from "../../graphql/payment_response.queries";
|
||||
import { INSERT_NEW_PAYMENT } from "../../graphql/payments.queries";
|
||||
import { insertAuditTrail } from "../../redux/application/application.actions";
|
||||
import { toggleModalVisible } from "../../redux/modals/modals.actions";
|
||||
import { selectCardPayment } from "../../redux/modals/modals.selectors";
|
||||
@@ -28,12 +26,12 @@ const mapDispatchToProps = (dispatch) => ({
|
||||
});
|
||||
|
||||
const CardPaymentModalComponent = ({ bodyshop, cardPaymentModal, toggleModalVisible, insertAuditTrail }) => {
|
||||
const { context } = cardPaymentModal;
|
||||
const { context, actions } = cardPaymentModal;
|
||||
|
||||
const [form] = Form.useForm();
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [insertPayment] = useMutation(INSERT_NEW_PAYMENT);
|
||||
// const [insertPayment] = useMutation(INSERT_NEW_PAYMENT);
|
||||
const [insertPaymentResponse] = useMutation(INSERT_PAYMENT_RESPONSE);
|
||||
const { t } = useTranslation();
|
||||
|
||||
@@ -42,7 +40,6 @@ const CardPaymentModalComponent = ({ bodyshop, cardPaymentModal, toggleModalVisi
|
||||
skip: true
|
||||
});
|
||||
|
||||
console.log("🚀 ~ file: card-payment-modal.component..jsx:61 ~ data:", data);
|
||||
//Initialize the intellipay window.
|
||||
const SetIntellipayCallbackFunctions = () => {
|
||||
console.log("*** Set IntelliPay callback functions.");
|
||||
@@ -51,16 +48,20 @@ const CardPaymentModalComponent = ({ bodyshop, cardPaymentModal, toggleModalVisi
|
||||
});
|
||||
|
||||
window.intellipay.runOnApproval(async function (response) {
|
||||
console.warn("*** Running On Approval Script ***");
|
||||
form.setFieldValue("paymentResponse", response);
|
||||
form.submit();
|
||||
//2024-04-25: Nothing is going to happen here anymore. We'll completely rely on the callback.
|
||||
//Add a slight delay to allow the refetch to properly get the data.
|
||||
setTimeout(() => {
|
||||
if (actions && actions.refetch && typeof actions.refetch === "function")
|
||||
actions.refetch();
|
||||
setLoading(false);
|
||||
toggleModalVisible();
|
||||
}, 750);
|
||||
});
|
||||
|
||||
window.intellipay.runOnNonApproval(async function (response) {
|
||||
// Mutate unsuccessful payment
|
||||
|
||||
const { payments } = form.getFieldsValue();
|
||||
|
||||
await insertPaymentResponse({
|
||||
variables: {
|
||||
paymentResponse: payments.map((payment) => ({
|
||||
@@ -85,50 +86,9 @@ const CardPaymentModalComponent = ({ bodyshop, cardPaymentModal, toggleModalVisi
|
||||
});
|
||||
};
|
||||
|
||||
const handleFinish = async (values) => {
|
||||
try {
|
||||
await insertPayment({
|
||||
variables: {
|
||||
paymentInput: values.payments.map((payment) => ({
|
||||
amount: payment.amount,
|
||||
transactionid: (values.paymentResponse.paymentid || "").toString(),
|
||||
payer: t("payments.labels.customer"),
|
||||
type: values.paymentResponse.cardbrand,
|
||||
jobid: payment.jobid,
|
||||
date: dayjs(Date.now()),
|
||||
payment_responses: {
|
||||
data: [
|
||||
{
|
||||
amount: payment.amount,
|
||||
bodyshopid: bodyshop.id,
|
||||
|
||||
jobid: payment.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();
|
||||
@@ -140,7 +100,8 @@ const CardPaymentModalComponent = ({ bodyshop, cardPaymentModal, toggleModalVisi
|
||||
try {
|
||||
const response = await axios.post("/intellipay/lightbox_credentials", {
|
||||
bodyshop,
|
||||
refresh: !!window.intellipay
|
||||
refresh: !!window.intellipay,
|
||||
paymentSplitMeta: form.getFieldsValue(),
|
||||
});
|
||||
|
||||
if (window.intellipay) {
|
||||
@@ -169,7 +130,6 @@ const CardPaymentModalComponent = ({ bodyshop, cardPaymentModal, toggleModalVisi
|
||||
<Card title="Card Payment">
|
||||
<Spin spinning={loading}>
|
||||
<Form
|
||||
onFinish={handleFinish}
|
||||
form={form}
|
||||
layout="vertical"
|
||||
initialValues={{
|
||||
@@ -246,18 +206,14 @@ const CardPaymentModalComponent = ({ bodyshop, cardPaymentModal, toggleModalVisi
|
||||
}
|
||||
>
|
||||
{() => {
|
||||
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.");
|
||||
if (
|
||||
payments?.length > 0 &&
|
||||
payments?.filter((p) => p?.jobid).length === payments?.length
|
||||
) {
|
||||
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
|
||||
@@ -300,6 +256,13 @@ const CardPaymentModalComponent = ({ bodyshop, cardPaymentModal, toggleModalVisi
|
||||
type="hidden"
|
||||
value={totalAmountToCharge?.toFixed(2)}
|
||||
/>
|
||||
<Input
|
||||
className="ipayfield"
|
||||
data-ipayname="comment"
|
||||
type="hidden"
|
||||
value={btoa(JSON.stringify(payments))}
|
||||
hidden
|
||||
/>
|
||||
<Button
|
||||
type="primary"
|
||||
// data-ipayname="submit"
|
||||
@@ -314,11 +277,6 @@ const CardPaymentModalComponent = ({ bodyshop, cardPaymentModal, toggleModalVisi
|
||||
);
|
||||
}}
|
||||
</Form.Item>
|
||||
|
||||
{/* Lightbox payment response when it is completed */}
|
||||
<Form.Item name="paymentResponse" hidden>
|
||||
<Input type="hidden" />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Spin>
|
||||
</Card>
|
||||
|
||||
@@ -28,6 +28,7 @@ const CourtesyCarStatusComponent = ({ value, onChange }, ref) => {
|
||||
<Option value="courtesycars.status.out">{t("courtesycars.status.out")}</Option>
|
||||
<Option value="courtesycars.status.sold">{t("courtesycars.status.sold")}</Option>
|
||||
<Option value="courtesycars.status.leasereturn">{t("courtesycars.status.leasereturn")}</Option>
|
||||
<Option value="courtesycars.status.unavailable">{t("courtesycars.status.unavailable")}</Option>
|
||||
</Select>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -61,7 +61,11 @@ export default function CourtesyCarsList({ loading, courtesycars, refetch }) {
|
||||
{
|
||||
text: t("courtesycars.status.leasereturn"),
|
||||
value: "courtesycars.status.leasereturn"
|
||||
}
|
||||
},
|
||||
{
|
||||
text: t("courtesycars.status.unavailable"),
|
||||
value: "courtesycars.status.unavailable",
|
||||
},
|
||||
],
|
||||
onFilter: (value, record) => record.status === value,
|
||||
sortOrder: state.sortedInfo.columnKey === "status" && state.sortedInfo.order,
|
||||
|
||||
@@ -12,6 +12,7 @@ import { createStructuredSelector } from "reselect";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import { QUERY_JOBLINE_TASKS_PAGINATED } from "../../graphql/tasks.queries.js";
|
||||
import TaskListContainer from "../task-list/task-list.container.jsx";
|
||||
import FeatureWrapper from "../feature-wrapper/feature-wrapper.component.jsx";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop
|
||||
@@ -98,13 +99,16 @@ export function JobLinesExpander({ jobline, jobid, bodyshop }) {
|
||||
</Row>
|
||||
)
|
||||
}))
|
||||
: {
|
||||
: [
|
||||
{
|
||||
key: "dispatch-lines",
|
||||
children: t("parts_orders.labels.notyetordered")
|
||||
children: t("parts_dispatch.labels.notyetdispatched")
|
||||
}
|
||||
]
|
||||
}
|
||||
/>
|
||||
</Col>
|
||||
<FeatureWrapper featureName="bills" noauth={() => null}>
|
||||
<Col md={24} lg={8}>
|
||||
<Typography.Title level={4}>{t("bills.labels.bills")}</Typography.Title>
|
||||
<Timeline
|
||||
@@ -147,6 +151,7 @@ export function JobLinesExpander({ jobline, jobid, bodyshop }) {
|
||||
}
|
||||
/>
|
||||
</Col>
|
||||
</FeatureWrapper>
|
||||
<Col md={24} lg={24}>
|
||||
<TaskListContainer
|
||||
parentJobId={jobid}
|
||||
|
||||
@@ -43,6 +43,7 @@ import PartsOrderModalContainer from "../parts-order-modal/parts-order-modal.con
|
||||
import JobLinesExpander from "./job-lines-expander.component";
|
||||
import JobLinesPartPriceChange from "./job-lines-part-price-change.component";
|
||||
import { FaTasks } from "react-icons/fa";
|
||||
import InstanceRenderManager from "../../utils/instanceRenderMgr";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
@@ -552,7 +553,7 @@ export function JobLinesComponent({
|
||||
>
|
||||
{t("joblines.actions.new")}
|
||||
</Button>
|
||||
{bodyshop.region_config.toLowerCase().startsWith("us") && <JobSendPartPriceChangeComponent job={job} />}
|
||||
{InstanceRenderManager({ rome: <JobSendPartPriceChangeComponent job={job} /> })}
|
||||
<JobCreateIOU job={job} selectedJobLines={selectedLines} />
|
||||
<Input.Search
|
||||
placeholder={t("general.labels.search")}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { DownCircleFilled } from "@ant-design/icons";
|
||||
import { useApolloClient, useMutation } from "@apollo/client";
|
||||
import { Button, Card, Dropdown, Form, Input, Modal, notification, Popconfirm, Popover, Select, Space } from "antd";
|
||||
import { useSplitTreatments } from "@splitsoftware/splitio-react";
|
||||
import { Button, Card, Dropdown, Form, Input, Modal, Popconfirm, Popover, Select, Space, notification } from "antd";
|
||||
import axios from "axios";
|
||||
import parsePhoneNumber from "libphonenumber-js";
|
||||
import React, { useMemo, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
@@ -8,27 +11,24 @@ import { Link, useNavigate } from "react-router-dom";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { auth, logImEXEvent } from "../../firebase/firebase.utils";
|
||||
import { CANCEL_APPOINTMENTS_BY_JOB_ID, INSERT_MANUAL_APPT } from "../../graphql/appointments.queries";
|
||||
import { GET_CURRENT_QUESTIONSET_ID, INSERT_CSI } from "../../graphql/csi.queries";
|
||||
import { DELETE_JOB, UPDATE_JOB, VOID_JOB } from "../../graphql/jobs.queries";
|
||||
import { insertAuditTrail } from "../../redux/application/application.actions";
|
||||
import { selectJobReadOnly } from "../../redux/application/application.selectors";
|
||||
import { setEmailOptions } from "../../redux/email/email.actions";
|
||||
import { openChatByPhone, setMessage } from "../../redux/messaging/messaging.actions";
|
||||
import { setModalContext } from "../../redux/modals/modals.actions";
|
||||
import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors";
|
||||
import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
||||
import { DateTimeFormatter } from "../../utils/DateFormatter";
|
||||
import { TemplateList } from "../../utils/TemplateConstants";
|
||||
import dayjs from "../../utils/day";
|
||||
import InstanceRenderManager from "../../utils/instanceRenderMgr";
|
||||
import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
|
||||
import FormDateTimePickerComponent from "../form-date-time-picker/form-date-time-picker.component";
|
||||
import RbacWrapper from "../rbac-wrapper/rbac-wrapper.component";
|
||||
import AddToProduction from "./jobs-detail-header-actions.addtoproduction.util";
|
||||
import DuplicateJob from "./jobs-detail-header-actions.duplicate.util";
|
||||
import axios from "axios";
|
||||
import { setEmailOptions } from "../../redux/email/email.actions";
|
||||
import { openChatByPhone, setMessage } from "../../redux/messaging/messaging.actions";
|
||||
import { GET_CURRENT_QUESTIONSET_ID, INSERT_CSI } from "../../graphql/csi.queries";
|
||||
import { TemplateList } from "../../utils/TemplateConstants";
|
||||
import parsePhoneNumber from "libphonenumber-js";
|
||||
import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
|
||||
import { DateTimeFormatter } from "../../utils/DateFormatter";
|
||||
import FormDateTimePickerComponent from "../form-date-time-picker/form-date-time-picker.component";
|
||||
import dayjs from "../../utils/day";
|
||||
import { useSplitTreatments } from "@splitsoftware/splitio-react";
|
||||
import InstanceRenderManager from "../../utils/instanceRenderMgr";
|
||||
import JobsDetailHeaderActionsToggleProduction from "./jobs-detail-header-actions.toggle-production";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
@@ -83,6 +83,13 @@ const mapDispatchToProps = (dispatch) => ({
|
||||
modal: "timeTicketTask"
|
||||
})
|
||||
),
|
||||
setTaskUpsertContext: (context) =>
|
||||
dispatch(
|
||||
setModalContext({
|
||||
context: context,
|
||||
modal: "taskUpsert"
|
||||
})
|
||||
),
|
||||
setEmailOptions: (e) => dispatch(setEmailOptions(e)),
|
||||
openChatByPhone: (phone) => dispatch(openChatByPhone(phone)),
|
||||
setMessage: (text) => dispatch(setMessage(text))
|
||||
@@ -104,7 +111,8 @@ export function JobsDetailHeaderActions({
|
||||
setEmailOptions,
|
||||
openChatByPhone,
|
||||
setMessage,
|
||||
setTimeTicketTaskContext
|
||||
setTimeTicketTaskContext,
|
||||
setTaskUpsertContext
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const client = useApolloClient();
|
||||
@@ -759,14 +767,14 @@ export function JobsDetailHeaderActions({
|
||||
logImEXEvent("job_header_enter_card_payment");
|
||||
|
||||
setCardPaymentContext({
|
||||
actions: {},
|
||||
actions: { refetch },
|
||||
context: { jobid: job.id }
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (HasFeatureAccess({ featureName: "courtesycars" })) {
|
||||
if (HasFeatureAccess({ featureName: "courtesycars", bodyshop })) {
|
||||
menuItems.push({
|
||||
key: "cccontract",
|
||||
disabled: jobRO || !job.converted,
|
||||
@@ -778,6 +786,16 @@ export function JobsDetailHeaderActions({
|
||||
});
|
||||
}
|
||||
|
||||
menuItems.push({
|
||||
key: "createtask",
|
||||
label: t("menus.header.create_task"),
|
||||
onClick: () =>
|
||||
setTaskUpsertContext({
|
||||
actions: {},
|
||||
context: { jobid: job.id }
|
||||
})
|
||||
});
|
||||
|
||||
menuItems.push(
|
||||
job.inproduction
|
||||
? {
|
||||
|
||||
@@ -315,34 +315,6 @@ export function JobsList({ bodyshop, setJoyRideSteps }) {
|
||||
title={t("titles.bc.jobs-active")}
|
||||
extra={
|
||||
<Space wrap>
|
||||
{InstanceRenderManager({
|
||||
promanager: (
|
||||
<Button
|
||||
onClick={() =>
|
||||
setJoyRideSteps([
|
||||
{
|
||||
target: "#active-jobs-list",
|
||||
content: "This is where you will see all work coming in and currently here."
|
||||
},
|
||||
{
|
||||
target: "#header-jobs",
|
||||
spotlightClicks: true,
|
||||
disableOverlayClose: true,
|
||||
content:
|
||||
"The jobs menu lets you access additional pages to see more information. You can import new jobs, search all jobs, or manage your current production."
|
||||
},
|
||||
{
|
||||
target: "#header-jobs-available",
|
||||
content: "You can find jobs to import here."
|
||||
}
|
||||
])
|
||||
}
|
||||
>
|
||||
Start Walk Through
|
||||
</Button>
|
||||
)
|
||||
})}
|
||||
|
||||
<Button onClick={() => refetch()}>
|
||||
<SyncOutlined />
|
||||
</Button>
|
||||
|
||||
@@ -6,7 +6,8 @@ import { Link } from "react-router-dom";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
||||
import { alphaSort, statusSort } from "../../utils/sorters";
|
||||
import { DateTimeFormatter } from "../../utils/DateFormatter";
|
||||
import { alphaSort, dateSort, statusSort } from "../../utils/sorters";
|
||||
import OwnerDetailUpdateJobsComponent from "../owner-detail-update-jobs/owner-detail-update-jobs.component";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
@@ -75,7 +76,18 @@ function OwnerDetailJobsComponent({ bodyshop, owner }) {
|
||||
})),
|
||||
onFilter: (value, record) => value.includes(record.status)
|
||||
},
|
||||
|
||||
{
|
||||
title: t("jobs.fields.actual_completion"),
|
||||
dataIndex: "actual_completion",
|
||||
key: "actual_completion",
|
||||
render: (text, record) => (
|
||||
<DateTimeFormatter>{record.actual_completion}</DateTimeFormatter>
|
||||
),
|
||||
sorter: (a, b) => dateSort(a.actual_completion, b.actual_completion),
|
||||
sortOrder:
|
||||
state.sortedInfo.columnKey === "actual_completion" &&
|
||||
state.sortedInfo.order,
|
||||
},
|
||||
{
|
||||
title: t("jobs.fields.clm_total"),
|
||||
dataIndex: "clm_total",
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
import { DeleteFilled, EyeFilled, SyncOutlined } from "@ant-design/icons";
|
||||
import { useMutation } from "@apollo/client";
|
||||
import { useLazyQuery, useMutation } from "@apollo/client";
|
||||
import { Button, Card, Checkbox, Drawer, Grid, Input, Popconfirm, Space, Table } from "antd";
|
||||
import { PageHeader } from "@ant-design/pro-layout";
|
||||
|
||||
import queryString from "query-string";
|
||||
import React, { useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { logImEXEvent } from "../../firebase/firebase.utils";
|
||||
import { QUERY_BILL_BY_PK } from "../../graphql/bills.queries";
|
||||
import { DELETE_PARTS_ORDER } from "../../graphql/parts-orders.queries";
|
||||
import { selectJobReadOnly } from "../../redux/application/application.selectors";
|
||||
import { setModalContext } from "../../redux/modals/modals.actions";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
||||
import { DateFormatter } from "../../utils/DateFormatter";
|
||||
import { alphaSort } from "../../utils/sorters";
|
||||
import { TemplateList } from "../../utils/TemplateConstants";
|
||||
import { alphaSort } from "../../utils/sorters";
|
||||
import DataLabel from "../data-label/data-label.component";
|
||||
import PartsOrderBackorderEta from "../parts-order-backorder-eta/parts-order-backorder-eta.component";
|
||||
import PartsOrderCmReceived from "../parts-order-cm-received/parts-order-cm-received.component";
|
||||
@@ -81,19 +82,46 @@ export function PartsOrderListTableComponent({
|
||||
const [state, setState] = useState({
|
||||
sortedInfo: {}
|
||||
});
|
||||
|
||||
const [returnfrombill, setReturnFromBill] = useState();
|
||||
const [billData, setBillData] = useState();
|
||||
const search = queryString.parse(useLocation().search);
|
||||
const selectedpartsorder = search.partsorderid;
|
||||
const [searchText, setSearchText] = useState("");
|
||||
|
||||
const [billQuery] = useLazyQuery(QUERY_BILL_BY_PK);
|
||||
const [deletePartsOrder] = useMutation(DELETE_PARTS_ORDER);
|
||||
|
||||
const parts_orders = billsQuery.data ? billsQuery.data.parts_orders : [];
|
||||
const { refetch } = billsQuery;
|
||||
|
||||
useEffect(() => {
|
||||
if (returnfrombill === null) {
|
||||
setBillData(null);
|
||||
} else {
|
||||
const fetchData = async () => {
|
||||
const result = await billQuery({
|
||||
variables: { billid: returnfrombill },
|
||||
});
|
||||
setBillData(result.data);
|
||||
};
|
||||
fetchData();
|
||||
}
|
||||
}, [returnfrombill, billQuery]);
|
||||
|
||||
const recordActions = (record, showView = false) => (
|
||||
<Space direction="horizontal" wrap>
|
||||
{showView && (
|
||||
<Button onClick={() => handleOnRowClick(record)}>
|
||||
<Button
|
||||
onClick={() => {
|
||||
if (record.returnfrombill) {
|
||||
setReturnFromBill(record.returnfrombill);
|
||||
} else {
|
||||
setReturnFromBill(null);
|
||||
}
|
||||
handleOnRowClick(record);
|
||||
}}
|
||||
>
|
||||
<EyeFilled />
|
||||
</Button>
|
||||
)}
|
||||
@@ -395,7 +423,14 @@ export function PartsOrderListTableComponent({
|
||||
|
||||
return (
|
||||
<div>
|
||||
<PageHeader title={record && `${record.vendor.name} - ${record.order_number}`} extra={recordActions(record)} />
|
||||
<PageHeader
|
||||
title={
|
||||
billData
|
||||
? `${record.vendor.name} - ${record.order_number} - ${t("bills.labels.returnfrombill")}: ${billData.bills_by_pk.invoice_number}`
|
||||
: `${record.vendor.name} - ${record.order_number}`
|
||||
}
|
||||
extra={recordActions(record)}
|
||||
/>
|
||||
<Table
|
||||
scroll={{
|
||||
x: true //y: "50rem"
|
||||
|
||||
@@ -119,8 +119,14 @@ const PaymentExpandedRowComponent = ({ record, bodyshop }) => {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Descriptions title={t("job_payments.titles.descriptions")} contentStyle={{ fontWeight: "600" }} column={4}>
|
||||
<Descriptions.Item label={t("job_payments.titles.payer")}>{record.payer}</Descriptions.Item>
|
||||
<Descriptions
|
||||
title={t("job_payments.titles.descriptions")}
|
||||
contentStyle={{ fontWeight: "600" }}
|
||||
column={4}
|
||||
>
|
||||
<Descriptions.Item label={t("job_payments.titles.hint")}>
|
||||
{payment_response?.response?.methodhint}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label={t("job_payments.titles.payername")}>
|
||||
{payment_response?.response?.nameOnCard ?? ""}
|
||||
</Descriptions.Item>
|
||||
@@ -132,7 +138,7 @@ const PaymentExpandedRowComponent = ({ record, bodyshop }) => {
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label={t("job_payments.titles.transactionid")}>{record.transactionid}</Descriptions.Item>
|
||||
<Descriptions.Item label={t("job_payments.titles.paymentid")}>
|
||||
{payment_response?.response?.paymentreferenceid ?? ""}
|
||||
{payment_response?.ext_paymentid ?? ""}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label={t("job_payments.titles.paymenttype")}>{record.type}</Descriptions.Item>
|
||||
<Descriptions.Item label={t("job_payments.titles.paymentnum")}>{record.paymentnum}</Descriptions.Item>
|
||||
|
||||
@@ -6,7 +6,8 @@ import { Link } from "react-router-dom";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
||||
import { alphaSort, statusSort } from "../../utils/sorters";
|
||||
import { DateTimeFormatter } from "../../utils/DateFormatter";
|
||||
import { alphaSort, dateSort, statusSort } from "../../utils/sorters";
|
||||
import OwnerNameDisplay, { OwnerNameDisplayFunction } from "../owner-name-display/owner-name-display.component";
|
||||
import VehicleDetailUpdateJobsComponent from "../vehicle-detail-update-jobs/vehicle-detail-update-jobs.component";
|
||||
|
||||
@@ -67,9 +68,20 @@ export function VehicleDetailJobsComponent({ vehicle, bodyshop }) {
|
||||
text: status,
|
||||
value: status
|
||||
})),
|
||||
onFilter: (value, record) => value.includes(record.status)
|
||||
onFilter: (value, record) => value.includes(record.status),
|
||||
},
|
||||
{
|
||||
title: t("jobs.fields.actual_completion"),
|
||||
dataIndex: "actual_completion",
|
||||
key: "actual_completion",
|
||||
render: (text, record) => (
|
||||
<DateTimeFormatter>{record.actual_completion}</DateTimeFormatter>
|
||||
),
|
||||
sorter: (a, b) => dateSort(a.actual_completion, b.actual_completion),
|
||||
sortOrder:
|
||||
state.sortedInfo.columnKey === "actual_completion" &&
|
||||
state.sortedInfo.order,
|
||||
},
|
||||
|
||||
{
|
||||
title: t("jobs.fields.clm_total"),
|
||||
dataIndex: "clm_total",
|
||||
|
||||
@@ -66,6 +66,7 @@ export const QUERY_BILLS_BY_JOBID = gql`
|
||||
order_date
|
||||
deliver_by
|
||||
return
|
||||
returnfrombill
|
||||
orderedby
|
||||
parts_order_lines {
|
||||
id
|
||||
|
||||
@@ -67,6 +67,7 @@ export const QUERY_OWNER_BY_ID = gql`
|
||||
tax_number
|
||||
jobs(order_by: { date_open: desc }) {
|
||||
id
|
||||
actual_completion
|
||||
ro_number
|
||||
clm_no
|
||||
status
|
||||
|
||||
@@ -30,6 +30,7 @@ export const QUERY_VEHICLE_BY_ID = gql`
|
||||
notes
|
||||
jobs(order_by: { date_open: desc }) {
|
||||
id
|
||||
actual_completion
|
||||
ro_number
|
||||
ownr_co_nm
|
||||
ownr_fn
|
||||
|
||||
@@ -51,6 +51,17 @@ export function JobsAvailablePageContainer({ partnerVersion, setBreadcrumbs, set
|
||||
{!partnerVersion && (
|
||||
<AlertComponent
|
||||
type="warning"
|
||||
action={
|
||||
<a
|
||||
href={InstanceRenderManager({
|
||||
imex: "https://partner.imex.online/Setup.exe",
|
||||
rome: "https://partner.romeonline.io/Setup.exe",
|
||||
promanager: "https://dzaenazwrgg60.cloudfront.net/Setup.exe"
|
||||
})}
|
||||
>
|
||||
<Button size="small">{t("general.actions.download")}</Button>
|
||||
</a>
|
||||
}
|
||||
message={t("general.messages.partnernotrunning", {
|
||||
app: InstanceRenderManager({
|
||||
imex: "$t(titles.imexonline)",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Button, Collapse, FloatButton, Layout, Space, Spin, Tag } from "antd";
|
||||
import { FloatButton, Layout, Spin } from "antd";
|
||||
// import preval from "preval.macro";
|
||||
import React, { lazy, Suspense, useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
@@ -117,7 +117,6 @@ const mapDispatchToProps = (dispatch) => ({
|
||||
export function Manage({ conflict, bodyshop, enableJoyRide, joyRideSteps, setJoyRideFinished }) {
|
||||
const { t } = useTranslation();
|
||||
const [chatVisible] = useState(false);
|
||||
const [tours, setTours] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
const widgetId = InstanceRenderManager({
|
||||
@@ -630,28 +629,6 @@ export function Manage({ conflict, bodyshop, enableJoyRide, joyRideSteps, setJoy
|
||||
Disclaimer & Notices
|
||||
</Link>
|
||||
</div>
|
||||
{InstanceRenderManager({
|
||||
promanager: (
|
||||
<Collapse>
|
||||
<Collapse.Panel header="DEVELOPMENT ONLY - ProductFruits Tours">
|
||||
<Space>
|
||||
<Button
|
||||
onClick={async () => {
|
||||
setTours(await window.productFruits.api.tours.getTours());
|
||||
}}
|
||||
>
|
||||
Get Tours
|
||||
</Button>
|
||||
{tours.map((tour) => (
|
||||
<Tag key={tour.id} onClick={() => window.productFruits.api.tours.tryStartTour(tour.id)}>
|
||||
{tour.name}
|
||||
</Tag>
|
||||
))}
|
||||
</Space>
|
||||
</Collapse.Panel>
|
||||
</Collapse>
|
||||
)
|
||||
})}
|
||||
</Footer>
|
||||
</Layout>
|
||||
</>
|
||||
|
||||
@@ -8,7 +8,8 @@ const INITIAL_STATE = {
|
||||
name: "ShopName",
|
||||
address: InstanceRenderManager({
|
||||
imex: "noreply@iemx.online",
|
||||
rome: "noreply@romeonline.io"
|
||||
rome: "noreply@romeonline.io",
|
||||
promanager: "noreply@promanager.web-est.com"
|
||||
})
|
||||
},
|
||||
to: null,
|
||||
|
||||
@@ -136,12 +136,12 @@
|
||||
"jobsupplement": "Job supplement imported.",
|
||||
"jobsuspend": "Suspend Toggle set to {{status}}",
|
||||
"jobvoid": "Job has been voided.",
|
||||
"tasks_created": "Task '{{title}}' created by {{createdBy}}",
|
||||
"tasks_updated": "Task '{{title}}' updated by {{updatedBy}}",
|
||||
"tasks_deleted": "Task '{{title}}' deleted by {{deletedBy}}",
|
||||
"tasks_undeleted": "Task '{{title}}' undeleted by {{undeletedBy}}",
|
||||
"tasks_completed": "Task '{{title}}' completed by {{completedBy}}",
|
||||
"tasks_uncompleted": "Task '{{title}}' uncompleted by {{uncompletedBy}}"
|
||||
"tasks_created": "Task '{{title}}' created by {{createdBy}}",
|
||||
"tasks_deleted": "Task '{{title}}' deleted by {{deletedBy}}",
|
||||
"tasks_uncompleted": "Task '{{title}}' uncompleted by {{uncompletedBy}}",
|
||||
"tasks_undeleted": "Task '{{title}}' undeleted by {{undeletedBy}}",
|
||||
"tasks_updated": "Task '{{title}}' updated by {{updatedBy}}"
|
||||
}
|
||||
},
|
||||
"billlines": {
|
||||
@@ -230,11 +230,12 @@
|
||||
"markexported": "Mark Exported",
|
||||
"markforreexport": "Mark for Re-export",
|
||||
"new": "New Bill",
|
||||
"nobilllines": "This part has not yet been recieved.",
|
||||
"nobilllines": "",
|
||||
"noneselected": "No bill selected.",
|
||||
"onlycmforinvoiced": "Only credit memos can be entered for any Job that has been invoiced, exported, or voided.",
|
||||
"printlabels": "Print Labels",
|
||||
"retailtotal": "Bills Retail Total",
|
||||
"returnfrombill": "Return From Bill",
|
||||
"savewithdiscrepancy": "You are about to save this bill with a discrepancy. The system will continue to use the calculated amount using the bill lines. Press cancel to return to the bill.",
|
||||
"state_tax": "State Tax",
|
||||
"subtotal": "Subtotal",
|
||||
@@ -865,10 +866,11 @@
|
||||
},
|
||||
"status": {
|
||||
"in": "Available",
|
||||
"inservice": "In Service",
|
||||
"inservice": "Service/Maintenance",
|
||||
"leasereturn": "Lease Returned",
|
||||
"out": "Rented",
|
||||
"sold": "Sold"
|
||||
"sold": "Sold",
|
||||
"unavailable": "Unavailable"
|
||||
},
|
||||
"successes": {
|
||||
"saved": "Courtesy Car saved successfully."
|
||||
@@ -924,7 +926,6 @@
|
||||
},
|
||||
"titles": {
|
||||
"joblifecycle": "Job Life Cycles",
|
||||
"tasks": "Tasks",
|
||||
"labhours": "Total Body Hours",
|
||||
"larhours": "Total Refinish Hours",
|
||||
"monthlyemployeeefficiency": "Monthly Employee Efficiency",
|
||||
@@ -939,7 +940,8 @@
|
||||
"scheduledindate": "Sheduled In Today: {{date}}",
|
||||
"scheduledintoday": "Sheduled In Today",
|
||||
"scheduledoutdate": "Sheduled Out Today: {{date}}",
|
||||
"scheduledouttoday": "Sheduled Out Today"
|
||||
"scheduledouttoday": "Sheduled Out Today",
|
||||
"tasks": "Tasks"
|
||||
}
|
||||
},
|
||||
"dms": {
|
||||
@@ -1134,6 +1136,7 @@
|
||||
"delete": "Delete",
|
||||
"deleteall": "Delete All",
|
||||
"deselectall": "Deselect All",
|
||||
"download": "Download",
|
||||
"edit": "Edit",
|
||||
"login": "Login",
|
||||
"print": "Print",
|
||||
@@ -1359,6 +1362,7 @@
|
||||
"amount": "Amount",
|
||||
"dateOfPayment": "Date of Payment",
|
||||
"descriptions": "Payment Details",
|
||||
"hint": "Hint",
|
||||
"payer": "Payer",
|
||||
"payername": "Payer Name",
|
||||
"paymentid": "Payment Reference ID",
|
||||
@@ -1868,7 +1872,6 @@
|
||||
"appointmentconfirmation": "Send confirmation to customer?",
|
||||
"associationwarning": "Any changes to associations will require updating the data from the new parent record to the Job.",
|
||||
"audit": "Audit Trail",
|
||||
"tasks": "Tasks",
|
||||
"available": "Available",
|
||||
"availablejobs": "Available Jobs",
|
||||
"ca_bc_pvrt": {
|
||||
@@ -2013,7 +2016,8 @@
|
||||
},
|
||||
"ppc": "This line contains a part price change.",
|
||||
"ppdnotexported": "PPDs not Exported",
|
||||
"profileadjustments": "Profile Disc./Mkup","profitbypassrequired": "Minimum gross profit requirements have not been met.",
|
||||
"profileadjustments": "Profile Disc./Mkup",
|
||||
"profitbypassrequired": "Minimum gross profit requirements have not been met.",
|
||||
"profits": "Job Profits",
|
||||
"prt_dsmk_total": "Line Item Adjustment",
|
||||
"rates": "Rates",
|
||||
@@ -2035,7 +2039,6 @@
|
||||
"remove_from_ar": "Remove from AR",
|
||||
"returntotals": "Return Totals",
|
||||
"ro_guard": {
|
||||
|
||||
"enforce_ar": "AR collection enforced.",
|
||||
"enforce_bills": "Bill discrepancy enforced.",
|
||||
"enforce_cm": "Credit memo entry enforced.",
|
||||
@@ -2064,6 +2067,7 @@
|
||||
"supplementnote": "The Job had a supplement imported.",
|
||||
"suspended": "SUSPENDED",
|
||||
"suspense": "Suspense",
|
||||
"tasks": "Tasks",
|
||||
"threshhold": "Max Threshold: ${{amount}}",
|
||||
"total_cost": "Total Cost",
|
||||
"total_cust_payable": "Total Customer Amount Payable",
|
||||
@@ -2150,107 +2154,18 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"tasks": {
|
||||
"failures": {
|
||||
"created": "Failed to create Task.",
|
||||
"deleted": "Failed to toggle Task deletion.",
|
||||
"updated": "Failed to update Task.",
|
||||
"completed": "Failed to toggle Task completion."
|
||||
},
|
||||
"successes": {
|
||||
"created": "Task created successfully.",
|
||||
"deleted": "Toggled Task deletion successfully.",
|
||||
"updated": "Task updated successfully.",
|
||||
"completed": "Toggled Task completion successfully."
|
||||
},
|
||||
"date_presets": {
|
||||
"next_week": "Next Week",
|
||||
"two_weeks": "Two Weeks",
|
||||
"three_weeks": "Three Weeks",
|
||||
"one_month": "One Month",
|
||||
"today": "Today",
|
||||
"tomorrow": "Tomorrow",
|
||||
"three_months": "Three Months",
|
||||
"day": "Day",
|
||||
"days": "Days",
|
||||
"delivery": "Delivery",
|
||||
"completion": "Completion"
|
||||
},
|
||||
"actions": {
|
||||
"new": "New Task",
|
||||
"edit": "Edit Task"
|
||||
},
|
||||
"titles": {
|
||||
"all_tasks": "All Tasks",
|
||||
"job_tasks": "Job Tasks",
|
||||
"mine": "My Tasks",
|
||||
"my_tasks": "My Tasks",
|
||||
"completed": "Completed Tasks",
|
||||
"deleted": "Deleted Tasks"
|
||||
},
|
||||
"buttons": {
|
||||
"create": "Create Task",
|
||||
"complete": "Toggle Complete",
|
||||
"delete": "Toggle Delete",
|
||||
"edit": "Edit",
|
||||
"refresh": "Refresh",
|
||||
"myTasks": "Mine",
|
||||
"allTasks": "All"
|
||||
},
|
||||
"placeholders": {
|
||||
"description": "Enter a description",
|
||||
"jobid": "Select a Job",
|
||||
"joblineid": "Select a Job Line",
|
||||
"partsorderid": "Select a Parts Order",
|
||||
"billid": "Select a Bill",
|
||||
"assigned_to": "Select an Employee"
|
||||
},
|
||||
"fields": {
|
||||
"priorities": {
|
||||
"low": "Low",
|
||||
"medium": "Medium",
|
||||
"high": "High"
|
||||
},
|
||||
"created_at": "Created At",
|
||||
"jobline": "Job Line",
|
||||
"parts_order": "Parts Order",
|
||||
"bill": "Bill",
|
||||
"title": "Title",
|
||||
"joblineid": "Job Line",
|
||||
"jobid": "Job",
|
||||
"partsorderid": "Parts Order",
|
||||
"billid": "Bill",
|
||||
"description": "Description",
|
||||
"due_date": "Due Date",
|
||||
"actions": "Actions",
|
||||
"priority": "Priority",
|
||||
"remind_at": "Remind At",
|
||||
"assigned_to": "Assigned To",
|
||||
"completed": "Completed",
|
||||
"job": {
|
||||
"ro_number": "RO #"
|
||||
}
|
||||
},
|
||||
"validation": {
|
||||
"due_at_error_message": "The due date must be in the future!",
|
||||
"remind_at_error_message": "The reminder date and time must be at least 30 minutes in the future!"
|
||||
}
|
||||
},
|
||||
"menus": {
|
||||
"currentuser": {
|
||||
"languageselector": "Language",
|
||||
"profile": "Profile"
|
||||
},
|
||||
"header": {
|
||||
"create_task": "Create Task",
|
||||
"tasks": "Tasks",
|
||||
"my_tasks": "My Tasks",
|
||||
"all_tasks": "All Tasks",
|
||||
"accounting": "Accounting",
|
||||
"accounting-payables": "Payables",
|
||||
"accounting-payments": "Payments",
|
||||
"accounting-receivables": "Receivables",
|
||||
"activejobs": "Active Jobs",
|
||||
"all_tasks": "All Tasks",
|
||||
"alljobs": "All Jobs",
|
||||
"allpayments": "All Payments",
|
||||
"availablejobs": "Available Jobs",
|
||||
@@ -2259,6 +2174,7 @@
|
||||
"courtesycars-all": "All Courtesy Cars",
|
||||
"courtesycars-contracts": "Contracts",
|
||||
"courtesycars-newcontract": "New Contract",
|
||||
"create_task": "Create Task",
|
||||
"customers": "Customers",
|
||||
"dashboard": "Dashboard",
|
||||
"enterbills": "Enter Bills",
|
||||
@@ -2271,6 +2187,7 @@
|
||||
"home": "Home",
|
||||
"inventory": "Inventory",
|
||||
"jobs": "Jobs",
|
||||
"my_tasks": "My Tasks",
|
||||
"newjob": "Create New Job",
|
||||
"owners": "Owners",
|
||||
"parts-queue": "Parts Queue",
|
||||
@@ -2297,6 +2214,7 @@
|
||||
"shop_csi": "CSI",
|
||||
"shop_templates": "Templates",
|
||||
"shop_vendors": "Vendors",
|
||||
"tasks": "Tasks",
|
||||
"temporarydocs": "Temporary Documents",
|
||||
"timetickets": "Time Tickets",
|
||||
"ttapprovals": "Time Ticket Approvals",
|
||||
@@ -2490,6 +2408,7 @@
|
||||
"percent_accepted": "% Accepted"
|
||||
},
|
||||
"labels": {
|
||||
"notyetdispatched": "This part has not been dispatched.",
|
||||
"parts_dispatch": "Parts Dispatch"
|
||||
}
|
||||
},
|
||||
@@ -3106,6 +3025,92 @@
|
||||
"updated": "Scoreboard updated."
|
||||
}
|
||||
},
|
||||
"tasks": {
|
||||
"actions": {
|
||||
"edit": "Edit Task",
|
||||
"new": "New Task"
|
||||
},
|
||||
"buttons": {
|
||||
"allTasks": "All",
|
||||
"complete": "Toggle Complete",
|
||||
"create": "Create Task",
|
||||
"delete": "Toggle Delete",
|
||||
"edit": "Edit",
|
||||
"myTasks": "Mine",
|
||||
"refresh": "Refresh"
|
||||
},
|
||||
"date_presets": {
|
||||
"completion": "Completion",
|
||||
"day": "Day",
|
||||
"days": "Days",
|
||||
"delivery": "Delivery",
|
||||
"next_week": "Next Week",
|
||||
"one_month": "One Month",
|
||||
"three_months": "Three Months",
|
||||
"three_weeks": "Three Weeks",
|
||||
"today": "Today",
|
||||
"tomorrow": "Tomorrow",
|
||||
"two_weeks": "Two Weeks"
|
||||
},
|
||||
"failures": {
|
||||
"completed": "Failed to toggle Task completion.",
|
||||
"created": "Failed to create Task.",
|
||||
"deleted": "Failed to toggle Task deletion.",
|
||||
"updated": "Failed to update Task."
|
||||
},
|
||||
"fields": {
|
||||
"actions": "Actions",
|
||||
"assigned_to": "Assigned To",
|
||||
"bill": "Bill",
|
||||
"billid": "Bill",
|
||||
"completed": "Completed",
|
||||
"created_at": "Created At",
|
||||
"description": "Description",
|
||||
"due_date": "Due Date",
|
||||
"job": {
|
||||
"ro_number": "RO #"
|
||||
},
|
||||
"jobid": "Job",
|
||||
"jobline": "Job Line",
|
||||
"joblineid": "Job Line",
|
||||
"parts_order": "Parts Order",
|
||||
"partsorderid": "Parts Order",
|
||||
"priorities": {
|
||||
"high": "High",
|
||||
"low": "Low",
|
||||
"medium": "Medium"
|
||||
},
|
||||
"priority": "Priority",
|
||||
"remind_at": "Remind At",
|
||||
"title": "Title"
|
||||
},
|
||||
"placeholders": {
|
||||
"assigned_to": "Select an Employee",
|
||||
"billid": "Select a Bill",
|
||||
"description": "Enter a description",
|
||||
"jobid": "Select a Job",
|
||||
"joblineid": "Select a Job Line",
|
||||
"partsorderid": "Select a Parts Order"
|
||||
},
|
||||
"successes": {
|
||||
"completed": "Toggled Task completion successfully.",
|
||||
"created": "Task created successfully.",
|
||||
"deleted": "Toggled Task deletion successfully.",
|
||||
"updated": "Task updated successfully."
|
||||
},
|
||||
"titles": {
|
||||
"all_tasks": "All Tasks",
|
||||
"completed": "Completed Tasks",
|
||||
"deleted": "Deleted Tasks",
|
||||
"job_tasks": "Job Tasks",
|
||||
"mine": "My Tasks",
|
||||
"my_tasks": "My Tasks"
|
||||
},
|
||||
"validation": {
|
||||
"due_at_error_message": "The due date must be in the future!",
|
||||
"remind_at_error_message": "The reminder date and time must be at least 30 minutes in the future!"
|
||||
}
|
||||
},
|
||||
"tech": {
|
||||
"fields": {
|
||||
"employeeid": "Employee ID",
|
||||
@@ -3207,20 +3212,16 @@
|
||||
}
|
||||
},
|
||||
"titles": {
|
||||
"tasks": "Tasks",
|
||||
"all_tasks": "All Tasks",
|
||||
"my_tasks": "My Tasks",
|
||||
"accounting-payables": "Payables | {{app}}",
|
||||
"accounting-payments": "Payments | {{app}}",
|
||||
"accounting-receivables": "Receivables | {{app}}",
|
||||
"all_tasks": "All Tasks",
|
||||
"app": "",
|
||||
"bc": {
|
||||
"tasks": "Tasks",
|
||||
"all_tasks": "All Tasks",
|
||||
"my_tasks": "My Tasks",
|
||||
"accounting-payables": "Payables",
|
||||
"accounting-payments": "Payments",
|
||||
"accounting-receivables": "Receivables",
|
||||
"all_tasks": "All Tasks",
|
||||
"availablejobs": "Available Jobs",
|
||||
"bills-list": "Bills",
|
||||
"contracts": "Contracts",
|
||||
@@ -3244,6 +3245,7 @@
|
||||
"jobs-intake": "Intake",
|
||||
"jobs-new": "Create a New Job",
|
||||
"jobs-ready": "Ready Jobs",
|
||||
"my_tasks": "My Tasks",
|
||||
"owner-detail": "{{name}}",
|
||||
"owners": "Owners",
|
||||
"parts-queue": "Parts Queue",
|
||||
@@ -3258,6 +3260,7 @@
|
||||
"shop-csi": "CSI Responses",
|
||||
"shop-templates": "Shop Templates",
|
||||
"shop-vendors": "Vendors",
|
||||
"tasks": "Tasks",
|
||||
"temporarydocs": "Temporary Documents",
|
||||
"timetickets": "Time Tickets",
|
||||
"ttapprovals": "Time Ticket Approvals",
|
||||
@@ -3288,6 +3291,7 @@
|
||||
"jobsdetail": "Job {{ro_number}} | {{app}}",
|
||||
"jobsdocuments": "Job Documents {{ro_number}} | {{app}}",
|
||||
"manageroot": "Home | {{app}}",
|
||||
"my_tasks": "My Tasks",
|
||||
"owners": "All Owners | {{app}}",
|
||||
"owners-detail": "{{name}} | {{app}}",
|
||||
"parts-queue": "Parts Queue | {{app}}",
|
||||
@@ -3307,6 +3311,7 @@
|
||||
"shop-csi": "CSI Responses | {{app}}",
|
||||
"shop-templates": "Shop Templates | {{app}}",
|
||||
"shop_vendors": "Vendors | {{app}}",
|
||||
"tasks": "Tasks",
|
||||
"techconsole": "Technician Console | {{app}}",
|
||||
"techjobclock": "Technician Job Clock | {{app}}",
|
||||
"techjoblookup": "Technician Job Lookup | {{app}}",
|
||||
|
||||
@@ -136,12 +136,12 @@
|
||||
"jobsupplement": "",
|
||||
"jobsuspend": "",
|
||||
"jobvoid": "",
|
||||
"tasks_created": "",
|
||||
"tasks_updated": "",
|
||||
"tasks_deleted": "",
|
||||
"tasks_undeleted": "",
|
||||
"tasks_completed": "",
|
||||
"tasks_uncompleted": ""
|
||||
"tasks_created": "",
|
||||
"tasks_deleted": "",
|
||||
"tasks_uncompleted": "",
|
||||
"tasks_undeleted": "",
|
||||
"tasks_updated": ""
|
||||
}
|
||||
},
|
||||
"billlines": {
|
||||
@@ -230,10 +230,12 @@
|
||||
"markexported": "",
|
||||
"markforreexport": "",
|
||||
"new": "",
|
||||
"nobilllines": "",
|
||||
"noneselected": "",
|
||||
"onlycmforinvoiced": "",
|
||||
"printlabels": "",
|
||||
"retailtotal": "",
|
||||
"returnfrombill": "",
|
||||
"savewithdiscrepancy": "",
|
||||
"state_tax": "",
|
||||
"subtotal": "",
|
||||
@@ -867,7 +869,8 @@
|
||||
"inservice": "",
|
||||
"leasereturn": "",
|
||||
"out": "",
|
||||
"sold": ""
|
||||
"sold": "",
|
||||
"unavailable": ""
|
||||
},
|
||||
"successes": {
|
||||
"saved": ""
|
||||
@@ -923,7 +926,6 @@
|
||||
},
|
||||
"titles": {
|
||||
"joblifecycle": "",
|
||||
"tasks": "",
|
||||
"labhours": "",
|
||||
"larhours": "",
|
||||
"monthlyemployeeefficiency": "",
|
||||
@@ -938,7 +940,8 @@
|
||||
"scheduledindate": "",
|
||||
"scheduledintoday": "",
|
||||
"scheduledoutdate": "",
|
||||
"scheduledouttoday": ""
|
||||
"scheduledouttoday": "",
|
||||
"tasks": ""
|
||||
}
|
||||
},
|
||||
"dms": {
|
||||
@@ -1133,6 +1136,7 @@
|
||||
"delete": "Borrar",
|
||||
"deleteall": "",
|
||||
"deselectall": "",
|
||||
"download": "",
|
||||
"edit": "Editar",
|
||||
"login": "",
|
||||
"print": "",
|
||||
@@ -1358,6 +1362,7 @@
|
||||
"amount": "",
|
||||
"dateOfPayment": "",
|
||||
"descriptions": "",
|
||||
"hint": "",
|
||||
"payer": "",
|
||||
"payername": "",
|
||||
"paymentid": "",
|
||||
@@ -1867,7 +1872,6 @@
|
||||
"appointmentconfirmation": "¿Enviar confirmación al cliente?",
|
||||
"associationwarning": "",
|
||||
"audit": "",
|
||||
"tasks": "",
|
||||
"available": "",
|
||||
"availablejobs": "",
|
||||
"ca_bc_pvrt": {
|
||||
@@ -2039,7 +2043,8 @@
|
||||
"enforce_bills": "",
|
||||
"enforce_cm": "",
|
||||
"enforce_labor": "",
|
||||
"enforce_ppd": "","enforce_profit": "",
|
||||
"enforce_ppd": "",
|
||||
"enforce_profit": "",
|
||||
"enforce_sublet": "",
|
||||
"enforce_validation": "",
|
||||
"enforced": ""
|
||||
@@ -2062,6 +2067,7 @@
|
||||
"supplementnote": "",
|
||||
"suspended": "",
|
||||
"suspense": "",
|
||||
"tasks": "",
|
||||
"threshhold": "",
|
||||
"total_cost": "",
|
||||
"total_cust_payable": "",
|
||||
@@ -2148,107 +2154,18 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"tasks": {
|
||||
"failures": {
|
||||
"created": "",
|
||||
"deleted": "",
|
||||
"updated": "",
|
||||
"completed": ""
|
||||
},
|
||||
"successes": {
|
||||
"created": "",
|
||||
"deleted": "",
|
||||
"updated": "",
|
||||
"completed": ""
|
||||
},
|
||||
"date_presets": {
|
||||
"next_week": "",
|
||||
"two_weeks": "",
|
||||
"three_weeks": "",
|
||||
"one_month": "",
|
||||
"today": "",
|
||||
"tomorrow": "",
|
||||
"three_months": "",
|
||||
"day": "",
|
||||
"days": "",
|
||||
"delivery": "",
|
||||
"completion": ""
|
||||
},
|
||||
"actions": {
|
||||
"new": "",
|
||||
"edit": ""
|
||||
},
|
||||
"titles": {
|
||||
"all_tasks": "",
|
||||
"job_tasks": "",
|
||||
"mine": "",
|
||||
"my_tasks": "",
|
||||
"completed": "",
|
||||
"deleted": ""
|
||||
},
|
||||
"buttons": {
|
||||
"create": "",
|
||||
"complete": "",
|
||||
"delete": "",
|
||||
"edit": "",
|
||||
"refresh": "",
|
||||
"myTasks": "",
|
||||
"allTasks": ""
|
||||
},
|
||||
"placeholders": {
|
||||
"description": "",
|
||||
"jobid": "",
|
||||
"joblineid": "",
|
||||
"partsorderid": "",
|
||||
"billid": "",
|
||||
"assigned_to": ""
|
||||
},
|
||||
"fields": {
|
||||
"created_at": "" ,
|
||||
"jobline": "",
|
||||
"parts_order": "",
|
||||
"bill": "",
|
||||
"priorities": {
|
||||
"low": "",
|
||||
"medium": "",
|
||||
"high": ""
|
||||
},
|
||||
"title": "",
|
||||
"joblineid": "",
|
||||
"jobid": "",
|
||||
"partsorderid": "",
|
||||
"billid": "",
|
||||
"description": "",
|
||||
"due_date": "",
|
||||
"actions": "",
|
||||
"priority": "",
|
||||
"remind_at": "",
|
||||
"assigned_to": "",
|
||||
"completed": "",
|
||||
"job": {
|
||||
"ro_number": ""
|
||||
}
|
||||
},
|
||||
"validation": {
|
||||
"due_at_error_message": "",
|
||||
"remind_at_error_message": ""
|
||||
}
|
||||
},
|
||||
"menus": {
|
||||
"currentuser": {
|
||||
"languageselector": "idioma",
|
||||
"profile": "Perfil"
|
||||
},
|
||||
"header": {
|
||||
"create_task": "",
|
||||
"tasks": "",
|
||||
"all_tasks": "",
|
||||
"my_tasks": "",
|
||||
"accounting": "",
|
||||
"accounting-payables": "",
|
||||
"accounting-payments": "",
|
||||
"accounting-receivables": "",
|
||||
"activejobs": "Empleos activos",
|
||||
"all_tasks": "",
|
||||
"alljobs": "",
|
||||
"allpayments": "",
|
||||
"availablejobs": "Trabajos disponibles",
|
||||
@@ -2257,6 +2174,7 @@
|
||||
"courtesycars-all": "",
|
||||
"courtesycars-contracts": "",
|
||||
"courtesycars-newcontract": "",
|
||||
"create_task": "",
|
||||
"customers": "Clientes",
|
||||
"dashboard": "",
|
||||
"enterbills": "",
|
||||
@@ -2269,6 +2187,7 @@
|
||||
"home": "Casa",
|
||||
"inventory": "",
|
||||
"jobs": "Trabajos",
|
||||
"my_tasks": "",
|
||||
"newjob": "",
|
||||
"owners": "propietarios",
|
||||
"parts-queue": "",
|
||||
@@ -2295,6 +2214,7 @@
|
||||
"shop_csi": "",
|
||||
"shop_templates": "",
|
||||
"shop_vendors": "Vendedores",
|
||||
"tasks": "",
|
||||
"temporarydocs": "",
|
||||
"timetickets": "",
|
||||
"ttapprovals": "",
|
||||
@@ -2488,6 +2408,7 @@
|
||||
"percent_accepted": ""
|
||||
},
|
||||
"labels": {
|
||||
"notyetdispatched": "",
|
||||
"parts_dispatch": ""
|
||||
}
|
||||
},
|
||||
@@ -3104,6 +3025,92 @@
|
||||
"updated": ""
|
||||
}
|
||||
},
|
||||
"tasks": {
|
||||
"actions": {
|
||||
"edit": "",
|
||||
"new": ""
|
||||
},
|
||||
"buttons": {
|
||||
"allTasks": "",
|
||||
"complete": "",
|
||||
"create": "",
|
||||
"delete": "",
|
||||
"edit": "",
|
||||
"myTasks": "",
|
||||
"refresh": ""
|
||||
},
|
||||
"date_presets": {
|
||||
"completion": "",
|
||||
"day": "",
|
||||
"days": "",
|
||||
"delivery": "",
|
||||
"next_week": "",
|
||||
"one_month": "",
|
||||
"three_months": "",
|
||||
"three_weeks": "",
|
||||
"today": "",
|
||||
"tomorrow": "",
|
||||
"two_weeks": ""
|
||||
},
|
||||
"failures": {
|
||||
"completed": "",
|
||||
"created": "",
|
||||
"deleted": "",
|
||||
"updated": ""
|
||||
},
|
||||
"fields": {
|
||||
"actions": "",
|
||||
"assigned_to": "",
|
||||
"bill": "",
|
||||
"billid": "",
|
||||
"completed": "",
|
||||
"created_at": "",
|
||||
"description": "",
|
||||
"due_date": "",
|
||||
"job": {
|
||||
"ro_number": ""
|
||||
},
|
||||
"jobid": "",
|
||||
"jobline": "",
|
||||
"joblineid": "",
|
||||
"parts_order": "",
|
||||
"partsorderid": "",
|
||||
"priorities": {
|
||||
"high": "",
|
||||
"low": "",
|
||||
"medium": ""
|
||||
},
|
||||
"priority": "",
|
||||
"remind_at": "",
|
||||
"title": ""
|
||||
},
|
||||
"placeholders": {
|
||||
"assigned_to": "",
|
||||
"billid": "",
|
||||
"description": "",
|
||||
"jobid": "",
|
||||
"joblineid": "",
|
||||
"partsorderid": ""
|
||||
},
|
||||
"successes": {
|
||||
"completed": "",
|
||||
"created": "",
|
||||
"deleted": "",
|
||||
"updated": ""
|
||||
},
|
||||
"titles": {
|
||||
"all_tasks": "",
|
||||
"completed": "",
|
||||
"deleted": "",
|
||||
"job_tasks": "",
|
||||
"mine": "",
|
||||
"my_tasks": ""
|
||||
},
|
||||
"validation": {
|
||||
"due_at_error_message": "",
|
||||
"remind_at_error_message": ""
|
||||
}
|
||||
},
|
||||
"tech": {
|
||||
"fields": {
|
||||
"employeeid": "",
|
||||
@@ -3205,20 +3212,16 @@
|
||||
}
|
||||
},
|
||||
"titles": {
|
||||
"tasks": "",
|
||||
"all_tasks": "",
|
||||
"my_tasks": "",
|
||||
"accounting-payables": "",
|
||||
"accounting-payments": "",
|
||||
"accounting-receivables": "",
|
||||
"all_tasks": "",
|
||||
"app": "",
|
||||
"bc": {
|
||||
"tasks": "",
|
||||
"all_tasks": "",
|
||||
"my_tasks": "",
|
||||
"accounting-payables": "",
|
||||
"accounting-payments": "",
|
||||
"accounting-receivables": "",
|
||||
"all_tasks": "",
|
||||
"availablejobs": "",
|
||||
"bills-list": "",
|
||||
"contracts": "",
|
||||
@@ -3242,6 +3245,7 @@
|
||||
"jobs-intake": "",
|
||||
"jobs-new": "",
|
||||
"jobs-ready": "",
|
||||
"my_tasks": "",
|
||||
"owner-detail": "",
|
||||
"owners": "",
|
||||
"parts-queue": "",
|
||||
@@ -3256,6 +3260,7 @@
|
||||
"shop-csi": "",
|
||||
"shop-templates": "",
|
||||
"shop-vendors": "",
|
||||
"tasks": "",
|
||||
"temporarydocs": "",
|
||||
"timetickets": "",
|
||||
"ttapprovals": "",
|
||||
@@ -3286,6 +3291,7 @@
|
||||
"jobsdetail": "Trabajo {{ro_number}} | {{app}}",
|
||||
"jobsdocuments": "Documentos de trabajo {{ro_number}} | {{app}}",
|
||||
"manageroot": "Casa | {{app}}",
|
||||
"my_tasks": "",
|
||||
"owners": "Todos los propietarios | {{app}}",
|
||||
"owners-detail": "",
|
||||
"parts-queue": "",
|
||||
@@ -3305,6 +3311,7 @@
|
||||
"shop-csi": "",
|
||||
"shop-templates": "",
|
||||
"shop_vendors": "Vendedores | {{app}}",
|
||||
"tasks": "",
|
||||
"techconsole": "{{app}}",
|
||||
"techjobclock": "{{app}}",
|
||||
"techjoblookup": "{{app}}",
|
||||
|
||||
@@ -136,12 +136,12 @@
|
||||
"jobsupplement": "",
|
||||
"jobsuspend": "",
|
||||
"jobvoid": "",
|
||||
"tasks_created": "",
|
||||
"tasks_updated": "",
|
||||
"tasks_deleted": "",
|
||||
"tasks_undeleted": "",
|
||||
"tasks_completed": "",
|
||||
"tasks_uncompleted": ""
|
||||
"tasks_created": "",
|
||||
"tasks_deleted": "",
|
||||
"tasks_uncompleted": "",
|
||||
"tasks_undeleted": "",
|
||||
"tasks_updated": ""
|
||||
}
|
||||
},
|
||||
"billlines": {
|
||||
@@ -230,10 +230,12 @@
|
||||
"markexported": "",
|
||||
"markforreexport": "",
|
||||
"new": "",
|
||||
"nobilllines": "",
|
||||
"noneselected": "",
|
||||
"onlycmforinvoiced": "",
|
||||
"printlabels": "",
|
||||
"retailtotal": "",
|
||||
"returnfrombill": "",
|
||||
"savewithdiscrepancy": "",
|
||||
"state_tax": "",
|
||||
"subtotal": "",
|
||||
@@ -867,7 +869,8 @@
|
||||
"inservice": "",
|
||||
"leasereturn": "",
|
||||
"out": "",
|
||||
"sold": ""
|
||||
"sold": "",
|
||||
"unavailable": ""
|
||||
},
|
||||
"successes": {
|
||||
"saved": ""
|
||||
@@ -923,7 +926,6 @@
|
||||
},
|
||||
"titles": {
|
||||
"joblifecycle": "",
|
||||
"tasks": "",
|
||||
"labhours": "",
|
||||
"larhours": "",
|
||||
"monthlyemployeeefficiency": "",
|
||||
@@ -938,7 +940,8 @@
|
||||
"scheduledindate": "",
|
||||
"scheduledintoday": "",
|
||||
"scheduledoutdate": "",
|
||||
"scheduledouttoday": ""
|
||||
"scheduledouttoday": "",
|
||||
"tasks": ""
|
||||
}
|
||||
},
|
||||
"dms": {
|
||||
@@ -1133,6 +1136,7 @@
|
||||
"delete": "Effacer",
|
||||
"deleteall": "",
|
||||
"deselectall": "",
|
||||
"download": "",
|
||||
"edit": "modifier",
|
||||
"login": "",
|
||||
"print": "",
|
||||
@@ -1358,6 +1362,7 @@
|
||||
"amount": "",
|
||||
"dateOfPayment": "",
|
||||
"descriptions": "",
|
||||
"hint": "",
|
||||
"payer": "",
|
||||
"payername": "",
|
||||
"paymentid": "",
|
||||
@@ -1867,7 +1872,6 @@
|
||||
"appointmentconfirmation": "Envoyer une confirmation au client?",
|
||||
"associationwarning": "",
|
||||
"audit": "",
|
||||
"tasks": "",
|
||||
"available": "",
|
||||
"availablejobs": "",
|
||||
"ca_bc_pvrt": {
|
||||
@@ -2039,7 +2043,8 @@
|
||||
"enforce_bills": "",
|
||||
"enforce_cm": "",
|
||||
"enforce_labor": "",
|
||||
"enforce_ppd": "","enforce_profit": "",
|
||||
"enforce_ppd": "",
|
||||
"enforce_profit": "",
|
||||
"enforce_sublet": "",
|
||||
"enforce_validation": "",
|
||||
"enforced": ""
|
||||
@@ -2062,6 +2067,7 @@
|
||||
"supplementnote": "",
|
||||
"suspended": "",
|
||||
"suspense": "",
|
||||
"tasks": "",
|
||||
"threshhold": "",
|
||||
"total_cost": "",
|
||||
"total_cust_payable": "",
|
||||
@@ -2148,107 +2154,18 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"tasks": {
|
||||
"failures": {
|
||||
"created": "",
|
||||
"deleted": "",
|
||||
"updated": "",
|
||||
"completed": ""
|
||||
},
|
||||
"successes": {
|
||||
"created": "",
|
||||
"deleted": "",
|
||||
"updated": "",
|
||||
"completed": ""
|
||||
},
|
||||
"date_presets": {
|
||||
"next_week": "",
|
||||
"two_weeks": "",
|
||||
"three_weeks": "",
|
||||
"one_month": "",
|
||||
"today": "",
|
||||
"tomorrow": "",
|
||||
"three_months": "",
|
||||
"day": "",
|
||||
"days": "",
|
||||
"delivery": "",
|
||||
"completion": ""
|
||||
},
|
||||
"actions": {
|
||||
"new": "",
|
||||
"edit": ""
|
||||
},
|
||||
"titles": {
|
||||
"all_tasks": "",
|
||||
"job_tasks": "",
|
||||
"mine": "",
|
||||
"my_tasks": "",
|
||||
"completed": "",
|
||||
"deleted": ""
|
||||
},
|
||||
"buttons": {
|
||||
"create": "",
|
||||
"complete": "",
|
||||
"delete": "",
|
||||
"edit": "",
|
||||
"refresh": "",
|
||||
"myTasks": "",
|
||||
"allTasks": ""
|
||||
},
|
||||
"placeholders": {
|
||||
"description": "",
|
||||
"jobid": "",
|
||||
"joblineid": "",
|
||||
"partsorderid": "",
|
||||
"billid": "",
|
||||
"assigned_to": ""
|
||||
},
|
||||
"fields": {
|
||||
"created_at": "",
|
||||
"jobline": "",
|
||||
"parts_order": "",
|
||||
"bill": "",
|
||||
"priorities": {
|
||||
"low": "",
|
||||
"medium": "",
|
||||
"high": ""
|
||||
},
|
||||
"title": "",
|
||||
"joblineid": "",
|
||||
"jobid": "",
|
||||
"partsorderid": "",
|
||||
"billid": "",
|
||||
"description": "",
|
||||
"due_date": "",
|
||||
"actions": "",
|
||||
"priority": "",
|
||||
"remind_at": "",
|
||||
"assigned_to": "",
|
||||
"completed": "",
|
||||
"job": {
|
||||
"ro_number": ""
|
||||
}
|
||||
},
|
||||
"validation": {
|
||||
"due_at_error_message": "",
|
||||
"remind_at_error_message": ""
|
||||
}
|
||||
},
|
||||
"menus": {
|
||||
"currentuser": {
|
||||
"languageselector": "La langue",
|
||||
"profile": "Profil"
|
||||
},
|
||||
"header": {
|
||||
"create_task": "",
|
||||
"tasks": "",
|
||||
"my_tasks": "",
|
||||
"all_tasks": "",
|
||||
"accounting": "",
|
||||
"accounting-payables": "",
|
||||
"accounting-payments": "",
|
||||
"accounting-receivables": "",
|
||||
"activejobs": "Emplois actifs",
|
||||
"all_tasks": "",
|
||||
"alljobs": "",
|
||||
"allpayments": "",
|
||||
"availablejobs": "Emplois disponibles",
|
||||
@@ -2257,6 +2174,7 @@
|
||||
"courtesycars-all": "",
|
||||
"courtesycars-contracts": "",
|
||||
"courtesycars-newcontract": "",
|
||||
"create_task": "",
|
||||
"customers": "Les clients",
|
||||
"dashboard": "",
|
||||
"enterbills": "",
|
||||
@@ -2269,6 +2187,7 @@
|
||||
"home": "Accueil",
|
||||
"inventory": "",
|
||||
"jobs": "Emplois",
|
||||
"my_tasks": "",
|
||||
"newjob": "",
|
||||
"owners": "Propriétaires",
|
||||
"parts-queue": "",
|
||||
@@ -2295,6 +2214,7 @@
|
||||
"shop_csi": "",
|
||||
"shop_templates": "",
|
||||
"shop_vendors": "Vendeurs",
|
||||
"tasks": "",
|
||||
"temporarydocs": "",
|
||||
"timetickets": "",
|
||||
"ttapprovals": "",
|
||||
@@ -2488,6 +2408,7 @@
|
||||
"percent_accepted": ""
|
||||
},
|
||||
"labels": {
|
||||
"notyetdispatched": "",
|
||||
"parts_dispatch": ""
|
||||
}
|
||||
},
|
||||
@@ -3104,6 +3025,92 @@
|
||||
"updated": ""
|
||||
}
|
||||
},
|
||||
"tasks": {
|
||||
"actions": {
|
||||
"edit": "",
|
||||
"new": ""
|
||||
},
|
||||
"buttons": {
|
||||
"allTasks": "",
|
||||
"complete": "",
|
||||
"create": "",
|
||||
"delete": "",
|
||||
"edit": "",
|
||||
"myTasks": "",
|
||||
"refresh": ""
|
||||
},
|
||||
"date_presets": {
|
||||
"completion": "",
|
||||
"day": "",
|
||||
"days": "",
|
||||
"delivery": "",
|
||||
"next_week": "",
|
||||
"one_month": "",
|
||||
"three_months": "",
|
||||
"three_weeks": "",
|
||||
"today": "",
|
||||
"tomorrow": "",
|
||||
"two_weeks": ""
|
||||
},
|
||||
"failures": {
|
||||
"completed": "",
|
||||
"created": "",
|
||||
"deleted": "",
|
||||
"updated": ""
|
||||
},
|
||||
"fields": {
|
||||
"actions": "",
|
||||
"assigned_to": "",
|
||||
"bill": "",
|
||||
"billid": "",
|
||||
"completed": "",
|
||||
"created_at": "",
|
||||
"description": "",
|
||||
"due_date": "",
|
||||
"job": {
|
||||
"ro_number": ""
|
||||
},
|
||||
"jobid": "",
|
||||
"jobline": "",
|
||||
"joblineid": "",
|
||||
"parts_order": "",
|
||||
"partsorderid": "",
|
||||
"priorities": {
|
||||
"high": "",
|
||||
"low": "",
|
||||
"medium": ""
|
||||
},
|
||||
"priority": "",
|
||||
"remind_at": "",
|
||||
"title": ""
|
||||
},
|
||||
"placeholders": {
|
||||
"assigned_to": "",
|
||||
"billid": "",
|
||||
"description": "",
|
||||
"jobid": "",
|
||||
"joblineid": "",
|
||||
"partsorderid": ""
|
||||
},
|
||||
"successes": {
|
||||
"completed": "",
|
||||
"created": "",
|
||||
"deleted": "",
|
||||
"updated": ""
|
||||
},
|
||||
"titles": {
|
||||
"all_tasks": "",
|
||||
"completed": "",
|
||||
"deleted": "",
|
||||
"job_tasks": "",
|
||||
"mine": "",
|
||||
"my_tasks": ""
|
||||
},
|
||||
"validation": {
|
||||
"due_at_error_message": "",
|
||||
"remind_at_error_message": ""
|
||||
}
|
||||
},
|
||||
"tech": {
|
||||
"fields": {
|
||||
"employeeid": "",
|
||||
@@ -3208,17 +3215,13 @@
|
||||
"accounting-payables": "",
|
||||
"accounting-payments": "",
|
||||
"accounting-receivables": "",
|
||||
"all_tasks": "",
|
||||
"app": "",
|
||||
"tasks": "",
|
||||
"all_tasks": "",
|
||||
"my_tasks": "",
|
||||
"bc": {
|
||||
"tasks": "",
|
||||
"all_tasks": "",
|
||||
"my_tasks": "",
|
||||
"accounting-payables": "",
|
||||
"accounting-payments": "",
|
||||
"accounting-receivables": "",
|
||||
"all_tasks": "",
|
||||
"availablejobs": "",
|
||||
"bills-list": "",
|
||||
"contracts": "",
|
||||
@@ -3242,6 +3245,7 @@
|
||||
"jobs-intake": "",
|
||||
"jobs-new": "",
|
||||
"jobs-ready": "",
|
||||
"my_tasks": "",
|
||||
"owner-detail": "",
|
||||
"owners": "",
|
||||
"parts-queue": "",
|
||||
@@ -3256,6 +3260,7 @@
|
||||
"shop-csi": "",
|
||||
"shop-templates": "",
|
||||
"shop-vendors": "",
|
||||
"tasks": "",
|
||||
"temporarydocs": "",
|
||||
"timetickets": "",
|
||||
"ttapprovals": "",
|
||||
@@ -3286,6 +3291,7 @@
|
||||
"jobsdetail": "Travail {{ro_number}} | {{app}}",
|
||||
"jobsdocuments": "Documents de travail {{ro_number}} | {{app}}",
|
||||
"manageroot": "Accueil | {{app}}",
|
||||
"my_tasks": "",
|
||||
"owners": "Tous les propriétaires | {{app}}",
|
||||
"owners-detail": "",
|
||||
"parts-queue": "",
|
||||
@@ -3305,6 +3311,7 @@
|
||||
"shop-csi": "",
|
||||
"shop-templates": "",
|
||||
"shop_vendors": "Vendeurs | {{app}}",
|
||||
"tasks": "",
|
||||
"techconsole": "{{app}}",
|
||||
"techjobclock": "{{app}}",
|
||||
"techjoblookup": "{{app}}",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import axios from "axios";
|
||||
import { auth } from "../firebase/firebase.utils";
|
||||
import InstanceRenderManager from "./instanceRenderMgr";
|
||||
|
||||
axios.defaults.baseURL =
|
||||
import.meta.env.VITE_APP_AXIOS_BASE_API_URL ||
|
||||
@@ -12,6 +13,15 @@ export const axiosAuthInterceptorId = axios.interceptors.request.use(
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
}
|
||||
InstanceRenderManager({
|
||||
executeFunction: true,
|
||||
args: [],
|
||||
promanager: () => {
|
||||
if (!config.url.startsWith("http://localhost:1337")) {
|
||||
config.headers["Convenient-Company"] = "promanager";
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return config;
|
||||
|
||||
@@ -10,6 +10,7 @@ import client from "../utils/GraphQLClient";
|
||||
import cleanAxios from "./CleanAxios";
|
||||
import { TemplateList } from "./TemplateConstants";
|
||||
import { generateTemplate } from "./graphQLmodifier";
|
||||
import InstanceRenderManager from "./instanceRenderMgr";
|
||||
const server = import.meta.env.VITE_APP_REPORTS_SERVER_URL;
|
||||
|
||||
jsreport.serverUrl = server;
|
||||
@@ -71,8 +72,8 @@ export default async function RenderTemplate(
|
||||
...contextData,
|
||||
...templateObject.variables,
|
||||
...templateObject.context,
|
||||
headerpath: `/${bodyshop.imexshopid}/header.html`,
|
||||
footerpath: `/${bodyshop.imexshopid}/footer.html`,
|
||||
headerpath: `/${InstanceRenderManager({ imex: bodyshop.imexshopid, rome: bodyshop.imexshopid, promanager: "GENERIC" })}/header.html`,
|
||||
footerpath: `/${InstanceRenderManager({ imex: bodyshop.imexshopid, rome: bodyshop.imexshopid, promanager: "GENERIC" })}/footer.html`,
|
||||
bodyshop: bodyshop,
|
||||
filters: templateObject?.filters,
|
||||
sorters: templateObject?.sorters,
|
||||
|
||||
@@ -920,6 +920,7 @@
|
||||
- cdk_dealerid
|
||||
- city
|
||||
- claimscorpid
|
||||
- convenient_company
|
||||
- country
|
||||
- created_at
|
||||
- default_adjustment_rate
|
||||
|
||||
@@ -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 "convenient_company" text
|
||||
-- null;
|
||||
@@ -0,0 +1,2 @@
|
||||
alter table "public"."bodyshops" add column "convenient_company" text
|
||||
null;
|
||||
@@ -236,10 +236,36 @@ exports.default = async function (socket, jobid) {
|
||||
const mapaAccountName = selectedDmsAllocationConfig.costs.MAPA;
|
||||
const mapaAccount = bodyshop.md_responsibility_centers.costs.find((c) => c.name === mapaAccountName);
|
||||
if (mapaAccount) {
|
||||
if (!costCenterHash[mapaAccountName]) costCenterHash[mapaAccountName] = Dinero();
|
||||
costCenterHash[mapaAccountName] = costCenterHash[mapaAccountName].add(
|
||||
Dinero(job.job_totals.rates.mapa.total).percentage(bodyshop?.cdk_configuration?.sendmaterialscosting)
|
||||
if (!costCenterHash[mapaAccountName])
|
||||
costCenterHash[mapaAccountName] = Dinero();
|
||||
if (job.bodyshop.use_paint_scale_data === true) {
|
||||
if (job.mixdata.length > 0) {
|
||||
costCenterHash[mapaAccountName] = costCenterHash[
|
||||
mapaAccountName
|
||||
].add(
|
||||
Dinero({
|
||||
amount: Math.round(
|
||||
((job.mixdata[0] && job.mixdata[0].totalliquidcost) || 0) *
|
||||
100
|
||||
),
|
||||
})
|
||||
);
|
||||
} else {
|
||||
costCenterHash[mapaAccountName] = costCenterHash[
|
||||
mapaAccountName
|
||||
].add(
|
||||
Dinero(job.job_totals.rates.mapa.total).percentage(
|
||||
bodyshop?.cdk_configuration?.sendmaterialscosting
|
||||
)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
costCenterHash[mapaAccountName] = costCenterHash[mapaAccountName].add(
|
||||
Dinero(job.job_totals.rates.mapa.total).percentage(
|
||||
bodyshop?.cdk_configuration?.sendmaterialscosting
|
||||
)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
//console.log("NO MAPA ACCOUNT FOUND!!");
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ const ses = new aws.SES({
|
||||
|
||||
const transporter = nodemailer.createTransport({
|
||||
SES: { ses, aws },
|
||||
sendingRate: 40 // 40 emails per second.
|
||||
sendingRate: InstanceManager({ imex: 40, rome: 10 })
|
||||
});
|
||||
|
||||
// Initialize the Tasks Email Queue
|
||||
@@ -41,6 +41,7 @@ const tasksEmailQueueCleanup = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
if (process.env.NODE_ENV !== "development") {
|
||||
// Handling SIGINT (e.g., Ctrl+C)
|
||||
process.on("SIGINT", async () => {
|
||||
await tasksEmailQueueCleanup();
|
||||
@@ -61,18 +62,7 @@ process.on("unhandledRejection", async (reason, promise) => {
|
||||
await tasksEmailQueueCleanup();
|
||||
process.exit(1); // Exit with an 'error' code
|
||||
});
|
||||
|
||||
const fromEmails = InstanceManager({
|
||||
imex: "ImEX Online <noreply@imex.online>",
|
||||
rome: "Rome Online <noreply@romeonline.io>",
|
||||
promanager: "ProManager <noreply@promanager.web-est.com>"
|
||||
});
|
||||
|
||||
const endPoints = InstanceManager({
|
||||
imex: process.env?.NODE_ENV === "test" ? "https://test.imex.online" : "https://imex.online",
|
||||
rome: process.env?.NODE_ENV === "test" ? "https//test.romeonline.io" : "https://romeonline.io",
|
||||
promanager: process.env?.NODE_ENV === "test" ? "https//test.promanager.web-est.com" : "https://promanager.web-est.com"
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the date for the email.
|
||||
@@ -105,6 +95,17 @@ const formatPriority = (priority) => {
|
||||
* @returns {{header, body: string, subHeader: string}}
|
||||
*/
|
||||
const generateTemplateArgs = (title, priority, description, dueDate, bodyshop, job, taskId) => {
|
||||
const endPoints = InstanceManager({
|
||||
imex: process.env?.NODE_ENV === "test" ? "https://test.imex.online" : "https://imex.online",
|
||||
rome:
|
||||
bodyshop.convenient_company === "promanager"
|
||||
? process.env?.NODE_ENV === "test"
|
||||
? "https//test.promanager.web-est.com"
|
||||
: "https://promanager.web-est.com"
|
||||
: process.env?.NODE_ENV === "test"
|
||||
? "https//test.romeonline.io"
|
||||
: "https://romeonline.io"
|
||||
});
|
||||
return {
|
||||
header: title,
|
||||
subHeader: `Body Shop: ${bodyshop.shopname} | Priority: ${formatPriority(priority)} ${formatDate(dueDate)}`,
|
||||
@@ -121,12 +122,15 @@ const generateTemplateArgs = (title, priority, description, dueDate, bodyshop, j
|
||||
* @param taskIds
|
||||
* @param successCallback
|
||||
*/
|
||||
const sendMail = (type, to, subject, html, taskIds, successCallback) => {
|
||||
// Push next messages to Nodemailer
|
||||
//transporter.once("idle", () => {
|
||||
// Note: This is commented out because despite being in the documentation, it does not work
|
||||
// and stackoverflow suggests it is not needed
|
||||
// if (transporter.isIdle()) {
|
||||
const sendMail = (type, to, subject, html, taskIds, successCallback, requestInstance) => {
|
||||
const fromEmails = InstanceManager({
|
||||
imex: "ImEX Online <noreply@imex.online>",
|
||||
rome:
|
||||
requestInstance === "promanager"
|
||||
? "ProManager <noreply@promanager.web-est.com>"
|
||||
: "Rome Online <noreply@romeonline.io>"
|
||||
});
|
||||
|
||||
transporter.sendMail(
|
||||
{
|
||||
from: fromEmails,
|
||||
@@ -184,7 +188,10 @@ const taskAssignedEmail = async (req, res) => {
|
||||
tasks_by_pk.job,
|
||||
newTask.id
|
||||
)
|
||||
)
|
||||
),
|
||||
null,
|
||||
null,
|
||||
tasks_by_pk.bodyshop.convenient_company
|
||||
);
|
||||
|
||||
// We return success regardless because we don't want to block the event trigger.
|
||||
@@ -233,6 +240,14 @@ const tasksRemindEmail = async (req, res) => {
|
||||
|
||||
// Iterate over all recipients and send the email.
|
||||
recipientCounts.forEach((recipient) => {
|
||||
const fromEmails = InstanceManager({
|
||||
imex: "ImEX Online <noreply@imex.online>",
|
||||
rome:
|
||||
onlyTask.bodyshop.convenient_company === "promanager"
|
||||
? "ProManager <noreply@promanager.web-est.com>"
|
||||
: "Rome Online <noreply@romeonline.io>"
|
||||
});
|
||||
|
||||
const emailData = {
|
||||
from: fromEmails,
|
||||
to: recipient.email
|
||||
@@ -261,6 +276,18 @@ const tasksRemindEmail = async (req, res) => {
|
||||
}
|
||||
// There are multiple emails to send to this author.
|
||||
else {
|
||||
const endPoints = InstanceManager({
|
||||
imex: process.env?.NODE_ENV === "test" ? "https://test.imex.online" : "https://imex.online",
|
||||
rome:
|
||||
allTasks[0].bodyshop.convenient_company === "promanager"
|
||||
? process.env?.NODE_ENV === "test"
|
||||
? "https//test.promanager.web-est.com"
|
||||
: "https://promanager.web-est.com"
|
||||
: process.env?.NODE_ENV === "test"
|
||||
? "https//test.romeonline.io"
|
||||
: "https://romeonline.io"
|
||||
});
|
||||
|
||||
const allTasks = groupedTasks[recipient.email];
|
||||
emailData.subject = `New Tasks Reminder - ${allTasks.length} Tasks require your attention`;
|
||||
emailData.html = generateEmailTemplate({
|
||||
@@ -278,11 +305,19 @@ const tasksRemindEmail = async (req, res) => {
|
||||
|
||||
if (emailData?.subject && emailData?.html) {
|
||||
// Send Email
|
||||
sendMail("remind", emailData.to, emailData.subject, emailData.html, taskIds, (taskIds) => {
|
||||
sendMail(
|
||||
"remind",
|
||||
emailData.to,
|
||||
emailData.subject,
|
||||
emailData.html,
|
||||
taskIds,
|
||||
(taskIds) => {
|
||||
for (const taskId of taskIds) {
|
||||
tasksEmailQueue.push(taskId);
|
||||
}
|
||||
});
|
||||
},
|
||||
allTasks[0].bodyshop.convenient_company
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1790,6 +1790,7 @@ exports.GET_CDK_ALLOCATIONS = `query QUERY_JOB_CLOSE_DETAILS($id: uuid!) {
|
||||
md_responsibility_centers
|
||||
cdk_configuration
|
||||
pbs_configuration
|
||||
use_paint_scale_data
|
||||
}
|
||||
ro_number
|
||||
dms_allocation
|
||||
@@ -1897,6 +1898,10 @@ exports.GET_CDK_ALLOCATIONS = `query QUERY_JOB_CLOSE_DETAILS($id: uuid!) {
|
||||
line_ref
|
||||
unq_seq
|
||||
}
|
||||
mixdata(limit: 1, order_by: {updated_at: desc}) {
|
||||
jobid
|
||||
totalliquidcost
|
||||
}
|
||||
}
|
||||
}`;
|
||||
|
||||
@@ -2431,6 +2436,7 @@ exports.QUERY_REMIND_TASKS = `
|
||||
jobid
|
||||
bodyshop {
|
||||
shopname
|
||||
convenient_company
|
||||
}
|
||||
bodyshopid
|
||||
}
|
||||
@@ -2453,6 +2459,7 @@ query QUERY_TASK_BY_ID($id: uuid!) {
|
||||
}
|
||||
bodyshop{
|
||||
shopname
|
||||
convenient_company
|
||||
}
|
||||
job{
|
||||
ro_number
|
||||
@@ -2467,3 +2474,12 @@ query QUERY_TASK_BY_ID($id: uuid!) {
|
||||
}
|
||||
|
||||
`;
|
||||
|
||||
|
||||
exports.GET_JOBS_BY_PKS = `query GET_JOBS_BY_PKS($ids: [uuid!]!) {
|
||||
jobs(where: {id: {_in: $ids}}) {
|
||||
id
|
||||
shopid
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -16,7 +16,7 @@ const domain = process.env.NODE_ENV ? "secure" : "test";
|
||||
const { SecretsManagerClient, GetSecretValueCommand } = require("@aws-sdk/client-secrets-manager");
|
||||
|
||||
const client = new SecretsManagerClient({
|
||||
region: "ca-central-1"
|
||||
region: "ca-central-1" //TODO-AIO: instance manager required when merged to master-AIO
|
||||
});
|
||||
|
||||
const gqlClient = require("../graphql-client/graphql-client").client;
|
||||
@@ -145,24 +145,29 @@ exports.generate_payment_url = async (req, res) => {
|
||||
};
|
||||
|
||||
exports.postback = async (req, res) => {
|
||||
logger.log("intellipay-postback", "ERROR", req.user?.email, null, req.body);
|
||||
logger.log("intellipay-postback", "DEBUG", req.user?.email, null, req.body);
|
||||
const { body: values } = req;
|
||||
|
||||
if (!values.invoice) {
|
||||
const comment = Buffer.from(values?.comment, "base64").toString();
|
||||
|
||||
if ((!values.invoice || values.invoice === "") && !comment) {
|
||||
//invoice is specified through the pay link. Comment by IO.
|
||||
logger.log("intellipay-postback-ignored", "DEBUG", req.user?.email, null, req.body);
|
||||
res.sendStatus(200);
|
||||
return;
|
||||
}
|
||||
// TODO query job by account name
|
||||
|
||||
try {
|
||||
if (values.invoice) {
|
||||
//This is a link email that's been sent out.
|
||||
const job = await gqlClient.request(queries.GET_JOB_BY_PK, {
|
||||
id: values.invoice
|
||||
});
|
||||
// TODO add mutation to database
|
||||
|
||||
try {
|
||||
const paymentResult = await gqlClient.request(queries.INSERT_NEW_PAYMENT, {
|
||||
paymentInput: {
|
||||
amount: values.total,
|
||||
transactionid: `C00 ${values.authcode}`,
|
||||
transactionid: values.authcode,
|
||||
payer: "Customer",
|
||||
type: values.cardtype,
|
||||
jobid: values.invoice,
|
||||
@@ -170,7 +175,7 @@ exports.postback = async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
await gqlClient.request(queries.INSERT_PAYMENT_RESPONSE, {
|
||||
const responseResults = await gqlClient.request(queries.INSERT_PAYMENT_RESPONSE, {
|
||||
paymentResponse: {
|
||||
amount: values.total,
|
||||
bodyshopid: job.jobs_by_pk.shopid,
|
||||
@@ -183,7 +188,46 @@ exports.postback = async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
res.send({ message: "Postback Successful" });
|
||||
logger.log("intellipay-postback-link-success", "DEBUG", req.user?.email, null, {
|
||||
iprequest: values,
|
||||
responseResults,
|
||||
paymentResult
|
||||
});
|
||||
res.sendStatus(200);
|
||||
} else if (comment) {
|
||||
//This has been triggered by IO and may have multiple jobs.
|
||||
const partialPayments = JSON.parse(comment);
|
||||
const jobs = await gqlClient.request(queries.GET_JOBS_BY_PKS, {
|
||||
ids: partialPayments.map((p) => p.jobid)
|
||||
});
|
||||
|
||||
const paymentResult = await gqlClient.request(queries.INSERT_NEW_PAYMENT, {
|
||||
paymentInput: partialPayments.map((p) => ({
|
||||
amount: p.amount,
|
||||
transactionid: values.authcode,
|
||||
payer: "Customer",
|
||||
type: values.cardtype,
|
||||
jobid: p.jobid,
|
||||
date: moment(Date.now()),
|
||||
payment_responses: {
|
||||
data: {
|
||||
amount: values.total,
|
||||
bodyshopid: jobs.jobs[0].shopid,
|
||||
jobid: p.jobid,
|
||||
declinereason: "Approved",
|
||||
ext_paymentid: values.paymentid,
|
||||
successful: true,
|
||||
response: values
|
||||
}
|
||||
}
|
||||
}))
|
||||
});
|
||||
logger.log("intellipay-postback-app-success", "DEBUG", req.user?.email, null, {
|
||||
iprequest: values,
|
||||
paymentResult
|
||||
});
|
||||
res.sendStatus(200);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.log("intellipay-postback-error", "ERROR", req.user?.email, null, {
|
||||
error: JSON.stringify(error),
|
||||
|
||||
Reference in New Issue
Block a user