diff --git a/client/src/components/bill-delete-button/bill-delete-button.component.jsx b/client/src/components/bill-delete-button/bill-delete-button.component.jsx
new file mode 100644
index 000000000..729eff9ed
--- /dev/null
+++ b/client/src/components/bill-delete-button/bill-delete-button.component.jsx
@@ -0,0 +1,52 @@
+import { useMutation } from "@apollo/react-hooks";
+import { Button, notification } from "antd";
+import React, { useState } from "react";
+import { useTranslation } from "react-i18next";
+import { DELETE_BILL } from "../../graphql/bills.queries";
+
+export default function BillDeleteButton({ bill }) {
+ const [loading, setLoading] = useState(false);
+ const { t } = useTranslation();
+ const [deleteBill] = useMutation(DELETE_BILL);
+
+ const handleDelete = async () => {
+ setLoading(true);
+ const result = await deleteBill({
+ variables: { billId: bill.id },
+ update(cache) {
+ cache.modify({
+ fields: {
+ bills(existingBills, { readField }) {
+ return existingBills.filter(
+ (billref) => bill.id !== readField("id", billref)
+ );
+ },
+ search_bills(existingBills, { readField }) {
+ return existingBills.filter(
+ (billref) => bill.id !== readField("id", billref)
+ );
+ },
+ },
+ });
+ },
+ });
+
+ if (!!!result.errors) {
+ notification["success"]({ message: t("bills.successes.deleted") });
+ } else {
+ notification["error"]({
+ message: t("bills.errors.deleting", {
+ error: JSON.stringify(result.errors),
+ }),
+ });
+ }
+
+ setLoading(false);
+ };
+
+ return (
+
+ );
+}
diff --git a/client/src/components/bills-list-table/bills-list-table.component.jsx b/client/src/components/bills-list-table/bills-list-table.component.jsx
index a1ebff9d4..506f1c4a7 100644
--- a/client/src/components/bills-list-table/bills-list-table.component.jsx
+++ b/client/src/components/bills-list-table/bills-list-table.component.jsx
@@ -1,5 +1,13 @@
import { SyncOutlined } from "@ant-design/icons";
-import { Button, Checkbox, Descriptions, Input, Table, Typography } from "antd";
+import {
+ Button,
+ Checkbox,
+ Descriptions,
+ Input,
+ Space,
+ Table,
+ Typography,
+} from "antd";
import queryString from "query-string";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
@@ -10,6 +18,7 @@ import { setModalContext } from "../../redux/modals/modals.actions";
import CurrencyFormatter from "../../utils/CurrencyFormatter";
import { DateFormatter } from "../../utils/DateFormatter";
import { alphaSort } from "../../utils/sorters";
+import BillDeleteButton from "../bill-delete-button/bill-delete-button.component";
const mapStateToProps = createStructuredSelector({
//jobRO: selectJobReadOnly,
@@ -106,7 +115,7 @@ export function BillsListTableComponent({
dataIndex: "actions",
key: "actions",
render: (text, record) => (
-
+
{record.exported ? (
) : (
@@ -116,7 +125,8 @@ export function BillsListTableComponent({
)}
-
+
+
),
},
];
diff --git a/client/src/graphql/bills.queries.js b/client/src/graphql/bills.queries.js
index 247005449..a92ce8691 100644
--- a/client/src/graphql/bills.queries.js
+++ b/client/src/graphql/bills.queries.js
@@ -10,6 +10,14 @@ export const INSERT_NEW_BILL = gql`
}
`;
+export const DELETE_BILL = gql`
+ mutation DELETE_BILL($billId: uuid!) {
+ delete_bills_by_pk(id: $billId) {
+ id
+ }
+ }
+`;
+
export const QUERY_ALL_BILLS_PAGINATED = gql`
query QUERY_ALL_BILLS_PAGINATED(
$search: String
diff --git a/client/src/pages/bills/bills.page.component.jsx b/client/src/pages/bills/bills.page.component.jsx
index 0728cf806..be151ba2a 100644
--- a/client/src/pages/bills/bills.page.component.jsx
+++ b/client/src/pages/bills/bills.page.component.jsx
@@ -1,10 +1,11 @@
import { SyncOutlined } from "@ant-design/icons";
-import { Button, Checkbox, Input, Table, Typography } from "antd";
+import { Button, Checkbox, Input, Space, Table, Typography } from "antd";
import queryString from "query-string";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { Link, useHistory, useLocation } from "react-router-dom";
+import BillDeleteButton from "../../components/bill-delete-button/bill-delete-button.component";
import { setModalContext } from "../../redux/modals/modals.actions";
import CurrencyFormatter from "../../utils/CurrencyFormatter";
import { DateFormatter } from "../../utils/DateFormatter";
@@ -98,7 +99,7 @@ export function BillsListPage({
dataIndex: "actions",
key: "actions",
render: (text, record) => (
-
+
@@ -128,7 +129,8 @@ export function BillsListPage({
>
{t("bills.actions.return")}
-
+
+
),
},
];
diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json
index b4d652e11..b9d9746a6 100644
--- a/client/src/translations/en_us/common.json
+++ b/client/src/translations/en_us/common.json
@@ -112,7 +112,8 @@
"return": "Return Items"
},
"errors": {
- "creating": "Error adding bill.",
+ "creating": "Error adding bill. {{error}}",
+ "deleting": "Error deleting bill. {{error}}",
"exporting": "Error exporting payable(s). {{error}}",
"exporting-partner": "Unable to connect to ImEX Partner. Please ensure it is running and logged in.",
"invalidro": "Not a valid RO.",
@@ -154,7 +155,8 @@
"subtotal": "Subtotal"
},
"successes": {
- "created": "Invoice added successfully."
+ "created": "Invoice added successfully.",
+ "deleted": "Bill deleted successfully."
},
"validation": {
"unique_invoice_number": "This invoice number has already been entered for this vendor."
diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json
index 61f9f7afe..db73a6b2c 100644
--- a/client/src/translations/es/common.json
+++ b/client/src/translations/es/common.json
@@ -113,6 +113,7 @@
},
"errors": {
"creating": "",
+ "deleting": "",
"exporting": "",
"exporting-partner": "",
"invalidro": "",
@@ -154,7 +155,8 @@
"subtotal": ""
},
"successes": {
- "created": ""
+ "created": "",
+ "deleted": ""
},
"validation": {
"unique_invoice_number": ""
diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json
index ae6896832..f7c7096ca 100644
--- a/client/src/translations/fr/common.json
+++ b/client/src/translations/fr/common.json
@@ -113,6 +113,7 @@
},
"errors": {
"creating": "",
+ "deleting": "",
"exporting": "",
"exporting-partner": "",
"invalidro": "",
@@ -154,7 +155,8 @@
"subtotal": ""
},
"successes": {
- "created": ""
+ "created": "",
+ "deleted": ""
},
"validation": {
"unique_invoice_number": ""
diff --git a/hasura/migrations/1611272576261_update_permission_user_public_table_bills/down.yaml b/hasura/migrations/1611272576261_update_permission_user_public_table_bills/down.yaml
new file mode 100644
index 000000000..e6a9c5c2a
--- /dev/null
+++ b/hasura/migrations/1611272576261_update_permission_user_public_table_bills/down.yaml
@@ -0,0 +1,6 @@
+- args:
+ role: user
+ table:
+ name: bills
+ schema: public
+ type: drop_delete_permission
diff --git a/hasura/migrations/1611272576261_update_permission_user_public_table_bills/up.yaml b/hasura/migrations/1611272576261_update_permission_user_public_table_bills/up.yaml
new file mode 100644
index 000000000..858e53df4
--- /dev/null
+++ b/hasura/migrations/1611272576261_update_permission_user_public_table_bills/up.yaml
@@ -0,0 +1,21 @@
+- args:
+ permission:
+ backend_only: false
+ filter:
+ _and:
+ - job:
+ bodyshop:
+ associations:
+ _and:
+ - user:
+ authid:
+ _eq: X-Hasura-User-Id
+ - active:
+ _eq: true
+ - exported:
+ _eq: false
+ role: user
+ table:
+ name: bills
+ schema: public
+ type: create_delete_permission
diff --git a/hasura/migrations/1611272645898_set_fk_public_documents_billid/down.yaml b/hasura/migrations/1611272645898_set_fk_public_documents_billid/down.yaml
new file mode 100644
index 000000000..bd8a427a6
--- /dev/null
+++ b/hasura/migrations/1611272645898_set_fk_public_documents_billid/down.yaml
@@ -0,0 +1,12 @@
+- args:
+ cascade: false
+ read_only: false
+ sql: |-
+ alter table "public"."documents" drop constraint "documents_billid_fkey",
+ add constraint "documents_invoiceid_fkey"
+ foreign key ("billid")
+ references "public"."bills"
+ ("id")
+ on update restrict
+ on delete restrict;
+ type: run_sql
diff --git a/hasura/migrations/1611272645898_set_fk_public_documents_billid/up.yaml b/hasura/migrations/1611272645898_set_fk_public_documents_billid/up.yaml
new file mode 100644
index 000000000..478200f55
--- /dev/null
+++ b/hasura/migrations/1611272645898_set_fk_public_documents_billid/up.yaml
@@ -0,0 +1,10 @@
+- args:
+ cascade: false
+ read_only: false
+ sql: |-
+ alter table "public"."documents" drop constraint "documents_invoiceid_fkey",
+ add constraint "documents_billid_fkey"
+ foreign key ("billid")
+ references "public"."bills"
+ ("id") on update restrict on delete set null;
+ type: run_sql
diff --git a/hasura/migrations/metadata.yaml b/hasura/migrations/metadata.yaml
index 418f4b87f..687bcfc13 100644
--- a/hasura/migrations/metadata.yaml
+++ b/hasura/migrations/metadata.yaml
@@ -587,6 +587,22 @@ tables:
- active:
_eq: true
check: null
+ delete_permissions:
+ - role: user
+ permission:
+ filter:
+ _and:
+ - job:
+ bodyshop:
+ associations:
+ _and:
+ - user:
+ authid:
+ _eq: X-Hasura-User-Id
+ - active:
+ _eq: true
+ - exported:
+ _eq: false
- table:
schema: public
name: bodyshops