diff --git a/client/src/components/jobs-admin-change-status/jobs-admin-change.status.component.jsx b/client/src/components/jobs-admin-change-status/jobs-admin-change.status.component.jsx
index edef81343..54a020d37 100644
--- a/client/src/components/jobs-admin-change-status/jobs-admin-change.status.component.jsx
+++ b/client/src/components/jobs-admin-change-status/jobs-admin-change.status.component.jsx
@@ -53,12 +53,14 @@ export function JobsAdminStatus({ insertAuditTrail, bodyshop, job }) {
);
return (
-
-
+
+ >
);
}
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 190778437..ec1bd976b 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
@@ -1,34 +1,18 @@
import { useMutation } from "@apollo/client";
-import { Button, notification } from "antd";
-import { gql } from "@apollo/client";
+import { Button, Space, notification } from "antd";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
+import {
+ DELETE_DELIVERY_CHECKLIST,
+ DELETE_INTAKE_CHECKLIST,
+} from "../../graphql/jobs.queries";
+
export default function JobAdminDeleteIntake({ job }) {
const { t } = useTranslation();
const [loading, setLoading] = useState(false);
- const [deleteIntake] = useMutation(gql`
- mutation DELETE_INTAKE($jobId: uuid!) {
- update_jobs_by_pk(
- pk_columns: { id: $jobId }
- _set: { intakechecklist: null }
- ) {
- id
- intakechecklist
- }
- }
- `);
- const [DELETE_DELIVERY] = useMutation(gql`
- mutation DELETE_DELIVERY($jobId: uuid!) {
- update_jobs_by_pk(
- pk_columns: { id: $jobId }
- _set: { deliverchecklist: null }
- ) {
- id
- deliverchecklist
- }
- }
- `);
+ const [deleteIntake] = useMutation(DELETE_INTAKE_CHECKLIST);
+ const [deleteDelivery] = useMutation(DELETE_DELIVERY_CHECKLIST);
const handleDelete = async (values) => {
setLoading(true);
@@ -50,7 +34,7 @@ export default function JobAdminDeleteIntake({ job }) {
const handleDeleteDelivery = async (values) => {
setLoading(true);
- const result = await DELETE_DELIVERY({
+ const result = await deleteDelivery({
variables: { jobId: job.id },
});
@@ -68,12 +52,22 @@ export default function JobAdminDeleteIntake({ job }) {
return (
<>
-
- {t("jobs.labels.deleteintake")}
-
-
- {t("jobs.labels.deletedelivery")}
-
+
+
+ {t("jobs.labels.deleteintake")}
+
+
+ {t("jobs.labels.deletedelivery")}
+
+
>
);
}
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 c47c30def..ae193fa72 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
@@ -1,5 +1,5 @@
-import { gql, useMutation } from "@apollo/client";
-import { Button, notification } from "antd";
+import { useMutation } from "@apollo/client";
+import { Button, Space, notification } from "antd";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
@@ -7,6 +7,11 @@ import moment from "moment";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { INSERT_EXPORT_LOG } from "../../graphql/accounting.queries";
+import {
+ MARK_JOB_AS_EXPORTED,
+ MARK_JOB_AS_UNINVOICED,
+ MARK_JOB_FOR_REEXPORT,
+} from "../../graphql/jobs.queries";
import { insertAuditTrail } from "../../redux/application/application.actions";
import {
selectBodyshop,
@@ -35,58 +40,18 @@ export function JobAdminMarkReexport({
const { t } = useTranslation();
const [loading, setLoading] = useState(false);
const [insertExportLog] = useMutation(INSERT_EXPORT_LOG);
- const [markJobForReexport] = useMutation(gql`
- mutation MARK_JOB_FOR_REEXPORT($jobId: uuid!) {
- update_jobs_by_pk(
- pk_columns: { id: $jobId }
- _set: { date_exported: null
- status: "${bodyshop.md_ro_statuses.default_invoiced}"
- }
- ) {
- id
- date_exported
- status
- date_invoiced
- }
- }
- `);
- 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 [markJobForReexport] = useMutation(MARK_JOB_FOR_REEXPORT);
+ const [markJobExported] = useMutation(MARK_JOB_AS_EXPORTED);
+ const [markJobUninvoiced] = useMutation(MARK_JOB_AS_UNINVOICED);
const handleMarkForExport = async () => {
setLoading(true);
const result = await markJobForReexport({
- variables: { jobId: job.id },
+ variables: {
+ jobId: job.id,
+ default_invoiced: bodyshop.md_ro_statuses.default_invoiced,
+ },
});
if (!result.errors) {
@@ -108,7 +73,11 @@ export function JobAdminMarkReexport({
const handleMarkExported = async () => {
setLoading(true);
const result = await markJobExported({
- variables: { jobId: job.id, date_exported: moment() },
+ variables: {
+ jobId: job.id,
+ date_exported: moment(),
+ default_exported: bodyshop.md_ro_statuses.default_exported,
+ },
});
await insertExportLog({
@@ -144,7 +113,10 @@ export function JobAdminMarkReexport({
const handleUninvoice = async () => {
setLoading(true);
const result = await markJobUninvoiced({
- variables: { jobId: job.id },
+ variables: {
+ jobId: job.id,
+ default_delivered: bodyshop.md_ro_statuses.default_delivered,
+ },
});
if (!result.errors) {
@@ -165,27 +137,29 @@ export function JobAdminMarkReexport({
return (
<>
-
- {t("jobs.labels.markforreexport")}
-
-
- {t("jobs.actions.markasexported")}
-
-
- {t("jobs.actions.uninvoice")}
-
+
+
+ {t("jobs.labels.markforreexport")}
+
+
+ {t("jobs.actions.markasexported")}
+
+
+ {t("jobs.actions.uninvoice")}
+
+
>
);
}
diff --git a/client/src/components/jobs-admin-remove-ar/jobs-admin-remove-ar.component.jsx b/client/src/components/jobs-admin-remove-ar/jobs-admin-remove-ar.component.jsx
new file mode 100644
index 000000000..f1bda15ce
--- /dev/null
+++ b/client/src/components/jobs-admin-remove-ar/jobs-admin-remove-ar.component.jsx
@@ -0,0 +1,65 @@
+import { useMutation } from "@apollo/client";
+import { Switch, notification } from "antd";
+import React, { useState } from "react";
+import { useTranslation } from "react-i18next";
+import { connect } from "react-redux";
+import { createStructuredSelector } from "reselect";
+import { UPDATE_REMOVE_FROM_AR } from "../../graphql/jobs.queries";
+import { insertAuditTrail } from "../../redux/application/application.actions";
+import AuditTrailMapping from "../../utils/AuditTrailMappings";
+
+const mapStateToProps = createStructuredSelector({});
+const mapDispatchToProps = (dispatch) => ({
+ insertAuditTrail: ({ jobid, operation }) =>
+ dispatch(insertAuditTrail({ jobid, operation })),
+});
+
+export default connect(mapStateToProps, mapDispatchToProps)(JobsAdminRemoveAR);
+
+export function JobsAdminRemoveAR({ insertAuditTrail, job }) {
+ const { t } = useTranslation();
+ const [loading, setLoading] = useState(false);
+ const [switchValue, setSwitchValue] = useState(job.remove_from_ar);
+
+ const [mutationUpdateRemoveFromAR] = useMutation(UPDATE_REMOVE_FROM_AR);
+
+ const handleChange = async (value) => {
+ setLoading(true);
+ const result = await mutationUpdateRemoveFromAR({
+ variables: { jobId: job.id, remove_from_ar: value },
+ });
+
+ if (!result.errors) {
+ notification["success"]({ message: t("jobs.successes.save") });
+ insertAuditTrail({
+ jobid: job.id,
+ operation: AuditTrailMapping.admin_job_remove_from_ar(value),
+ });
+ setSwitchValue(value);
+ } else {
+ notification["error"]({
+ message: t("jobs.errors.saving", {
+ error: JSON.stringify(result.errors),
+ }),
+ });
+ }
+ setLoading(false);
+ };
+
+ return (
+ <>
+
+
+ {t("jobs.labels.remove_from_ar")}:
+
+
+
+
+
+ >
+ );
+}
diff --git a/client/src/components/jobs-admin-unvoid/jobs-admin-unvoid.component.jsx b/client/src/components/jobs-admin-unvoid/jobs-admin-unvoid.component.jsx
index 7963fd05f..2094178c4 100644
--- a/client/src/components/jobs-admin-unvoid/jobs-admin-unvoid.component.jsx
+++ b/client/src/components/jobs-admin-unvoid/jobs-admin-unvoid.component.jsx
@@ -1,9 +1,10 @@
-import { gql, useMutation } from "@apollo/client";
+import { useMutation } from "@apollo/client";
import { Button, notification } from "antd";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
+import { UNVOID_JOB } from "../../graphql/jobs.queries";
import { insertAuditTrail } from "../../redux/application/application.actions";
import {
selectBodyshop,
@@ -29,66 +30,17 @@ export function JobsAdminUnvoid({
}) {
const { t } = useTranslation();
const [loading, setLoading] = useState(false);
- const [updateJob] = useMutation(gql`
-mutation UNVOID_JOB($jobId: uuid!) {
- update_jobs_by_pk(pk_columns: {id: $jobId}, _set: {voided: false, status: "${
- bodyshop.md_ro_statuses.default_imported
- }", date_void: null}) {
- id
- date_void
- voided
- status
- }
- insert_notes(objects: {jobid: $jobId, audit: true, created_by: "${
- currentUser.email
- }", text: "${t("jobs.labels.unvoidnote")}"}) {
- returning {
- id
- }
- }
-}
-
- `);
-
- // const result = await voidJob({
- // variables: {
- // jobId: job.id,
- // job: {
- // status: bodyshop.md_ro_statuses.default_void,
- // voided: true,
- // },
- // note: [
- // {
- // jobid: job.id,
- // created_by: currentUser.email,
- // audit: true,
- // text: t("jobs.labels.voidnote", {
- // date: moment().format("MM/DD/yyy"),
- // time: moment().format("hh:mm a"),
- // }),
- // },
- // ],
- // },
- // });
-
- // if (!!!result.errors) {
- // notification["success"]({
- // message: t("jobs.successes.voided"),
- // });
- // //go back to jobs list.
- // history.push(`/manage/`);
- // } else {
- // notification["error"]({
- // message: t("jobs.errors.voiding", {
- // error: JSON.stringify(result.errors),
- // }),
- // });
- // }
+ const [mutationUnvoidJob] = useMutation(UNVOID_JOB);
const handleUpdate = async (values) => {
setLoading(true);
- const result = await updateJob({
- variables: { jobId: job.id },
+ const result = await mutationUnvoidJob({
+ variables: {
+ jobId: job.id,
+ default_imported: bodyshop.md_ro_statuses.default_imported,
+ currentUserEmail: currentUser.email,
+ text: t("jobs.labels.unvoidnote"),
+ },
});
if (!result.errors) {
@@ -110,8 +62,10 @@ mutation UNVOID_JOB($jobId: uuid!) {
};
return (
-
- {t("jobs.actions.unvoid")}
-
+ <>
+
+ {t("jobs.actions.unvoid")}
+
+ >
);
}
diff --git a/client/src/components/report-center-modal/report-center-modal.component.jsx b/client/src/components/report-center-modal/report-center-modal.component.jsx
index 913d27282..c4bef11c3 100644
--- a/client/src/components/report-center-modal/report-center-modal.component.jsx
+++ b/client/src/components/report-center-modal/report-center-modal.component.jsx
@@ -68,8 +68,8 @@ export function ReportCenterModalComponent({ reportCenterModal }) {
const handleFinish = async (values) => {
setLoading(true);
- const start = values.dates[0];
- const end = values.dates[1];
+ const start = values.dates ? values.dates[0] : null;
+ const end = values.dates ? values.dates[1] : null;
const { id } = values;
await GenerateDocument(
@@ -239,20 +239,30 @@ export function ReportCenterModalComponent({ reportCenterModal }) {
else return null;
}}
-
-
+
+ {() => {
+ const key = form.getFieldValue("key");
+ const datedisable = Templates[key] && Templates[key].datedisable;
+ if (datedisable !== true) {
+ return (
+
+
+
+ );
+ } else return null;
+ }}
{() => {
diff --git a/client/src/graphql/jobs.queries.js b/client/src/graphql/jobs.queries.js
index 4a1c85036..57bb935f8 100644
--- a/client/src/graphql/jobs.queries.js
+++ b/client/src/graphql/jobs.queries.js
@@ -545,147 +545,166 @@ export const QUERY_JOB_COSTING_DETAILS = gql`
export const GET_JOB_BY_PK = gql`
query GET_JOB_BY_PK($id: uuid!) {
jobs_by_pk(id: $id) {
- updated_at
+ actual_completion
+ actual_delivery
+ actual_in
+ adjustment_bottom_line
+ area_of_damage
+ auto_add_ats
+ available_jobs {
+ id
+ }
+ alt_transport
+ ca_bc_pvrt
+ ca_customer_gst
+ ca_gst_registrant
+ category
+ cccontracts {
+ agreementnumber
+ courtesycar {
+ fleetnumber
+ id
+ make
+ model
+ plate
+ year
+ }
+ id
+ scheduledreturn
+ start
+ status
+ }
+ cieca_ttl
+ class
+ clm_no
+ clm_total
+ comment
+ converted
+ csiinvites {
+ completedon
+ id
+ }
+ date_estimated
+ date_exported
+ date_invoiced
+ date_last_contacted
+ date_lost_sale
+ date_next_contact
+ date_open
+ date_rentalresp
+ date_repairstarted
+ date_scheduled
+ date_towin
+ date_void
+ ded_amt
+ ded_note
+ ded_status
+ deliverchecklist
+ depreciation_taxes
+ driveable
+ employee_body
employee_body_rel {
id
first_name
last_name
}
- employee_refinish_rel {
- id
- first_name
- last_name
- }
- employee_prep_rel {
- id
- first_name
- last_name
- }
+ employee_csr
employee_csr_rel {
id
first_name
last_name
}
- employee_csr
employee_prep
+ employee_prep_rel {
+ id
+ first_name
+ last_name
+ }
employee_refinish
- employee_body
- alt_transport
- intakechecklist
- invoice_final_note
- comment
- loss_desc
- kmin
- kmout
- referral_source
- referral_source_extra
- unit_number
- po_number
- special_coverage_policy
- scheduled_delivery
- converted
- lbr_adjustments
- ro_number
- po_number
- clm_total
+ employee_refinish_rel {
+ id
+ first_name
+ last_name
+ }
+ est_co_nm
+ est_ct_fn
+ est_ct_ln
+ est_ea
+ est_ph1
+ federal_tax_rate
+ id
inproduction
- vehicleid
- plate_no
- plate_st
- v_vin
- v_model_yr
- v_model_desc
- v_make_desc
- v_color
- vehicleid
- driveable
- towin
- loss_of_use
- lost_sale_reason
- vehicle {
- id
- plate_no
- plate_st
- v_vin
- v_model_yr
- v_model_desc
- v_make_desc
- v_color
- notes
- v_paint_codes
- jobs {
- id
- ro_number
- status
- clm_no
- }
- }
- available_jobs {
- id
- }
- ins_co_id
- policy_no
- loss_date
- clm_no
- area_of_damage
- ins_co_nm
ins_addr1
ins_city
+ ins_co_id
+ ins_co_nm
ins_ct_ln
ins_ct_fn
ins_ea
ins_ph1
- est_co_nm
- est_ct_fn
- est_ct_ln
- est_ph1
- est_ea
- selling_dealer
- servicing_dealer
- selling_dealer_contact
- servicing_dealer_contact
- regie_number
- scheduled_completion
- id
- ded_amt
- ded_status
- depreciation_taxes
- other_amount_payable
- towing_payable
- storage_payable
- adjustment_bottom_line
- federal_tax_rate
- state_tax_rate
- local_tax_rate
- tax_tow_rt
- tax_str_rt
- tax_paint_mat_rt
- tax_shop_mat_rt
- tax_sub_rt
- tax_lbr_rt
- tax_levies_rt
- parts_tax_rates
- job_totals
- ownr_fn
- ownr_ln
- ownr_co_nm
- ownr_ea
- ownr_addr1
- ownr_addr2
- ownr_city
- ownr_st
- ownr_zip
- ownr_ctry
- ownr_ph1
- ownr_ph2
- production_vars
- ca_gst_registrant
- ownerid
- ded_note
- materials
- auto_add_ats
- rate_ats
+ intakechecklist
+ invoice_final_note
iouparent
+ job_totals
+ joblines(where: { removed: { _eq: false } }, order_by: { line_no: asc }) {
+ act_price
+ ah_detail_line
+ alt_partm
+ alt_partno
+ billlines(limit: 1, order_by: { bill: { date: desc } }) {
+ actual_cost
+ actual_price
+ bill {
+ id
+ invoice_number
+ vendor {
+ id
+ name
+ }
+ }
+ joblineid
+ id
+ quantity
+ }
+ convertedtolbr
+ critical
+ db_hrs
+ db_price
+ db_ref
+ id
+ ioucreated
+ lbr_amt
+ lbr_op
+ line_desc
+ line_ind
+ line_no
+ line_ref
+ location
+ manual_line
+ mod_lb_hrs
+ mod_lbr_ty
+ notes
+ oem_partno
+ op_code_desc
+ part_qty
+ part_type
+ prt_dsmk_m
+ prt_dsmk_p
+ status
+ tax_part
+ unq_seq
+ }
+ kmin
+ kmout
+ labor_rate_desc
+ lbr_adjustments
+ local_tax_rate
+ loss_date
+ loss_desc
+ loss_of_use
+ lost_sale_reason
+ materials
+ other_amount_payable
owner {
id
ownr_fn
@@ -702,7 +721,40 @@ export const GET_JOB_BY_PK = gql`
ownr_ph2
tax_number
}
- labor_rate_desc
+ owner_owing
+ ownerid
+ ownr_addr1
+ ownr_addr2
+ ownr_ctry
+ ownr_city
+ ownr_co_nm
+ ownr_ea
+ ownr_fn
+ ownr_ln
+ ownr_ph1
+ ownr_ph2
+ ownr_st
+ ownr_zip
+ parts_tax_rates
+ payments {
+ amount
+ created_at
+ date
+ exportedat
+ id
+ jobid
+ memo
+ payer
+ paymentnum
+ transactionid
+ type
+ }
+ plate_no
+ plate_st
+ po_number
+ policy_no
+ production_vars
+ rate_ats
rate_la1
rate_la2
rate_la3
@@ -726,121 +778,64 @@ export const GET_JOB_BY_PK = gql`
rate_mapa
rate_mash
rate_matd
- actual_in
- federal_tax_rate
- local_tax_rate
- state_tax_rate
+ regie_number
+ referral_source
+ referral_source_extra
+ remove_from_ar
+ ro_number
scheduled_completion
- scheduled_in
- actual_completion
scheduled_delivery
- actual_delivery
- date_estimated
- date_open
- date_scheduled
- date_invoiced
- date_last_contacted
- date_lost_sale
- date_next_contact
- date_towin
- date_rentalresp
- date_exported
- date_repairstarted
- date_void
+ scheduled_in
+ selling_dealer
+ servicing_dealer
+ selling_dealer_contact
+ servicing_dealer_contact
+ special_coverage_policy
+ state_tax_rate
status
- owner_owing
- tax_registration_number
- class
- category
- deliverchecklist
- voided
- ca_bc_pvrt
- ca_customer_gst
+ storage_payable
suspended
- joblines(where: { removed: { _eq: false } }, order_by: { line_no: asc }) {
+ tax_lbr_rt
+ tax_levies_rt
+ tax_paint_mat_rt
+ tax_registration_number
+ tax_shop_mat_rt
+ tax_str_rt
+ tax_sub_rt
+ tax_tow_rt
+ towin
+ towing_payable
+ unit_number
+ updated_at
+ v_vin
+ v_model_yr
+ v_model_desc
+ v_make_desc
+ v_color
+ vehicleid
+ vehicle {
id
- alt_partm
- line_no
- unq_seq
- line_ind
- line_desc
- line_ref
- part_type
- oem_partno
- alt_partno
- db_price
- act_price
- part_qty
- mod_lbr_ty
- db_hrs
- mod_lb_hrs
- lbr_op
- lbr_amt
- op_code_desc
- status
+ jobs {
+ clm_no
+ id
+ ro_number
+ status
+ }
notes
- location
- tax_part
- db_ref
- manual_line
- prt_dsmk_p
- prt_dsmk_m
- ioucreated
- convertedtolbr
- ah_detail_line
- critical
- billlines(limit: 1, order_by: { bill: { date: desc } }) {
- id
- quantity
- actual_cost
- actual_price
- joblineid
- bill {
- id
- invoice_number
- vendor {
- id
- name
- }
- }
- }
- }
- payments {
- id
- jobid
- amount
- payer
- paymentnum
- created_at
- transactionid
- memo
- date
- type
- exportedat
- }
- cccontracts {
- id
- status
- start
- scheduledreturn
- agreementnumber
- courtesycar {
- id
- make
- model
- year
- plate
- fleetnumber
- }
- }
- cieca_ttl
- csiinvites {
- id
- completedon
+ plate_no
+ plate_st
+ v_color
+ v_make_desc
+ v_model_desc
+ v_model_yr
+ v_paint_codes
+ v_vin
}
+ voided
}
}
`;
+
export const GET_JOB_RECONCILIATION_BY_PK = gql`
query GET_JOB_RECONCILIATION_BY_PK($id: uuid!) {
bills(where: { jobid: { _eq: $id } }) {
@@ -905,6 +900,7 @@ export const GET_JOB_RECONCILIATION_BY_PK = gql`
}
}
`;
+
export const QUERY_JOB_CARD_DETAILS = gql`
query QUERY_JOB_CARD_DETAILS($id: uuid!) {
jobs_by_pk(id: $id) {
@@ -2225,3 +2221,120 @@ export const GET_JOB_LINE_ORDERS = gql`
}
}
`;
+
+export const UPDATE_REMOVE_FROM_AR = gql`
+ mutation UPDATE_REMOVE_FROM_AR($jobId: uuid!, $remove_from_ar: Boolean!) {
+ update_jobs_by_pk(
+ pk_columns: { id: $jobId }
+ _set: { remove_from_ar: $remove_from_ar }
+ ) {
+ id
+ remove_from_ar
+ }
+ }
+`;
+
+export const UNVOID_JOB = gql`
+ mutation UNVOID_JOB(
+ $jobId: uuid!
+ $default_imported: String!
+ $currentUserEmail: String!
+ $text: String!
+ ) {
+ update_jobs_by_pk(
+ pk_columns: { id: $jobId }
+ _set: { voided: false, status: $default_imported, date_void: null }
+ ) {
+ id
+ date_void
+ voided
+ status
+ }
+ insert_notes(
+ objects: {
+ jobid: $jobId
+ audit: true
+ created_by: $currentUserEmail
+ text: $text
+ }
+ ) {
+ returning {
+ id
+ }
+ }
+ }
+`;
+
+export const DELETE_INTAKE_CHECKLIST = gql`
+ mutation DELETE_INTAKE($jobId: uuid!) {
+ update_jobs_by_pk(
+ pk_columns: { id: $jobId }
+ _set: { intakechecklist: null }
+ ) {
+ id
+ intakechecklist
+ }
+ }
+`;
+
+export const DELETE_DELIVERY_CHECKLIST = gql`
+ mutation DELETE_DELIVERY($jobId: uuid!) {
+ update_jobs_by_pk(
+ pk_columns: { id: $jobId }
+ _set: { deliverchecklist: null }
+ ) {
+ id
+ deliverchecklist
+ }
+ }
+`;
+
+export const MARK_JOB_FOR_REEXPORT = gql`
+ mutation MARK_JOB_FOR_REEXPORT($jobId: uuid!, $default_invoiced: String!) {
+ update_jobs_by_pk(
+ pk_columns: { id: $jobId }
+ _set: { date_exported: null, status: $default_invoiced }
+ ) {
+ id
+ date_exported
+ status
+ date_invoiced
+ }
+ }
+`;
+
+export const MARK_JOB_AS_EXPORTED = gql`
+ mutation MARK_JOB_AS_EXPORTED(
+ $jobId: uuid!
+ $date_exported: timestamptz!
+ $default_exported: String!
+ ) {
+ update_jobs_by_pk(
+ pk_columns: { id: $jobId }
+ _set: { date_exported: $date_exported, status: $default_exported }
+ ) {
+ id
+ date_exported
+ date_invoiced
+ status
+ }
+ }
+`;
+
+export const MARK_JOB_AS_UNINVOICED = gql`
+ mutation MARK_JOB_AS_UNINVOICED($jobId: uuid!, $default_delivered: String!) {
+ update_jobs_by_pk(
+ pk_columns: { id: $jobId }
+ _set: {
+ date_exported: null
+ date_invoiced: null
+ status: $default_delivered
+ }
+ ) {
+ id
+ date_exported
+ date_invoiced
+ status
+ }
+ }
+`;
diff --git a/client/src/pages/jobs-admin/jobs-admin.page.jsx b/client/src/pages/jobs-admin/jobs-admin.page.jsx
index 0d08e5114..0c7eb9a33 100644
--- a/client/src/pages/jobs-admin/jobs-admin.page.jsx
+++ b/client/src/pages/jobs-admin/jobs-admin.page.jsx
@@ -7,16 +7,16 @@ import { useParams } from "react-router-dom";
import AlertComponent from "../../components/alert/alert.component";
import JobCalculateTotals from "../../components/job-calculate-totals/job-calculate-totals.component";
import ScoreboardAddButton from "../../components/job-scoreboard-add-button/job-scoreboard-add-button.component";
+import JobsAdminStatus from "../../components/jobs-admin-change-status/jobs-admin-change.status.component";
import JobsAdminClass from "../../components/jobs-admin-class/jobs-admin-class.component";
import JobsAdminDatesChange from "../../components/jobs-admin-dates/jobs-admin-dates.component";
import JobsAdminDeleteIntake from "../../components/jobs-admin-delete-intake/jobs-admin-delete-intake.component";
import JobsAdminMarkReexport from "../../components/jobs-admin-mark-reexport/jobs-admin-mark-reexport.component";
import JobAdminOwnerReassociate from "../../components/jobs-admin-owner-reassociate/jobs-admin-owner-reassociate.component";
+import JobsAdminRemoveAR from "../../components/jobs-admin-remove-ar/jobs-admin-remove-ar.component";
import JobsAdminUnvoid from "../../components/jobs-admin-unvoid/jobs-admin-unvoid.component";
import JobAdminVehicleReassociate from "../../components/jobs-admin-vehicle-reassociate/jobs-admin-vehicle-reassociate.component";
import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component";
-import JobsAdminStatus from "../../components/jobs-admin-change-status/jobs-admin-change.status.component";
-
import NotFound from "../../components/not-found/not-found.component";
import RbacWrapper from "../../components/rbac-wrapper/rbac-wrapper.component";
import { GET_JOB_BY_PK } from "../../graphql/jobs.queries";
@@ -104,6 +104,7 @@ export function JobsCloseContainer({ setBreadcrumbs, setSelectedHeader }) {
+
diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json
index 919f7e297..1589e9b5f 100644
--- a/client/src/translations/en_us/common.json
+++ b/client/src/translations/en_us/common.json
@@ -99,6 +99,7 @@
},
"audit_trail": {
"messages": {
+ "admin_job_remove_from_ar": "ADMIN: Remove from AR updated to: {{status}}",
"admin_jobmarkexported": "ADMIN: Job marked as exported.",
"admin_jobmarkforreexport": "ADMIN: Job marked for re-export.",
"admin_jobuninvoice": "ADMIN: Job has been uninvoiced.",
@@ -1833,6 +1834,7 @@
},
"reconciliationheader": "Parts & Sublet Reconciliation",
"relatedros": "Related ROs",
+ "remove_from_ar": "Remove from AR",
"returntotals": "Return Totals",
"rosaletotal": "RO Parts Total",
"sale_additional": "Sales - Additional",
@@ -2563,6 +2565,7 @@
},
"templates": {
"anticipated_revenue": "Anticipated Revenue",
+ "ar_aging": "AR Aging",
"attendance_detail": "Attendance (All Employees)",
"attendance_employee": "Employee Attendance",
"attendance_summary": "Attendance Summary (All Employees)",
diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json
index a798f790c..fc977e7eb 100644
--- a/client/src/translations/es/common.json
+++ b/client/src/translations/es/common.json
@@ -99,6 +99,7 @@
},
"audit_trail": {
"messages": {
+ "admin_job_remove_from_ar": "",
"admin_jobmarkexported": "",
"admin_jobmarkforreexport": "",
"admin_jobuninvoice": "",
@@ -1833,6 +1834,7 @@
},
"reconciliationheader": "",
"relatedros": "",
+ "remove_from_ar": "",
"returntotals": "",
"rosaletotal": "",
"sale_additional": "",
@@ -2563,6 +2565,7 @@
},
"templates": {
"anticipated_revenue": "",
+ "ar_aging": "",
"attendance_detail": "",
"attendance_employee": "",
"attendance_summary": "",
diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json
index b65abaf04..76e3ce6a9 100644
--- a/client/src/translations/fr/common.json
+++ b/client/src/translations/fr/common.json
@@ -99,6 +99,7 @@
},
"audit_trail": {
"messages": {
+ "admin_job_remove_from_ar": "",
"admin_jobmarkexported": "",
"admin_jobmarkforreexport": "",
"admin_jobuninvoice": "",
@@ -1833,6 +1834,7 @@
},
"reconciliationheader": "",
"relatedros": "",
+ "remove_from_ar": "",
"returntotals": "",
"rosaletotal": "",
"sale_additional": "",
@@ -2563,6 +2565,7 @@
},
"templates": {
"anticipated_revenue": "",
+ "ar_aging": "",
"attendance_detail": "",
"attendance_employee": "",
"attendance_summary": "",
diff --git a/client/src/utils/AuditTrailMappings.js b/client/src/utils/AuditTrailMappings.js
index d7098fa2d..eefbb3a11 100644
--- a/client/src/utils/AuditTrailMappings.js
+++ b/client/src/utils/AuditTrailMappings.js
@@ -1,54 +1,56 @@
import i18n from "i18next";
const AuditTrailMapping = {
- alertToggle: (status) => i18n.t("audit_trail.messages.alerttoggle", { status }),
+ admin_job_remove_from_ar: (status) =>
+ i18n.t("audit_trail.messages.admin_job_remove_from_ar", { status }),
+ admin_jobfieldchange: (field, value) =>
+ "ADMIN: " +
+ i18n.t("audit_trail.messages.jobfieldchanged", { field, value }),
+ admin_jobmarkexported: () =>
+ i18n.t("audit_trail.messages.admin_jobmarkexported"),
+ admin_jobmarkforreexport: () =>
+ i18n.t("audit_trail.messages.admin_jobmarkforreexport"),
+ admin_jobstatuschange: (status) =>
+ "ADMIN: " + i18n.t("audit_trail.messages.jobstatuschange", { status }),
+ admin_jobuninvoice: () => i18n.t("audit_trail.messages.admin_jobuninvoice"),
+ admin_jobunvoid: () => i18n.t("audit_trail.messages.admin_jobunvoid"),
+ alertToggle: (status) =>
+ i18n.t("audit_trail.messages.alerttoggle", { status }),
appointmentcancel: (lost_sale_reason) =>
i18n.t("audit_trail.messages.appointmentcancel", { lost_sale_reason }),
appointmentinsert: (start) =>
i18n.t("audit_trail.messages.appointmentinsert", { start }),
- jobstatuschange: (status) =>
- i18n.t("audit_trail.messages.jobstatuschange", { status }),
- admin_jobstatuschange: (status) =>
- "ADMIN: " + i18n.t("audit_trail.messages.jobstatuschange", { status }),
- jobsupplement: () => i18n.t("audit_trail.messages.jobsupplement"),
- jobimported: () => i18n.t("audit_trail.messages.jobimported"),
- jobinvoiced: () =>
- i18n.t("audit_trail.messages.jobinvoiced"),
- jobconverted: (ro_number) =>
- i18n.t("audit_trail.messages.jobconverted", { ro_number }),
- jobfieldchange: (field, value) =>
- i18n.t("audit_trail.messages.jobfieldchanged", { field, value }),
- admin_jobfieldchange: (field, value) =>
- "ADMIN: " +
- i18n.t("audit_trail.messages.jobfieldchanged", { field, value }),
- jobspartsorder: (order_number) =>
- i18n.t("audit_trail.messages.jobspartsorder", { order_number }),
- jobspartsreturn: (order_number) =>
- i18n.t("audit_trail.messages.jobspartsreturn", { order_number }),
- jobmodifylbradj: ({ mod_lbr_ty, hours }) =>
- i18n.t("audit_trail.messages.jobmodifylbradj", { mod_lbr_ty, hours }),
billposted: (invoice_number) =>
i18n.t("audit_trail.messages.billposted", { invoice_number }),
billupdated: (invoice_number) =>
i18n.t("audit_trail.messages.billupdated", { invoice_number }),
+ failedpayment: () => i18n.t("audit_trail.messages.failedpayment"),
jobassignmentchange: (operation, name) =>
i18n.t("audit_trail.messages.jobassignmentchange", { operation, name }),
jobassignmentremoved: (operation) =>
i18n.t("audit_trail.messages.jobassignmentremoved", { operation }),
- jobinproductionchange: (inproduction) =>
- i18n.t("audit_trail.messages.jobinproductionchange", { inproduction }),
jobchecklist: (type, inproduction, status) =>
i18n.t("audit_trail.messages.jobchecklist", { type, inproduction, status }),
+ jobconverted: (ro_number) =>
+ i18n.t("audit_trail.messages.jobconverted", { ro_number }),
+ jobfieldchange: (field, value) =>
+ i18n.t("audit_trail.messages.jobfieldchanged", { field, value }),
+ jobimported: () => i18n.t("audit_trail.messages.jobimported"),
+ jobinproductionchange: (inproduction) =>
+ i18n.t("audit_trail.messages.jobinproductionchange", { inproduction }),
+ jobinvoiced: () => i18n.t("audit_trail.messages.jobinvoiced"),
+ jobmodifylbradj: ({ mod_lbr_ty, hours }) =>
+ i18n.t("audit_trail.messages.jobmodifylbradj", { mod_lbr_ty, hours }),
jobnoteadded: () => i18n.t("audit_trail.messages.jobnoteadded"),
- jobnoteupdated: () => i18n.t("audit_trail.messages.jobnoteupdated"),
jobnotedeleted: () => i18n.t("audit_trail.messages.jobnotedeleted"),
- admin_jobunvoid: () => i18n.t("audit_trail.messages.admin_jobunvoid"),
- admin_jobuninvoice: () => i18n.t("audit_trail.messages.admin_jobuninvoice"),
- admin_jobmarkforreexport: () =>
- i18n.t("audit_trail.messages.admin_jobmarkforreexport"),
- admin_jobmarkexported: () =>
- i18n.t("audit_trail.messages.admin_jobmarkexported"),
- failedpayment: () => i18n.t("audit_trail.messages.failedpayment"),
+ jobnoteupdated: () => i18n.t("audit_trail.messages.jobnoteupdated"),
+ jobspartsorder: (order_number) =>
+ i18n.t("audit_trail.messages.jobspartsorder", { order_number }),
+ jobspartsreturn: (order_number) =>
+ i18n.t("audit_trail.messages.jobspartsreturn", { order_number }),
+ jobstatuschange: (status) =>
+ i18n.t("audit_trail.messages.jobstatuschange", { status }),
+ jobsupplement: () => i18n.t("audit_trail.messages.jobsupplement"),
};
export default AuditTrailMapping;
diff --git a/client/src/utils/TemplateConstants.js b/client/src/utils/TemplateConstants.js
index eeb937c3a..ad614af3b 100644
--- a/client/src/utils/TemplateConstants.js
+++ b/client/src/utils/TemplateConstants.js
@@ -2020,6 +2020,7 @@ export const TemplateList = (type, context) => {
key: "lost_sales",
//idtype: "vendor",
disabled: false,
+ datedisable: true,
rangeFilter: {
object: i18n.t("reportcenter.labels.objects.jobs"),
field: i18n.t("jobs.fields.date_lost_sale"),
@@ -2039,6 +2040,15 @@ export const TemplateList = (type, context) => {
},
group: "jobs",
},
+ ar_aging: {
+ title: i18n.t("reportcenter.templates.ar_aging"),
+ subject: i18n.t("reportcenter.templates.ar_aging"),
+ key: "ar_aging",
+ //idtype: "vendor",
+ disabled: false,
+ datedisable: true,
+ group: "customers",
+ },
}
: {}),
...(!type || type === "courtesycarcontract"
diff --git a/hasura/migrations/1706207204357_run_sql_migration/down.sql b/hasura/migrations/1706207204357_run_sql_migration/down.sql
new file mode 100644
index 000000000..1deabac64
--- /dev/null
+++ b/hasura/migrations/1706207204357_run_sql_migration/down.sql
@@ -0,0 +1,35 @@
+-- Could not auto-generate a down migration.
+-- Please write an appropriate down migration for the SQL below:
+-- CREATE OR REPLACE FUNCTION public.jobs_ar_summary ()
+-- RETURNS SETOF job_ar_schema
+-- LANGUAGE plpgsql
+-- STABLE
+-- AS $function$
+-- BEGIN
+--
+-- RETURN query
+-- select
+-- j.id,
+-- j.ro_number,
+-- j.clm_total,
+-- coalesce (p.total_payments,0) as total_payments,
+-- j.clm_total - coalesce (p.total_payments,0) as balance,
+-- j.date_invoiced,
+-- j.shopid
+-- from
+-- jobs j
+-- left join (
+-- select
+-- p.jobid,
+-- coalesce (sum(p.amount),0) as total_payments
+-- from
+-- payments p
+-- group by
+-- p.jobid
+-- ) p on
+-- j.id = p.jobid
+-- where j.remove_from_ar = false and j.date_invoiced is not null and j.clm_total - coalesce (p.total_payments,0) != 0;
+--
+--
+-- END
+-- $function$;
diff --git a/hasura/migrations/1706207204357_run_sql_migration/up.sql b/hasura/migrations/1706207204357_run_sql_migration/up.sql
new file mode 100644
index 000000000..6a42b8d7a
--- /dev/null
+++ b/hasura/migrations/1706207204357_run_sql_migration/up.sql
@@ -0,0 +1,33 @@
+CREATE OR REPLACE FUNCTION public.jobs_ar_summary ()
+ RETURNS SETOF job_ar_schema
+ LANGUAGE plpgsql
+ STABLE
+ AS $function$
+BEGIN
+
+ RETURN query
+select
+ j.id,
+ j.ro_number,
+ j.clm_total,
+ coalesce (p.total_payments,0) as total_payments,
+ j.clm_total - coalesce (p.total_payments,0) as balance,
+ j.date_invoiced,
+ j.shopid
+from
+ jobs j
+left join (
+ select
+ p.jobid,
+ coalesce (sum(p.amount),0) as total_payments
+ from
+ payments p
+ group by
+ p.jobid
+ ) p on
+ j.id = p.jobid
+where j.remove_from_ar = false and j.date_invoiced is not null and j.clm_total - coalesce (p.total_payments,0) != 0;
+
+
+END
+$function$;
diff --git a/hasura/migrations/1706207267558_run_sql_migration/down.sql b/hasura/migrations/1706207267558_run_sql_migration/down.sql
new file mode 100644
index 000000000..1deabac64
--- /dev/null
+++ b/hasura/migrations/1706207267558_run_sql_migration/down.sql
@@ -0,0 +1,35 @@
+-- Could not auto-generate a down migration.
+-- Please write an appropriate down migration for the SQL below:
+-- CREATE OR REPLACE FUNCTION public.jobs_ar_summary ()
+-- RETURNS SETOF job_ar_schema
+-- LANGUAGE plpgsql
+-- STABLE
+-- AS $function$
+-- BEGIN
+--
+-- RETURN query
+-- select
+-- j.id,
+-- j.ro_number,
+-- j.clm_total,
+-- coalesce (p.total_payments,0) as total_payments,
+-- j.clm_total - coalesce (p.total_payments,0) as balance,
+-- j.date_invoiced,
+-- j.shopid
+-- from
+-- jobs j
+-- left join (
+-- select
+-- p.jobid,
+-- coalesce (sum(p.amount),0) as total_payments
+-- from
+-- payments p
+-- group by
+-- p.jobid
+-- ) p on
+-- j.id = p.jobid
+-- where j.remove_from_ar = false and j.date_invoiced is not null and j.clm_total - coalesce (p.total_payments,0) != 0;
+--
+--
+-- END
+-- $function$;
diff --git a/hasura/migrations/1706207267558_run_sql_migration/up.sql b/hasura/migrations/1706207267558_run_sql_migration/up.sql
new file mode 100644
index 000000000..6a42b8d7a
--- /dev/null
+++ b/hasura/migrations/1706207267558_run_sql_migration/up.sql
@@ -0,0 +1,33 @@
+CREATE OR REPLACE FUNCTION public.jobs_ar_summary ()
+ RETURNS SETOF job_ar_schema
+ LANGUAGE plpgsql
+ STABLE
+ AS $function$
+BEGIN
+
+ RETURN query
+select
+ j.id,
+ j.ro_number,
+ j.clm_total,
+ coalesce (p.total_payments,0) as total_payments,
+ j.clm_total - coalesce (p.total_payments,0) as balance,
+ j.date_invoiced,
+ j.shopid
+from
+ jobs j
+left join (
+ select
+ p.jobid,
+ coalesce (sum(p.amount),0) as total_payments
+ from
+ payments p
+ group by
+ p.jobid
+ ) p on
+ j.id = p.jobid
+where j.remove_from_ar = false and j.date_invoiced is not null and j.clm_total - coalesce (p.total_payments,0) != 0;
+
+
+END
+$function$;