Compare commits
20 Commits
feature/IO
...
feature/IO
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
521a7084b7 | ||
|
|
a3c71fdfc0 | ||
|
|
90edf94fee | ||
|
|
123066f1cd | ||
|
|
a153cca3c0 | ||
|
|
35c7c32c8e | ||
|
|
6d6b64ebc3 | ||
|
|
338d8e2136 | ||
|
|
6674206b4f | ||
|
|
c46ad521d1 | ||
|
|
66e5bec4d8 | ||
|
|
0d3161ef84 | ||
|
|
1cd11bdc18 | ||
|
|
9cce2696e2 | ||
|
|
508d32d2d9 | ||
|
|
cccc307862 | ||
|
|
0772139a60 | ||
|
|
70028c8be6 | ||
|
|
3dc22bfdab | ||
|
|
f3ee421030 |
@@ -26,6 +26,7 @@ import { CalculateBillTotal } from "../bill-form/bill-form.totals.utility";
|
|||||||
import { handleUpload as handleLocalUpload } from "../documents-local-upload/documents-local-upload.utility";
|
import { handleUpload as handleLocalUpload } from "../documents-local-upload/documents-local-upload.utility";
|
||||||
import { handleUpload } from "../documents-upload/documents-upload.utility";
|
import { handleUpload } from "../documents-upload/documents-upload.utility";
|
||||||
import { handleUpload as handleUploadToImageProxy } from "../documents-upload-imgproxy/documents-upload-imgproxy.utility";
|
import { handleUpload as handleUploadToImageProxy } from "../documents-upload-imgproxy/documents-upload-imgproxy.utility";
|
||||||
|
import RbacWrapper from "../../components/rbac-wrapper/rbac-wrapper.component";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
billEnterModal: selectBillEnterModal,
|
billEnterModal: selectBillEnterModal,
|
||||||
@@ -450,7 +451,9 @@ function BillEnterModalContainer({ billEnterModal, toggleModalVisible, bodyshop,
|
|||||||
setEnterAgain(false);
|
setEnterAgain(false);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<BillFormContainer form={form} disableInvNumber={billEnterModal.context.disableInvNumber} />
|
<RbacWrapper action="bills:enter">
|
||||||
|
<BillFormContainer form={form} disableInvNumber={billEnterModal.context.disableInvNumber} />
|
||||||
|
</RbacWrapper>
|
||||||
</Form>
|
</Form>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,10 +4,18 @@ import { useTranslation } from "react-i18next";
|
|||||||
import { TemplateList } from "../../utils/TemplateConstants";
|
import { TemplateList } from "../../utils/TemplateConstants";
|
||||||
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
|
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
|
||||||
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
||||||
|
import InstanceRenderManager from "../../utils/instanceRenderMgr";
|
||||||
|
|
||||||
export default function ShopInfoSpeedPrint() {
|
export default function ShopInfoSpeedPrint() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const TemplateListGenerated = TemplateList("job");
|
const allTemplates = TemplateList("job");
|
||||||
|
const TemplateListGenerated = InstanceRenderManager({
|
||||||
|
imex: Object.fromEntries(
|
||||||
|
Object.entries(allTemplates).filter(([, { enhanced_payroll }]) => !enhanced_payroll)
|
||||||
|
),
|
||||||
|
rome: allTemplates
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form.List name={["speedprint"]}>
|
<Form.List name={["speedprint"]}>
|
||||||
{(fields, { add, remove, move }) => {
|
{(fields, { add, remove, move }) => {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ const mapDispatchToProps = () => ({
|
|||||||
export function TechHeader({ technician }) {
|
export function TechHeader({ technician }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<Header style={{ textAlign: "center" }}>
|
<Header style={{ textAlign: "center", height: "auto", overflow: "visible" }}>
|
||||||
<Typography.Title style={{ color: "#fff" }}>
|
<Typography.Title style={{ color: "#fff" }}>
|
||||||
{technician
|
{technician
|
||||||
? t("tech.labels.loggedin", {
|
? t("tech.labels.loggedin", {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useMutation, useQuery } from "@apollo/client";
|
import { useMutation, useQuery } from "@apollo/client";
|
||||||
import { Button, Card, Col, Form, InputNumber, Popover, Row, Select } from "antd";
|
import { Button, Card, Form, InputNumber, Popover, Select, Space } from "antd";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
@@ -124,103 +124,12 @@ export function TechClockOffButton({
|
|||||||
cost_center: isShiftTicket ? "timetickets.labels.shift" : technician ? technician.cost_center : null
|
cost_center: isShiftTicket ? "timetickets.labels.shift" : technician ? technician.cost_center : null
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Row gutter={[16, 16]}>
|
<Space direction="vertical">
|
||||||
<Col span={!isShiftTicket ? 8 : 24}>
|
{!isShiftTicket ? (
|
||||||
{!isShiftTicket ? (
|
<div>
|
||||||
<div>
|
|
||||||
<Form.Item
|
|
||||||
label={t("timetickets.fields.actualhrs")}
|
|
||||||
name="actualhrs"
|
|
||||||
rules={[
|
|
||||||
{
|
|
||||||
required: true
|
|
||||||
//message: t("general.validation.required"),
|
|
||||||
}
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<InputNumber min={0} precision={1} />
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item
|
|
||||||
label={t("timetickets.fields.productivehrs")}
|
|
||||||
name="productivehrs"
|
|
||||||
rules={[
|
|
||||||
{
|
|
||||||
required: true
|
|
||||||
//message: t("general.validation.required"),
|
|
||||||
},
|
|
||||||
({ getFieldValue }) => ({
|
|
||||||
validator(rule, value) {
|
|
||||||
if (!bodyshop.tt_enforce_hours_for_tech_console) {
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
if (!value || getFieldValue("cost_center") === null || !lineTicketData)
|
|
||||||
return Promise.resolve();
|
|
||||||
|
|
||||||
//Check the cost center,
|
|
||||||
const totals = CalculateAllocationsTotals(
|
|
||||||
bodyshop,
|
|
||||||
lineTicketData.joblines,
|
|
||||||
lineTicketData.timetickets,
|
|
||||||
lineTicketData.jobs_by_pk.lbr_adjustments
|
|
||||||
);
|
|
||||||
|
|
||||||
const fieldTypeToCheck =
|
|
||||||
bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber ? "mod_lbr_ty" : "cost_center";
|
|
||||||
|
|
||||||
const costCenterDiff =
|
|
||||||
Math.round(
|
|
||||||
totals.find((total) => total[fieldTypeToCheck] === getFieldValue("cost_center"))
|
|
||||||
?.difference * 10
|
|
||||||
) / 10;
|
|
||||||
|
|
||||||
if (value > costCenterDiff)
|
|
||||||
return Promise.reject(t("timetickets.validation.hoursenteredmorethanavailable"));
|
|
||||||
else {
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<InputNumber min={0} precision={1} />
|
|
||||||
</Form.Item>
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
<Form.Item
|
|
||||||
name="cost_center"
|
|
||||||
label={t("timetickets.fields.cost_center")}
|
|
||||||
rules={[
|
|
||||||
{
|
|
||||||
required: true
|
|
||||||
//message: t("general.validation.required"),
|
|
||||||
}
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<Select disabled={isShiftTicket}>
|
|
||||||
{isShiftTicket ? (
|
|
||||||
<Select.Option value="timetickets.labels.shift">{t("timetickets.labels.shift")}</Select.Option>
|
|
||||||
) : (
|
|
||||||
emps &&
|
|
||||||
emps.rates.map((item) => (
|
|
||||||
<Select.Option key={item.cost_center}>
|
|
||||||
{item.cost_center === "timetickets.labels.shift"
|
|
||||||
? t(item.cost_center)
|
|
||||||
: bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber
|
|
||||||
? t(`joblines.fields.lbr_types.${item.cost_center.toUpperCase()}`)
|
|
||||||
: item.cost_center}
|
|
||||||
</Select.Option>
|
|
||||||
))
|
|
||||||
)}
|
|
||||||
</Select>
|
|
||||||
</Form.Item>
|
|
||||||
|
|
||||||
{isShiftTicket ? (
|
|
||||||
<div></div>
|
|
||||||
) : (
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="status"
|
label={t("timetickets.fields.actualhrs")}
|
||||||
label={t("jobs.fields.status")}
|
name="actualhrs"
|
||||||
initialValue={lineTicketData && lineTicketData.jobs_by_pk.status}
|
|
||||||
rules={[
|
rules={[
|
||||||
{
|
{
|
||||||
required: true
|
required: true
|
||||||
@@ -228,35 +137,117 @@ export function TechClockOffButton({
|
|||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<Select>
|
<InputNumber min={0} precision={1} />
|
||||||
{bodyshop.md_ro_statuses.production_statuses.map((item) => (
|
|
||||||
<Select.Option key={item}></Select.Option>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
)}
|
<Form.Item
|
||||||
<Button type="primary" htmlType="submit" loading={loading}>
|
label={t("timetickets.fields.productivehrs")}
|
||||||
{t("general.actions.save")}
|
name="productivehrs"
|
||||||
</Button>
|
rules={[
|
||||||
<TechJobClockoutDelete completedCallback={completedCallback} timeTicketId={timeTicketId} />
|
{
|
||||||
</Col>
|
required: true
|
||||||
{!isShiftTicket && (
|
//message: t("general.validation.required"),
|
||||||
<Col span={16}>
|
},
|
||||||
<LaborAllocationContainer
|
({ getFieldValue }) => ({
|
||||||
jobid={jobId || null}
|
validator(rule, value) {
|
||||||
loading={queryLoading}
|
if (!bodyshop.tt_enforce_hours_for_tech_console) {
|
||||||
lineTicketData={lineTicketData}
|
return Promise.resolve();
|
||||||
/>
|
}
|
||||||
</Col>
|
if (!value || getFieldValue("cost_center") === null || !lineTicketData)
|
||||||
|
return Promise.resolve();
|
||||||
|
//Check the cost center,
|
||||||
|
const totals = CalculateAllocationsTotals(
|
||||||
|
bodyshop,
|
||||||
|
lineTicketData.joblines,
|
||||||
|
lineTicketData.timetickets,
|
||||||
|
lineTicketData.jobs_by_pk.lbr_adjustments
|
||||||
|
);
|
||||||
|
const fieldTypeToCheck =
|
||||||
|
bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber ? "mod_lbr_ty" : "cost_center";
|
||||||
|
const costCenterDiff =
|
||||||
|
Math.round(
|
||||||
|
totals.find((total) => total[fieldTypeToCheck] === getFieldValue("cost_center"))
|
||||||
|
?.difference * 10
|
||||||
|
) / 10;
|
||||||
|
if (value > costCenterDiff)
|
||||||
|
return Promise.reject(t("timetickets.validation.hoursenteredmorethanavailable"));
|
||||||
|
else {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<InputNumber min={0} precision={1} />
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
<Form.Item
|
||||||
|
name="cost_center"
|
||||||
|
label={t("timetickets.fields.cost_center")}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true
|
||||||
|
//message: t("general.validation.required"),
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Select disabled={isShiftTicket}>
|
||||||
|
{isShiftTicket ? (
|
||||||
|
<Select.Option value="timetickets.labels.shift">{t("timetickets.labels.shift")}</Select.Option>
|
||||||
|
) : (
|
||||||
|
emps &&
|
||||||
|
emps.rates.map((item) => (
|
||||||
|
<Select.Option key={item.cost_center}>
|
||||||
|
{item.cost_center === "timetickets.labels.shift"
|
||||||
|
? t(item.cost_center)
|
||||||
|
: bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber
|
||||||
|
? t(`joblines.fields.lbr_types.${item.cost_center.toUpperCase()}`)
|
||||||
|
: item.cost_center}
|
||||||
|
</Select.Option>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
{isShiftTicket ? (
|
||||||
|
<div></div>
|
||||||
|
) : (
|
||||||
|
<Form.Item
|
||||||
|
name="status"
|
||||||
|
label={t("jobs.fields.status")}
|
||||||
|
initialValue={lineTicketData && lineTicketData.jobs_by_pk.status}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true
|
||||||
|
//message: t("general.validation.required"),
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Select>
|
||||||
|
{bodyshop.md_ro_statuses.production_statuses.map((item) => (
|
||||||
|
<Select.Option key={item}></Select.Option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
)}
|
)}
|
||||||
</Row>
|
<Button type="primary" htmlType="submit" loading={loading}>
|
||||||
|
{t("general.actions.save")}
|
||||||
|
</Button>
|
||||||
|
<TechJobClockoutDelete completedCallback={completedCallback} timeTicketId={timeTicketId} />
|
||||||
|
{!isShiftTicket && (
|
||||||
|
<LaborAllocationContainer jobid={jobId || null} loading={queryLoading} lineTicketData={lineTicketData} />
|
||||||
|
)}
|
||||||
|
</Space>
|
||||||
</Form>
|
</Form>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Popover content={overlay} trigger="click">
|
<Popover
|
||||||
|
content={<div style={{ maxHeight: "75vh", overflowY: "auto" }}>{overlay}</div>}
|
||||||
|
trigger="click"
|
||||||
|
getPopupContainer={() => document.querySelector('#time-ticket-modal')}
|
||||||
|
>
|
||||||
<Button loading={loading} {...otherBtnProps}>
|
<Button loading={loading} {...otherBtnProps}>
|
||||||
{t("timetickets.actions.clockout")}
|
{t("timetickets.actions.clockout")}
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -3209,6 +3209,7 @@
|
|||||||
"parts_not_recieved_vendor": "Parts Not Received by Vendor",
|
"parts_not_recieved_vendor": "Parts Not Received by Vendor",
|
||||||
"parts_received_not_scheduled": "Parts Received for Jobs Not Scheduled",
|
"parts_received_not_scheduled": "Parts Received for Jobs Not Scheduled",
|
||||||
"payments_by_date": "Payments by Date",
|
"payments_by_date": "Payments by Date",
|
||||||
|
"payments_by_date_excel": "Payments by Date - Excel",
|
||||||
"payments_by_date_payment": "Payments by Date and Payment Type",
|
"payments_by_date_payment": "Payments by Date and Payment Type",
|
||||||
"payments_by_date_type": "Payments by Date and Customer Type",
|
"payments_by_date_type": "Payments by Date and Customer Type",
|
||||||
"production_by_category": "Production by Category",
|
"production_by_category": "Production by Category",
|
||||||
|
|||||||
@@ -3209,6 +3209,7 @@
|
|||||||
"parts_not_recieved_vendor": "",
|
"parts_not_recieved_vendor": "",
|
||||||
"parts_received_not_scheduled": "",
|
"parts_received_not_scheduled": "",
|
||||||
"payments_by_date": "",
|
"payments_by_date": "",
|
||||||
|
"payments_by_date_excel": "",
|
||||||
"payments_by_date_payment": "",
|
"payments_by_date_payment": "",
|
||||||
"payments_by_date_type": "",
|
"payments_by_date_type": "",
|
||||||
"production_by_category": "",
|
"production_by_category": "",
|
||||||
|
|||||||
@@ -3209,6 +3209,7 @@
|
|||||||
"parts_not_recieved_vendor": "",
|
"parts_not_recieved_vendor": "",
|
||||||
"parts_received_not_scheduled": "",
|
"parts_received_not_scheduled": "",
|
||||||
"payments_by_date": "",
|
"payments_by_date": "",
|
||||||
|
"payments_by_date_excel": "",
|
||||||
"payments_by_date_payment": "",
|
"payments_by_date_payment": "",
|
||||||
"payments_by_date_type": "",
|
"payments_by_date_type": "",
|
||||||
"production_by_category": "",
|
"production_by_category": "",
|
||||||
|
|||||||
@@ -1218,6 +1218,18 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
group: "customers"
|
group: "customers"
|
||||||
},
|
},
|
||||||
|
payments_by_date_excel: {
|
||||||
|
title: i18n.t("reportcenter.templates.payments_by_date_excel"),
|
||||||
|
subject: i18n.t("reportcenter.templates.payments_by_date_excel"),
|
||||||
|
key: "payments_by_date_excel",
|
||||||
|
reporttype: "excel",
|
||||||
|
disabled: false,
|
||||||
|
rangeFilter: {
|
||||||
|
object: i18n.t("reportcenter.labels.objects.payments"),
|
||||||
|
field: i18n.t("payments.fields.date")
|
||||||
|
},
|
||||||
|
group: "customers"
|
||||||
|
},
|
||||||
schedule: {
|
schedule: {
|
||||||
title: i18n.t("reportcenter.templates.schedule"),
|
title: i18n.t("reportcenter.templates.schedule"),
|
||||||
subject: i18n.t("reportcenter.templates.schedule"),
|
subject: i18n.t("reportcenter.templates.schedule"),
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
alter table "public"."media_analytics_detail" drop constraint "media_analytics_detail_jobid_fkey",
|
||||||
|
add constraint "media_analytics_detail_jobid_fkey"
|
||||||
|
foreign key ("jobid")
|
||||||
|
references "public"."jobs"
|
||||||
|
("id") on update restrict on delete restrict;
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
alter table "public"."media_analytics_detail" drop constraint "media_analytics_detail_jobid_fkey",
|
||||||
|
add constraint "media_analytics_detail_jobid_fkey"
|
||||||
|
foreign key ("jobid")
|
||||||
|
references "public"."jobs"
|
||||||
|
("id") on update set null on delete set null;
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
-- Could not auto-generate a down migration.
|
||||||
|
-- Please write an appropriate down migration for the SQL below:
|
||||||
|
-- CREATE OR REPLACE FUNCTION set_fk_to_null_if_invalid_media_analytics()
|
||||||
|
-- RETURNS TRIGGER AS $$
|
||||||
|
-- BEGIN
|
||||||
|
-- -- Check if the foreign key value is not NULL
|
||||||
|
-- IF NEW.jobid IS NOT NULL THEN
|
||||||
|
-- -- Check if the corresponding record exists in the parent table
|
||||||
|
-- IF NOT EXISTS (SELECT 1 FROM jobs WHERE id = NEW.jobid) THEN
|
||||||
|
-- -- If it doesn't exist, set the foreign key to NULL
|
||||||
|
-- NEW.jobid = NULL;
|
||||||
|
-- END IF;
|
||||||
|
-- END IF;
|
||||||
|
--
|
||||||
|
-- -- Return the (potentially modified) record to be inserted/updated
|
||||||
|
-- RETURN NEW;
|
||||||
|
-- END;
|
||||||
|
-- $$ LANGUAGE plpgsql;
|
||||||
|
--
|
||||||
|
-- CREATE TRIGGER media_analytics_fk_null
|
||||||
|
-- BEFORE INSERT OR UPDATE ON media_analytics_detail
|
||||||
|
-- FOR EACH ROW
|
||||||
|
-- EXECUTE FUNCTION set_fk_to_null_if_invalid_media_analytics();
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
CREATE OR REPLACE FUNCTION set_fk_to_null_if_invalid_media_analytics()
|
||||||
|
RETURNS TRIGGER AS $$
|
||||||
|
BEGIN
|
||||||
|
-- Check if the foreign key value is not NULL
|
||||||
|
IF NEW.jobid IS NOT NULL THEN
|
||||||
|
-- Check if the corresponding record exists in the parent table
|
||||||
|
IF NOT EXISTS (SELECT 1 FROM jobs WHERE id = NEW.jobid) THEN
|
||||||
|
-- If it doesn't exist, set the foreign key to NULL
|
||||||
|
NEW.jobid = NULL;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- Return the (potentially modified) record to be inserted/updated
|
||||||
|
RETURN NEW;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
CREATE TRIGGER media_analytics_fk_null
|
||||||
|
BEFORE INSERT OR UPDATE ON media_analytics_detail
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE FUNCTION set_fk_to_null_if_invalid_media_analytics();
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
DROP INDEX IF EXISTS "public"."media_analytics_detail_bodyshopid";
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
CREATE INDEX "media_analytics_detail_bodyshopid" on
|
||||||
|
"public"."media_analytics_detail" using btree ("bodyshopid");
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
DROP INDEX IF EXISTS "public"."media_analytics_detail_jobid";
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
CREATE INDEX "media_analytics_detail_jobid" on
|
||||||
|
"public"."media_analytics_detail" using btree ("jobid");
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
DROP INDEX IF EXISTS "public"."media_analytics_detail_media_analytics";
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
CREATE INDEX "media_analytics_detail_media_analytics" on
|
||||||
|
"public"."media_analytics_detail" using btree ("media_analytics_id");
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- Could not auto-generate a down migration.
|
||||||
|
-- Please write an appropriate down migration for the SQL below:
|
||||||
|
-- alter table "public"."media_analytics" add column "unique_documents" numeric
|
||||||
|
-- null;
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
alter table "public"."media_analytics" add column "unique_documents" numeric
|
||||||
|
null;
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- Could not auto-generate a down migration.
|
||||||
|
-- Please write an appropriate down migration for the SQL below:
|
||||||
|
-- alter table "public"."media_analytics" add column "duplicate_documents" numeric
|
||||||
|
-- null;
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
alter table "public"."media_analytics" add column "duplicate_documents" numeric
|
||||||
|
null;
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- Could not auto-generate a down migration.
|
||||||
|
-- Please write an appropriate down migration for the SQL below:
|
||||||
|
-- alter table "public"."media_analytics_detail" add column "unique_documents" numeric
|
||||||
|
-- null;
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
alter table "public"."media_analytics_detail" add column "unique_documents" numeric
|
||||||
|
null;
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- Could not auto-generate a down migration.
|
||||||
|
-- Please write an appropriate down migration for the SQL below:
|
||||||
|
-- alter table "public"."media_analytics_detail" add column "duplicate_documents" numeric
|
||||||
|
-- null;
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
alter table "public"."media_analytics_detail" add column "duplicate_documents" numeric
|
||||||
|
null;
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
alter table "public"."media_analytics_detail" rename column "unique_document_count" to "unique_documents";
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
alter table "public"."media_analytics_detail" rename column "unique_documents" to "unique_document_count";
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
alter table "public"."media_analytics_detail" rename column "duplicate_count" to "duplicate_documents";
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
alter table "public"."media_analytics_detail" rename column "duplicate_documents" to "duplicate_count";
|
||||||
@@ -234,11 +234,10 @@ const CreateRepairOrderTag = (job, errorCallback) => {
|
|||||||
const ret = {
|
const ret = {
|
||||||
ro_number: crypto.createHash("md5").update(job.id, "utf8").digest("hex"),
|
ro_number: crypto.createHash("md5").update(job.id, "utf8").digest("hex"),
|
||||||
v_vin: job.v_vin || "",
|
v_vin: job.v_vin || "",
|
||||||
v_year: job.v_model_yr
|
v_year: (() => {
|
||||||
? parseInt(job.v_model_yr.match(/\d/g))
|
const y = parseInt(job.v_model_yr);
|
||||||
? parseInt(job.v_model_yr.match(/\d/g).join(""), 10)
|
return isNaN(y) ? null : y < 100 ? y + (y >= (new Date().getFullYear() + 1) % 100 ? 1900 : 2000) : y;
|
||||||
: ""
|
})(),
|
||||||
: "",
|
|
||||||
v_make: job.v_makedesc || "",
|
v_make: job.v_makedesc || "",
|
||||||
v_model: job.v_model || "",
|
v_model: job.v_model || "",
|
||||||
|
|
||||||
|
|||||||
@@ -286,11 +286,10 @@ const CreateRepairOrderTag = (job, errorCallback) => {
|
|||||||
const ret = {
|
const ret = {
|
||||||
ro_number: crypto.createHash("md5").update(job.ro_number, "utf8").digest("hex"),
|
ro_number: crypto.createHash("md5").update(job.ro_number, "utf8").digest("hex"),
|
||||||
v_vin: job.v_vin || "",
|
v_vin: job.v_vin || "",
|
||||||
v_year: job.v_model_yr
|
v_year: (() => {
|
||||||
? parseInt(job.v_model_yr.match(/\d/g))
|
const y = parseInt(job.v_model_yr);
|
||||||
? parseInt(job.v_model_yr.match(/\d/g).join(""), 10)
|
return isNaN(y) ? null : y < 100 ? y + (y >= (new Date().getFullYear() + 1) % 100 ? 1900 : 2000) : y;
|
||||||
: ""
|
})(),
|
||||||
: "",
|
|
||||||
v_make: job.v_make_desc || "",
|
v_make: job.v_make_desc || "",
|
||||||
v_model: job.v_model_desc || "",
|
v_model: job.v_model_desc || "",
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,9 @@ exports.default = async (req, res) => {
|
|||||||
"patrick.fic@convenient-brands.com",
|
"patrick.fic@convenient-brands.com",
|
||||||
"bradley.rhoades@convenient-brands.com",
|
"bradley.rhoades@convenient-brands.com",
|
||||||
"jrome@rometech.com",
|
"jrome@rometech.com",
|
||||||
"ivana@imexsystems.ca"
|
"ivana@imexsystems.ca",
|
||||||
|
"support@imexsystems.ca",
|
||||||
|
"sarah@rometech.com"
|
||||||
],
|
],
|
||||||
subject: `RO Usage Report - ${moment().format("MM/DD/YYYY")}`,
|
subject: `RO Usage Report - ${moment().format("MM/DD/YYYY")}`,
|
||||||
text: `
|
text: `
|
||||||
|
|||||||
Reference in New Issue
Block a user