From 842cb548674ff6521e7712925e1f15702773da21 Mon Sep 17 00:00:00 2001
From: Patrick Fic <>
Date: Thu, 27 May 2021 13:15:58 -0700
Subject: [PATCH 06/10] IO-1153 Phonebook Validation
---
bodyshop_translations.babel | 42 +++++++++++++++++++
.../phonebook-form.component.jsx | 26 +++++++++++-
client/src/translations/en_us/common.json | 2 +
client/src/translations/es/common.json | 2 +
client/src/translations/fr/common.json | 2 +
5 files changed, 73 insertions(+), 1 deletion(-)
diff --git a/bodyshop_translations.babel b/bodyshop_translations.babel
index a4c57daea..36244a534 100644
--- a/bodyshop_translations.babel
+++ b/bodyshop_translations.babel
@@ -27901,6 +27901,48 @@
labels
+
+ noneselected
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+ onenamerequired
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
vendorcategory
false
diff --git a/client/src/components/phonebook-form/phonebook-form.component.jsx b/client/src/components/phonebook-form/phonebook-form.component.jsx
index e962a34c6..e40096ce9 100644
--- a/client/src/components/phonebook-form/phonebook-form.component.jsx
+++ b/client/src/components/phonebook-form/phonebook-form.component.jsx
@@ -82,7 +82,31 @@ export function PhonebookFormComponent({
-
+ ({
+ validator(rule, value) {
+ const { firstname, lastname, company } = getFieldsValue([
+ "firstname",
+ "lastname",
+ "company",
+ ]);
+
+ if (
+ (firstname && firstname.trim() !== "") ||
+ (lastname && lastname.trim() !== "") ||
+ (company && company.trim() !== "")
+ ) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("phonebook.labels.onenamerequired"));
+ },
+ }),
+ ]}
+ >
diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json
index 4dc554b3a..b978a4ac3 100644
--- a/client/src/translations/en_us/common.json
+++ b/client/src/translations/en_us/common.json
@@ -1666,6 +1666,8 @@
"state": "Province/State"
},
"labels": {
+ "noneselected": "No phone book entry selected. ",
+ "onenamerequired": "At least one name related field is required.",
"vendorcategory": "Vendor"
},
"successes": {
diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json
index 0e50e4a16..9ebe3517d 100644
--- a/client/src/translations/es/common.json
+++ b/client/src/translations/es/common.json
@@ -1666,6 +1666,8 @@
"state": ""
},
"labels": {
+ "noneselected": "",
+ "onenamerequired": "",
"vendorcategory": ""
},
"successes": {
diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json
index 4529a34e9..05d7f3ccf 100644
--- a/client/src/translations/fr/common.json
+++ b/client/src/translations/fr/common.json
@@ -1666,6 +1666,8 @@
"state": ""
},
"labels": {
+ "noneselected": "",
+ "onenamerequired": "",
"vendorcategory": ""
},
"successes": {
From 0b21b8d97609875a41fda10bb5ffb88dd97d86fe Mon Sep 17 00:00:00 2001
From: Patrick Fic <>
Date: Thu, 27 May 2021 13:32:57 -0700
Subject: [PATCH 07/10] IO-1138 Offline detection.
---
bodyshop_translations.babel | 42 +++++++++++++++++++
client/src/App/App.container.jsx | 1 +
client/src/App/App.jsx | 35 +++++++++++++++-
.../redux/application/application.actions.js | 5 +++
.../redux/application/application.reducer.js | 6 +++
.../application/application.selectors.js | 4 ++
.../redux/application/application.types.js | 1 +
client/src/translations/en_us/common.json | 2 +
client/src/translations/es/common.json | 2 +
client/src/translations/fr/common.json | 2 +
10 files changed, 99 insertions(+), 1 deletion(-)
diff --git a/bodyshop_translations.babel b/bodyshop_translations.babel
index 36244a534..1f7b2a5c9 100644
--- a/bodyshop_translations.babel
+++ b/bodyshop_translations.babel
@@ -12968,6 +12968,48 @@
+
+ nointernet
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+ nointernet_sub
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
none
false
diff --git a/client/src/App/App.container.jsx b/client/src/App/App.container.jsx
index c8e619c05..1f5298da2 100644
--- a/client/src/App/App.container.jsx
+++ b/client/src/App/App.container.jsx
@@ -14,6 +14,7 @@ if (process.env.NODE_ENV === "production") LogRocket.init("gvfvfw/bodyshopapp");
export default function AppContainer() {
const { t } = useTranslation();
+
return (
const mapStateToProps = createStructuredSelector({
currentUser: selectCurrentUser,
+ online: selectOnline,
});
const mapDispatchToProps = (dispatch) => ({
checkUserSession: () => dispatch(checkUserSession()),
+ setOnline: (isOnline) => dispatch(setOnline(isOnline)),
});
-export function App({ checkUserSession, currentUser }) {
+export function App({ checkUserSession, currentUser, online, setOnline }) {
useEffect(() => {
checkUserSession();
}, [checkUserSession]);
@@ -42,10 +47,38 @@ export function App({ checkUserSession, currentUser }) {
const { t } = useTranslation();
+ window.addEventListener("offline", function (e) {
+ console.log("Internet connection lost.");
+ setOnline(false);
+ });
+
+ window.addEventListener("online", function (e) {
+ setOnline(true);
+ });
+
if (currentUser.authorized === null) {
return ;
}
+ if (!online)
+ return (
+ {
+ window.location.reload();
+ }}
+ >
+ {t("general.actions.refresh")}
+
+ }
+ />
+ );
+
return (
}>
diff --git a/client/src/redux/application/application.actions.js b/client/src/redux/application/application.actions.js
index cffcaa4fc..3f3fb4012 100644
--- a/client/src/redux/application/application.actions.js
+++ b/client/src/redux/application/application.actions.js
@@ -48,3 +48,8 @@ export const setPartnerVersion = (version) => ({
type: ApplicationActionTypes.SET_PARTNER_VERSION,
payload: version,
});
+
+export const setOnline = (isOnline) => ({
+ type: ApplicationActionTypes.SET_ONLINE_STATUS,
+ payload: isOnline,
+});
diff --git a/client/src/redux/application/application.reducer.js b/client/src/redux/application/application.reducer.js
index 40fece7d7..60685e2cc 100644
--- a/client/src/redux/application/application.reducer.js
+++ b/client/src/redux/application/application.reducer.js
@@ -2,6 +2,7 @@ import ApplicationActionTypes from "./application.types";
const INITIAL_STATE = {
loading: false,
+ online: true,
breadcrumbs: [],
recentItems: [],
selectedHeader: "home",
@@ -21,6 +22,11 @@ const applicationReducer = (state = INITIAL_STATE, action) => {
...state,
selectedHeader: action.payload,
};
+ case ApplicationActionTypes.SET_ONLINE_STATUS:
+ return {
+ ...state,
+ online: action.payload,
+ };
case ApplicationActionTypes.ADD_RECENT_ITEM:
return {
...state,
diff --git a/client/src/redux/application/application.selectors.js b/client/src/redux/application/application.selectors.js
index 2dba7b8ea..5c48a17d1 100644
--- a/client/src/redux/application/application.selectors.js
+++ b/client/src/redux/application/application.selectors.js
@@ -40,3 +40,7 @@ export const selectJobReadOnly = createSelector(
[selectApplication],
(application) => application.jobReadOnly
);
+export const selectOnline = createSelector(
+ [selectApplication],
+ (application) => application.online
+);
diff --git a/client/src/redux/application/application.types.js b/client/src/redux/application/application.types.js
index 2de24c05d..8714692cb 100644
--- a/client/src/redux/application/application.types.js
+++ b/client/src/redux/application/application.types.js
@@ -9,5 +9,6 @@ const ApplicationActionTypes = {
SET_SELECTED_HEADER: "SET_SELECTED_HEADER",
SET_JOB_READONLY: "SET_JOB_READONLY",
SET_PARTNER_VERSION: "SET_PARTNER_VERSION",
+ SET_ONLINE_STATUS: "SET_ONLINE_STATUS",
};
export default ApplicationActionTypes;
diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json
index b978a4ac3..9dfef4704 100644
--- a/client/src/translations/en_us/common.json
+++ b/client/src/translations/en_us/common.json
@@ -821,6 +821,8 @@
"monday": "Monday",
"na": "N/A",
"no": "No",
+ "nointernet": "It looks like you're not connected to the internet.",
+ "nointernet_sub": "Please check your connection and try again. ",
"none": "None",
"out": "Out",
"password": "Password",
diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json
index 9ebe3517d..5777c3745 100644
--- a/client/src/translations/es/common.json
+++ b/client/src/translations/es/common.json
@@ -821,6 +821,8 @@
"monday": "",
"na": "N / A",
"no": "",
+ "nointernet": "",
+ "nointernet_sub": "",
"none": "",
"out": "Afuera",
"password": "",
diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json
index 05d7f3ccf..1bf35e380 100644
--- a/client/src/translations/fr/common.json
+++ b/client/src/translations/fr/common.json
@@ -821,6 +821,8 @@
"monday": "",
"na": "N / A",
"no": "",
+ "nointernet": "",
+ "nointernet_sub": "",
"none": "",
"out": "En dehors",
"password": "",
From d91a83a13762aa364424ba6e75388cecf59e3671 Mon Sep 17 00:00:00 2001
From: Patrick Fic <>
Date: Thu, 27 May 2021 14:04:52 -0700
Subject: [PATCH 08/10] IO-1157 Add mapa/mash costs to costing.
---
bodyshop_translations.babel | 47 +++++++++++
.../shop-info/shop-info.general.component.jsx | 14 +++-
client/src/graphql/bodyshop.queries.js | 2 +
client/src/translations/en_us/common.json | 4 +
client/src/translations/es/common.json | 4 +
client/src/translations/fr/common.json | 4 +
.../down.yaml | 6 ++
.../up.yaml | 5 ++
.../down.yaml | 5 ++
.../up.yaml | 6 ++
.../down.yaml | 83 ++++++++++++++++++
.../up.yaml | 84 +++++++++++++++++++
.../down.yaml | 77 +++++++++++++++++
.../up.yaml | 78 +++++++++++++++++
hasura/migrations/metadata.yaml | 2 +
server/graphql-client/queries.js | 2 +
server/job/job-costing.js | 60 +++++++++++--
17 files changed, 474 insertions(+), 9 deletions(-)
create mode 100644 hasura/migrations/1622147830428_alter_table_public_bodyshops_alter_column_autohouseid/down.yaml
create mode 100644 hasura/migrations/1622147830428_alter_table_public_bodyshops_alter_column_autohouseid/up.yaml
create mode 100644 hasura/migrations/1622147892235_alter_table_public_bodyshops_add_column_jc_hourly_rates/down.yaml
create mode 100644 hasura/migrations/1622147892235_alter_table_public_bodyshops_add_column_jc_hourly_rates/up.yaml
create mode 100644 hasura/migrations/1622147902848_update_permission_user_public_table_bodyshops/down.yaml
create mode 100644 hasura/migrations/1622147902848_update_permission_user_public_table_bodyshops/up.yaml
create mode 100644 hasura/migrations/1622147914381_update_permission_user_public_table_bodyshops/down.yaml
create mode 100644 hasura/migrations/1622147914381_update_permission_user_public_table_bodyshops/up.yaml
diff --git a/bodyshop_translations.babel b/bodyshop_translations.babel
index 1f7b2a5c9..a6258dd82 100644
--- a/bodyshop_translations.babel
+++ b/bodyshop_translations.babel
@@ -3339,6 +3339,53 @@
+
+ jc_hourly_rates
+
+
+ mapa
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+ mash
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+
lastnumberworkingdays
false
diff --git a/client/src/components/shop-info/shop-info.general.component.jsx b/client/src/components/shop-info/shop-info.general.component.jsx
index 00c6225a6..74170bf3c 100644
--- a/client/src/components/shop-info/shop-info.general.component.jsx
+++ b/client/src/components/shop-info/shop-info.general.component.jsx
@@ -16,7 +16,7 @@ import PhoneFormItem, {
} 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 CurrencyInput from "../form-items-formatted/currency-form-item.component";
export default function ShopInfoGeneral({ form }) {
const { t } = useTranslation();
return (
@@ -425,6 +425,18 @@ export default function ShopInfoGeneral({ form }) {
>
+
+
+
+
+
+
diff --git a/client/src/graphql/bodyshop.queries.js b/client/src/graphql/bodyshop.queries.js
index 5f456e88a..5bbea1ef5 100644
--- a/client/src/graphql/bodyshop.queries.js
+++ b/client/src/graphql/bodyshop.queries.js
@@ -87,6 +87,7 @@ export const QUERY_BODYSHOP = gql`
md_ccc_rates
enforce_referral
website
+ jc_hourly_rates
employees {
id
active
@@ -171,6 +172,7 @@ export const UPDATE_SHOP = gql`
md_ccc_rates
enforce_referral
website
+ jc_hourly_rates
employees {
id
first_name
diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json
index 9dfef4704..7c5106e75 100644
--- a/client/src/translations/en_us/common.json
+++ b/client/src/translations/en_us/common.json
@@ -218,6 +218,10 @@
"invoice_federal_tax_rate": "Invoices - Federal Tax Rate",
"invoice_local_tax_rate": "Invoices - Local Tax Rate",
"invoice_state_tax_rate": "Invoices - Provincial/State Tax Rate",
+ "jc_hourly_rates": {
+ "mapa": "Job Costing - Paint Materials Hourly Cost Rate",
+ "mash": "Job Costing - Shop Materials Hourly Cost Rate"
+ },
"lastnumberworkingdays": "Scoreboard - Last Number of Working Days",
"logo_img_path": "Shop Logo",
"logo_img_path_height": "Logo Image Height",
diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json
index 5777c3745..d4b8d2c1e 100644
--- a/client/src/translations/es/common.json
+++ b/client/src/translations/es/common.json
@@ -218,6 +218,10 @@
"invoice_federal_tax_rate": "",
"invoice_local_tax_rate": "",
"invoice_state_tax_rate": "",
+ "jc_hourly_rates": {
+ "mapa": "",
+ "mash": ""
+ },
"lastnumberworkingdays": "",
"logo_img_path": "",
"logo_img_path_height": "",
diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json
index 1bf35e380..6f7f00692 100644
--- a/client/src/translations/fr/common.json
+++ b/client/src/translations/fr/common.json
@@ -218,6 +218,10 @@
"invoice_federal_tax_rate": "",
"invoice_local_tax_rate": "",
"invoice_state_tax_rate": "",
+ "jc_hourly_rates": {
+ "mapa": "",
+ "mash": ""
+ },
"lastnumberworkingdays": "",
"logo_img_path": "",
"logo_img_path_height": "",
diff --git a/hasura/migrations/1622147830428_alter_table_public_bodyshops_alter_column_autohouseid/down.yaml b/hasura/migrations/1622147830428_alter_table_public_bodyshops_alter_column_autohouseid/down.yaml
new file mode 100644
index 000000000..6393d9f29
--- /dev/null
+++ b/hasura/migrations/1622147830428_alter_table_public_bodyshops_alter_column_autohouseid/down.yaml
@@ -0,0 +1,6 @@
+- args:
+ cascade: false
+ read_only: false
+ sql: ALTER TABLE "public"."bodyshops" ADD CONSTRAINT "bodyshops_autohouseid_key"
+ UNIQUE ("autohouseid");
+ type: run_sql
diff --git a/hasura/migrations/1622147830428_alter_table_public_bodyshops_alter_column_autohouseid/up.yaml b/hasura/migrations/1622147830428_alter_table_public_bodyshops_alter_column_autohouseid/up.yaml
new file mode 100644
index 000000000..13be53f1d
--- /dev/null
+++ b/hasura/migrations/1622147830428_alter_table_public_bodyshops_alter_column_autohouseid/up.yaml
@@ -0,0 +1,5 @@
+- args:
+ cascade: false
+ read_only: false
+ sql: ALTER TABLE "public"."bodyshops" DROP CONSTRAINT "bodyshops_autohouseid_key";
+ type: run_sql
diff --git a/hasura/migrations/1622147892235_alter_table_public_bodyshops_add_column_jc_hourly_rates/down.yaml b/hasura/migrations/1622147892235_alter_table_public_bodyshops_add_column_jc_hourly_rates/down.yaml
new file mode 100644
index 000000000..40520bed4
--- /dev/null
+++ b/hasura/migrations/1622147892235_alter_table_public_bodyshops_add_column_jc_hourly_rates/down.yaml
@@ -0,0 +1,5 @@
+- args:
+ cascade: false
+ read_only: false
+ sql: ALTER TABLE "public"."bodyshops" DROP COLUMN "jc_hourly_rates";
+ type: run_sql
diff --git a/hasura/migrations/1622147892235_alter_table_public_bodyshops_add_column_jc_hourly_rates/up.yaml b/hasura/migrations/1622147892235_alter_table_public_bodyshops_add_column_jc_hourly_rates/up.yaml
new file mode 100644
index 000000000..b943423ad
--- /dev/null
+++ b/hasura/migrations/1622147892235_alter_table_public_bodyshops_add_column_jc_hourly_rates/up.yaml
@@ -0,0 +1,6 @@
+- args:
+ cascade: false
+ read_only: false
+ sql: ALTER TABLE "public"."bodyshops" ADD COLUMN "jc_hourly_rates" jsonb NULL
+ DEFAULT jsonb_build_object();
+ type: run_sql
diff --git a/hasura/migrations/1622147902848_update_permission_user_public_table_bodyshops/down.yaml b/hasura/migrations/1622147902848_update_permission_user_public_table_bodyshops/down.yaml
new file mode 100644
index 000000000..f17e43eb2
--- /dev/null
+++ b/hasura/migrations/1622147902848_update_permission_user_public_table_bodyshops/down.yaml
@@ -0,0 +1,83 @@
+- args:
+ role: user
+ table:
+ name: bodyshops
+ schema: public
+ type: drop_select_permission
+- args:
+ permission:
+ allow_aggregations: false
+ columns:
+ - accountingconfig
+ - address1
+ - address2
+ - appt_alt_transport
+ - appt_colors
+ - appt_length
+ - bill_tax_rates
+ - city
+ - country
+ - created_at
+ - default_adjustment_rate
+ - deliverchecklist
+ - email
+ - enforce_class
+ - enforce_referral
+ - federal_tax_id
+ - id
+ - imexshopid
+ - inhousevendorid
+ - insurance_vendor_id
+ - intakechecklist
+ - jobsizelimit
+ - logo_img_path
+ - md_categories
+ - md_ccc_rates
+ - md_classes
+ - md_hour_split
+ - md_ins_cos
+ - md_labor_rates
+ - md_messaging_presets
+ - md_notes_presets
+ - md_order_statuses
+ - md_parts_locations
+ - md_payment_types
+ - md_rbac
+ - md_referral_sources
+ - md_responsibility_centers
+ - md_ro_statuses
+ - messagingservicesid
+ - phone
+ - prodtargethrs
+ - production_config
+ - region_config
+ - schedule_end_time
+ - schedule_start_time
+ - scoreboard_target
+ - shopname
+ - shoprates
+ - speedprint
+ - ssbuckets
+ - state
+ - state_tax_id
+ - stripe_acct_id
+ - sub_status
+ - target_touchtime
+ - template_header
+ - textid
+ - updated_at
+ - use_fippa
+ - website
+ - workingdays
+ - zip_post
+ computed_fields: []
+ filter:
+ associations:
+ user:
+ authid:
+ _eq: X-Hasura-User-Id
+ role: user
+ table:
+ name: bodyshops
+ schema: public
+ type: create_select_permission
diff --git a/hasura/migrations/1622147902848_update_permission_user_public_table_bodyshops/up.yaml b/hasura/migrations/1622147902848_update_permission_user_public_table_bodyshops/up.yaml
new file mode 100644
index 000000000..a1885496e
--- /dev/null
+++ b/hasura/migrations/1622147902848_update_permission_user_public_table_bodyshops/up.yaml
@@ -0,0 +1,84 @@
+- args:
+ role: user
+ table:
+ name: bodyshops
+ schema: public
+ type: drop_select_permission
+- args:
+ permission:
+ allow_aggregations: false
+ columns:
+ - accountingconfig
+ - address1
+ - address2
+ - appt_alt_transport
+ - appt_colors
+ - appt_length
+ - bill_tax_rates
+ - city
+ - country
+ - created_at
+ - default_adjustment_rate
+ - deliverchecklist
+ - email
+ - enforce_class
+ - enforce_referral
+ - federal_tax_id
+ - id
+ - imexshopid
+ - inhousevendorid
+ - insurance_vendor_id
+ - intakechecklist
+ - jc_hourly_rates
+ - jobsizelimit
+ - logo_img_path
+ - md_categories
+ - md_ccc_rates
+ - md_classes
+ - md_hour_split
+ - md_ins_cos
+ - md_labor_rates
+ - md_messaging_presets
+ - md_notes_presets
+ - md_order_statuses
+ - md_parts_locations
+ - md_payment_types
+ - md_rbac
+ - md_referral_sources
+ - md_responsibility_centers
+ - md_ro_statuses
+ - messagingservicesid
+ - phone
+ - prodtargethrs
+ - production_config
+ - region_config
+ - schedule_end_time
+ - schedule_start_time
+ - scoreboard_target
+ - shopname
+ - shoprates
+ - speedprint
+ - ssbuckets
+ - state
+ - state_tax_id
+ - stripe_acct_id
+ - sub_status
+ - target_touchtime
+ - template_header
+ - textid
+ - updated_at
+ - use_fippa
+ - website
+ - workingdays
+ - zip_post
+ computed_fields: []
+ filter:
+ associations:
+ user:
+ authid:
+ _eq: X-Hasura-User-Id
+ role: user
+ table:
+ name: bodyshops
+ schema: public
+ type: create_select_permission
diff --git a/hasura/migrations/1622147914381_update_permission_user_public_table_bodyshops/down.yaml b/hasura/migrations/1622147914381_update_permission_user_public_table_bodyshops/down.yaml
new file mode 100644
index 000000000..cf88f05a1
--- /dev/null
+++ b/hasura/migrations/1622147914381_update_permission_user_public_table_bodyshops/down.yaml
@@ -0,0 +1,77 @@
+- args:
+ role: user
+ table:
+ name: bodyshops
+ schema: public
+ type: drop_update_permission
+- args:
+ permission:
+ columns:
+ - accountingconfig
+ - address1
+ - address2
+ - appt_alt_transport
+ - appt_colors
+ - appt_length
+ - bill_tax_rates
+ - city
+ - country
+ - created_at
+ - default_adjustment_rate
+ - deliverchecklist
+ - email
+ - enforce_class
+ - enforce_referral
+ - federal_tax_id
+ - id
+ - inhousevendorid
+ - insurance_vendor_id
+ - intakechecklist
+ - logo_img_path
+ - md_categories
+ - md_ccc_rates
+ - md_classes
+ - md_hour_split
+ - md_ins_cos
+ - md_labor_rates
+ - md_messaging_presets
+ - md_notes_presets
+ - md_order_statuses
+ - md_parts_locations
+ - md_payment_types
+ - md_rbac
+ - md_referral_sources
+ - md_responsibility_centers
+ - md_ro_statuses
+ - phone
+ - prodtargethrs
+ - production_config
+ - schedule_end_time
+ - schedule_start_time
+ - scoreboard_target
+ - shopname
+ - shoprates
+ - speedprint
+ - ssbuckets
+ - state
+ - state_tax_id
+ - target_touchtime
+ - updated_at
+ - use_fippa
+ - website
+ - workingdays
+ - zip_post
+ filter:
+ associations:
+ _and:
+ - user:
+ authid:
+ _eq: X-Hasura-User-Id
+ - active:
+ _eq: true
+ set: {}
+ role: user
+ table:
+ name: bodyshops
+ schema: public
+ type: create_update_permission
diff --git a/hasura/migrations/1622147914381_update_permission_user_public_table_bodyshops/up.yaml b/hasura/migrations/1622147914381_update_permission_user_public_table_bodyshops/up.yaml
new file mode 100644
index 000000000..e8583e4ca
--- /dev/null
+++ b/hasura/migrations/1622147914381_update_permission_user_public_table_bodyshops/up.yaml
@@ -0,0 +1,78 @@
+- args:
+ role: user
+ table:
+ name: bodyshops
+ schema: public
+ type: drop_update_permission
+- args:
+ permission:
+ columns:
+ - accountingconfig
+ - address1
+ - address2
+ - appt_alt_transport
+ - appt_colors
+ - appt_length
+ - bill_tax_rates
+ - city
+ - country
+ - created_at
+ - default_adjustment_rate
+ - deliverchecklist
+ - email
+ - enforce_class
+ - enforce_referral
+ - federal_tax_id
+ - id
+ - inhousevendorid
+ - insurance_vendor_id
+ - intakechecklist
+ - jc_hourly_rates
+ - logo_img_path
+ - md_categories
+ - md_ccc_rates
+ - md_classes
+ - md_hour_split
+ - md_ins_cos
+ - md_labor_rates
+ - md_messaging_presets
+ - md_notes_presets
+ - md_order_statuses
+ - md_parts_locations
+ - md_payment_types
+ - md_rbac
+ - md_referral_sources
+ - md_responsibility_centers
+ - md_ro_statuses
+ - phone
+ - prodtargethrs
+ - production_config
+ - schedule_end_time
+ - schedule_start_time
+ - scoreboard_target
+ - shopname
+ - shoprates
+ - speedprint
+ - ssbuckets
+ - state
+ - state_tax_id
+ - target_touchtime
+ - updated_at
+ - use_fippa
+ - website
+ - workingdays
+ - zip_post
+ filter:
+ associations:
+ _and:
+ - user:
+ authid:
+ _eq: X-Hasura-User-Id
+ - active:
+ _eq: true
+ set: {}
+ role: user
+ table:
+ name: bodyshops
+ schema: public
+ type: create_update_permission
diff --git a/hasura/migrations/metadata.yaml b/hasura/migrations/metadata.yaml
index 3aef96e54..02291ea5a 100644
--- a/hasura/migrations/metadata.yaml
+++ b/hasura/migrations/metadata.yaml
@@ -771,6 +771,7 @@ tables:
- inhousevendorid
- insurance_vendor_id
- intakechecklist
+ - jc_hourly_rates
- jobsizelimit
- logo_img_path
- md_categories
@@ -841,6 +842,7 @@ tables:
- inhousevendorid
- insurance_vendor_id
- intakechecklist
+ - jc_hourly_rates
- logo_img_path
- md_categories
- md_ccc_rates
diff --git a/server/graphql-client/queries.js b/server/graphql-client/queries.js
index fd3a07228..9b7b3677c 100644
--- a/server/graphql-client/queries.js
+++ b/server/graphql-client/queries.js
@@ -680,6 +680,7 @@ exports.QUERY_JOB_COSTING_DETAILS = ` query QUERY_JOB_COSTING_DETAILS($id: uuid!
bodyshop{
id
md_responsibility_centers
+ jc_hourly_rates
}
}
}`;
@@ -780,6 +781,7 @@ exports.QUERY_JOB_COSTING_DETAILS_MULTI = ` query QUERY_JOB_COSTING_DETAILS_MULT
bodyshop {
id
md_responsibility_centers
+ jc_hourly_rates
}
}
}
diff --git a/server/job/job-costing.js b/server/job/job-costing.js
index 7b98acf1e..24d1d6382 100644
--- a/server/job/job-costing.js
+++ b/server/job/job-costing.js
@@ -10,8 +10,7 @@ Dinero.globalRoundingMode = "HALF_EVEN";
async function JobCosting(req, res) {
const { jobid } = req.body;
- console.log("🚀 ~ file: job-costing.js ~ line 13 ~ jobid", jobid);
- console.time("querydata");
+ console.time("Query for Data");
const BearerToken = req.headers.authorization;
const client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, {
@@ -209,6 +208,8 @@ function GenerateCostingData(job) {
job.bodyshop.md_responsibility_centers.costs.map((p) => p.name)
);
+ const materialsHours = { mapaHrs: 0, mashHrs: 0 };
+
//Massage the data.
const jobLineTotalsByProfitCenter =
job &&
@@ -234,6 +235,7 @@ function GenerateCostingData(job) {
if (!acc.labor[defaultProfits["MAPA"]])
acc.labor[defaultProfits["MAPA"]] = Dinero();
+ materialsHours.mapaHrs += val.mod_lb_hrs || 0;
acc.labor[defaultProfits["MAPA"]] = acc.labor[
defaultProfits["MAPA"]
].add(
@@ -253,6 +255,7 @@ function GenerateCostingData(job) {
amount: Math.round((job.rate_mash || 0) * 100),
}).multiply(val.mod_lb_hrs || 0)
);
+ materialsHours.mashHrs += val.mod_lb_hrs || 0;
}
//If labor line, add to paint and shop materials.
}
@@ -309,12 +312,7 @@ function GenerateCostingData(job) {
.multiply(val.part_qty || 0)
.percentage(val.prt_dsmk_p)
);
- console.log(
- `*** partsAmount`,
- val.line_desc,
- partsProfitCenter,
- partsAmount.toJSON()
- );
+
if (!acc.parts[partsProfitCenter])
acc.parts[partsProfitCenter] = Dinero();
acc.parts[partsProfitCenter] =
@@ -348,6 +346,52 @@ function GenerateCostingData(job) {
return bill_acc;
}, {});
+ //If the hourly rates for job costing are set, add them in.
+ if (job.bodyshop.jc_hourly_rates && job.bodyshop.jc_hourly_rates.mapa) {
+ if (
+ !billTotalsByCostCenters[
+ job.bodyshop.md_responsibility_centers.defaults.costs.MAPA
+ ]
+ )
+ billTotalsByCostCenters[
+ job.bodyshop.md_responsibility_centers.defaults.costs.MAPA
+ ] = Dinero();
+ billTotalsByCostCenters[
+ job.bodyshop.md_responsibility_centers.defaults.costs.MAPA
+ ] = billTotalsByCostCenters[
+ job.bodyshop.md_responsibility_centers.defaults.costs.MAPA
+ ].add(
+ Dinero({
+ amount:
+ (job.bodyshop.jc_hourly_rates &&
+ job.bodyshop.jc_hourly_rates.mapa * 100) ||
+ 0,
+ }).multiply(materialsHours.mapaHrs)
+ );
+ }
+ if (job.bodyshop.jc_hourly_rates && job.bodyshop.jc_hourly_rates.mash) {
+ if (
+ !billTotalsByCostCenters[
+ job.bodyshop.md_responsibility_centers.defaults.costs.MASH
+ ]
+ )
+ billTotalsByCostCenters[
+ job.bodyshop.md_responsibility_centers.defaults.costs.MASH
+ ] = Dinero();
+ billTotalsByCostCenters[
+ job.bodyshop.md_responsibility_centers.defaults.costs.MASH
+ ] = billTotalsByCostCenters[
+ job.bodyshop.md_responsibility_centers.defaults.costs.MASH
+ ].add(
+ Dinero({
+ amount:
+ (job.bodyshop.jc_hourly_rates &&
+ job.bodyshop.jc_hourly_rates.mash * 100) ||
+ 0,
+ }).multiply(materialsHours.mashHrs)
+ );
+ }
+
const ticketTotalsByCostCenter = job.timetickets.reduce(
(ticket_acc, ticket_val) => {
//At the invoice level.
From 79f2c7dd3d67c0bbae41c6c99ac8b05f479fe953 Mon Sep 17 00:00:00 2001
From: Patrick Fic <>
Date: Thu, 27 May 2021 14:11:16 -0700
Subject: [PATCH 09/10] IO-1086 confirmation on profile update.
---
bodyshop_translations.babel | 26 +++++++++++++++++++++++
client/src/redux/user/user.sagas.js | 6 ++++++
client/src/translations/en_us/common.json | 3 +++
client/src/translations/es/common.json | 3 +++
client/src/translations/fr/common.json | 3 +++
5 files changed, 41 insertions(+)
diff --git a/bodyshop_translations.babel b/bodyshop_translations.babel
index a6258dd82..abc4f8118 100644
--- a/bodyshop_translations.babel
+++ b/bodyshop_translations.babel
@@ -30465,6 +30465,32 @@
+
+ successes
+
+
+ updated
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+
diff --git a/client/src/redux/user/user.sagas.js b/client/src/redux/user/user.sagas.js
index a70964387..cbeba03af 100644
--- a/client/src/redux/user/user.sagas.js
+++ b/client/src/redux/user/user.sagas.js
@@ -1,4 +1,6 @@
import Fingerprint2 from "@fingerprintjs/fingerprintjs";
+import { notification } from "antd";
+import i18next from "i18next";
import LogRocket from "logrocket";
import { all, call, delay, put, select, takeLatest } from "redux-saga/effects";
import {
@@ -100,6 +102,10 @@ export function* updateUserDetails(userDetails) {
try {
yield updateCurrentUser(userDetails.payload);
yield put(updateUserDetailsSuccess(userDetails.payload));
+ notification.open({
+ type: "success",
+ message: i18next.t("profile.successes.updated"),
+ });
} catch (error) {
//yield put(signOutFailure(error.message));
}
diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json
index 7c5106e75..164bdd128 100644
--- a/client/src/translations/en_us/common.json
+++ b/client/src/translations/en_us/common.json
@@ -1825,6 +1825,9 @@
},
"labels": {
"activeshop": "Active Shop"
+ },
+ "successes": {
+ "updated": "Profile updated successfully."
}
},
"reportcenter": {
diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json
index d4b8d2c1e..4fae2a134 100644
--- a/client/src/translations/es/common.json
+++ b/client/src/translations/es/common.json
@@ -1825,6 +1825,9 @@
},
"labels": {
"activeshop": ""
+ },
+ "successes": {
+ "updated": ""
}
},
"reportcenter": {
diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json
index 6f7f00692..63fde29b6 100644
--- a/client/src/translations/fr/common.json
+++ b/client/src/translations/fr/common.json
@@ -1825,6 +1825,9 @@
},
"labels": {
"activeshop": ""
+ },
+ "successes": {
+ "updated": ""
}
},
"reportcenter": {
From c8506387f6500964b12eb5d9b2d7a40acac93670 Mon Sep 17 00:00:00 2001
From: Patrick Fic <>
Date: Thu, 27 May 2021 14:58:23 -0700
Subject: [PATCH 10/10] IO-1131 - Remove version #.
---
client/src/pages/manage/manage.page.component.jsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/client/src/pages/manage/manage.page.component.jsx b/client/src/pages/manage/manage.page.component.jsx
index 9563b5bfd..364520735 100644
--- a/client/src/pages/manage/manage.page.component.jsx
+++ b/client/src/pages/manage/manage.page.component.jsx
@@ -385,7 +385,7 @@ export function Manage({ match, conflict, bodyshop }) {