import { EditFilled, SyncOutlined } from "@ant-design/icons";
import { Button, Card, Checkbox, Input, Space, Table, Typography } from "antd";
import { useQuery } from "@apollo/client";
import axios from "axios";
import queryString from "query-string";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { Link, useLocation, useNavigate } from "react-router-dom";
import BillDeleteButton from "../../components/bill-delete-button/bill-delete-button.component";
import PartsOrderModalContainer from "../../components/parts-order-modal/parts-order-modal.container";
import PrintWrapperComponent from "../../components/print-wrapper/print-wrapper.component";
import { setModalContext } from "../../redux/modals/modals.actions";
import CurrencyFormatter from "../../utils/CurrencyFormatter";
import { DateFormatter } from "../../utils/DateFormatter";
import { TemplateList } from "../../utils/TemplateConstants";
import { pageLimit } from "../../utils/config";
import { alphaSort, dateSort } from "../../utils/sorters";
import { QUERY_ALL_VENDORS } from "../../graphql/vendors.queries";
import { logImEXEvent } from "../../firebase/firebase.utils";
const mapDispatchToProps = (dispatch) => ({
setBillEnterContext: (context) => dispatch(setModalContext({ context: context, modal: "billEnter" }))
});
export function BillsListPage({ loading, data, refetch, total, setBillEnterContext, handleTableChange, sortedInfo }) {
const search = queryString.parse(useLocation().search);
const [openSearchResults, setOpenSearchResults] = useState([]);
const [searchLoading, setSearchLoading] = useState(false);
const { page } = search;
const history = useNavigate();
const Templates = TemplateList("bill");
const { t } = useTranslation();
const { data: vendorsData } = useQuery(QUERY_ALL_VENDORS);
const columns = [
{
title: t("bills.fields.vendorname"),
dataIndex: "vendorname",
key: "vendorname",
sorter: (a, b) => alphaSort(a.vendor.name, b.vendor.name),
sortObject: (order) => ({
vendor: { name: order === "descend" ? "desc" : "asc" }
}),
filters: (vendorsData?.vendors || []).map((v) => ({ text: v.name, value: v.id })),
filteredValue: search.vendorIds ? search.vendorIds.split(",") : null,
sortOrder: sortedInfo.columnKey === "vendorname" && sortedInfo.order,
render: (text, record) => {record.vendor.name}
},
{
title: t("bills.fields.invoice_number"),
dataIndex: "invoice_number",
key: "invoice_number",
sorter: (a, b) => alphaSort(a.invoice_number, b.invoice_number),
sortOrder: sortedInfo.columnKey === "invoice_number" && sortedInfo.order
},
{
title: t("jobs.fields.ro_number"),
dataIndex: "ro_number",
key: "ro_number",
sorter: (a, b) => alphaSort(a.job.ro_number, b.job.ro_number),
sortObject: (order) => ({
job: { ro_number: order === "descend" ? "desc" : "asc" }
}),
sortOrder: sortedInfo.columnKey === "ro_number" && sortedInfo.order,
render: (text, record) => record.job && {record.job.ro_number}
},
{
title: t("bills.fields.date"),
dataIndex: "date",
key: "date",
sorter: (a, b) => dateSort(a.date, b.date),
sortOrder: sortedInfo.columnKey === "date" && sortedInfo.order,
render: (text, record) => {record.date}
},
{
title: t("bills.fields.total"),
dataIndex: "total",
key: "total",
sorter: (a, b) => a.total - b.total,
sortOrder: sortedInfo.columnKey === "total" && sortedInfo.order,
render: (text, record) => {record.total}
},
{
title: t("bills.fields.is_credit_memo"),
dataIndex: "is_credit_memo",
key: "is_credit_memo",
sorter: (a, b) => a.is_credit_memo - b.is_credit_memo,
sortOrder: sortedInfo.columnKey === "is_credit_memo" && sortedInfo.order,
render: (text, record) =>
},
{
title: t("bills.fields.exported"),
dataIndex: "exported",
key: "exported",
sorter: (a, b) => a.exported - b.exported,
sortOrder: sortedInfo.columnKey === "exported" && sortedInfo.order,
render: (text, record) =>
},
{
title: t("general.labels.actions"),
dataIndex: "actions",
key: "actions",
render: (text, record) => (
{
//
}
{
//Filter out the state and set it again.
setOpenSearchResults((currentResults) => currentResults.filter((bill) => bill.id !== deletedBillid));
}}
/>
{record.isinhouse && (
)}
)
}
];
// (State & URL handling moved to container - Option C)
useEffect(() => {
if (search.search && search.search.trim() !== "") {
searchBills();
}
}, []);
async function searchBills(value) {
try {
setSearchLoading(true);
const searchData = await axios.post("/search", {
search: value || search.search,
index: "bills"
});
logImEXEvent("bills_search", { search: value || search.search, results: searchData?.data?.hits?.hits?.length });
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 && (
{t("general.labels.searchresults", { search: search.search })}
)}
{
search.search = value;
history({ search: queryString.stringify(search) });
searchBills(value);
}}
loading={loading || searchLoading}
enterButton
/>
}
>
);
}
export default connect(null, mapDispatchToProps)(BillsListPage);