From 2215c8439e706f7232e983747e823252c1f51b50 Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Fri, 15 Mar 2024 16:12:27 -0400 Subject: [PATCH 01/41] - Hasura Migration Changes Signed-off-by: Dave Richer --- hasura/metadata/tables.yaml | 194 +++++++++++++++++- .../down.sql | 1 + .../up.sql | 18 ++ 3 files changed, 212 insertions(+), 1 deletion(-) create mode 100644 hasura/migrations/1710532848432_create_table_public_tasks/down.sql create mode 100644 hasura/migrations/1710532848432_create_table_public_tasks/up.sql diff --git a/hasura/metadata/tables.yaml b/hasura/metadata/tables.yaml index 587fa8ac3..2f47a4e8f 100644 --- a/hasura/metadata/tables.yaml +++ b/hasura/metadata/tables.yaml @@ -569,6 +569,13 @@ table: name: parts_orders schema: public + - name: tasks + using: + foreign_key_constraint_on: + column: billid + table: + name: tasks + schema: public insert_permissions: - role: user permission: @@ -818,6 +825,13 @@ table: name: inventory schema: public + - name: ioevents + using: + foreign_key_constraint_on: + column: bodyshopid + table: + name: ioevents + schema: public - name: jobs using: foreign_key_constraint_on: @@ -846,6 +860,13 @@ table: name: phonebook schema: public + - name: tasks + using: + foreign_key_constraint_on: + column: bodyshopid + table: + name: tasks + schema: public - name: timetickets using: foreign_key_constraint_on: @@ -2675,6 +2696,13 @@ - table: name: ioevents schema: public + object_relationships: + - name: bodyshop + using: + foreign_key_constraint_on: bodyshopid + - name: user + using: + foreign_key_constraint_on: useremail - table: name: job_ar_schema schema: public @@ -2824,6 +2852,13 @@ table: name: parts_order_lines schema: public + - name: tasks + using: + foreign_key_constraint_on: + column: joblineid + table: + name: tasks + schema: public insert_permissions: - role: user permission: @@ -3311,6 +3346,13 @@ table: name: scoreboard schema: public + - name: tasks + using: + foreign_key_constraint_on: + column: jobid + table: + name: tasks + schema: public - name: timetickets using: foreign_key_constraint_on: @@ -4200,7 +4242,7 @@ interval_sec: 10 num_retries: 0 timeout_sec: 60 - webhook_from_env: HASURA_API_URL + webhook: https://worktest.home.irony.online headers: - name: event-secret value_from_env: EVENT_SECRET @@ -5008,6 +5050,13 @@ table: name: parts_order_lines schema: public + - name: tasks + using: + foreign_key_constraint_on: + column: partsorderid + table: + name: tasks + schema: public insert_permissions: - role: user permission: @@ -5623,6 +5672,128 @@ _eq: X-Hasura-User-Id - active: _eq: true +- table: + name: tasks + schema: public + object_relationships: + - name: bill + using: + foreign_key_constraint_on: billid + - name: bodyshop + using: + foreign_key_constraint_on: bodyshopid + - name: job + using: + foreign_key_constraint_on: jobid + - name: jobline + using: + foreign_key_constraint_on: joblineid + - name: parts_order + using: + foreign_key_constraint_on: partsorderid + - name: user + using: + foreign_key_constraint_on: assigned_to + - name: userByCreatedBy + using: + foreign_key_constraint_on: created_by + insert_permissions: + - role: user + permission: + check: + bodyshop: + associations: + _and: + - user: + authid: + _eq: X-Hasura-User-Id + - active: + _eq: true + columns: + - completed + - deleted + - priority + - assigned_to + - created_by + - description + - title + - completed_at + - created_at + - deleted_at + - due_date + - remind_at + - updated_at + - billid + - bodyshopid + - id + - jobid + - joblineid + - partsorderid + select_permissions: + - role: user + permission: + columns: + - completed + - deleted + - priority + - assigned_to + - created_by + - description + - title + - completed_at + - created_at + - deleted_at + - due_date + - remind_at + - updated_at + - billid + - bodyshopid + - id + - jobid + - joblineid + - partsorderid + filter: + bodyshop: + associations: + _and: + - user: + authid: + _eq: X-Hasura-User-Id + - active: + _eq: true + update_permissions: + - role: user + permission: + columns: + - completed + - deleted + - priority + - assigned_to + - created_by + - description + - title + - completed_at + - created_at + - deleted_at + - due_date + - remind_at + - updated_at + - billid + - bodyshopid + - id + - jobid + - joblineid + - partsorderid + filter: + bodyshop: + associations: + _and: + - user: + authid: + _eq: X-Hasura-User-Id + - active: + _eq: true + check: null - table: name: timetickets schema: public @@ -6006,6 +6177,13 @@ table: name: exportlog schema: public + - name: ioevents + using: + foreign_key_constraint_on: + column: useremail + table: + name: ioevents + schema: public - name: messages using: foreign_key_constraint_on: @@ -6034,6 +6212,20 @@ table: name: parts_orders schema: public + - name: tasks + using: + foreign_key_constraint_on: + column: assigned_to + table: + name: tasks + schema: public + - name: tasksByCreatedBy + using: + foreign_key_constraint_on: + column: created_by + table: + name: tasks + schema: public - name: timetickets using: foreign_key_constraint_on: diff --git a/hasura/migrations/1710532848432_create_table_public_tasks/down.sql b/hasura/migrations/1710532848432_create_table_public_tasks/down.sql new file mode 100644 index 000000000..ba949320f --- /dev/null +++ b/hasura/migrations/1710532848432_create_table_public_tasks/down.sql @@ -0,0 +1 @@ +DROP TABLE "public"."tasks"; diff --git a/hasura/migrations/1710532848432_create_table_public_tasks/up.sql b/hasura/migrations/1710532848432_create_table_public_tasks/up.sql new file mode 100644 index 000000000..f5e9db3c6 --- /dev/null +++ b/hasura/migrations/1710532848432_create_table_public_tasks/up.sql @@ -0,0 +1,18 @@ +CREATE TABLE "public"."tasks" ("id" uuid NOT NULL DEFAULT gen_random_uuid(), "created_at" timestamptz NOT NULL DEFAULT now(), "updated_at" timestamptz NOT NULL DEFAULT now(), "title" text NOT NULL, "description" Text, "deleted" boolean NOT NULL DEFAULT false, "deleted_at" timestamptz, "due_date" timestamptz, "created_by" text NOT NULL, "assigned_to" Text, "completed" boolean NOT NULL DEFAULT false, "completed_at" timestamptz, "remind_at" timestamptz, "priority" numeric, "bodyshopid" UUID NOT NULL, "jobid" UUID NOT NULL, "joblineid" UUID, "partsorderid" UUID, "billid" UUID, PRIMARY KEY ("id") , FOREIGN KEY ("created_by") REFERENCES "public"."users"("email") ON UPDATE restrict ON DELETE restrict, FOREIGN KEY ("assigned_to") REFERENCES "public"."users"("email") ON UPDATE restrict ON DELETE restrict, FOREIGN KEY ("bodyshopid") REFERENCES "public"."bodyshops"("id") ON UPDATE restrict ON DELETE restrict, FOREIGN KEY ("jobid") REFERENCES "public"."jobs"("id") ON UPDATE cascade ON DELETE cascade, FOREIGN KEY ("joblineid") REFERENCES "public"."joblines"("id") ON UPDATE set null ON DELETE set null, FOREIGN KEY ("partsorderid") REFERENCES "public"."parts_orders"("id") ON UPDATE set null ON DELETE set null, FOREIGN KEY ("billid") REFERENCES "public"."bills"("id") ON UPDATE set null ON DELETE set null); +CREATE OR REPLACE FUNCTION "public"."set_current_timestamp_updated_at"() +RETURNS TRIGGER AS $$ +DECLARE + _new record; +BEGIN + _new := NEW; + _new."updated_at" = NOW(); + RETURN _new; +END; +$$ LANGUAGE plpgsql; +CREATE TRIGGER "set_public_tasks_updated_at" +BEFORE UPDATE ON "public"."tasks" +FOR EACH ROW +EXECUTE PROCEDURE "public"."set_current_timestamp_updated_at"(); +COMMENT ON TRIGGER "set_public_tasks_updated_at" ON "public"."tasks" +IS 'trigger to set value of column "updated_at" to current timestamp on row update'; +CREATE EXTENSION IF NOT EXISTS pgcrypto; From 85f973f5e6c9c5afdc4ce6743cf366e3000759be Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Mon, 18 Mar 2024 13:40:06 -0700 Subject: [PATCH 02/41] IO-2685 Resolve missing parts rates for ImEX. --- .../jobs-detail-rates.component.jsx | 452 ++++++++---------- 1 file changed, 208 insertions(+), 244 deletions(-) diff --git a/client/src/components/jobs-detail-rates/jobs-detail-rates.component.jsx b/client/src/components/jobs-detail-rates/jobs-detail-rates.component.jsx index bf02521ac..a64582c7c 100644 --- a/client/src/components/jobs-detail-rates/jobs-detail-rates.component.jsx +++ b/client/src/components/jobs-detail-rates/jobs-detail-rates.component.jsx @@ -1,261 +1,225 @@ -import {Divider, Form, Input, InputNumber, Select, Space, Switch, Tooltip,} from "antd"; -import React from "react"; -import {useTranslation} from "react-i18next"; -import {connect} from "react-redux"; -import {createStructuredSelector} from "reselect"; -import {selectJobReadOnly} from "../../redux/application/application.selectors"; -import {selectBodyshop} from "../../redux/user/user.selectors"; -import CABCpvrtCalculator from "../ca-bc-pvrt-calculator/ca-bc-pvrt-calculator.component"; -import CurrencyInput from "../form-items-formatted/currency-form-item.component"; -import JobsDetailRatesChangeButton from "../jobs-detail-rates-change-button/jobs-detail-rates-change-button.component"; -import JobsMarkPstExempt from "../jobs-mark-pst-exempt/jobs-mark-pst-exempt.component"; -import FormRow from "../layout-form-row/layout-form-row.component"; -import JobsDetailRatesLabor from "./jobs-detail-rates.labor.component"; -import JobsDetailRatesMaterials from "./jobs-detail-rates.materials.component"; -import JobsDetailRatesOther from "./jobs-detail-rates.other.component"; -import JobsDetailRatesParts from "./jobs-detail-rates.parts.component"; -import JobsDetailRatesTaxes from "./jobs-detail-rates.taxes.component"; -import JobsDetailRatesProfileOVerride from "./jobs-detail-rates.profile-override.component"; -import InstanceRenderManager from "../../utils/instanceRenderMgr"; +import { Divider, Form, Input, InputNumber, Select, Space, Switch, Tooltip } from 'antd'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { connect } from 'react-redux'; +import { createStructuredSelector } from 'reselect'; +import { selectJobReadOnly } from '../../redux/application/application.selectors'; +import { selectBodyshop } from '../../redux/user/user.selectors'; +import CABCpvrtCalculator from '../ca-bc-pvrt-calculator/ca-bc-pvrt-calculator.component'; +import CurrencyInput from '../form-items-formatted/currency-form-item.component'; +import JobsDetailRatesChangeButton from '../jobs-detail-rates-change-button/jobs-detail-rates-change-button.component'; +import JobsMarkPstExempt from '../jobs-mark-pst-exempt/jobs-mark-pst-exempt.component'; +import FormRow from '../layout-form-row/layout-form-row.component'; +import JobsDetailRatesLabor from './jobs-detail-rates.labor.component'; +import JobsDetailRatesMaterials from './jobs-detail-rates.materials.component'; +import JobsDetailRatesOther from './jobs-detail-rates.other.component'; +import JobsDetailRatesParts from './jobs-detail-rates.parts.component'; +import JobsDetailRatesTaxes from './jobs-detail-rates.taxes.component'; +import JobsDetailRatesProfileOVerride from './jobs-detail-rates.profile-override.component'; +import InstanceRenderManager from '../../utils/instanceRenderMgr'; const mapStateToProps = createStructuredSelector({ - jobRO: selectJobReadOnly, - bodyshop: selectBodyshop, + jobRO: selectJobReadOnly, + bodyshop: selectBodyshop, }); -export function JobsDetailRates({jobRO, form, job, bodyshop}) { - const {t} = useTranslation(); - return ( -
- - - + + + + {bodyshop.region_config.toLowerCase().startsWith('ca') && ( + + + + + + )} + + + + + + + + + + + + + {bodyshop.region_config === 'CA_BC' && ( + + + + + + + )} - + + + prev.auto_add_ats !== cur.auto_add_ats}> + {() => { + if (form.getFieldValue('auto_add_ats')) + return ( + + + + ); + + return null; + }} + + + {InstanceRenderManager({ + imex: ( + + + + + + - - - - - {bodyshop.region_config.toLowerCase().startsWith("ca") && ( - + + + + + {bodyshop.region_config.toLowerCase().startsWith('ca') && ( + - - - )} - }) -} - - {t("jobs.forms.laborrates")} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { - // - // - // - // - // - // - } - - - - - { - InstanceRenderManager({rome: <> - Tax Profile - - - - - - - - }) - } -
- ); + > + + + )} + + ), + })} + + {t('jobs.forms.laborrates')} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { + // + // + // + // + // + // + } + + + + + {InstanceRenderManager({ + imex: , + rome: ( + <> + Tax Profile + + + + + + + + ), + promanager: "USE_ROME" + })} + + ); } export default connect(mapStateToProps, null)(JobsDetailRates); From 737c4164c4b133ddf74964c246aacee979f6758b Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Mon, 18 Mar 2024 13:43:23 -0700 Subject: [PATCH 03/41] IO-2688 Add default GST for bill posting on ImEX. --- .../bill-form/bill-form.lines.component.jsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/client/src/components/bill-form/bill-form.lines.component.jsx b/client/src/components/bill-form/bill-form.lines.component.jsx index 9bb65de9c..ee02d3acc 100644 --- a/client/src/components/bill-form/bill-form.lines.component.jsx +++ b/client/src/components/bill-form/bill-form.lines.component.jsx @@ -689,14 +689,14 @@ export function BillEnterModalLinesComponent({ formItemProps: (field) => { return { - key: `${field.index}fedtax`, - valuePropName: "checked", - // initialValue: true, - name: [ - field.name, - "applicable_taxes", - "federal", - ], + key: `${field.index}fedtax`, + valuePropName: 'checked', + initialValue: InstanceRenderManager({ + imex: true, + rome: false, + promanager: false, + }), + name: [field.name, 'applicable_taxes', 'federal'], }; }, formInput: (record, index) => ( From 2604507403d426c9401035f0e76b8f70dd8d5e09 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Mon, 18 Mar 2024 13:52:02 -0700 Subject: [PATCH 04/41] IO-2689 Resolve save and new for bill posting. --- .../bill-enter-modal/bill-enter-modal.container.jsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/client/src/components/bill-enter-modal/bill-enter-modal.container.jsx b/client/src/components/bill-enter-modal/bill-enter-modal.container.jsx index c4f8a062d..c707aa5dd 100644 --- a/client/src/components/bill-enter-modal/bill-enter-modal.container.jsx +++ b/client/src/components/bill-enter-modal/bill-enter-modal.container.jsx @@ -373,12 +373,12 @@ function BillEnterModalContainer({ }); if (enterAgain) { - // form.resetFields(); - form.setFieldsValue({ - ...formValues, - billlines: [], - }); - form.resetFields(); + form.resetFields(); + form.setFieldsValue({ + ...formValues, + billlines: [], + }); + // form.resetFields(); } else { toggleModalVisible(); } From bc25c2398246b6a2edbfb48ae6b830673ec277e3 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Mon, 18 Mar 2024 15:41:32 -0700 Subject: [PATCH 05/41] Resolve event env var. --- hasura/metadata/tables.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hasura/metadata/tables.yaml b/hasura/metadata/tables.yaml index 2f47a4e8f..1dd02cf6a 100644 --- a/hasura/metadata/tables.yaml +++ b/hasura/metadata/tables.yaml @@ -4242,7 +4242,7 @@ interval_sec: 10 num_retries: 0 timeout_sec: 60 - webhook: https://worktest.home.irony.online + webhook_from_env: HASURA_API_URL headers: - name: event-secret value_from_env: EVENT_SECRET From a6497bb14e3e03dbc16981bd2cb876dd32b12525 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Tue, 19 Mar 2024 08:20:08 -0700 Subject: [PATCH 06/41] IO-2689 Preserve vendor on save and new. --- .../components/bill-enter-modal/bill-enter-modal.container.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/client/src/components/bill-enter-modal/bill-enter-modal.container.jsx b/client/src/components/bill-enter-modal/bill-enter-modal.container.jsx index c707aa5dd..019de445c 100644 --- a/client/src/components/bill-enter-modal/bill-enter-modal.container.jsx +++ b/client/src/components/bill-enter-modal/bill-enter-modal.container.jsx @@ -376,6 +376,7 @@ function BillEnterModalContainer({ form.resetFields(); form.setFieldsValue({ ...formValues, + vendorid:values.vendorid, billlines: [], }); // form.resetFields(); From 1b16d75dc75f76091f2b9218879c8eec21a8cadf Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Tue, 19 Mar 2024 08:52:30 -0700 Subject: [PATCH 07/41] IO-2687 Delay template load to wait for translations. --- .../parts-dispatch-table.component.jsx | 19 ++++++----- client/src/translations/i18n.js | 33 ++++++++++++------- client/src/utils/RenderTemplate.js | 7 +++- 3 files changed, 37 insertions(+), 22 deletions(-) diff --git a/client/src/components/parts-dispatch-table/parts-dispatch-table.component.jsx b/client/src/components/parts-dispatch-table/parts-dispatch-table.component.jsx index 103dba636..1be7491da 100644 --- a/client/src/components/parts-dispatch-table/parts-dispatch-table.component.jsx +++ b/client/src/components/parts-dispatch-table/parts-dispatch-table.component.jsx @@ -34,19 +34,20 @@ export function PartDispatchTableComponent({ // const selectedBill = search.billid; const [searchText, setSearchText] = useState(""); - const Templates = TemplateList("job_special"); + const Templates = TemplateList("job_special", job); const {refetch} = billsQuery; const recordActions = (record) => ( - - - + + + ); const columns = [ { diff --git a/client/src/translations/i18n.js b/client/src/translations/i18n.js index 12173a881..13c362124 100644 --- a/client/src/translations/i18n.js +++ b/client/src/translations/i18n.js @@ -4,6 +4,7 @@ import { initReactI18next } from 'react-i18next'; import en_Translation from './en_us/common.json'; import es_Translation from './es/common.json'; import fr_Translation from './fr/common.json'; +import { GenerateTemplates } from '../utils/RenderTemplate'; // the translations // (tip move them in a JSON file and import them) @@ -13,19 +14,27 @@ const resources = { 'es-MX': es_Translation, }; i18n - .use(initReactI18next) .use(LanguageDetector) // passes i18n down to react-i18next - .init({ - resources, - //lng: "en", - detection: {}, - fallbackLng: 'en-US', - debug: import.meta.env.DEV, - //keySeparator: false, // we do not use keys in form messages.welcome - interpolation: { - escapeValue: false, // react already safes from xss - skipOnVariables: false, + .use(initReactI18next) + .init( + { + resources, + //lng: "en", + detection: {}, + fallbackLng: 'en-US', + debug: import.meta.env.DEV, + react: { + useSuspense: true, + }, + //keySeparator: false, // we do not use keys in form messages.welcome + interpolation: { + escapeValue: false, // react already safes from xss + skipOnVariables: false, + }, }, - }); + (error) => { + GenerateTemplates(); + } + ); export default i18n; diff --git a/client/src/utils/RenderTemplate.js b/client/src/utils/RenderTemplate.js index 3295f33ce..c878246f1 100644 --- a/client/src/utils/RenderTemplate.js +++ b/client/src/utils/RenderTemplate.js @@ -14,7 +14,12 @@ const server = import.meta.env.VITE_APP_REPORTS_SERVER_URL; jsreport.serverUrl = server; -const Templates = TemplateList(); +let Templates; +export function GenerateTemplates(){ + //Required as a part of the transition to Vite. + //Previous method had the template hash generating before translations loaded, resulting in empty files. + Templates = TemplateList() +} export default async function RenderTemplate( templateObject, From f618719419cd10f954a200ba5881ff65890c29eb Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Tue, 19 Mar 2024 08:56:23 -0700 Subject: [PATCH 08/41] IO-2693 Remove committed column in table for non-enhanced payroll. --- .../time-ticket-list.component.jsx | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/client/src/components/time-ticket-list/time-ticket-list.component.jsx b/client/src/components/time-ticket-list/time-ticket-list.component.jsx index 77d322496..05c39e0d1 100644 --- a/client/src/components/time-ticket-list/time-ticket-list.component.jsx +++ b/client/src/components/time-ticket-list/time-ticket-list.component.jsx @@ -65,14 +65,19 @@ export function TimeTicketList({ }, [timetickets]); const columns = [ - { - title: t("timetickets.fields.committed"), - dataIndex: "committed_at", - key: "committed_at", - render: (text, record) => ( - - ), - }, + ...(Enhanced_Payroll.treatment === "on" + ? [{ + title: t("timetickets.fields.committed"), + dataIndex: "committed_at", + key: "committed_at", + render: (text, record) => ( + + ), + },] + : [ + + ]), + { title: t("timetickets.fields.date"), dataIndex: "date", From 214e29d29221849e2f2ece8cdc9961d80b4b463c Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Tue, 19 Mar 2024 09:20:09 -0700 Subject: [PATCH 09/41] IO-2695 Respect payroll treatment for prod table column generation. --- .../production-list-columns.add.component.jsx | 11 ++++++++++- .../production-list-columns.data.jsx | 7 ++++--- .../production-list-table-view-select.component.jsx | 9 +++++++++ .../production-list-table.component.jsx | 9 +++++---- 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/client/src/components/production-list-columns/production-list-columns.add.component.jsx b/client/src/components/production-list-columns/production-list-columns.add.component.jsx index 09e99625a..c7f14ea7c 100644 --- a/client/src/components/production-list-columns/production-list-columns.add.component.jsx +++ b/client/src/components/production-list-columns/production-list-columns.add.component.jsx @@ -7,6 +7,7 @@ import {connect} from "react-redux"; import {createStructuredSelector} from "reselect"; import {selectTechnician} from "../../redux/tech/tech.selectors"; import {selectBodyshop} from "../../redux/user/user.selectors"; +import {useSplitTreatments} from "@splitsoftware/splitio-react"; const mapStateToProps = createStructuredSelector({ //currentUser: selectCurrentUser @@ -31,7 +32,13 @@ export function ProductionColumnsComponent({ }) { const [columns, setColumns] = columnState; const {t} = useTranslation(); - + const { + treatments: { Enhanced_Payroll }, + } = useSplitTreatments({ + attributes: {}, + names: ['Enhanced_Payroll'], + splitKey: bodyshop.imexshopid, + }); const handleAdd = (e) => { setColumns([ ...columns, @@ -41,6 +48,7 @@ export function ProductionColumnsComponent({ state: tableState, data, activeStatuses: bodyshop.md_ro_statuses.active_statuses, + treatments:{Enhanced_Payroll} }).filter((i) => i.key === e.key), ]); }; @@ -52,6 +60,7 @@ export function ProductionColumnsComponent({ state: tableState, activeStatuses: bodyshop.md_ro_statuses.active_statuses, refetch, + treatments:{Enhanced_Payroll} }); const menu = { diff --git a/client/src/components/production-list-columns/production-list-columns.data.jsx b/client/src/components/production-list-columns/production-list-columns.data.jsx index 479f41f9d..0dd7a849f 100644 --- a/client/src/components/production-list-columns/production-list-columns.data.jsx +++ b/client/src/components/production-list-columns/production-list-columns.data.jsx @@ -29,7 +29,8 @@ import ProductionlistColumnTouchTime from "./prodution-list-columns.touchtime.co import {store} from "../../redux/store"; import {setModalContext} from "../../redux/modals/modals.actions"; -const r = ({technician, state, activeStatuses, data, bodyshop, refetch}) => { +const r = ({technician, state, activeStatuses, data, bodyshop, refetch, treatments}) => { +const {Enhanced_Payroll} = treatments; return [ { title: i18n.t("jobs.actions.viewdetail"), @@ -42,7 +43,7 @@ const r = ({technician, state, activeStatuses, data, bodyshop, refetch}) => { ), }, - { + ...Enhanced_Payroll.treatment === "on" ? [ { title: i18n.t("timetickets.actions.claimtasks"), dataIndex: "claimtasks", key: "claimtasks", @@ -64,7 +65,7 @@ const r = ({technician, state, activeStatuses, data, bodyshop, refetch}) => { {i18n.t("timetickets.actions.claimtasks")} ), - }, + },] : [], { title: i18n.t("jobs.fields.ro_number"), dataIndex: "ro_number", diff --git a/client/src/components/production-list-table/production-list-table-view-select.component.jsx b/client/src/components/production-list-table/production-list-table-view-select.component.jsx index a313ec8f1..e9c96ef58 100644 --- a/client/src/components/production-list-table/production-list-table-view-select.component.jsx +++ b/client/src/components/production-list-table/production-list-table-view-select.component.jsx @@ -10,6 +10,7 @@ import {UPDATE_SHOP} from "../../graphql/bodyshop.queries"; import {selectTechnician} from "../../redux/tech/tech.selectors"; import {selectBodyshop, selectCurrentUser,} from "../../redux/user/user.selectors"; import ProductionListColumns from "../production-list-columns/production-list-columns.data"; +import {useSplitTreatments} from '@splitsoftware/splitio-react'; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -31,6 +32,12 @@ export function ProductionListTable({ const [updateDefaultProdView] = useMutation(UPDATE_ACTIVE_PROD_LIST_VIEW); const [updateShop] = useMutation(UPDATE_SHOP); + const {treatments: {Enhanced_Payroll}} = useSplitTreatments({ + attributes: {}, + names: ["Enhanced_Payroll"], + splitKey: bodyshop.imexshopid, +}); + const handleSelect = async (value, option) => { setColumns( bodyshop.production_config @@ -44,6 +51,7 @@ export function ProductionListTable({ state, data: data, activeStatuses: bodyshop.md_ro_statuses.active_statuses, + treatments:{Enhanced_Payroll} }).find((e) => e.key === k.key), width: k.width, }; @@ -100,6 +108,7 @@ export function ProductionListTable({ refetch, data: data, activeStatuses: bodyshop.md_ro_statuses.active_statuses, + treatments: {Enhanced_Payroll} }).find((e) => e.key === k.key), width: k.width, }; diff --git a/client/src/components/production-list-table/production-list-table.component.jsx b/client/src/components/production-list-table/production-list-table.component.jsx index c99f662d4..7c2e24038 100644 --- a/client/src/components/production-list-table/production-list-table.component.jsx +++ b/client/src/components/production-list-table/production-list-table.component.jsx @@ -28,13 +28,12 @@ export function ProductionListTable({loading, data, refetch, bodyshop, technicia const [searchText, setSearchText] = useState(""); - const {treatments: {Production_List_Status_Colors}} = useSplitTreatments({ + const {treatments: {Production_List_Status_Colors, Enhanced_Payroll}} = useSplitTreatments({ attributes: {}, - names: ["Production_List_Status_Colors"], + names: ["Production_List_Status_Colors","Enhanced_Payroll"], splitKey: bodyshop.imexshopid, }); - const assoc = bodyshop.associations.find( (a) => a.useremail === currentUser.email ); @@ -69,6 +68,7 @@ export function ProductionListTable({loading, data, refetch, bodyshop, technicia state, data, activeStatuses: bodyshop.md_ro_statuses.active_statuses, + treatments: {Production_List_Status_Colors, Enhanced_Payroll} }).find((e) => e.key === k.key), width: k.width ?? 100, }; @@ -88,7 +88,8 @@ export function ProductionListTable({loading, data, refetch, bodyshop, technicia refetch, state, data: data, - activeStatuses: bodyshop.md_ro_statuses.active_statuses, + activeStatuses: bodyshop.md_ro_statuses.active_statuses, + treatments: {Production_List_Status_Colors, Enhanced_Payroll} }).find((e) => e.key === k.key), width: k.width ?? 100, }; From 2ea3a10c8bf8b89a5d69825e90334c9b53841258 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Tue, 19 Mar 2024 09:42:07 -0700 Subject: [PATCH 10/41] IO-2696 Incorrect job totals showing per instance. --- .../job-totals.table.totals.component.jsx | 227 ++++++++++-------- client/src/translations/en_us/common.json | 4 +- 2 files changed, 127 insertions(+), 104 deletions(-) diff --git a/client/src/components/job-totals-table/job-totals.table.totals.component.jsx b/client/src/components/job-totals-table/job-totals.table.totals.component.jsx index 415df9695..c38b5c642 100644 --- a/client/src/components/job-totals-table/job-totals.table.totals.component.jsx +++ b/client/src/components/job-totals-table/job-totals.table.totals.component.jsx @@ -6,6 +6,7 @@ import {useTranslation} from "react-i18next"; import {connect} from "react-redux"; import {createStructuredSelector} from "reselect"; import {selectBodyshop} from "../../redux/user/user.selectors"; +import InstanceRenderManager from '../../utils/instanceRenderMgr'; const mapStateToProps = createStructuredSelector({ //currentUser: selectCurrentUser @@ -29,108 +30,130 @@ export function JobTotalsTableTotals({bodyshop, job}) { total: job.job_totals.totals.subtotal, bold: true, }, - - ...(job.job_totals.totals.us_sales_tax_breakdown - ? [ - { - key: `${ - bodyshop.md_responsibility_centers.taxes.tax_ty1?.tax_type1 || - "T1" - } - ${[ - job.cieca_pft.ty1_rate1, - job.cieca_pft.ty1_rate2, - job.cieca_pft.ty1_rate3, - job.cieca_pft.ty1_rate4, - job.cieca_pft.ty1_rate5, - ] - .filter((i) => i > 0) - .join(", ")}%`, - total: job.job_totals.totals.us_sales_tax_breakdown.ty1Tax, - }, - { - key: `${ - bodyshop.md_responsibility_centers.taxes.tax_ty2?.tax_type2 || - "T2" - } - ${[ - job.cieca_pft.ty2_rate1, - job.cieca_pft.ty2_rate2, - job.cieca_pft.ty2_rate3, - job.cieca_pft.ty2_rate4, - job.cieca_pft.ty2_rate5, - ] - .filter((i) => i > 0) - .join(", ")}%`, - total: job.job_totals.totals.us_sales_tax_breakdown.ty2Tax, - }, - { - key: `${ - bodyshop.md_responsibility_centers.taxes.tax_ty3?.tax_type3 || - "T3" - } - ${[ - job.cieca_pft.ty3_rate1, - job.cieca_pft.ty3_rate2, - job.cieca_pft.ty3_rate3, - job.cieca_pft.ty3_rate4, - job.cieca_pft.ty3_rate5, - ] - .filter((i) => i > 0) - .join(", ")}%`, - total: job.job_totals.totals.us_sales_tax_breakdown.ty3Tax, - }, - { - key: `${ - bodyshop.md_responsibility_centers.taxes.tax_ty4?.tax_type4 || - "T4" - } - ${[ - job.cieca_pft.ty4_rate1, - job.cieca_pft.ty4_rate2, - job.cieca_pft.ty4_rate3, - job.cieca_pft.ty4_rate4, - job.cieca_pft.ty4_rate5, - ] - .filter((i) => i > 0) - .join(", ")}%`, - total: job.job_totals.totals.us_sales_tax_breakdown.ty4Tax, - }, - { - key: `${ - bodyshop.md_responsibility_centers.taxes.tax_ty5?.tax_type5 || - "TT" - } - ${[ - job.cieca_pft.ty5_rate1, - job.cieca_pft.ty5_rate2, - job.cieca_pft.ty5_rate3, - job.cieca_pft.ty5_rate4, - job.cieca_pft.ty5_rate5, - ] - .filter((i) => i > 0) - .join(", ")}%`, - total: job.job_totals.totals.us_sales_tax_breakdown.ty5Tax, - }, - { - key: t("jobs.labels.total_sales_tax"), - bold: true, - total: Dinero(job.job_totals.totals.us_sales_tax_breakdown.ty1Tax) - .add( - Dinero(job.job_totals.totals.us_sales_tax_breakdown.ty2Tax) - ) - .add( - Dinero(job.job_totals.totals.us_sales_tax_breakdown.ty3Tax) - ) - .add( - Dinero(job.job_totals.totals.us_sales_tax_breakdown.ty4Tax) - ) - .add( - Dinero(job.job_totals.totals.us_sales_tax_breakdown.ty5Tax) - ).toJSON(), - }, - ].filter((item) => item.total.amount !== 0) - : [ - { - key: t("jobs.labels.state_tax_amt"), - total: job.job_totals.totals.state_tax, - }, - ]), +...InstanceRenderManager({imex: [ { + key: t("jobs.labels.local_tax_amt"), + total: job.job_totals.totals.local_tax, +}, +{ + key: t("jobs.labels.state_tax_amt"), + total: job.job_totals.totals.state_tax, +}, +...(bodyshop.region_config === "CA_BC" + ? [ + { + key: t("jobs.fields.ca_bc_pvrt"), + total: job.job_totals.additional.pvrt, + }, + ] + : []), +{ + key: t("jobs.labels.federal_tax_amt"), + total: job.job_totals.totals.federal_tax, +},], + promanager: "USE_ROME", +rome: [(job.job_totals.totals.us_sales_tax_breakdown + ? [ + { + key: `${ + bodyshop.md_responsibility_centers.taxes.tax_ty1?.tax_type1 || + "T1" + } - ${[ + job.cieca_pft.ty1_rate1, + job.cieca_pft.ty1_rate2, + job.cieca_pft.ty1_rate3, + job.cieca_pft.ty1_rate4, + job.cieca_pft.ty1_rate5, + ] + .filter((i) => i > 0) + .join(", ")}%`, + total: job.job_totals.totals.us_sales_tax_breakdown.ty1Tax, + }, + { + key: `${ + bodyshop.md_responsibility_centers.taxes.tax_ty2?.tax_type2 || + "T2" + } - ${[ + job.cieca_pft.ty2_rate1, + job.cieca_pft.ty2_rate2, + job.cieca_pft.ty2_rate3, + job.cieca_pft.ty2_rate4, + job.cieca_pft.ty2_rate5, + ] + .filter((i) => i > 0) + .join(", ")}%`, + total: job.job_totals.totals.us_sales_tax_breakdown.ty2Tax, + }, + { + key: `${ + bodyshop.md_responsibility_centers.taxes.tax_ty3?.tax_type3 || + "T3" + } - ${[ + job.cieca_pft.ty3_rate1, + job.cieca_pft.ty3_rate2, + job.cieca_pft.ty3_rate3, + job.cieca_pft.ty3_rate4, + job.cieca_pft.ty3_rate5, + ] + .filter((i) => i > 0) + .join(", ")}%`, + total: job.job_totals.totals.us_sales_tax_breakdown.ty3Tax, + }, + { + key: `${ + bodyshop.md_responsibility_centers.taxes.tax_ty4?.tax_type4 || + "T4" + } - ${[ + job.cieca_pft.ty4_rate1, + job.cieca_pft.ty4_rate2, + job.cieca_pft.ty4_rate3, + job.cieca_pft.ty4_rate4, + job.cieca_pft.ty4_rate5, + ] + .filter((i) => i > 0) + .join(", ")}%`, + total: job.job_totals.totals.us_sales_tax_breakdown.ty4Tax, + }, + { + key: `${ + bodyshop.md_responsibility_centers.taxes.tax_ty5?.tax_type5 || + "TT" + } - ${[ + job.cieca_pft.ty5_rate1, + job.cieca_pft.ty5_rate2, + job.cieca_pft.ty5_rate3, + job.cieca_pft.ty5_rate4, + job.cieca_pft.ty5_rate5, + ] + .filter((i) => i > 0) + .join(", ")}%`, + total: job.job_totals.totals.us_sales_tax_breakdown.ty5Tax, + }, + { + key: t("jobs.labels.total_sales_tax"), + bold: true, + total: Dinero(job.job_totals.totals.us_sales_tax_breakdown.ty1Tax) + .add( + Dinero(job.job_totals.totals.us_sales_tax_breakdown.ty2Tax) + ) + .add( + Dinero(job.job_totals.totals.us_sales_tax_breakdown.ty3Tax) + ) + .add( + Dinero(job.job_totals.totals.us_sales_tax_breakdown.ty4Tax) + ) + .add( + Dinero(job.job_totals.totals.us_sales_tax_breakdown.ty5Tax) + ).toJSON(), + }, + ].filter((item) => item.total.amount !== 0) + : [ + { + key: t("jobs.labels.state_tax_amt"), + total: job.job_totals.totals.state_tax, + }, + ])] +}), + { key: t("jobs.labels.total_repairs"), diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json index 334fdbc42..2e240846c 100644 --- a/client/src/translations/en_us/common.json +++ b/client/src/translations/en_us/common.json @@ -749,7 +749,7 @@ "refuelcharge": "Refuel Charge (per liter/gallon)", "scheduledreturn": "Scheduled Return", "start": "Contract Start", - "statetax": "State Taxes", + "statetax": "Provincial/State Taxes", "status": "Status" }, "labels": { @@ -2001,7 +2001,7 @@ "savebeforeconversion": "You have unsaved changes on the Job. Please save them before converting it. ", "scheduledinchange": "The scheduled in is based off the latest appointment. To change this date, please schedule or reschedule the Job. ", "specialcoveragepolicy": "Special Coverage Policy Applies", - "state_tax_amt": "State Taxes", + "state_tax_amt": "Provincial/State Taxes", "subletstotal": "Sublets Total", "subtotal": "Subtotal", "supplementnote": "The Job had a supplement imported.", From 01a9e7dc34950ec8fc3943e3b84d23b129f0f81f Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Tue, 19 Mar 2024 09:48:30 -0700 Subject: [PATCH 11/41] IO-2700 Remove committed button for non-enhanced payroll on time ticket list. --- .../time-tickets/time-tickets.container.jsx | 191 +++++++++--------- 1 file changed, 99 insertions(+), 92 deletions(-) diff --git a/client/src/pages/time-tickets/time-tickets.container.jsx b/client/src/pages/time-tickets/time-tickets.container.jsx index 0c1bc69c4..6c41a2657 100644 --- a/client/src/pages/time-tickets/time-tickets.container.jsx +++ b/client/src/pages/time-tickets/time-tickets.container.jsx @@ -1,103 +1,110 @@ -import {useQuery} from "@apollo/client"; -import {Col, Row, Space} from "antd"; -import dayjs from "../../utils/day"; -import React, {useEffect} from "react"; -import {useTranslation} from "react-i18next"; -import {connect} from "react-redux"; -import {useSearchParams} from "react-router-dom"; -import {createStructuredSelector} from "reselect"; -import AlertComponent from "../../components/alert/alert.component"; -import RbacWrapper from "../../components/rbac-wrapper/rbac-wrapper.component"; -import TimeTicketsDatesSelector - from "../../components/ticket-tickets-dates-selector/time-tickets-dates-selector.component"; -import TimeTicketList from "../../components/time-ticket-list/time-ticket-list.component"; -import TimeTicketsPayrollTable from "../../components/time-tickets-payroll-table/time-tickets-payroll-table.component"; -import TimeTicketsSummaryEmployees - from "../../components/time-tickets-summary-employees/time-tickets-summary-employees.component"; -import {QUERY_TIME_TICKETS_IN_RANGE} from "../../graphql/timetickets.queries"; -import TimeTicketsAttendanceTable - from "../../components/time-tickets-attendance-table/time-tickets-attendance-table.component"; -import {setBreadcrumbs, setSelectedHeader,} from "../../redux/application/application.actions"; -import TimeTicketsCommit from "../../components/time-tickets-commit/time-tickets-commit.component"; -import FeatureWrapperComponent from "../../components/feature-wrapper/feature-wrapper.component"; +import { useQuery } from '@apollo/client'; +import { Col, Row, Space } from 'antd'; +import dayjs from '../../utils/day'; +import React, { useEffect } from 'react'; +import { useTranslation } from 'react-i18next'; +import { connect } from 'react-redux'; +import { useSearchParams } from 'react-router-dom'; +import { createStructuredSelector } from 'reselect'; +import AlertComponent from '../../components/alert/alert.component'; +import RbacWrapper from '../../components/rbac-wrapper/rbac-wrapper.component'; +import TimeTicketsDatesSelector from '../../components/ticket-tickets-dates-selector/time-tickets-dates-selector.component'; +import TimeTicketList from '../../components/time-ticket-list/time-ticket-list.component'; +import TimeTicketsPayrollTable from '../../components/time-tickets-payroll-table/time-tickets-payroll-table.component'; +import TimeTicketsSummaryEmployees from '../../components/time-tickets-summary-employees/time-tickets-summary-employees.component'; +import { QUERY_TIME_TICKETS_IN_RANGE } from '../../graphql/timetickets.queries'; +import TimeTicketsAttendanceTable from '../../components/time-tickets-attendance-table/time-tickets-attendance-table.component'; +import { setBreadcrumbs, setSelectedHeader } from '../../redux/application/application.actions'; +import TimeTicketsCommit from '../../components/time-tickets-commit/time-tickets-commit.component'; +import FeatureWrapperComponent from '../../components/feature-wrapper/feature-wrapper.component'; import InstanceRenderManager from '../../utils/instanceRenderMgr'; +import { useSplitTreatments } from '@splitsoftware/splitio-react'; +import { selectBodyshop } from '../../redux/user/user.selectors'; -const mapStateToProps = createStructuredSelector({}); - -const mapDispatchToProps = (dispatch) => ({ - setBreadcrumbs: (breadcrumbs) => dispatch(setBreadcrumbs(breadcrumbs)), - setSelectedHeader: (key) => dispatch(setSelectedHeader(key)), +const mapStateToProps = createStructuredSelector({ + bodyshop:selectBodyshop }); -export function TimeTicketsContainer({ - bodyshop, - setBreadcrumbs, - setSelectedHeader, - }) { - const {t} = useTranslation(); - const [searchParams] = useSearchParams(); - const {start, end} = Object.fromEntries(searchParams); +const mapDispatchToProps = (dispatch) => ({ + setBreadcrumbs: (breadcrumbs) => dispatch(setBreadcrumbs(breadcrumbs)), + setSelectedHeader: (key) => dispatch(setSelectedHeader(key)), +}); - const startDate = start - ? dayjs(start) - : dayjs().startOf("week").subtract(7, "day"); - const endDate = end ? dayjs(end) : dayjs().endOf("week"); +export function TimeTicketsContainer({ bodyshop, setBreadcrumbs, setSelectedHeader }) { + const { + treatments: { Enhanced_Payroll }, + } = useSplitTreatments({ + attributes: {}, + names: ['Enhanced_Payroll'], + splitKey: bodyshop.imexshopid, + }); + const { t } = useTranslation(); + const [searchParams] = useSearchParams(); + const { start, end } = Object.fromEntries(searchParams); - const {loading, error, data} = useQuery(QUERY_TIME_TICKETS_IN_RANGE, { - variables: { - start: startDate, - end: endDate, - }, - fetchPolicy: "network-only", - nextFetchPolicy: "network-only", + const startDate = start ? dayjs(start) : dayjs().startOf('week').subtract(7, 'day'); + const endDate = end ? dayjs(end) : dayjs().endOf('week'); + + const { loading, error, data } = useQuery(QUERY_TIME_TICKETS_IN_RANGE, { + variables: { + start: startDate, + end: endDate, + }, + fetchPolicy: 'network-only', + nextFetchPolicy: 'network-only', + }); + + useEffect(() => { + document.title = t('titles.timetickets', { + app: InstanceRenderManager({ + imex: '$t(titles.imexonline)', + rome: '$t(titles.romeonline)', + promanager: '$t(titles.promanager)', + }), }); + setSelectedHeader('timetickets'); + setBreadcrumbs([ + { + link: '/manage/timetickets', + label: t('titles.bc.timetickets'), + }, + ]); + }, [t, setBreadcrumbs, setSelectedHeader]); - useEffect(() => { - document.title = t("titles.timetickets",{app: InstanceRenderManager({imex:'$t(titles.imexonline)', rome: '$t(titles.romeonline)', promanager: '$t(titles.promanager)'})} ); - setSelectedHeader("timetickets"); - setBreadcrumbs([ - { - link: "/manage/timetickets", - label: t("titles.bc.timetickets"), - }, - ]); - }, [t, setBreadcrumbs, setSelectedHeader]); + if (error) return ; - if (error) return ; - - return ( - - - - - - - - - - - } - /> - - - - - - - - ); + return ( + + + + + + + + {Enhanced_Payroll.treatment === 'on' && ( + + )} + + + } + /> + + + + + + + + ); } -export default connect( - mapStateToProps, - mapDispatchToProps -)(TimeTicketsContainer); +export default connect(mapStateToProps, mapDispatchToProps)(TimeTicketsContainer); From cdd5b264437d98f0798b1e5a63c06d2c0d9be6b5 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Tue, 19 Mar 2024 10:16:42 -0700 Subject: [PATCH 12/41] IO-2703 Resolve incorrect Feature wrapper use. --- .../feature-wrapper.component.jsx | 36 ++++++++++--------- .../job-detail-lines/job-lines.component.jsx | 2 +- .../report-center-modal.component.jsx | 7 ++-- .../shop-info/shop-info.component.jsx | 1 - client/src/pages/shop/shop.page.component.jsx | 2 +- 5 files changed, 25 insertions(+), 23 deletions(-) diff --git a/client/src/components/feature-wrapper/feature-wrapper.component.jsx b/client/src/components/feature-wrapper/feature-wrapper.component.jsx index 042b6c92c..7a3ca5b47 100644 --- a/client/src/components/feature-wrapper/feature-wrapper.component.jsx +++ b/client/src/components/feature-wrapper/feature-wrapper.component.jsx @@ -1,23 +1,17 @@ -import dayjs from "../../utils/day"; -import React from "react"; -import { useTranslation } from "react-i18next"; -import { connect } from "react-redux"; -import { createStructuredSelector } from "reselect"; -import { selectBodyshop } from "../../redux/user/user.selectors"; -import AlertComponent from "../alert/alert.component"; +import dayjs from '../../utils/day'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { connect } from 'react-redux'; +import { createStructuredSelector } from 'reselect'; +import { selectBodyshop } from '../../redux/user/user.selectors'; +import AlertComponent from '../alert/alert.component'; import InstanceRenderManager from '../../utils/instanceRenderMgr'; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, }); -function FeatureWrapper({ - bodyshop, - featureName, - noauth, - children, - ...restProps -}) { +function FeatureWrapper({ bodyshop, featureName, noauth, children, ...restProps }) { const { t } = useTranslation(); if (HasFeatureAccess({ featureName, bodyshop })) return children; @@ -25,7 +19,13 @@ function FeatureWrapper({ return ( noauth || ( ) @@ -33,10 +33,12 @@ function FeatureWrapper({ } export function HasFeatureAccess({ featureName, bodyshop }) { - return ( - bodyshop?.features.allAccess || + console.log( + 'Feature Name', featureName, + bodyshop?.features.allAccess, dayjs(bodyshop?.features[featureName]).isAfter(dayjs()) ); + return bodyshop?.features.allAccess || dayjs(bodyshop?.features[featureName]).isAfter(dayjs()); } export default connect(mapStateToProps, null)(FeatureWrapper); diff --git a/client/src/components/job-detail-lines/job-lines.component.jsx b/client/src/components/job-detail-lines/job-lines.component.jsx index f8f3198d5..492fa57df 100644 --- a/client/src/components/job-detail-lines/job-lines.component.jsx +++ b/client/src/components/job-detail-lines/job-lines.component.jsx @@ -290,7 +290,7 @@ export function JobLinesComponent({ key: 'location', render: (text, record) => , }, - ...(HasFeatureAccess({ featureName: 'bills' }) + ...(HasFeatureAccess({ featureName: 'bills', bodyshop }) ? [ { title: t('joblines.labels.billref'), diff --git a/client/src/components/report-center-modal/report-center-modal.component.jsx b/client/src/components/report-center-modal/report-center-modal.component.jsx index 6130a5e62..5830c1c04 100644 --- a/client/src/components/report-center-modal/report-center-modal.component.jsx +++ b/client/src/components/report-center-modal/report-center-modal.component.jsx @@ -141,9 +141,10 @@ export function ReportCenterModalComponent({reportCenterModal, bodyshop}) { const grouped = _.groupBy(FilteredReportsList, "group"); - const groupExcludeKeyFilter = [...!HasFeatureAccess({featureName: 'bills'})? ["purchases"]:[], - ...!HasFeatureAccess({featureName: 'timetickets'})? ["payroll"]:[], - ] + const groupExcludeKeyFilter = [ + ...(!HasFeatureAccess({ featureName: 'bills', bodyshop }) ? ['purchases'] : []), + ...(!HasFeatureAccess({ featureName: 'timetickets', bodyshop }) ? ['payroll'] : []), + ]; return (
diff --git a/client/src/components/shop-info/shop-info.component.jsx b/client/src/components/shop-info/shop-info.component.jsx index 304ae029e..ae116411b 100644 --- a/client/src/components/shop-info/shop-info.component.jsx +++ b/client/src/components/shop-info/shop-info.component.jsx @@ -18,7 +18,6 @@ import ShopInfoSpeedPrint from "./shop-info.speedprint.component"; import {useLocation, useNavigate} from "react-router-dom"; import ShopInfoTaskPresets from "./shop-info.task-presets.component"; import queryString from "query-string"; -import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component"; import InstanceRenderManager from "../../utils/instanceRenderMgr"; const mapStateToProps = createStructuredSelector({ diff --git a/client/src/pages/shop/shop.page.component.jsx b/client/src/pages/shop/shop.page.component.jsx index a4b0a7503..13efc59fc 100644 --- a/client/src/pages/shop/shop.page.component.jsx +++ b/client/src/pages/shop/shop.page.component.jsx @@ -72,7 +72,7 @@ export function ShopPage({bodyshop, setSelectedHeader, setBreadcrumbs}) { }, ); - if(HasFeatureAccess("csi")){ + if(HasFeatureAccess({featureName:"csi", bodyshop})){ items.push({ key: "csiq", label: t("bodyshop.labels.csiq"), From 8cb18d6d1d9d670d96cfd4afa281adc37fd072a3 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Tue, 19 Mar 2024 10:42:07 -0700 Subject: [PATCH 13/41] IO-2701 resolve missing dashboard translation. --- bodyshop_translations.babel | 21 +++++++++++++++++++++ client/src/translations/en_us/common.json | 1 + client/src/translations/es/common.json | 1 + client/src/translations/fr/common.json | 1 + 4 files changed, 24 insertions(+) diff --git a/bodyshop_translations.babel b/bodyshop_translations.babel index bac95454e..16033ffdb 100644 --- a/bodyshop_translations.babel +++ b/bodyshop_translations.babel @@ -14791,6 +14791,27 @@ titles + + joblifecycle + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + labhours false diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json index 2e240846c..7e61fc11e 100644 --- a/client/src/translations/en_us/common.json +++ b/client/src/translations/en_us/common.json @@ -899,6 +899,7 @@ "refhrs": "Refinish Hrs" }, "titles": { + "joblifecycle": "Job Life Cycles", "labhours": "Total Body Hours", "larhours": "Total Refinish Hours", "monthlyemployeeefficiency": "Monthly Employee Efficiency", diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json index 3bdda9711..7c4416b16 100644 --- a/client/src/translations/es/common.json +++ b/client/src/translations/es/common.json @@ -899,6 +899,7 @@ "refhrs": "" }, "titles": { + "joblifecycle": "", "labhours": "", "larhours": "", "monthlyemployeeefficiency": "", diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json index 8f180d52a..c219fbd89 100644 --- a/client/src/translations/fr/common.json +++ b/client/src/translations/fr/common.json @@ -899,6 +899,7 @@ "refhrs": "" }, "titles": { + "joblifecycle": "", "labhours": "", "larhours": "", "monthlyemployeeefficiency": "", From 8460a99085864a8af66583c6e9daff935e3afce8 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Tue, 19 Mar 2024 10:54:25 -0700 Subject: [PATCH 14/41] IO-2704 QBO/D Export resolution --- .../components/feature-wrapper/feature-wrapper.component.jsx | 5 ----- server/accounting/qb-receivables-lines.js | 4 ++-- server/accounting/qbxml/qbxml-receivables.js | 2 +- server/cdk/cdk-calculate-allocations.js | 2 +- 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/client/src/components/feature-wrapper/feature-wrapper.component.jsx b/client/src/components/feature-wrapper/feature-wrapper.component.jsx index 7a3ca5b47..f249bfa37 100644 --- a/client/src/components/feature-wrapper/feature-wrapper.component.jsx +++ b/client/src/components/feature-wrapper/feature-wrapper.component.jsx @@ -33,11 +33,6 @@ function FeatureWrapper({ bodyshop, featureName, noauth, children, ...restProps } export function HasFeatureAccess({ featureName, bodyshop }) { - console.log( - 'Feature Name', featureName, - bodyshop?.features.allAccess, - dayjs(bodyshop?.features[featureName]).isAfter(dayjs()) - ); return bodyshop?.features.allAccess || dayjs(bodyshop?.features[featureName]).isAfter(dayjs()); } diff --git a/server/accounting/qb-receivables-lines.js b/server/accounting/qb-receivables-lines.js index 6f20fafa8..1a6c5f339 100644 --- a/server/accounting/qb-receivables-lines.js +++ b/server/accounting/qb-receivables-lines.js @@ -605,9 +605,9 @@ exports.default = function ({ const state_tax = Dinero(job_totals.totals.state_tax); const local_tax = Dinero(job_totals.totals.local_tax); - const RulesetToUse = InstanceManager({imex:"CANADA",rome: "US"}) + const RulesetToUse = InstanceManager({ imex: 'CANADA', rome: 'US', promanager: 'US' }); - if(RulesetToUse = "CANADA"){ + if(RulesetToUse === "CANADA"){ if (federal_tax.getAmount() > 0) { if (qbo) { // do qbo diff --git a/server/accounting/qbxml/qbxml-receivables.js b/server/accounting/qbxml/qbxml-receivables.js index 758449e25..f0322b0a3 100644 --- a/server/accounting/qbxml/qbxml-receivables.js +++ b/server/accounting/qbxml/qbxml-receivables.js @@ -7,7 +7,7 @@ const builder = require("xmlbuilder2"); const QbXmlUtils = require("./qbxml-utils"); const CreateInvoiceLines = require("../qb-receivables-lines").default; const logger = require('../../utils/logger'); -const InstanceManager = require('../../utils/instanceMgr'); +const InstanceManager = require('../../utils/instanceMgr').default; require("dotenv").config({ path: path.resolve( diff --git a/server/cdk/cdk-calculate-allocations.js b/server/cdk/cdk-calculate-allocations.js index 119c535e3..a1564ab69 100644 --- a/server/cdk/cdk-calculate-allocations.js +++ b/server/cdk/cdk-calculate-allocations.js @@ -13,7 +13,7 @@ const CdkBase = require("../web-sockets/web-socket"); const Dinero = require("dinero.js"); const _ = require("lodash"); const {DiscountNotAlreadyCounted} = require("../job/job-totals"); -const InstanceManager = require('../utils/instanceMgr'); +const InstanceManager = require('../utils/instanceMgr').default; exports.default = async function (socket, jobid) { try { From a4297568230e823f6f71c1e7e35d2e85810026c0 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Tue, 19 Mar 2024 11:33:50 -0700 Subject: [PATCH 15/41] IO-2706 Missing translation --- bodyshop_translations.babel | 2 +- client/src/translations/en_us/common.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bodyshop_translations.babel b/bodyshop_translations.babel index 16033ffdb..6b24dfd21 100644 --- a/bodyshop_translations.babel +++ b/bodyshop_translations.babel @@ -1,4 +1,4 @@ - +