Merge pull request 'At the time of Update in Purchase Automatically hit the sumit without click.' (#526) from Purchase_Invoice_Update into Purchase_Invoice_Management

Reviewed-on: #526
merged
This commit is contained in:
pramod.mahajan 2025-12-02 04:13:53 +00:00
commit 444ffa9696
5 changed files with 260 additions and 162 deletions

View File

@ -127,8 +127,6 @@ const ManagePurchase = ({ onClose, purchaseId }) => {
const onSubmit = useCallback(
(formData) => {
if (activeTab !== 2) return;
if (purchaseId) {
const payload = generatePatchOps(formData);
updatePurchase({ purchaseId, payload });
@ -136,7 +134,7 @@ const ManagePurchase = ({ onClose, purchaseId }) => {
CreateInvoice(formData);
}
},
[activeTab, purchaseId, generatePatchOps, updatePurchase, CreateInvoice]
[purchaseId, generatePatchOps, updatePurchase, CreateInvoice]
);
return (
<div className="bs-stepper horizontically mt-2 b-secondry shadow-none border-0">
@ -184,18 +182,10 @@ const ManagePurchase = ({ onClose, purchaseId }) => {
{/* --- Form Content --- */}
<div className="bs-stepper-content py-2 px-3">
<AppFormProvider {...purchaseOrder}>
<form
onSubmitCapture={(e) => {
if (activeTab !== 2) {
e.preventDefault();
e.stopPropagation();
}
}}
onSubmit={purchaseOrder.handleSubmit(onSubmit)}
>
{activeTab !== 2 && (
<div>
{stepsConfig[activeTab].component}
{/* Buttons */}
<div className="d-flex justify-content-between mt-4">
<button
type="button"
@ -206,28 +196,39 @@ const ManagePurchase = ({ onClose, purchaseId }) => {
Previous
</button>
<div>
{activeTab < stepsConfig.length - 1 ? (
<button
type="button"
className="btn btn-sm btn-primary"
onClick={handleNext}
disabled={isPending || isUpdating}
>
Next
</button>
) : (
</div>
</div>
)}
{activeTab === 2 && (
<form onSubmit={purchaseOrder.handleSubmit(onSubmit)}>
{stepsConfig[2].component}
<div className="d-flex justify-content-between mt-4">
<button
type={activeTab == 2 ? "submit" : "button"}
type="button"
className="btn btn-sm btn-outline-secondary"
onClick={handlePrev}
>
Previous
</button>
<button
type="submit"
className="btn btn-sm btn-primary"
disabled={isPending || isUpdating}
>
{isPending || isUpdating ? "Please Wait" : "Submit"}
</button>
)}
</div>
</div>
</form>
)}
</AppFormProvider>
</div>
</div>

View File

@ -1,21 +1,28 @@
import React, { useState } from "react";
import { usePurchasesList } from "../../hooks/usePurchase";
import { useDeletePurchaseInvoice, usePurchasesList } from "../../hooks/usePurchase";
import { ITEMS_PER_PAGE } from "../../utils/constants";
import Pagination from "../common/Pagination";
import { PurchaseColumn } from "./Purchasetable";
import { SpinnerLoader } from "../common/Loader";
import { useDebounce } from "../../utils/appUtils";
import { usePurchaseContext } from "../../pages/purchase/PurchasePage";
import ConfirmModal from "../common/ConfirmModal";
const PurchaseList = ({ searchString }) => {
const PurchaseList = ({ searchString, isActive }) => {
const { setViewPurchase, setManagePurchase, setChallan } =
usePurchaseContext();
const [currentPage, setCurrentPage] = useState(1);
const { mutate: DeletePurchaseInvoice, isPending } = useDeletePurchaseInvoice();
const [IsDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
const [deletingId, setDeletingId] = useState(null);
const debounceSearch = useDebounce(searchString, 300);
const { data, isLoading } = usePurchasesList(
ITEMS_PER_PAGE,
currentPage,
true,
// true,
!isActive,
{},
debounceSearch
);
@ -28,9 +35,35 @@ const PurchaseList = ({ searchString }) => {
const visibleColumns = PurchaseColumn.filter((col) => !col.hidden);
const handleDeleteRestore = (id) => {
DeletePurchaseInvoice(
{ id, isActive: isActive }, // delete if active, restore if deleted
{
onSettled: () => {
setDeletingId(null);
setIsDeleteModalOpen(false);
},
}
);
};
return (
<div className="card mt-2 page-min-h px-sm-4">
<div className="table-responsive px-2">
<>
{IsDeleteModalOpen && (
<ConfirmModal
isOpen={IsDeleteModalOpen}
type={!isActive ? "delete" : "undo"}
header={!isActive ? "Delete Invoice" : "Restore Invoice"}
message={!isActive ? "Are you sure you want to delete?" : "Are you sure you want to restore?"}
onSubmit={handleDeleteRestore}
onClose={() => setIsDeleteModalOpen(false)}
loading={isPending}
paramData={deletingId}
/>
)}
<div className="card mt-2 page-min-h table-responsive px-sm-4">
<div className="px-2">
<table className="datatables-users table border-top text-nowrap">
<thead>
<tr>
@ -47,24 +80,31 @@ const PurchaseList = ({ searchString }) => {
{/* LOADING */}
{isLoading && (
<tr>
<td colSpan={visibleColumns.length + 1} className="border-0">
<div className="py-6 py-12">
<td
colSpan={visibleColumns.length + 1}
className="border-0"
style={{ height: "300px", verticalAlign: "middle" }}
>
<div className="d-flex justify-content-center align-items-center w-100 h-100">
<SpinnerLoader />
</div>
</td>
</tr>
)}
{!isLoading && data?.data?.length === 0 && (
<tr>
<td
colSpan={visibleColumns.length}
className="text-center py-4 border-0"
colSpan={visibleColumns.length + 1}
className="text-center border-0"
style={{ height: "400px", verticalAlign: "middle" }}
>
No Data Found
</td>
</tr>
)}
{!isLoading &&
data?.data?.map((item, index) => (
<tr key={item?.id || index}>
@ -94,46 +134,55 @@ const PurchaseList = ({ searchString }) => {
<li>
<a
className="dropdown-item cursor-pointer"
onClick={() =>
setViewPurchase({
isOpen: true,
purchaseId: item.id,
})
}
onClick={() => setViewPurchase({ isOpen: true, purchaseId: item.id })}
>
<i className="bx bx-show me-2"></i>
<span className="align-left">view</span>
<i className="bx bx-show me-2"></i> View
</a>
</li>
{!isActive ? (
<>
<li>
<a
className="dropdown-item cursor-pointer"
onClick={() => setManagePurchase({ isOpen: true, purchaseId: item.id })}
>
<i className="bx bx-edit me-2"></i> Edit
</a>
</li>
<li>
<a
className="dropdown-item cursor-pointer"
onClick={() =>
setManagePurchase({
isOpen: true,
purchaseId: item.id,
})
}
onClick={() => {
setDeletingId(item.id);
setIsDeleteModalOpen(true);
}}
>
<i className="bx bx-edit me-2"></i>
<span className="align-left">Edit</span>
<i className="bx bx-trash me-2"></i> Delete
</a>
</li>
<li>
<a
className="dropdown-item cursor-pointer"
onClick={() =>
setChallan({
isOpen: true,
purchaseId: item.id,
})
}
onClick={() => setChallan({ isOpen: true, purchaseId: item.id })}
>
<i className="bx bx-file bx-plus me-2"></i>
<i className="bx bx-file bx-plus me-2"></i> Add Delivery Challan
</a>
</li>
</>
) : (
<li>
<a
className="dropdown-item cursor-pointer"
onClick={() => {
setDeletingId(item.id);
setIsDeleteModalOpen(true);
}}
>
<i className="bx bx-undo me-2"></i> Restore
</a>
</li>
)}
<span className="align-left">Add Delivery Challan</span>
</a>
</li>
</ul>
</div>
</td>
@ -151,6 +200,7 @@ const PurchaseList = ({ searchString }) => {
/>
)}
</div>
</>
);
};

View File

@ -120,3 +120,30 @@ export const useAddDeliverChallan = (onSuccessCallback) => {
},
});
};
export const useDeletePurchaseInvoice = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ id, isActive }) =>
await PurchaseRepository.deletePurchase(id, isActive),
onSuccess: (_, variable) => {
queryClient.invalidateQueries({ queryKey: ["purchase_list"] });
showToast(
`Purchase Invoice ${variable.isActive ? "restored" : "deleted"} successfully`,
"success"
);
},
onError: (error) => {
showToast(
error?.response?.data?.message ||
error.message ||
"Failed to delete branch",
"error"
);
},
});
};

View File

@ -19,6 +19,8 @@ export const usePurchaseContext = () => {
};
const PurchasePage = () => {
const [searchText, setSearchText] = useState("");
const [showDelete, setShowDelete] = useState(false);
const [showInactive, setShowInactive] = useState(false);
const [addChallan, setChallan] = useState({
isOpen: false,
purchaseId: null,
@ -61,6 +63,21 @@ const PurchasePage = () => {
aria-controls="DataTables_Table_0"
/>
</label>
<div className="form-check form-switch d-inline-flex align-items-center ms-3">
<input
type="checkbox"
className="form-check-input"
id="inactiveEmployeesCheckbox"
checked={showInactive}
onChange={() => setShowInactive(!showInactive)}
/>
<label
htmlFor="inactiveEmployeesCheckbox"
className="ms-2 text-xs"
>
{!showInactive ? "Show Deleted" : "Hide Deleted"}
</label>
</div>
</div>
<di className="col-sm-6 text-end">
<button
@ -78,7 +95,7 @@ const PurchasePage = () => {
</div>
</div>
<PurchaseList searchString={searchText} />
<PurchaseList searchString={searchText} isActive={showInactive} />
{managePurchase.isOpen && (
<GlobalModel
isOpen={managePurchase.isOpen}

View File

@ -14,6 +14,9 @@ export const PurchaseRepository = {
api.get(`/api/PurchaseInvoice/delivery-challan/list/${purchaseInvoiceId}`),
addDelievryChallan: (data) =>
api.post(`/api/PurchaseInvoice/delivery-challan/create`, data),
deletePurchase: (id, isActive = false) =>
api.delete(`/api/PurchaseInvoice/delete/${id}?isActive=${isActive}`),
};
// const filterPayload = JSON.stringify({