added merged payment and delete

This commit is contained in:
pramod.mahajan 2025-12-02 10:58:38 +05:30
parent 76d99d6a14
commit aa2e732ff4
6 changed files with 174 additions and 64 deletions

View File

@ -0,0 +1,102 @@
export const getPurchaseActions = ({
item,
isActive,
canDelete,
canAddChallan,
setViewPurchase,
setManagePurchase,
setDeletingId,
setIsDeleteModalOpen,
setChallan,
setAddPayment,
}) => {
const actions = [];
// VIEW
actions.push({
key: "view",
label: "View",
icon: "bx bx-show",
show: true,
onClick: () =>
setViewPurchase({
isOpen: true,
purchaseId: item.id,
}),
});
if (!isActive) {
// EDIT
actions.push({
key: "edit",
label: "Edit",
icon: "bx bx-edit",
show: true,
onClick: () =>
setManagePurchase({
isOpen: true,
purchaseId: item.id,
}),
});
// DELETE
actions.push({
key: "delete",
label: "Delete",
icon: "bx bx-trash",
show: canDelete,
onClick: () => {
setDeletingId(item.id);
setIsDeleteModalOpen(true);
},
});
// ADD CHALLAN
actions.push({
key: "challan",
label: "Add Delivery Challan",
icon: "bx bx-file bx-plus",
show: canAddChallan,
onClick: () =>
setChallan({
isOpen: true,
purchaseId: item.id,
}),
});
// ADD PAYMENT
actions.push({
key: "payment",
label: "Add Payment",
icon: "bx bx-wallet",
show: true,
onClick: () =>
setAddPayment({
isOpen: true,
purchaseId: item.id,
}),
});
} else {
// RESTORE
actions.push({
key: "restore",
label: "Restore",
icon: "bx bx-undo",
show: true,
onClick: () => {
setDeletingId(item.id);
setIsDeleteModalOpen(true);
},
});
}
return actions.filter((a) => a.show);
};
export const DropdownItem = ({ icon, label, onClick }) => (
<li>
<a className="dropdown-item cursor-pointer" onClick={onClick}>
<i className={`${icon} me-2`}></i> {label}
</a>
</li>
);

View File

