diff --git a/bodyshop_translations.babel b/bodyshop_translations.babel index c2bb2b5a5..39f7c8a01 100644 --- a/bodyshop_translations.babel +++ b/bodyshop_translations.babel @@ -16967,6 +16967,27 @@ + + markasexported + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + markpstexempt false @@ -17177,6 +17198,27 @@ + + uninvoice + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + unvoid false @@ -21517,6 +21559,27 @@ + + adminwarning + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + allocations false @@ -22461,6 +22524,27 @@ + + deletedelivery + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + deleteintake false diff --git a/client/src/components/jobs-admin-delete-intake/jobs-admin-delete-intake.component.jsx b/client/src/components/jobs-admin-delete-intake/jobs-admin-delete-intake.component.jsx index 011ba9f99..db96f74ef 100644 --- a/client/src/components/jobs-admin-delete-intake/jobs-admin-delete-intake.component.jsx +++ b/client/src/components/jobs-admin-delete-intake/jobs-admin-delete-intake.component.jsx @@ -6,8 +6,8 @@ import { useTranslation } from "react-i18next"; export default function JobAdminDeleteIntake({ job }) { const { t } = useTranslation(); const [loading, setLoading] = useState(false); - const [updateJob] = useMutation(gql` - mutation UPDATE_JOB($jobId: uuid!) { + const [deleteIntake] = useMutation(gql` + mutation DELETE_INTAKE($jobId: uuid!) { update_jobs_by_pk( pk_columns: { id: $jobId } _set: { intakechecklist: null } @@ -18,9 +18,39 @@ export default function JobAdminDeleteIntake({ job }) { } `); + const [DELETE_DELIVERY] = useMutation(gql` + mutation DELETE_DELIVERY($jobId: uuid!) { + update_jobs_by_pk( + pk_columns: { id: $jobId } + _set: { deliverychecklist: null } + ) { + id + deliverychecklist + } + } + `); + const handleDelete = async (values) => { setLoading(true); - const result = await updateJob({ + const result = await deleteIntake({ + variables: { jobId: job.id }, + }); + + if (!!!result.errors) { + notification["success"]({ message: t("jobs.successes.save") }); + } else { + notification["error"]({ + message: t("jobs.errors.saving", { + error: JSON.stringify(result.errors), + }), + }); + } + setLoading(false); + }; + + const handleDeleteDelivery = async (values) => { + setLoading(true); + const result = await DELETE_DELIVERY({ variables: { jobId: job.id }, }); @@ -34,12 +64,16 @@ export default function JobAdminDeleteIntake({ job }) { }); } setLoading(false); - //Get the owner details, populate it all back into the job. }; return ( - + <> + + + ); } diff --git a/client/src/components/jobs-admin-mark-reexport/jobs-admin-mark-reexport.component.jsx b/client/src/components/jobs-admin-mark-reexport/jobs-admin-mark-reexport.component.jsx index f6002d144..18b624606 100644 --- a/client/src/components/jobs-admin-mark-reexport/jobs-admin-mark-reexport.component.jsx +++ b/client/src/components/jobs-admin-mark-reexport/jobs-admin-mark-reexport.component.jsx @@ -7,6 +7,7 @@ import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { selectBodyshop } from "../../redux/user/user.selectors"; +import moment from "moment"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, }); @@ -21,8 +22,8 @@ export default connect( export function JobAdminMarkReexport({ bodyshop, job }) { const { t } = useTranslation(); const [loading, setLoading] = useState(false); - const [updateJob] = useMutation(gql` - mutation UPDATE_JOB($jobId: uuid!) { + const [markJobForReexport] = useMutation(gql` + mutation MARK_JOB_FOR_REEXPORT($jobId: uuid!) { update_jobs_by_pk( pk_columns: { id: $jobId } _set: { date_exported: null @@ -30,14 +31,84 @@ export function JobAdminMarkReexport({ bodyshop, job }) { } ) { id - intakechecklist + date_exported + status + date_invoiced } } `); - const handleUpdate = async (values) => { + const [markJobExported] = useMutation(gql` + mutation MARK_JOB_AS_EXPORTED($jobId: uuid!, $date_exported: timestamptz!) { + update_jobs_by_pk( + pk_columns: { id: $jobId } + _set: { date_exported: $date_exported + status: "${bodyshop.md_ro_statuses.default_exported}" + } + ) { + id + date_exported + date_invoiced + status + } + } + `); + const [markJobUninvoiced] = useMutation(gql` + mutation MARK_JOB_AS_UNINVOICED($jobId: uuid!, ) { + update_jobs_by_pk( + pk_columns: { id: $jobId } + _set: { date_exported: null + date_invoiced: null + status: "${bodyshop.md_ro_statuses.default_delivered}" + } + ) { + id + date_exported + date_invoiced + status + } + } + `); + + const handleMarkForExport = async () => { setLoading(true); - const result = await updateJob({ + const result = await markJobForReexport({ + variables: { jobId: job.id }, + }); + + if (!result.errors) { + notification["success"]({ message: t("jobs.successes.save") }); + } else { + notification["error"]({ + message: t("jobs.errors.saving", { + error: JSON.stringify(result.errors), + }), + }); + } + setLoading(false); + }; + + const handleMarkExported = async () => { + setLoading(true); + const result = await markJobExported({ + variables: { jobId: job.id, date_exported: moment() }, + }); + + if (!result.errors) { + notification["success"]({ message: t("jobs.successes.save") }); + } else { + notification["error"]({ + message: t("jobs.errors.saving", { + error: JSON.stringify(result.errors), + }), + }); + } + setLoading(false); + }; + + const handleUninvoice = async () => { + setLoading(true); + const result = await markJobUninvoiced({ variables: { jobId: job.id }, }); @@ -51,16 +122,31 @@ export function JobAdminMarkReexport({ bodyshop, job }) { }); } setLoading(false); - //Get the owner details, populate it all back into the job. }; return ( - + <> + + + + ); } diff --git a/client/src/pages/jobs-admin/jobs-admin.page.jsx b/client/src/pages/jobs-admin/jobs-admin.page.jsx index b133e314e..ba7e4a989 100644 --- a/client/src/pages/jobs-admin/jobs-admin.page.jsx +++ b/client/src/pages/jobs-admin/jobs-admin.page.jsx @@ -1,5 +1,5 @@ import { useQuery } from "@apollo/client"; -import { Card, Col, Result, Row, Space } from "antd"; +import { Card, Col, Result, Row, Space, Typography } from "antd"; import React, { useEffect } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -84,6 +84,9 @@ export function JobsCloseContainer({ setBreadcrumbs, setSelectedHeader }) { return ( + + {t("jobs.labels.adminwarning")} + diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json index 7c629ead4..c63152b36 100644 --- a/client/src/translations/en_us/common.json +++ b/client/src/translations/en_us/common.json @@ -1059,6 +1059,7 @@ "intake": "Intake", "manualnew": "Create New Job Manually", "mark": "Mark", + "markasexported": "Mark as Exported", "markpstexempt": "Mark Job PST Exempt", "markpstexemptconfirm": "Are you sure you want to do this? To undo this, you must manually update all PST rates.", "postbills": "Post Bills", @@ -1069,6 +1070,7 @@ "schedule": "Schedule", "sendcsi": "Send CSI", "sync": "Sync", + "uninvoice": "Uninvoice", "unvoid": "Unvoid Job", "viewchecklist": "View Checklists", "viewdetail": "View Details" @@ -1288,6 +1290,7 @@ "additionaltotal": "Additional Total", "adjustmentrate": "Adjustment Rate", "adjustments": "Adjustments", + "adminwarning": "Use the functionality on this page at your own risk. You are responsible for any and all changes to your data.", "allocations": "Allocations", "alreadyclosed": "This job has already been closed.", "appointmentconfirmation": "Send confirmation to customer?", @@ -1340,7 +1343,8 @@ "waived": "Waived" }, "deleteconfirm": "Are you sure you want to delete this job? This cannot be undone. ", - "deleteintake": "Delete Intake", + "deletedelivery": "Delete Delivery Checklist", + "deleteintake": "Delete Intake Checklist", "deliverchecklist": "Deliver Checklist", "difference": "Difference", "diskscan": "Scan Disk for Estimates", diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json index 63e5f30df..fbe1d0b23 100644 --- a/client/src/translations/es/common.json +++ b/client/src/translations/es/common.json @@ -1059,6 +1059,7 @@ "intake": "", "manualnew": "", "mark": "", + "markasexported": "", "markpstexempt": "", "markpstexemptconfirm": "", "postbills": "Contabilizar facturas", @@ -1069,6 +1070,7 @@ "schedule": "Programar", "sendcsi": "", "sync": "", + "uninvoice": "", "unvoid": "", "viewchecklist": "", "viewdetail": "" @@ -1288,6 +1290,7 @@ "additionaltotal": "", "adjustmentrate": "", "adjustments": "", + "adminwarning": "", "allocations": "", "alreadyclosed": "", "appointmentconfirmation": "¿Enviar confirmación al cliente?", @@ -1340,6 +1343,7 @@ "waived": "" }, "deleteconfirm": "", + "deletedelivery": "", "deleteintake": "", "deliverchecklist": "", "difference": "", diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json index 32f7b95d9..fd657e45a 100644 --- a/client/src/translations/fr/common.json +++ b/client/src/translations/fr/common.json @@ -1059,6 +1059,7 @@ "intake": "", "manualnew": "", "mark": "", + "markasexported": "", "markpstexempt": "", "markpstexemptconfirm": "", "postbills": "Poster des factures", @@ -1069,6 +1070,7 @@ "schedule": "Programme", "sendcsi": "", "sync": "", + "uninvoice": "", "unvoid": "", "viewchecklist": "", "viewdetail": "" @@ -1288,6 +1290,7 @@ "additionaltotal": "", "adjustmentrate": "", "adjustments": "", + "adminwarning": "", "allocations": "", "alreadyclosed": "", "appointmentconfirmation": "Envoyer une confirmation au client?", @@ -1340,6 +1343,7 @@ "waived": "" }, "deleteconfirm": "", + "deletedelivery": "", "deleteintake": "", "deliverchecklist": "", "difference": "",