diff --git a/client/src/components/jobs-list-paginated/jobs-list-paginated.component.jsx b/client/src/components/jobs-list-paginated/jobs-list-paginated.component.jsx index 5ef3ab976..ec50e618c 100644 --- a/client/src/components/jobs-list-paginated/jobs-list-paginated.component.jsx +++ b/client/src/components/jobs-list-paginated/jobs-list-paginated.component.jsx @@ -1,8 +1,9 @@ import { SyncOutlined } from "@ant-design/icons"; import { Button, Card, Input, Space, Table, Typography } from "antd"; +import axios from "axios"; import _ from "lodash"; import queryString from "query-string"; -import React from "react"; +import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { Link, useHistory, useLocation } from "react-router-dom"; @@ -21,6 +22,8 @@ const mapDispatchToProps = (dispatch) => ({ export function JobsList({ bodyshop, refetch, loading, jobs, total }) { const search = queryString.parse(useLocation().search); + const [openSearchResults, setOpenSearchResults] = useState([]); + const [searchLoading, setSearchLoading] = useState(false); const { page, sortcolumn, sortorder } = search; const history = useHistory(); @@ -193,6 +196,28 @@ export function JobsList({ bodyshop, refetch, loading, jobs, total }) { history.push({ search: queryString.stringify(search) }); }; + useEffect(() => { + if (search.search && search.search.trim() !== "") { + searchJobs(); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + async function searchJobs(value) { + try { + setSearchLoading(true); + const searchData = await axios.post("/search", { + search: value || search.search, + index: "jobs", + }); + setOpenSearchResults(searchData.data.hits.hits.map((s) => s._source)); + } catch (error) { + console.log("Error while fetching search results", error); + } finally { + setSearchLoading(false); + } + } + return ( { search.search = value; history.push({ search: queryString.stringify(search) }); + searchJobs(value); }} + loading={loading || searchLoading} enterButton /> } > diff --git a/client/src/components/payments-list-paginated/payment-list-paginated.component.jsx b/client/src/components/payments-list-paginated/payment-list-paginated.component.jsx index 50b3d2b98..c06f04c78 100644 --- a/client/src/components/payments-list-paginated/payment-list-paginated.component.jsx +++ b/client/src/components/payments-list-paginated/payment-list-paginated.component.jsx @@ -1,7 +1,8 @@ import { EditFilled, SyncOutlined } from "@ant-design/icons"; import { Button, Card, Input, Space, Table, Typography } from "antd"; +import axios from "axios"; import queryString from "query-string"; -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { Link, useHistory, useLocation } from "react-router-dom"; @@ -10,11 +11,11 @@ import { setModalContext } from "../../redux/modals/modals.actions"; import { selectBodyshop } from "../../redux/user/user.selectors"; import CurrencyFormatter from "../../utils/CurrencyFormatter"; import { DateFormatter, DateTimeFormatter } from "../../utils/DateFormatter"; -import { alphaSort } from "../../utils/sorters"; import { TemplateList } from "../../utils/TemplateConstants"; +import { alphaSort } from "../../utils/sorters"; import CaBcEtfTableModalContainer from "../ca-bc-etf-table-modal/ca-bc-etf-table-modal.container"; -import PrintWrapperComponent from "../print-wrapper/print-wrapper.component"; import OwnerNameDisplay from "../owner-name-display/owner-name-display.component"; +import PrintWrapperComponent from "../print-wrapper/print-wrapper.component"; const mapStateToProps = createStructuredSelector({ //currentUser: selectCurrentUser @@ -39,6 +40,8 @@ export function PaymentsListPaginated({ bodyshop, }) { const search = queryString.parse(useLocation().search); + const [openSearchResults, setOpenSearchResults] = useState([]); + const [searchLoading, setSearchLoading] = useState(false); const { page, sortcolumn, sortorder } = search; const history = useHistory(); const [state, setState] = useState({ @@ -52,13 +55,17 @@ export function PaymentsListPaginated({ title: t("jobs.fields.ro_number"), dataIndex: "ro_number", key: "ro_number", - sorter: (a, b) => alphaSort(a.job.ro_number, b.job.ro_number), - sortOrder: sortcolumn === "ro_number" && sortorder, - render: (text, record) => ( - - {record.job.ro_number || t("general.labels.na")} - - ), + // sorter: (a, b) => alphaSort(a.job.ro_number, b.job.ro_number), + // sortOrder: sortcolumn === "ro_number" && sortorder, + render: (text, record) => { + return record.job ? ( + + {record.job.ro_number || t("general.labels.na")} + + ) : ( + {t("general.labels.na")} + ); + }, }, { title: t("payments.fields.paymentnum"), @@ -72,16 +79,16 @@ export function PaymentsListPaginated({ dataIndex: "owner", key: "owner", ellipsis: true, - sorter: (a, b) => alphaSort(a.job.ownr_ln, b.job.ownr_ln), - sortOrder: sortcolumn === "owner" && sortorder, + // sorter: (a, b) => alphaSort(a.job.ownr_ln, b.job.ownr_ln), + // sortOrder: sortcolumn === "owner" && sortorder, render: (text, record) => { - return record.job.owner ? ( - - + return record.job?.owner ? ( + + ) : ( - + ); }, @@ -177,6 +184,28 @@ export function PaymentsListPaginated({ history.push({ search: queryString.stringify(search) }); }; + useEffect(() => { + if (search.search && search.search.trim() !== "") { + searchPayments(); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + async function searchPayments(value) { + try { + setSearchLoading(true); + const searchData = await axios.post("/search", { + search: value || search.search, + index: "payments", + }); + setOpenSearchResults(searchData.data.hits.hits.map((s) => s._source)); + } catch (error) { + console.log("Error while fetching search results", error); + } finally { + setSearchLoading(false); + } + } + return ( { search.search = value; history.push({ search: queryString.stringify(search) }); + searchPayments(value); }} + loading={loading || searchLoading} enterButton /> } >
diff --git a/client/src/graphql/bills.queries.js b/client/src/graphql/bills.queries.js index 4d39eda47..6406edfe1 100644 --- a/client/src/graphql/bills.queries.js +++ b/client/src/graphql/bills.queries.js @@ -20,13 +20,11 @@ export const DELETE_BILL = gql` export const QUERY_ALL_BILLS_PAGINATED = gql` query QUERY_ALL_BILLS_PAGINATED( - $search: String $offset: Int $limit: Int $order: [bills_order_by!]! ) { - search_bills( - args: { search: $search } + bills( offset: $offset limit: $limit order_by: $order @@ -51,7 +49,7 @@ export const QUERY_ALL_BILLS_PAGINATED = gql` ro_number } } - search_bills_aggregate(args: { search: $search }) { + bills_aggregate { aggregate { count(distinct: true) } diff --git a/client/src/graphql/jobs.queries.js b/client/src/graphql/jobs.queries.js index 50225795f..103e21b16 100644 --- a/client/src/graphql/jobs.queries.js +++ b/client/src/graphql/jobs.queries.js @@ -1781,14 +1781,12 @@ export const QUERY_ALL_JOB_FIELDS = gql` export const QUERY_ALL_JOBS_PAGINATED_STATUS_FILTERED = gql` query QUERY_ALL_JOBS_PAGINATED_STATUS_FILTERED( - $search: String $offset: Int $limit: Int $order: [jobs_order_by!] $statusList: [String!] ) { - search_jobs( - args: { search: $search } + jobs( offset: $offset limit: $limit order_by: $order @@ -1819,10 +1817,7 @@ export const QUERY_ALL_JOBS_PAGINATED_STATUS_FILTERED = gql` updated_at ded_amt } - search_jobs_aggregate( - args: { search: $search } - where: { status: { _in: $statusList } } - ) { + jobs_aggregate(where: { status: { _in: $statusList } }) { aggregate { count(distinct: true) } diff --git a/client/src/graphql/payments.queries.js b/client/src/graphql/payments.queries.js index 554e6c497..5141e9acf 100644 --- a/client/src/graphql/payments.queries.js +++ b/client/src/graphql/payments.queries.js @@ -12,13 +12,11 @@ export const INSERT_NEW_PAYMENT = gql` export const QUERY_ALL_PAYMENTS_PAGINATED = gql` query QUERY_ALL_PAYMENTS_PAGINATED( - $search: String $offset: Int $limit: Int $order: [payments_order_by!]! ) { - search_payments( - args: { search: $search } + payments( offset: $offset limit: $limit order_by: $order @@ -31,9 +29,16 @@ export const QUERY_ALL_PAYMENTS_PAGINATED = gql` job { id ro_number + ownerid + ownr_co_nm ownr_fn ownr_ln - ownr_co_nm + owner { + id + ownr_co_nm + ownr_fn + ownr_ln + } } transactionid memo @@ -44,7 +49,7 @@ export const QUERY_ALL_PAYMENTS_PAGINATED = gql` stripeid payer } - search_payments_aggregate(args: { search: $search }) { + payments_aggregate { aggregate { count(distinct: true) } diff --git a/client/src/pages/bills/bills.page.component.jsx b/client/src/pages/bills/bills.page.component.jsx index d9dc322e1..bc1e50974 100644 --- a/client/src/pages/bills/bills.page.component.jsx +++ b/client/src/pages/bills/bills.page.component.jsx @@ -1,7 +1,8 @@ -import { SyncOutlined, EditFilled } from "@ant-design/icons"; +import { EditFilled, SyncOutlined } from "@ant-design/icons"; import { Button, Card, Checkbox, Input, Space, Table, Typography } from "antd"; +import axios from "axios"; import queryString from "query-string"; -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { Link, useHistory, useLocation } from "react-router-dom"; @@ -11,8 +12,8 @@ import PrintWrapperComponent from "../../components/print-wrapper/print-wrapper. import { setModalContext } from "../../redux/modals/modals.actions"; import CurrencyFormatter from "../../utils/CurrencyFormatter"; import { DateFormatter } from "../../utils/DateFormatter"; -import { alphaSort, dateSort } from "../../utils/sorters"; import { TemplateList } from "../../utils/TemplateConstants"; +import { alphaSort, dateSort } from "../../utils/sorters"; const mapDispatchToProps = (dispatch) => ({ setPartsOrderContext: (context) => @@ -29,34 +30,36 @@ export function BillsListPage({ setPartsOrderContext, setBillEnterContext, }) { - const { t } = useTranslation(); + const search = queryString.parse(useLocation().search); + const [openSearchResults, setOpenSearchResults] = useState([]); + const [searchLoading, setSearchLoading] = useState(false); + const { page } = search; + const history = useHistory(); const [state, setState] = useState({ sortedInfo: {}, + filteredInfo: { text: "" }, }); - const history = useHistory(); - const search = queryString.parse(useLocation().search); - const { page } = search; const Templates = TemplateList("bill"); - + const { t } = useTranslation(); const columns = [ { title: t("bills.fields.vendorname"), dataIndex: "vendorname", key: "vendorname", - sortObject: (direction) => { - return { - vendor: { - name: direction - ? direction === "descend" - ? "desc" - : "asc" - : "desc", - }, - }; - }, - sorter: (a, b) => alphaSort(a.vendor.name, b.vendor.name), - sortOrder: - state.sortedInfo.columnKey === "vendorname" && state.sortedInfo.order, + // sortObject: (direction) => { + // return { + // vendor: { + // name: direction + // ? direction === "descend" + // ? "desc" + // : "asc" + // : "desc", + // }, + // }; + // }, + // sorter: (a, b) => alphaSort(a.vendor.name, b.vendor.name), + // sortOrder: + // state.sortedInfo.columnKey === "vendorname" && state.sortedInfo.order, render: (text, record) => {record.vendor.name}, }, { @@ -72,20 +75,20 @@ export function BillsListPage({ title: t("jobs.fields.ro_number"), dataIndex: "ro_number", key: "ro_number", - sortObject: (direction) => { - return { - job: { - ro_number: direction - ? direction === "descend" - ? "desc" - : "asc" - : "desc", - }, - }; - }, - sorter: (a, b) => alphaSort(a.job.ro_number, b.job.ro_number), - sortOrder: - state.sortedInfo.columnKey === "ro_number" && state.sortedInfo.order, + // sortObject: (direction) => { + // return { + // job: { + // ro_number: direction + // ? direction === "descend" + // ? "desc" + // : "asc" + // : "desc", + // }, + // }; + // }, + // sorter: (a, b) => alphaSort(a.job.ro_number, b.job.ro_number), + // sortOrder: + // state.sortedInfo.columnKey === "ro_number" && state.sortedInfo.order, render: (text, record) => record.job && ( @@ -199,11 +202,32 @@ export function BillsListPage({ search.sortcolumn = sorter.order ? sorter.columnKey : null; search.sortorder = sorter.order; } - search.sort = JSON.stringify({ [sorter.columnKey]: sorter.order }); history.push({ search: queryString.stringify(search) }); }; + useEffect(() => { + if (search.search && search.search.trim() !== "") { + searchBills(); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + async function searchBills(value) { + try { + setSearchLoading(true); + const searchData = await axios.post("/search", { + search: value || search.search, + index: "bills", + }); + setOpenSearchResults(searchData.data.hits.hits.map((s) => s._source)); + } catch (error) { + console.log("Error while fetching search results", error); + } finally { + setSearchLoading(false); + } + } + return ( { search.search = value; history.push({ search: queryString.stringify(search) }); + searchBills(value); }} + loading={loading || searchLoading} + enterButton /> } @@ -251,19 +278,25 @@ export function BillsListPage({
diff --git a/client/src/pages/bills/bills.page.container.jsx b/client/src/pages/bills/bills.page.container.jsx index a0340187b..22a8b61b9 100644 --- a/client/src/pages/bills/bills.page.container.jsx +++ b/client/src/pages/bills/bills.page.container.jsx @@ -1,6 +1,6 @@ +import { useQuery } from "@apollo/client"; import queryString from "query-string"; import React, { useEffect } from "react"; -import { useQuery } from "@apollo/client"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { useLocation } from "react-router-dom"; @@ -22,7 +22,7 @@ const mapDispatchToProps = (dispatch) => ({ export function BillsPageContainer({ setBreadcrumbs, setSelectedHeader }) { const { t } = useTranslation(); const searchParams = queryString.parse(useLocation().search); - const { page, sortcolumn, sortorder, search, searchObj } = searchParams; + const { page, sortcolumn, sortorder, searchObj } = searchParams; useEffect(() => { document.title = t("titles.bills-list"); @@ -38,7 +38,6 @@ export function BillsPageContainer({ setBreadcrumbs, setSelectedHeader }) { fetchPolicy: "network-only", nextFetchPolicy: "network-only", variables: { - search: search || "", offset: page ? (page - 1) * 25 : 0, limit: 25, order: [ @@ -61,10 +60,10 @@ export function BillsPageContainer({ setBreadcrumbs, setSelectedHeader }) {
diff --git a/client/src/pages/jobs-all/jobs-all.container.jsx b/client/src/pages/jobs-all/jobs-all.container.jsx index a36745a0e..2518d6c16 100644 --- a/client/src/pages/jobs-all/jobs-all.container.jsx +++ b/client/src/pages/jobs-all/jobs-all.container.jsx @@ -25,7 +25,7 @@ const mapDispatchToProps = (dispatch) => ({ export function AllJobs({ setBreadcrumbs, setSelectedHeader }) { const searchParams = queryString.parse(useLocation().search); - const { page, sortcolumn, sortorder, search, statusFilters } = searchParams; + const { page, sortcolumn, sortorder, statusFilters } = searchParams; const { loading, error, data, refetch } = useQuery( QUERY_ALL_JOBS_PAGINATED_STATUS_FILTERED, @@ -33,7 +33,6 @@ export function AllJobs({ setBreadcrumbs, setSelectedHeader }) { fetchPolicy: "network-only", nextFetchPolicy: "network-only", variables: { - search: search || "", offset: page ? (page - 1) * 25 : 0, limit: 25, ...(statusFilters ? { statusList: JSON.parse(statusFilters) } : {}), @@ -67,8 +66,8 @@ export function AllJobs({ setBreadcrumbs, setSelectedHeader }) { refetch={refetch} loading={loading} searchParams={searchParams} - total={data ? data.search_jobs_aggregate.aggregate.count : 0} - jobs={data ? data.search_jobs : []} + total={data ? data.jobs_aggregate.aggregate.count : 0} + jobs={data ? data.jobs : []} /> ); diff --git a/client/src/pages/payments-all/payments-all.container.page.jsx b/client/src/pages/payments-all/payments-all.container.page.jsx index 53f3959b3..07547bc2e 100644 --- a/client/src/pages/payments-all/payments-all.container.page.jsx +++ b/client/src/pages/payments-all/payments-all.container.page.jsx @@ -26,7 +26,7 @@ const mapDispatchToProps = (dispatch) => ({ export function AllJobs({ bodyshop, setBreadcrumbs, setSelectedHeader }) { const searchParams = queryString.parse(useLocation().search); - const { page, sortcolumn, sortorder, search } = searchParams; + const { page, sortcolumn, sortorder, searchObj } = searchParams; const { loading, error, data, refetch } = useQuery( QUERY_ALL_PAYMENTS_PAGINATED, @@ -34,11 +34,12 @@ export function AllJobs({ bodyshop, setBreadcrumbs, setSelectedHeader }) { fetchPolicy: "network-only", nextFetchPolicy: "network-only", variables: { - search: search || "", offset: page ? (page - 1) * 25 : 0, limit: 25, order: [ - { + searchObj + ? JSON.parse(searchObj) + : { [sortcolumn || "date"]: sortorder ? sortorder === "descend" ? "desc" @@ -66,8 +67,8 @@ export function AllJobs({ bodyshop, setBreadcrumbs, setSelectedHeader }) { refetch={refetch} loading={loading} searchParams={searchParams} - total={data ? data.search_payments_aggregate.aggregate.count : 0} - payments={data ? data.search_payments : []} + total={data ? data.payments_aggregate.aggregate.count : 0} + payments={data ? data.payments : []} /> ); diff --git a/os-loader.js b/os-loader.js index f8b8de52a..335a04778 100644 --- a/os-loader.js +++ b/os-loader.js @@ -50,7 +50,7 @@ const getClient = async () => { async function OpenSearchUpdateHandler(req, res) { try { - var osClient = await getClient(); + var osClient = await getClient(); // const osClient = new Client({ // node: `https://imex:password@search-imexonline-search-ixp2stfvwp6qocjsowzjzyreoy.ca-central-1.es.amazonaws.com`, // }); @@ -74,12 +74,18 @@ async function OpenSearchUpdateHandler(req, res) { const jobsData = await gqlclient.request(`query{jobs{ id bodyshopid:shopid - ro_number clm_no + clm_total + comment + ins_co_nm + ownr_co_nm ownr_fn ownr_ln + ownr_ph1 + ownr_ph2 + plate_no + ro_number status - ownr_co_nm v_model_yr v_make_desc v_model_desc @@ -128,12 +134,12 @@ async function OpenSearchUpdateHandler(req, res) { vehicles { id bodyshopid: shopid -v_model_yr -v_model_desc -v_make_desc -v_color -v_vin -plate_no + plate_no + v_model_yr + v_model_desc + v_make_desc + v_color + v_vin } } `); @@ -155,11 +161,25 @@ plate_no payments { id amount - paymentnum + created_at + exportedat memo + payer + paymentnum transactionid + type job { id + ownerid + ownr_co_nm + ownr_fn + ownr_ln + owner { + id + ownr_co_nm + ownr_fn + ownr_ln + } ro_number bodyshopid: shopid } @@ -187,9 +207,11 @@ plate_no const billsData = await gqlclient.request(`{ bills { id - total - invoice_number date + exported + invoice_number + is_credit_memo + total vendor { name id @@ -200,9 +222,7 @@ plate_no bodyshopid: shopid } } - } - - `); + }`); for (let i = 0; i <= billsData.bills.length / batchSize; i++) { const slicedArray = billsData.bills.slice( i * batchSize, diff --git a/server/opensearch/os-handler.js b/server/opensearch/os-handler.js index 016e9530e..b82d48b21 100644 --- a/server/opensearch/os-handler.js +++ b/server/opensearch/os-handler.js @@ -70,12 +70,18 @@ async function OpenSearchUpdateHandler(req, res) { document = _.pick(req.body.event.data.new, [ "id", "bodyshopid", - "ro_number", "clm_no", + "clm_total", + "comment", + "ins_co_nm", + "ownr_co_nm", "ownr_fn", "ownr_ln", + "ownr_ph1", + "ownr_ph2", + "plate_no", + "ro_number", "status", - "ownr_co_nm", "v_model_yr", "v_make_desc", "v_model_desc", @@ -128,8 +134,10 @@ async function OpenSearchUpdateHandler(req, res) { document = { ..._.pick(req.body.event.data.new, [ "id", - "invoice_number", "date", + "exported", + "invoice_number", + "is_credit_memo", ]), ...bill.bills_by_pk, bodyshopid: bill.bills_by_pk.job.shopid, @@ -146,15 +154,34 @@ async function OpenSearchUpdateHandler(req, res) { id ro_number shopid + ownerid + ownr_co_nm + ownr_fn + ownr_ln + owner { + id + ownr_co_nm + ownr_fn + ownr_ln + } } } - } - - `, + } + `, { paymentId: req.body.event.data.new.id } ); document = { - ..._.pick(req.body.event.data.new, ["id", "invoice_number"]), + ..._.pick(req.body.event.data.new, [ + "id", + "amount", + "created_at", + "exportedat", + "memo", + "payer", + "paymentnum", + "transactionid", + "type", + ]), ...payment.payments_by_pk, bodyshopid: bill.payments_by_pk.job.shopid, }; @@ -180,7 +207,7 @@ async function OpenSearchUpdateHandler(req, res) { async function OpensearchSearchHandler(req, res) { try { - const { search, bodyshopid } = req.body; + const { search, bodyshopid, index } = req.body; if (!req.user) { res.sendStatus(401); return; @@ -209,6 +236,7 @@ async function OpensearchSearchHandler(req, res) { var osClient = await getClient(); const { body } = await osClient.search({ + ...(index ? { index } : {}), body: { size: 100, query: {