@ -1,21 +1,33 @@
import React, { useState } from "react";
import { useDeletePurchaseInvoice, usePurchasesList } from "../../hooks/usePurchase";
import { ITEMS_PER_PAGE } from "../../utils/constants";
import {
useDeletePurchaseInvoice,
usePurchasesList,
} from "../../hooks/usePurchase";
import {
ADD_DELIVERY_CHALLAN,
DELETEPURCHASE_INVOICE,
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";
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
import { DropdownItem, getPurchaseActions } from "./PurchaseActions";
const PurchaseList = ({ searchString, isActive }) => {
const { setViewPurchase, setManagePurchase, setChallan } =
const { setViewPurchase, setManagePurchase, setChallan, setAddPayment } =
usePurchaseContext();
const [currentPage, setCurrentPage] = useState(1);
const { mutate: DeletePurchaseInvoice, isPending } = useDeletePurchaseInvoice();
const { mutate: DeletePurchaseInvoice, isPending } =
useDeletePurchaseInvoice();
const [IsDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
const [deletingId, setDeletingId] = useState(null);
const canAddChallan = useHasUserPermission(ADD_DELIVERY_CHALLAN);
const canDelete = useHasUserPermission(DELETEPURCHASE_INVOICE);
const debounceSearch = useDebounce(searchString, 300);
const { data, isLoading } = usePurchasesList(
@ -47,7 +59,6 @@ const PurchaseList = ({ searchString, isActive }) => {
);
};
return (
<>
{IsDeleteModalOpen && (
@ -55,7 +66,11 @@ const PurchaseList = ({ searchString, isActive }) => {
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?"}
message={
!isActive
? "Are you sure you want to delete?"
: "Are you sure you want to restore?"
}
onSubmit={handleDeleteRestore}
onClose={() => setIsDeleteModalOpen(false)}
loading={isPending}
@ -104,7 +119,6 @@ const PurchaseList = ({ searchString, isActive }) => {
</tr>
)}
{!isLoading &&
data?.data?.map((item, index) => (
<tr key={item?.id || index}>
@ -113,7 +127,7 @@ const PurchaseList = ({ searchString, isActive }) => {
{col.render ? col.render(item) : item[col.key] || "NA"}
</td>
))}
<td >
<td>
<div className="dropdown z-2">
<button
type="button"
@ -131,58 +145,25 @@ const PurchaseList = ({ searchString, isActive }) => {
></i>
</button>
<ul className="dropdown-menu dropdown-menu-end">
<li>
<a
className="dropdown-item cursor-pointer"
onClick={() => setViewPurchase({ isOpen: true, purchaseId: item.id })}
>
<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={() => {
setDeletingId(item.id);
setIsDeleteModalOpen(true);
}}
>
<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 })}
>
<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>
)}
{getPurchaseActions({
item,
isActive,
canDelete,
canAddChallan,
setViewPurchase,
setManagePurchase,
setDeletingId,
setIsDeleteModalOpen,
setChallan,
setAddPayment,
}).map((action) => (
<DropdownItem
key={action.key}
icon={action.icon}
label={action.label}
onClick={action.onClick}
/>
))}
</ul>
</div>
</td>

View File

@ -20,7 +20,7 @@ import { SpinnerLoader } from "../common/Loader";
import { formatUTCToLocalTime } from "../../utils/dateUtils";
import Avatar from "../common/Avatar";
const PurchasePayment = ({ purchaseId }) => {
const PurchasePayment = ({onClose, purchaseId }) => {
const {
data: Purchase,
isLoading: isPurchaseLoading,

View File

@ -131,6 +131,27 @@ export const useAddDeliverChallan = (onSuccessCallback) => {
},
});
};
export const useAddPurchasePayment =(onSuccessCallback)=>{
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (payload) =>
PurchaseRepository.AddPayment(payload),
onSuccess: (data, variables) => {
queryClient.invalidateQueries({ queryKey: ["purchase_payment_history"] });
showToast("Payment added successfully", "success");
if (onSuccessCallback) onSuccessCallback();
},
onError: (error) => {
showToast(
error?.response?.data?.message ||
error.message ||
"Failed to Add payment",
"error"
);
},
});
}
export const useDeletePurchaseInvoice = () => {

View File

@ -89,7 +89,7 @@ const PurchasePage = () => {
</label>
</div>
</div>
<di className="col-sm-6 text-end">
<div className="col-sm-6 text-end">
{canCreatePurchase && (
<button
className="btn btn-sm btn-primary"
@ -103,7 +103,7 @@ const PurchasePage = () => {
<i className="bx bx-plus-circle me-2"></i>Add
</button>
)}
</di>
</div>
</div>
</div>
@ -164,7 +164,10 @@ const PurchasePage = () => {
setAddPayment({ isOpen: false, purchaseId: null })
}
>
<PurchasePayment purchaseId={addPayment.purchaseId} />
<PurchasePayment
onClose={() => setAddPayment({ isOpen: false, purchaseId: null })}
purchaseId={addPayment.purchaseId}
/>
</GlobalModel>
)}
</div>

View File

@ -15,6 +15,9 @@ export const PurchaseRepository = {
addDelievryChallan: (data) =>
api.post(`/api/PurchaseInvoice/delivery-challan/create`, data),
AddPayment: (data) => api.post(`/api/PurchaseInvoice/add/payment`, data),
GetPaymentHistory: (purchaseInvoiceId) =>
api.get(`/api/PurchaseInvoice/payment-history/list/${purchaseInvoiceId}`),
deletePurchase: (id, isActive = false) =>
api.delete(`/api/PurchaseInvoice/delete/${id}?isActive=${isActive}`),
};