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: