Compare commits
2 Commits
feature/IO
...
feature/IO
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9aa1279144 | ||
|
|
fd9a51209f |
@@ -433,7 +433,7 @@ workflows:
|
||||
branches:
|
||||
only: master-AIO
|
||||
- rome-hasura-migrate:
|
||||
secret: ${HASURA_ROME_PROD_SECRET}
|
||||
secret: ${HASURA_PROD_SECRET}
|
||||
filters:
|
||||
branches:
|
||||
only: master-AIO
|
||||
|
||||
@@ -18,6 +18,7 @@ import { checkUserSession } from "../redux/user/user.actions";
|
||||
import { selectBodyshop, selectCurrentEula, selectCurrentUser } from "../redux/user/user.selectors";
|
||||
import PrivateRoute from "../components/PrivateRoute";
|
||||
import "./App.styles.scss";
|
||||
import handleBeta from "../utils/handleBeta";
|
||||
import Eula from "../components/eula/eula.component";
|
||||
import InstanceRenderMgr from "../utils/instanceRenderMgr";
|
||||
import ProductFruitsWrapper from "./ProductFruitsWrapper.jsx";
|
||||
@@ -107,6 +108,8 @@ export function App({ bodyshop, checkUserSession, currentUser, online, setOnline
|
||||
return <LoadingSpinner message={t("general.labels.loggingin")} />;
|
||||
}
|
||||
|
||||
handleBeta();
|
||||
|
||||
if (!online) {
|
||||
return (
|
||||
<Result
|
||||
|
||||
@@ -13,6 +13,7 @@ import Icon, {
|
||||
FileFilled,
|
||||
HomeFilled,
|
||||
ImportOutlined,
|
||||
InfoCircleOutlined,
|
||||
LineChartOutlined,
|
||||
PaperClipOutlined,
|
||||
PhoneOutlined,
|
||||
@@ -26,8 +27,8 @@ import Icon, {
|
||||
UserOutlined
|
||||
} from "@ant-design/icons";
|
||||
import { useSplitTreatments } from "@splitsoftware/splitio-react";
|
||||
import { Layout, Menu } from "antd";
|
||||
import React from "react";
|
||||
import { Layout, Menu, Switch, Tooltip } from "antd";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { BsKanban } from "react-icons/bs";
|
||||
import { FaCalendarAlt, FaCarCrash, FaCreditCard, FaFileInvoiceDollar, FaTasks } from "react-icons/fa";
|
||||
@@ -42,6 +43,7 @@ import { selectRecentItems, selectSelectedHeader } from "../../redux/application
|
||||
import { setModalContext } from "../../redux/modals/modals.actions";
|
||||
import { signOutStart } from "../../redux/user/user.actions";
|
||||
import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors";
|
||||
import { checkBeta, handleBeta, setBeta } from "../../utils/handleBeta";
|
||||
import InstanceRenderManager from "../../utils/instanceRenderMgr";
|
||||
import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
|
||||
|
||||
@@ -113,21 +115,19 @@ function Header({
|
||||
names: ["ImEXPay", "DmsAp", "Simple_Inventory"],
|
||||
splitKey: bodyshop && bodyshop.imexshopid
|
||||
});
|
||||
|
||||
const [betaSwitch, setBetaSwitch] = useState(false);
|
||||
const { t } = useTranslation();
|
||||
|
||||
const deleteBetaCookie = () => {
|
||||
const cookieExists = document.cookie.split("; ").some((row) => row.startsWith(`betaSwitchImex=`));
|
||||
if (cookieExists) {
|
||||
const domain = window.location.hostname.split(".").slice(-2).join(".");
|
||||
document.cookie = `betaSwitchImex=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=.${domain}`;
|
||||
console.log(`betaSwitchImex cookie deleted`);
|
||||
} else {
|
||||
console.log(`betaSwitchImex cookie does not exist`);
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
const isBeta = checkBeta();
|
||||
setBetaSwitch(isBeta);
|
||||
}, []);
|
||||
|
||||
deleteBetaCookie();
|
||||
const betaSwitchChange = (checked) => {
|
||||
setBeta(checked);
|
||||
setBetaSwitch(checked);
|
||||
handleBeta();
|
||||
};
|
||||
|
||||
const accountingChildren = [];
|
||||
|
||||
@@ -695,6 +695,31 @@ function Header({
|
||||
}
|
||||
];
|
||||
|
||||
InstanceRenderManager({
|
||||
executeFunction: true,
|
||||
args: [],
|
||||
imex: () => {
|
||||
menuItems.push({
|
||||
key: "beta-switch",
|
||||
id: "header-beta-switch",
|
||||
style: { marginLeft: "auto" },
|
||||
label: (
|
||||
<Tooltip
|
||||
title={`A more modern ${InstanceRenderManager({
|
||||
imex: t("titles.imexonline"),
|
||||
rome: t("titles.romeonline"),
|
||||
promanager: t("titles.promanager")
|
||||
})} is ready for you to try! You can switch back at any time.`}
|
||||
>
|
||||
<InfoCircleOutlined />
|
||||
<span style={{ marginRight: 8 }}>Try the new app</span>
|
||||
<Switch checked={betaSwitch} onChange={betaSwitchChange} />
|
||||
</Tooltip>
|
||||
)
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<Layout.Header>
|
||||
<Menu
|
||||
|
||||
@@ -34,28 +34,34 @@ export function ReportCenterModalComponent({ reportCenterModal, bodyshop }) {
|
||||
const [form] = Form.useForm();
|
||||
const [search, setSearch] = useState("");
|
||||
const {
|
||||
treatments: { Enhanced_Payroll }
|
||||
treatments: { Enhanced_Payroll, ADPPayroll }
|
||||
} = useSplitTreatments({
|
||||
attributes: {},
|
||||
names: ["Enhanced_Payroll"],
|
||||
names: ["Enhanced_Payroll", "ADPPayroll"],
|
||||
splitKey: bodyshop.imexshopid
|
||||
});
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
const { t } = useTranslation();
|
||||
const Templates = TemplateList("report_center");
|
||||
const ReportsList =
|
||||
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 ReportsList = Object.keys(Templates)
|
||||
.map((key) => Templates[key])
|
||||
.filter((temp) => {
|
||||
const enhancedPayrollOn = Enhanced_Payroll.treatment === "on";
|
||||
const adpPayrollOn = ADPPayroll.treatment === "on";
|
||||
|
||||
if (enhancedPayrollOn && adpPayrollOn) {
|
||||
return temp.enhanced_payroll !== false || temp.adp_payroll !== false;
|
||||
}
|
||||
if (enhancedPayrollOn) {
|
||||
return temp.enhanced_payroll !== false && temp.adp_payroll !== true;
|
||||
}
|
||||
if (adpPayrollOn) {
|
||||
return temp.adp_payroll !== false && temp.enhanced_payroll !== true;
|
||||
}
|
||||
|
||||
return temp.enhanced_payroll !== true && temp.adp_payroll !== true;
|
||||
});
|
||||
|
||||
const { open } = reportCenterModal;
|
||||
|
||||
@@ -104,7 +110,7 @@ export function ReportCenterModalComponent({ reportCenterModal, bodyshop }) {
|
||||
to: values.to,
|
||||
subject: Templates[values.key]?.subject
|
||||
},
|
||||
values.sendbyexcel === "excel" ? "x" : values.sendby === "email" ? "e" : "p",
|
||||
values.sendbytext === "text" ? values.sendbytext : values.sendbyexcel === "excel" ? "x" : values.sendby === "email" ? "e" : "p",
|
||||
id
|
||||
);
|
||||
setLoading(false);
|
||||
@@ -291,7 +297,15 @@ export function ReportCenterModalComponent({ reportCenterModal, bodyshop }) {
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
);
|
||||
if (reporttype !== "excel")
|
||||
if (reporttype === "text")
|
||||
return (
|
||||
<Form.Item label={t("general.labels.sendby")} name="sendbytext" initialValue="text">
|
||||
<Radio.Group>
|
||||
<Radio value="text">{t("general.labels.text")}</Radio>
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
);
|
||||
if (reporttype !== "excel" || reporttype !== "text")
|
||||
return (
|
||||
<Form.Item label={t("general.labels.sendby")} name="sendby" initialValue="print">
|
||||
<Radio.Group>
|
||||
|
||||
@@ -7,13 +7,13 @@ import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import DatePickerRanges from "../../utils/DatePickerRanges";
|
||||
import InstanceRenderManager from "../../utils/instanceRenderMgr";
|
||||
import FeatureWrapper, { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
|
||||
import CurrencyInput from "../form-items-formatted/currency-form-item.component";
|
||||
import FormItemEmail from "../form-items-formatted/email-form-item.component";
|
||||
import PhoneFormItem, { PhoneItemFormatterValidation } from "../form-items-formatted/phone-form-item.component";
|
||||
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
|
||||
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
||||
import InstanceRenderManager from "../../utils/instanceRenderMgr";
|
||||
import FeatureWrapper, { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
|
||||
// TODO: Client Update, this might break
|
||||
const timeZonesList = Intl.supportedValuesOf("timeZone");
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
@@ -28,10 +28,10 @@ export function ShopInfoGeneral({ form, bodyshop }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const {
|
||||
treatments: { ClosingPeriod }
|
||||
treatments: { ClosingPeriod, ADPPayroll }
|
||||
} = useSplitTreatments({
|
||||
attributes: {},
|
||||
names: ["ClosingPeriod"],
|
||||
names: ["ClosingPeriod", "ADPPayroll"],
|
||||
splitKey: bodyshop && bodyshop.imexshopid
|
||||
});
|
||||
|
||||
@@ -98,7 +98,6 @@ export function ShopInfoGeneral({ form, bodyshop }) {
|
||||
<Form.Item label={t("bodyshop.fields.email")} name="email">
|
||||
<Input />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
label={t("bodyshop.fields.phone")}
|
||||
name="phone"
|
||||
@@ -356,14 +355,22 @@ export function ShopInfoGeneral({ form, bodyshop }) {
|
||||
<Select mode="tags" />
|
||||
</Form.Item>
|
||||
{ClosingPeriod.treatment === "on" && (
|
||||
<>
|
||||
<Form.Item
|
||||
name={["accountingconfig", "ClosingPeriod"]}
|
||||
label={t("bodyshop.fields.closingperiod")} //{t("reportcenter.labels.dates")}
|
||||
>
|
||||
<DatePicker.RangePicker format="MM/DD/YYYY" presets={DatePickerRanges} />
|
||||
</Form.Item>
|
||||
</>
|
||||
<Form.Item
|
||||
name={["accountingconfig", "ClosingPeriod"]}
|
||||
label={t("bodyshop.fields.closingperiod")} //{t("reportcenter.labels.dates")}
|
||||
>
|
||||
<DatePicker.RangePicker format="MM/DD/YYYY" presets={DatePickerRanges} />
|
||||
</Form.Item>
|
||||
)}
|
||||
{ADPPayroll.treatment === "on" && (
|
||||
<Form.Item name={["accountingconfig", "companyCode"]} label={t("bodyshop.fields.companycode")}>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
)}
|
||||
{ADPPayroll.treatment === "on" && (
|
||||
<Form.Item name={["accountingconfig", "batchID"]} label={t("bodyshop.fields.batchid")}>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
)}
|
||||
</LayoutFormRow>
|
||||
</FeatureWrapper>
|
||||
|
||||
@@ -5,7 +5,7 @@ import PhoneNumberFormatter from "../../utils/PhoneFormatter";
|
||||
|
||||
const { Option } = Select;
|
||||
|
||||
// To be used as a form element only.
|
||||
//To be used as a form element only.
|
||||
|
||||
const VendorSearchSelect = ({ value, onChange, options, onSelect, disabled, preferredMake, showPhone }, ref) => {
|
||||
const [option, setOption] = useState(value);
|
||||
@@ -33,25 +33,9 @@ const VendorSearchSelect = ({ value, onChange, options, onSelect, disabled, pref
|
||||
if (!value || !options) return label;
|
||||
const discount = options?.find((o) => o.id === value)?.discount;
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
flexWrap: "nowrap",
|
||||
width: "100%"
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
flex: 1,
|
||||
minWidth: 0,
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
whiteSpace: "nowrap"
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
</div>
|
||||
<div className="imex-flex-row" style={{ width: "100%" }}>
|
||||
<div style={{ flex: 1 }}>{label}</div>
|
||||
|
||||
{discount && discount !== 0 ? <Tag color="green">{`${discount * 100}%`}</Tag> : null}
|
||||
</div>
|
||||
);
|
||||
@@ -61,67 +45,36 @@ const VendorSearchSelect = ({ value, onChange, options, onSelect, disabled, pref
|
||||
optionFilterProp="name"
|
||||
onSelect={onSelect}
|
||||
disabled={disabled || false}
|
||||
optionLabelProp="name"
|
||||
optionLabelProp={"name"}
|
||||
>
|
||||
{favorites &&
|
||||
favorites.map((o) => (
|
||||
<Option key={`favorite-${o.id}`} value={o.id} name={o.name} discount={o.discount}>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
flexWrap: "nowrap",
|
||||
width: "100%"
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
flex: 1,
|
||||
minWidth: 0,
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
whiteSpace: "nowrap"
|
||||
}}
|
||||
>
|
||||
{o.name}
|
||||
{favorites
|
||||
? favorites.map((o) => (
|
||||
<Option key={`favorite-${o.id}`} value={o.id} name={o.name} discount={o.discount}>
|
||||
<div className="imex-flex-row">
|
||||
<div style={{ flex: 1 }}>{o.name}</div>
|
||||
<Space style={{ marginLeft: "1rem" }}>
|
||||
<HeartOutlined style={{ color: "red" }} />
|
||||
{o.phone && showPhone && <PhoneNumberFormatter>{o.phone}</PhoneNumberFormatter>}
|
||||
{o.discount && o.discount !== 0 ? <Tag color="green">{`${o.discount * 100}%`}</Tag> : null}
|
||||
</Space>
|
||||
</div>
|
||||
<Space style={{ marginLeft: "1rem" }}>
|
||||
<HeartOutlined style={{ color: "red" }} />
|
||||
{o.phone && showPhone && <PhoneNumberFormatter>{o.phone}</PhoneNumberFormatter>}
|
||||
{o.discount && o.discount !== 0 ? <Tag color="green">{`${o.discount * 100}%`}</Tag> : null}
|
||||
</Space>
|
||||
</div>
|
||||
</Option>
|
||||
))}
|
||||
{options &&
|
||||
options.map((o) => (
|
||||
<Option key={o.id} value={o.id} name={o.name} discount={o.discount}>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
flexWrap: "nowrap",
|
||||
width: "100%"
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
flex: 1,
|
||||
minWidth: 0,
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
whiteSpace: "nowrap"
|
||||
}}
|
||||
>
|
||||
{o.name}
|
||||
</Option>
|
||||
))
|
||||
: null}
|
||||
{options
|
||||
? options.map((o) => (
|
||||
<Option key={o.id} value={o.id} name={o.name} discount={o.discount}>
|
||||
<div className="imex-flex-row" style={{ width: "100%" }}>
|
||||
<div style={{ flex: 1 }}>{o.name}</div>
|
||||
|
||||
<Space style={{ marginLeft: "1rem" }}>
|
||||
{o.phone && showPhone && <PhoneNumberFormatter>{o.phone}</PhoneNumberFormatter>}
|
||||
{o.discount && o.discount !== 0 ? <Tag color="green">{`${o.discount * 100}%`}</Tag> : null}
|
||||
</Space>
|
||||
</div>
|
||||
<Space style={{ marginLeft: "1rem" }}>
|
||||
{o.phone && showPhone && <PhoneNumberFormatter>{o.phone}</PhoneNumberFormatter>}
|
||||
{o.discount && o.discount !== 0 ? <Tag color="green">{`${o.discount * 100}%`}</Tag> : null}
|
||||
</Space>
|
||||
</div>
|
||||
</Option>
|
||||
))}
|
||||
</Option>
|
||||
))
|
||||
: null}
|
||||
</Select>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@ import { getFirestore } from "firebase/firestore";
|
||||
import { getMessaging, getToken, onMessage } from "firebase/messaging";
|
||||
import { store } from "../redux/store";
|
||||
import axios from "axios";
|
||||
import { checkBeta } from "../utils/handleBeta";
|
||||
|
||||
const config = JSON.parse(import.meta.env.VITE_APP_FIREBASE_CONFIG);
|
||||
initializeApp(config);
|
||||
@@ -87,7 +88,7 @@ export const logImEXEvent = (eventName, additionalParams, stateProp = null) => {
|
||||
operationName: eventName,
|
||||
variables: additionalParams,
|
||||
dbevent: false,
|
||||
env: "master"
|
||||
env: checkBeta() ? "beta" : "master"
|
||||
});
|
||||
// console.log(
|
||||
// "%c[Analytics]",
|
||||
|
||||
@@ -285,12 +285,14 @@
|
||||
},
|
||||
"appt_length": "Default Appointment Length",
|
||||
"attach_pdf_to_email": "Attach PDF copy to sent emails?",
|
||||
"batchid": "ADP Batch ID",
|
||||
"bill_allow_post_to_closed": "Allow Bills to be posted to Closed Jobs",
|
||||
"bill_federal_tax_rate": "Bills - Federal Tax Rate %",
|
||||
"bill_local_tax_rate": "Bill - Local Tax Rate %",
|
||||
"bill_state_tax_rate": "Bill - Provincial/State Tax Rate %",
|
||||
"city": "City",
|
||||
"closingperiod": "Closing Period",
|
||||
"companycode": "ADP Company Code",
|
||||
"country": "Country",
|
||||
"dailybodytarget": "Scoreboard - Daily Body Target",
|
||||
"dailypainttarget": "Scoreboard - Daily Paint Target",
|
||||
@@ -2927,6 +2929,8 @@
|
||||
"vendor": "Vendor"
|
||||
},
|
||||
"templates": {
|
||||
"adp_payroll_flat": "ADP Payroll - Flat Rate",
|
||||
"adp_payroll_straight": "ADP Payroll - Straight Time",
|
||||
"anticipated_revenue": "Anticipated Revenue",
|
||||
"ar_aging": "AR Aging",
|
||||
"attendance_detail": "Attendance (All Employees)",
|
||||
|
||||
@@ -285,12 +285,14 @@
|
||||
},
|
||||
"appt_length": "",
|
||||
"attach_pdf_to_email": "",
|
||||
"batchid": "",
|
||||
"bill_allow_post_to_closed": "",
|
||||
"bill_federal_tax_rate": "",
|
||||
"bill_local_tax_rate": "",
|
||||
"bill_state_tax_rate": "",
|
||||
"city": "",
|
||||
"closingperiod": "",
|
||||
"companycode": "",
|
||||
"country": "",
|
||||
"dailybodytarget": "",
|
||||
"dailypainttarget": "",
|
||||
@@ -2927,6 +2929,8 @@
|
||||
"vendor": ""
|
||||
},
|
||||
"templates": {
|
||||
"adp_payroll_flat": "",
|
||||
"adp_payroll_straight": "",
|
||||
"anticipated_revenue": "",
|
||||
"ar_aging": "",
|
||||
"attendance_detail": "",
|
||||
|
||||
@@ -285,12 +285,14 @@
|
||||
},
|
||||
"appt_length": "",
|
||||
"attach_pdf_to_email": "",
|
||||
"batchid": "",
|
||||
"bill_allow_post_to_closed": "",
|
||||
"bill_federal_tax_rate": "",
|
||||
"bill_local_tax_rate": "",
|
||||
"bill_state_tax_rate": "",
|
||||
"city": "",
|
||||
"closingperiod": "",
|
||||
"companycode": "",
|
||||
"country": "",
|
||||
"dailybodytarget": "",
|
||||
"dailypainttarget": "",
|
||||
@@ -2927,6 +2929,8 @@
|
||||
"vendor": ""
|
||||
},
|
||||
"templates": {
|
||||
"adp_payroll_flat": "",
|
||||
"adp_payroll_straight": "",
|
||||
"anticipated_revenue": "",
|
||||
"ar_aging": "",
|
||||
"attendance_detail": "",
|
||||
|
||||
@@ -2158,6 +2158,32 @@ export const TemplateList = (type, context) => {
|
||||
field: i18n.t("tasks.fields.created_at")
|
||||
},
|
||||
group: "jobs"
|
||||
},
|
||||
adp_payroll_flat: {
|
||||
title: i18n.t("reportcenter.templates.adp_payroll_flat"),
|
||||
subject: i18n.t("reportcenter.templates.adp_payroll_flat"),
|
||||
key: "adp_payroll_flat",
|
||||
reporttype: "text",
|
||||
disabled: false,
|
||||
rangeFilter: {
|
||||
object: i18n.t("reportcenter.labels.objects.timetickets"),
|
||||
field: i18n.t("timetickets.fields.committed_at")
|
||||
},
|
||||
group: "payroll",
|
||||
adp_payroll: true
|
||||
},
|
||||
adp_payroll_straight: {
|
||||
title: i18n.t("reportcenter.templates.adp_payroll_straight"),
|
||||
subject: i18n.t("reportcenter.templates.adp_payroll_straight"),
|
||||
key: "adp_payroll_straight",
|
||||
reporttype: "text",
|
||||
disabled: false,
|
||||
rangeFilter: {
|
||||
object: i18n.t("reportcenter.labels.objects.timetickets"),
|
||||
field: i18n.t("timetickets.fields.date")
|
||||
},
|
||||
group: "payroll",
|
||||
adp_payroll: true
|
||||
}
|
||||
}
|
||||
: {}),
|
||||
|
||||
47
client/src/utils/handleBeta.js
Normal file
47
client/src/utils/handleBeta.js
Normal file
@@ -0,0 +1,47 @@
|
||||
export const BETA_KEY = "betaSwitchImex";
|
||||
|
||||
export const checkBeta = () => {
|
||||
const cookie = document.cookie.split("; ").find((row) => row.startsWith(BETA_KEY));
|
||||
return cookie ? cookie.split("=")[1] === "true" : false;
|
||||
};
|
||||
|
||||
export const setBeta = (value) => {
|
||||
const domain = window.location.hostname.split(".").slice(-2).join(".");
|
||||
document.cookie = `${BETA_KEY}=${value}; path=/; domain=.${domain}`;
|
||||
};
|
||||
|
||||
export const handleBeta = () => {
|
||||
if (window.location.hostname.startsWith("localhost")) {
|
||||
console.log("Not on beta or test, so no need to handle beta.");
|
||||
return;
|
||||
}
|
||||
|
||||
const isBeta = checkBeta();
|
||||
const currentHostName = window.location.hostname;
|
||||
|
||||
// Determine if the host name starts with "beta" or "www.beta"
|
||||
const isBetaHost = currentHostName.startsWith("beta.");
|
||||
const isBetaHostWithWWW = currentHostName.startsWith("www.beta.");
|
||||
|
||||
if (isBeta) {
|
||||
// If beta is on and we are not on a beta domain, redirect to the beta version
|
||||
if (!isBetaHost && !isBetaHostWithWWW) {
|
||||
const newHostName = currentHostName.startsWith("www.")
|
||||
? `www.beta.${currentHostName.replace(/^www\./, "")}`
|
||||
: `beta.${currentHostName}`;
|
||||
const href = `${window.location.protocol}//${newHostName}${window.location.pathname}${window.location.search}${window.location.hash}`;
|
||||
window.location.replace(href);
|
||||
}
|
||||
// Otherwise, if beta is on and we're already on a beta domain, stay there
|
||||
} else {
|
||||
// If beta is off and we are on a beta domain, redirect to the non-beta version
|
||||
if (isBetaHost || isBetaHostWithWWW) {
|
||||
const newHostName = currentHostName.replace(/^www\.beta\./, "www.").replace(/^beta\./, "");
|
||||
const href = `${window.location.protocol}//${newHostName}${window.location.pathname}${window.location.search}${window.location.hash}`;
|
||||
window.location.replace(href);
|
||||
}
|
||||
// Otherwise, if beta is off and we're not on a beta domain, stay there
|
||||
}
|
||||
};
|
||||
|
||||
export default handleBeta;
|
||||
@@ -94,10 +94,7 @@ exports.default = async (req, res) => {
|
||||
ret.push({
|
||||
billid: bill.id,
|
||||
success: false,
|
||||
errorMessage:
|
||||
(error && error.authResponse && error.authResponse.body) ||
|
||||
error.response?.data?.Fault?.Error.map((e) => e.Detail).join(", ") ||
|
||||
(error && error.message)
|
||||
errorMessage: (error && error.authResponse && error.authResponse.body) || (error && error.message)
|
||||
});
|
||||
|
||||
//Add the export log error.
|
||||
@@ -212,7 +209,7 @@ async function InsertBill(oauthClient, qbo_realmId, req, bill, vendor, bodyshop)
|
||||
AccountBasedExpenseLineDetail: {
|
||||
...(bill.job.class ? { ClassRef: { value: classes[bill.job.class] } } : {}),
|
||||
AccountRef: {
|
||||
value: accounts[bodyshop.md_responsibility_centers.taxes.federal_itc.accountdesc]
|
||||
value: accounts[bodyshop.md_responsibility_centers.taxes.federal.accountdesc]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -277,8 +274,6 @@ async function InsertBill(oauthClient, qbo_realmId, req, bill, vendor, bodyshop)
|
||||
} catch (error) {
|
||||
logger.log("qbo-payables-error", "DEBUG", req.user.email, bill.id, {
|
||||
error: error, //(error && error.authResponse && error.authResponse.body) || (error && error.message),
|
||||
validationError: JSON.stringify(error?.response?.data),
|
||||
accountmeta: JSON.stringify({ accounts, taxCodes, classes }),
|
||||
method: "InsertBill"
|
||||
});
|
||||
throw error;
|
||||
|
||||
@@ -179,10 +179,7 @@ exports.default = async (req, res) => {
|
||||
ret.push({
|
||||
jobid: job.id,
|
||||
success: false,
|
||||
errorMessage:
|
||||
(error && error.authResponse && error.authResponse.body) ||
|
||||
error.response?.data?.Fault?.Error.map((e) => e.Detail).join(", ") ||
|
||||
(error && error.message)
|
||||
errorMessage: (error && error.authResponse && error.authResponse.body) || (error && error.message)
|
||||
});
|
||||
console.log(error);
|
||||
logger.log("qbo-receivable-create-error", "ERROR", req.user.email, {
|
||||
@@ -257,6 +254,7 @@ async function InsertInsuranceCo(oauthClient, qbo_realmId, req, job, bodyshop) {
|
||||
throw new Error(
|
||||
`Insurance Company '${job.ins_co_nm}' not found in shop configuration. Please make sure it exists or change the insurance company name on the job to one that exists.`
|
||||
);
|
||||
return;
|
||||
}
|
||||
const Customer = {
|
||||
DisplayName: job.ins_co_nm.trim(),
|
||||
@@ -577,9 +575,7 @@ async function InsertInvoice(oauthClient, qbo_realmId, req, job, bodyshop, paren
|
||||
} catch (error) {
|
||||
logger.log("qbo-receivables-error", "DEBUG", req.user.email, job.id, {
|
||||
error,
|
||||
method: "InsertInvoice",
|
||||
validationError: JSON.stringify(error?.response?.data),
|
||||
accountmeta: JSON.stringify({ items, taxCodes, classes })
|
||||
method: "InsertOwner"
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user