From 136541b2914410012410a757a72d1addfa447178 Mon Sep 17 00:00:00 2001
From: Patrick Fic <>
Date: Fri, 9 Apr 2021 11:03:40 -0700
Subject: [PATCH] IO-868 IO-706 Unique vendor & employee names.
---
bodyshop_translations.babel | 52 +++++++++++++++++++
.../shop-employees-form.component.jsx | 36 ++++++++++++-
.../vendors-form/vendors-form.component.jsx | 37 ++++++++++++-
client/src/graphql/employees.queries.js | 15 ++++++
client/src/graphql/vendors.queries.js | 12 +++++
client/src/translations/en_us/common.json | 6 +++
client/src/translations/es/common.json | 6 +++
client/src/translations/fr/common.json | 6 +++
.../down.yaml | 39 ++++++++++++++
.../up.yaml | 39 ++++++++++++++
.../down.yaml | 43 +++++++++++++++
.../up.yaml | 43 +++++++++++++++
hasura/migrations/metadata.yaml | 2 +
13 files changed, 334 insertions(+), 2 deletions(-)
create mode 100644 hasura/migrations/1617990757965_update_permission_user_public_table_employees/down.yaml
create mode 100644 hasura/migrations/1617990757965_update_permission_user_public_table_employees/up.yaml
create mode 100644 hasura/migrations/1617990875647_update_permission_user_public_table_vendors/down.yaml
create mode 100644 hasura/migrations/1617990875647_update_permission_user_public_table_vendors/up.yaml
diff --git a/bodyshop_translations.babel b/bodyshop_translations.babel
index 9b099f05a..842c68575 100644
--- a/bodyshop_translations.babel
+++ b/bodyshop_translations.babel
@@ -11365,6 +11365,32 @@
+
+ validations
+
+
+ unique_employee_number
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+
@@ -33828,6 +33854,32 @@
+
+ validation
+
+
+ unique_vendor_name
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+
diff --git a/client/src/components/shop-employees/shop-employees-form.component.jsx b/client/src/components/shop-employees/shop-employees-form.component.jsx
index 6725c4682..8db14e979 100644
--- a/client/src/components/shop-employees/shop-employees-form.component.jsx
+++ b/client/src/components/shop-employees/shop-employees-form.component.jsx
@@ -6,7 +6,10 @@ import { useApolloClient } from "@apollo/client";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
-import { QUERY_USERS_BY_EMAIL } from "../../graphql/employees.queries";
+import {
+ CHECK_EMPLOYEE_NUMBER,
+ QUERY_USERS_BY_EMAIL,
+} from "../../graphql/employees.queries";
import { selectBodyshop } from "../../redux/user/user.selectors";
import FormDatePicker from "../form-date-picker/form-date-picker.component";
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
@@ -85,11 +88,42 @@ export function ShopEmployeesFormComponent({
({
+ async validator(rule, value) {
+ if (value) {
+ const response = await client.query({
+ query: CHECK_EMPLOYEE_NUMBER,
+ variables: {
+ employeenumber: value,
+ },
+ });
+
+ if (
+ response.data.employees_aggregate.aggregate.count === 0
+ ) {
+ return Promise.resolve();
+ } else if (
+ response.data.employees_aggregate.nodes.length === 1 &&
+ response.data.employees_aggregate.nodes[0].id ===
+ form.getFieldValue("id")
+ ) {
+ return Promise.resolve();
+ }
+ return Promise.reject(
+ t("employees.validation.unique_employee_number")
+ );
+ } else {
+ return Promise.resolve();
+ }
+ },
+ }),
]}
>
diff --git a/client/src/components/vendors-form/vendors-form.component.jsx b/client/src/components/vendors-form/vendors-form.component.jsx
index fa262750a..e3eb1330c 100644
--- a/client/src/components/vendors-form/vendors-form.component.jsx
+++ b/client/src/components/vendors-form/vendors-form.component.jsx
@@ -1,4 +1,5 @@
import { DeleteFilled } from "@ant-design/icons";
+import { useApolloClient } from "@apollo/client";
import {
Button,
Divider,
@@ -12,6 +13,7 @@ import {
} from "antd";
import React from "react";
import { useTranslation } from "react-i18next";
+import { CHECK_VENDOR_NAME } from "../../graphql/vendors.queries";
import FormFieldsChanged from "../form-fields-changed-alert/form-fields-changed-alert.component";
import FormItemEmail from "../form-items-formatted/email-form-item.component";
import PhoneFormItem, {
@@ -25,6 +27,7 @@ export default function VendorsFormComponent({
responsibilityCenters,
}) {
const { t } = useTranslation();
+ const client = useApolloClient();
const { getFieldValue } = form;
return (
@@ -58,8 +61,40 @@ export default function VendorsFormComponent({
({
+ async validator(rule, value) {
+ if (value) {
+ const response = await client.query({
+ query: CHECK_VENDOR_NAME,
+ variables: {
+ name: value,
+ },
+ });
+
+ if (response.data.vendors_aggregate.aggregate.count === 0) {
+ return Promise.resolve();
+ } else if (
+ response.data.vendors_aggregate.nodes.length === 1 &&
+ response.data.vendors_aggregate.nodes[0].id ===
+ form.getFieldValue("id")
+ ) {
+ return Promise.resolve();
+ }
+ return Promise.reject(
+ t("vendors.validation.unique_vendor_name")
+ );
+ } else {
+ return Promise.resolve();
+ }
+ },
+ }),
]}
>
diff --git a/client/src/graphql/employees.queries.js b/client/src/graphql/employees.queries.js
index 2b87e5522..4efb5657d 100644
--- a/client/src/graphql/employees.queries.js
+++ b/client/src/graphql/employees.queries.js
@@ -18,6 +18,21 @@ export const QUERY_EMPLOYEES = gql`
}
`;
+export const CHECK_EMPLOYEE_NUMBER = gql`
+ query CHECK_EMPLOYEE_NUMBER($employeenumber: String!) {
+ employees_aggregate(
+ where: { employee_number: { _ilike: $employeenumber } }
+ ) {
+ aggregate {
+ count
+ }
+ nodes {
+ id
+ }
+ }
+ }
+`;
+
export const QUERY_ACTIVE_EMPLOYEES = gql`
query QUERY_ACTIVE_EMPLOYEES {
employees(where: { active: { _eq: true } }) {
diff --git a/client/src/graphql/vendors.queries.js b/client/src/graphql/vendors.queries.js
index 46b3001ee..d4a3986cf 100644
--- a/client/src/graphql/vendors.queries.js
+++ b/client/src/graphql/vendors.queries.js
@@ -21,6 +21,18 @@ export const QUERY_VENDOR_BY_ID = gql`
}
}
`;
+export const CHECK_VENDOR_NAME = gql`
+ query CHECK_VENDOR_NAME($name: String!) {
+ vendors_aggregate(where: { name: { _ilike: $name } }) {
+ aggregate {
+ count
+ }
+ nodes {
+ id
+ }
+ }
+ }
+`;
export const UPDATE_VENDOR = gql`
mutation UPDATE_VENDOR($id: uuid!, $vendor: vendors_set_input!) {
diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json
index 315a0fe2a..4330cd513 100644
--- a/client/src/translations/en_us/common.json
+++ b/client/src/translations/en_us/common.json
@@ -734,6 +734,9 @@
"successes": {
"delete": "Employee deleted successfully.",
"save": "Employee saved successfully."
+ },
+ "validations": {
+ "unique_employee_number": "You must enter a unique employee number."
}
},
"general": {
@@ -2038,6 +2041,9 @@
"successes": {
"deleted": "Vendor deleted successfully. ",
"saved": "Vendor saved successfully."
+ },
+ "validation": {
+ "unique_vendor_name": "You must enter a unique vendor name."
}
}
}
diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json
index 15bd8e667..75e1655b4 100644
--- a/client/src/translations/es/common.json
+++ b/client/src/translations/es/common.json
@@ -734,6 +734,9 @@
"successes": {
"delete": "Empleado eliminado con éxito.",
"save": "Empleado guardado con éxito."
+ },
+ "validations": {
+ "unique_employee_number": ""
}
},
"general": {
@@ -2038,6 +2041,9 @@
"successes": {
"deleted": "Proveedor eliminado correctamente.",
"saved": "Proveedor guardado con éxito."
+ },
+ "validation": {
+ "unique_vendor_name": ""
}
}
}
diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json
index 1a73b55b2..69bcb7fed 100644
--- a/client/src/translations/fr/common.json
+++ b/client/src/translations/fr/common.json
@@ -734,6 +734,9 @@
"successes": {
"delete": "L'employé a bien été supprimé.",
"save": "L'employé a enregistré avec succès."
+ },
+ "validations": {
+ "unique_employee_number": ""
}
},
"general": {
@@ -2038,6 +2041,9 @@
"successes": {
"deleted": "Le fournisseur a bien été supprimé.",
"saved": "Le fournisseur a bien enregistré."
+ },
+ "validation": {
+ "unique_vendor_name": ""
}
}
}
diff --git a/hasura/migrations/1617990757965_update_permission_user_public_table_employees/down.yaml b/hasura/migrations/1617990757965_update_permission_user_public_table_employees/down.yaml
new file mode 100644
index 000000000..dabd89bba
--- /dev/null
+++ b/hasura/migrations/1617990757965_update_permission_user_public_table_employees/down.yaml
@@ -0,0 +1,39 @@
+- args:
+ role: user
+ table:
+ name: employees
+ schema: public
+ type: drop_select_permission
+- args:
+ permission:
+ allow_aggregations: false
+ columns:
+ - active
+ - created_at
+ - employee_number
+ - first_name
+ - flat_rate
+ - hire_date
+ - id
+ - last_name
+ - pin
+ - rates
+ - shopid
+ - termination_date
+ - updated_at
+ - user_email
+ computed_fields: []
+ filter:
+ bodyshop:
+ associations:
+ _and:
+ - user:
+ authid:
+ _eq: X-Hasura-User-Id
+ - active:
+ _eq: true
+ role: user
+ table:
+ name: employees
+ schema: public
+ type: create_select_permission
diff --git a/hasura/migrations/1617990757965_update_permission_user_public_table_employees/up.yaml b/hasura/migrations/1617990757965_update_permission_user_public_table_employees/up.yaml
new file mode 100644
index 000000000..9576da9bf
--- /dev/null
+++ b/hasura/migrations/1617990757965_update_permission_user_public_table_employees/up.yaml
@@ -0,0 +1,39 @@
+- args:
+ role: user
+ table:
+ name: employees
+ schema: public
+ type: drop_select_permission
+- args:
+ permission:
+ allow_aggregations: true
+ columns:
+ - active
+ - created_at
+ - employee_number
+ - first_name
+ - flat_rate
+ - hire_date
+ - id
+ - last_name
+ - pin
+ - rates
+ - shopid
+ - termination_date
+ - updated_at
+ - user_email
+ computed_fields: []
+ filter:
+ bodyshop:
+ associations:
+ _and:
+ - user:
+ authid:
+ _eq: X-Hasura-User-Id
+ - active:
+ _eq: true
+ role: user
+ table:
+ name: employees
+ schema: public
+ type: create_select_permission
diff --git a/hasura/migrations/1617990875647_update_permission_user_public_table_vendors/down.yaml b/hasura/migrations/1617990875647_update_permission_user_public_table_vendors/down.yaml
new file mode 100644
index 000000000..944fccf8b
--- /dev/null
+++ b/hasura/migrations/1617990875647_update_permission_user_public_table_vendors/down.yaml
@@ -0,0 +1,43 @@
+- args:
+ role: user
+ table:
+ name: vendors
+ schema: public
+ type: drop_select_permission
+- args:
+ permission:
+ allow_aggregations: false
+ columns:
+ - active
+ - bodyshopid
+ - city
+ - cost_center
+ - country
+ - created_at
+ - discount
+ - due_date
+ - email
+ - favorite
+ - id
+ - name
+ - phone
+ - state
+ - street1
+ - street2
+ - updated_at
+ - zip
+ computed_fields: []
+ filter:
+ bodyshop:
+ associations:
+ _and:
+ - user:
+ authid:
+ _eq: X-Hasura-User-Id
+ - active:
+ _eq: true
+ role: user
+ table:
+ name: vendors
+ schema: public
+ type: create_select_permission
diff --git a/hasura/migrations/1617990875647_update_permission_user_public_table_vendors/up.yaml b/hasura/migrations/1617990875647_update_permission_user_public_table_vendors/up.yaml
new file mode 100644
index 000000000..98b1676d8
--- /dev/null
+++ b/hasura/migrations/1617990875647_update_permission_user_public_table_vendors/up.yaml
@@ -0,0 +1,43 @@
+- args:
+ role: user
+ table:
+ name: vendors
+ schema: public
+ type: drop_select_permission
+- args:
+ permission:
+ allow_aggregations: true
+ columns:
+ - active
+ - bodyshopid
+ - city
+ - cost_center
+ - country
+ - created_at
+ - discount
+ - due_date
+ - email
+ - favorite
+ - id
+ - name
+ - phone
+ - state
+ - street1
+ - street2
+ - updated_at
+ - zip
+ computed_fields: []
+ filter:
+ bodyshop:
+ associations:
+ _and:
+ - user:
+ authid:
+ _eq: X-Hasura-User-Id
+ - active:
+ _eq: true
+ role: user
+ table:
+ name: vendors
+ schema: public
+ type: create_select_permission
diff --git a/hasura/migrations/metadata.yaml b/hasura/migrations/metadata.yaml
index a20024e37..1ad5a03ba 100644
--- a/hasura/migrations/metadata.yaml
+++ b/hasura/migrations/metadata.yaml
@@ -1686,6 +1686,7 @@ tables:
_eq: X-Hasura-User-Id
- active:
_eq: true
+ allow_aggregations: true
update_permissions:
- role: user
permission:
@@ -4172,6 +4173,7 @@ tables:
_eq: X-Hasura-User-Id
- active:
_eq: true
+ allow_aggregations: true
update_permissions:
- role: user
permission: