diff --git a/client/src/components/invoice-enter-modal/invoice-enter-modal.container.jsx b/client/src/components/invoice-enter-modal/invoice-enter-modal.container.jsx index ef031c7d2..d8371253c 100644 --- a/client/src/components/invoice-enter-modal/invoice-enter-modal.container.jsx +++ b/client/src/components/invoice-enter-modal/invoice-enter-modal.container.jsx @@ -1,5 +1,6 @@ import React, { useState } from "react"; -import { useLazyQuery, useQuery } from "react-apollo"; +import { notification } from "antd"; +import { useLazyQuery, useQuery, useMutation } from "react-apollo"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { GET_JOB_LINES_TO_ENTER_INVOICE } from "../../graphql/jobs-lines.queries"; @@ -9,6 +10,8 @@ import { toggleModalVisible } from "../../redux/modals/modals.actions"; import { selectInvoiceEnterModal } from "../../redux/modals/modals.selectors"; import { selectBodyshop } from "../../redux/user/user.selectors"; import InvoiceEnterModalComponent from "./invoice-enter-modal.component"; +import { INSERT_NEW_INVOICE } from "../../graphql/invoices.queries"; +import { useTranslation } from "react-i18next"; const mapStateToProps = createStructuredSelector({ invoiceEnterModal: selectInvoiceEnterModal, @@ -23,11 +26,13 @@ function InvoiceEnterModalContainer({ toggleModalVisible, bodyshop }) { - // const { t } = useTranslation(); + const { t } = useTranslation(); const linesState = useState([]); const roSearchState = useState({ text: "", selectedId: null }); const [roSearch, setRoSearch] = roSearchState; + const [insertInvoice] = useMutation(INSERT_NEW_INVOICE); + const { data: RoAutoCompleteData } = useQuery(ACTIVE_JOBS_FOR_AUTOCOMPLETE, { fetchPolicy: "network-only", variables: { statuses: bodyshop.md_ro_statuses.open_statuses || ["Open"] }, @@ -68,52 +73,49 @@ function InvoiceEnterModalContainer({ const handleFinish = values => { console.log("values", values); - alert("Closing this modal."); - // toggleModalVisible(); - // if (!jobLineEditModal.context.id) { - // insertJobLine({ - // variables: { - // lineInput: [{ jobid: jobLineEditModal.context.jobid, ...values }] - // } - // }) - // .then(r => { - // if (jobLineEditModal.actions.refetch) - // jobLineEditModal.actions.refetch(); - // toggleModalVisible(); - // notification["success"]({ - // message: t("joblines.successes.created") - // }); - // }) - // .catch(error => { - // notification["error"]({ - // message: t("joblines.errors.creating", { - // message: error.message - // }) - // }); - // }); - // } else { - // updateJobLine({ - // variables: { - // lineId: jobLineEditModal.context.id, - // line: values - // } - // }) - // .then(r => { - // notification["success"]({ - // message: t("joblines.successes.updated") - // }); - // }) - // .catch(error => { - // notification["success"]({ - // message: t("joblines.errors.updating", { - // message: error.message - // }) - // }); - // }); - // if (jobLineEditModal.actions.refetch) - // jobLineEditModal.actions.refetch(); - // toggleModalVisible(); - // } + console.log( + "Assigned", + Object.assign( + {}, + values, + { jobid: roSearch.selectedId }, + { vendorid: vendorSearch.selectedId }, + { + invoicelines: { + data: values.invoicelines.map(item => delete item.joblinename) + } + } + ) + ); + + insertInvoice({ + variables: { + invoice: [ + Object.assign( + {}, + values, + { jobid: roSearch.selectedId }, + { vendorid: vendorSearch.selectedId }, + { invoicelines: { data: values.invoicelines } } + ) + ] + } + }) + .then(r => { + // if (jobLineEditModal.actions.refetch) + // jobLineEditModal.actions.refetch(); + // toggleModalVisible(); + notification["success"]({ + message: t("invoices.successes.created") + }); + }) + .catch(error => { + notification["error"]({ + message: t("invoices.errors.creating", { + message: error.message + }) + }); + }); }; const handleCancel = () => { @@ -136,7 +138,8 @@ function InvoiceEnterModalContainer({ lineData={lineData ? lineData.joblines : null} vendor={ vendorSearch.selectedId - ? VendorAutoCompleteData.vendors.filter( + ? VendorAutoCompleteData && + VendorAutoCompleteData.vendors.filter( v => v.id === vendorSearch.selectedId )[0] : null diff --git a/client/src/components/invoice-enter-modal/invoice-enter-modal.lines.component.jsx b/client/src/components/invoice-enter-modal/invoice-enter-modal.lines.component.jsx index d265cf4a6..ae22fe19d 100644 --- a/client/src/components/invoice-enter-modal/invoice-enter-modal.lines.component.jsx +++ b/client/src/components/invoice-enter-modal/invoice-enter-modal.lines.component.jsx @@ -57,9 +57,9 @@ export default function InvoiceEnterModalLinesComponent({ ? "" : opt.value, actual_price: opt.cost ? opt.cost : 0, - cost_center: opt.mod_lbr_ty + cost_center: opt.part_type ? responsibilityCenters.defaults[ - opt.mod_lbr_ty + opt.part_type ] || null : null }; @@ -83,7 +83,7 @@ export default function InvoiceEnterModalLinesComponent({ key={item.id} value={item.line_desc} cost={item.act_price ? item.act_price : 0} - mod_lbr_ty={item.mod_lbr_ty} + part_type={item.part_type} > {item.line_desc} diff --git a/client/src/components/job-detail-cards/job-detail-cards.component.jsx b/client/src/components/job-detail-cards/job-detail-cards.component.jsx index 4edaccb00..b6c01bdae 100644 --- a/client/src/components/job-detail-cards/job-detail-cards.component.jsx +++ b/client/src/components/job-detail-cards/job-detail-cards.component.jsx @@ -1,18 +1,21 @@ -import { useQuery } from "@apollo/react-hooks"; import { - PrinterFilled, - FileImageFilled, EditFilled, + FileImageFilled, + PrinterFilled, ShoppingFilled } from "@ant-design/icons"; +import { useQuery } from "@apollo/react-hooks"; import { Button, PageHeader, Tag } from "antd"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; +import { connect } from "react-redux"; import { Link } from "react-router-dom"; import { QUERY_JOB_CARD_DETAILS } from "../../graphql/jobs.queries"; +import { setModalContext } from "../../redux/modals/modals.actions"; import AlertComponent from "../alert/alert.component"; import LoadingSpinner from "../loading-spinner/loading-spinner.component"; import NoteUpsertModal from "../note-upsert-modal/note-upsert-modal.container"; +import ScheduleJobModalContainer from "../schedule-job-modal/schedule-job-modal.container"; //import JobDetailCardsHeaderComponent from "./job-detail-cards.header.component"; import JobDetailCardsCustomerComponent from "./job-detail-cards.customer.component"; import JobDetailCardsDamageComponent from "./job-detail-cards.damage.component"; @@ -23,9 +26,13 @@ import JobDetailCardsNotesComponent from "./job-detail-cards.notes.component"; import JobDetailCardsPartsComponent from "./job-detail-cards.parts.component"; import "./job-detail-cards.styles.scss"; import JobDetailCardsTotalsComponent from "./job-detail-cards.totals.component"; -import ScheduleJobModalContainer from "../schedule-job-modal/schedule-job-modal.container"; -export default function JobDetailCards({ selectedJob }) { +const mapDispatchToProps = dispatch => ({ + setInvoiceEnterContext: context => + dispatch(setModalContext({ context: context, modal: "invoiceEnter" })) +}); + +function JobDetailCards({ selectedJob, setInvoiceEnterContext }) { const { loading, error, data, refetch } = useQuery(QUERY_JOB_CARD_DETAILS, { fetchPolicy: "network-only", variables: { id: selectedJob }, @@ -110,7 +117,17 @@ export default function JobDetailCards({ selectedJob }) { {t("jobs.actions.addNote")} , - @@ -181,3 +198,4 @@ export default function JobDetailCards({ selectedJob }) { ); } +export default connect(null, mapDispatchToProps)(JobDetailCards); diff --git a/client/src/graphql/invoices.queries.js b/client/src/graphql/invoices.queries.js new file mode 100644 index 000000000..309813be6 --- /dev/null +++ b/client/src/graphql/invoices.queries.js @@ -0,0 +1,11 @@ +import { gql } from "apollo-boost"; + +export const INSERT_NEW_INVOICE = gql` + mutation INSERT_NEW_INVOICE($invoice: [invoices_insert_input!]!) { + insert_invoices(objects: $invoice) { + returning { + id + } + } + } +`; diff --git a/client/src/pages/jobs/jobs.page.jsx b/client/src/pages/jobs/jobs.page.jsx index 41b9cfa15..91b6b57ed 100644 --- a/client/src/pages/jobs/jobs.page.jsx +++ b/client/src/pages/jobs/jobs.page.jsx @@ -10,6 +10,8 @@ import { selectBodyshop } from "../../redux/user/user.selectors"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; +import EnterInvoiceModalContainer from "../../components/invoice-enter-modal/invoice-enter-modal.container"; + const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop }); @@ -38,6 +40,7 @@ export default connect( return (
+