diff --git a/src/components/purchase/ManagePurchase.jsx b/src/components/purchase/ManagePurchase.jsx index 7120842f..7e470c33 100644 --- a/src/components/purchase/ManagePurchase.jsx +++ b/src/components/purchase/ManagePurchase.jsx @@ -1,4 +1,4 @@ -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; import { AppFormProvider, useAppForm } from "../../hooks/appHooks/useAppForm"; import { zodResolver } from "@hookform/resolvers/zod"; import { @@ -9,9 +9,13 @@ import { import PurchasePartyDetails from "./PurchasePartyDetails"; import PurchaseTransportDetails from "./PurchaseTransportDetails"; import PurchasePaymentDetails from "./PurchasePaymentDetails"; -import { useCreatePurchaseInvoice } from "../../hooks/usePurchase"; - -const ManagePurchase = ({ onClose }) => { +import { + useCreatePurchaseInvoice, + usePurchase, + useUpdatePurchaseInvoice, +} from "../../hooks/usePurchase"; +const ManagePurchase = ({ onClose, purchaseId }) => { + const { data } = usePurchase(purchaseId); const [activeTab, setActiveTab] = useState(0); const [completedTabs, setCompletedTabs] = useState([]); @@ -20,7 +24,7 @@ const ManagePurchase = ({ onClose }) => { name: "Party Details", icon: "bx bx-user bx-md", subtitle: "Supplier & project information", - component: , + component: , }, { name: "Invoice & Transport", @@ -40,10 +44,25 @@ const ManagePurchase = ({ onClose }) => { resolver: zodResolver(PurchaseSchema), defaultValues: defaultPurchaseValue, mode: "onChange", + shouldUnregister: false, }); - const {reset} = purchaseOrder; - const handleNext = async () => { + const { + reset, + formState: { errors }, + } = purchaseOrder; + + useEffect(() => { + if (purchaseId && data) { + reset(data); + setCompletedTabs([0, 1, 2]); + } + }, [purchaseId, data, reset]); + + const handleNext = async (e) => { + e.preventDefault(); + e.stopPropagation(); + const currentStepFields = getStepFields(activeTab); const valid = await purchaseOrder.trigger(currentStepFields); @@ -53,18 +72,53 @@ const ManagePurchase = ({ onClose }) => { } }; - const handlePrev = () => { + const handlePrev = (e) => { + e.preventDefault(); + e.stopPropagation(); setActiveTab((prev) => Math.max(prev - 1, 0)); }; - const { mutate: CreateInvoice, isPending } = useCreatePurchaseInvoice(() => { - reset() - onClose(); - }); + const { mutate: CreateInvoice, isPending } = + useCreatePurchaseInvoice(() => { + reset(); + onClose(); + }); + + const { mutate: updatePurchase, isPending: isUpdating } = + useUpdatePurchaseInvoice(() => { + reset(); + onClose(); + }); const onSubmit = (formData) => { - let payload = formData; - CreateInvoice(payload); + if (activeTab !== 2) { + console.warn("Submit blocked - not on last step"); + return; + } + + const dirtyFields = purchaseOrder.formState.dirtyFields; + + if (purchaseId) { + const changedData = Object.keys(dirtyFields).reduce((acc, key) => { + if (dirtyFields[key]) { + acc.push({ + operationType: 0, + path: `/${key}`, + op: "replace", + from: null, + value: formData[key], + }); + } + return acc; + }, []); + + updatePurchase({ + purchaseId, + payload: changedData, + }); + } else { + CreateInvoice(formData); + } }; return ( @@ -96,7 +150,9 @@ const ManagePurchase = ({ onClose }) => { {step.name} - {step.subtitle} + + {step.subtitle} + @@ -112,7 +168,23 @@ const ManagePurchase = ({ onClose }) => { {/* Content */}
-
+ { + if (e.key === "Enter" && activeTab !== 2) { + e.preventDefault(); + } + }} + onSubmit={(e) => { + e.preventDefault(); + + if (activeTab !== 2) { + console.warn("BLOCKED SUBMIT on step:", activeTab); + return; + } + + purchaseOrder.handleSubmit(onSubmit)(e); + }} + > {stepsConfig[activeTab].component}
@@ -124,21 +196,27 @@ const ManagePurchase = ({ onClose }) => { > Previous - + +
{activeTab < stepsConfig.length - 1 ? ( ) : ( - )} - +
@@ -148,3 +226,4 @@ const ManagePurchase = ({ onClose }) => { }; export default ManagePurchase; + diff --git a/src/components/purchase/PurchaseList.jsx b/src/components/purchase/PurchaseList.jsx index 672bccef..7c51f7a3 100644 --- a/src/components/purchase/PurchaseList.jsx +++ b/src/components/purchase/PurchaseList.jsx @@ -8,7 +8,7 @@ import { useDebounce } from "../../utils/appUtils"; import { usePurchaseContext } from "../../pages/purchase/PurchasePage"; const PurchaseList = ({ searchString }) => { - const { setViewPurchase } = usePurchaseContext(); + const { setViewPurchase, setManagePurchase } = usePurchaseContext(); const [currentPage, setCurrentPage] = useState(1); const debounceSearch = useDebounce(searchString, 300); const { data, isLoading } = usePurchasesList( @@ -101,14 +101,22 @@ const PurchaseList = ({ searchString }) => { }) } > - + view
  • - - - Add + + setManagePurchase({ + isOpen: true, + purchaseId: item.id, + }) + } + > + + Edit
  • diff --git a/src/components/purchase/PurchasePaymentDetails.jsx b/src/components/purchase/PurchasePaymentDetails.jsx index edaf4883..b39f8d0e 100644 --- a/src/components/purchase/PurchasePaymentDetails.jsx +++ b/src/components/purchase/PurchasePaymentDetails.jsx @@ -37,7 +37,7 @@ const PurchasePaymentDetails = () => { id="baseAmount" type="number" className="form-control form-control-md" - {...register("baseAmount")} + {...register("baseAmount", { valueAsNumber: true })} /> {errors?.baseAmount && ( @@ -56,7 +56,7 @@ const PurchasePaymentDetails = () => { id="taxAmount" type="number" className="form-control form-control-md" - {...register("taxAmount")} + {...register("taxAmount",{ valueAsNumber: true })} /> {errors?.taxAmount && ( @@ -75,7 +75,7 @@ const PurchasePaymentDetails = () => { id="totalAmount" type="number" className="form-control form-control-md" - {...register("totalAmount")} + {...register("totalAmount",{ valueAsNumber: true })} readOnly /> diff --git a/src/components/purchase/PurchaseSchema.jsx b/src/components/purchase/PurchaseSchema.jsx index 64ba0883..33d41bcb 100644 --- a/src/components/purchase/PurchaseSchema.jsx +++ b/src/components/purchase/PurchaseSchema.jsx @@ -49,7 +49,7 @@ export const PurchaseSchema = z.object({ proformaInvoiceNumber: z.string().nullable(), proformaInvoiceDate: z.coerce.date().nullable(), - proformaInvoiceAmount: z.string().nullable(), + proformaInvoiceAmount: z.number().optional(), invoiceNumber: z.string().nullable(), invoiceDate: z.coerce.date().nullable(), @@ -59,11 +59,11 @@ export const PurchaseSchema = z.object({ acknowledgmentDate: z.coerce.date().nullable(), acknowledgmentNumber: z.string().nullable(), - baseAmount: z.string().min(1, { message: "Base amount is required" }), - taxAmount: z.string().min(1, { message: "Tax amount is required" }), - totalAmount: z.string().min(1, { message: "Total amount is required" }), + baseAmount: z.number().min(1, { message: "Base amount is required" }), + taxAmount: z.number().min(1, { message: "Tax amount is required" }), + totalAmount: z.number().min(1, { message: "Total amount is required" }), paymentDueDate: z.coerce.date().nullable(), - transportCharges: z.string().nullable(), + transportCharges: z.number().nullable(), description: z.string().min(1, { message: "Description is required" }), attachments: z.array(AttachmentSchema([], 25)).optional(), @@ -98,9 +98,9 @@ export const defaultPurchaseValue = { acknowledgmentNumber: null, acknowledgmentDate: null, - baseAmount: "", - taxAmount: "", - totalAmount: "", + baseAmount: 0, + taxAmount: 0, + totalAmount: 0, paymentDueDate: null, transportCharges: null, description: "", diff --git a/src/hooks/useOrganization.js b/src/hooks/useOrganization.js index 028f6d72..dde865fa 100644 --- a/src/hooks/useOrganization.js +++ b/src/hooks/useOrganization.js @@ -39,13 +39,13 @@ export const useOrganizationModal = () => { // ================================Query============================================================= -export const useGlobaleOrganizations = (pageSize, pageNumber, searchString) => { +export const useGlobaleOrganizations = (pageSize, pageNumber,id, searchString) => { return useQuery({ - queryKey: ["global_organization",pageSize, pageNumber, searchString], + queryKey: ["global_organization",pageSize, pageNumber,id, searchString], queryFn: async () => { const resp = await OrganizationRepository.getGlobalOrganization( pageSize, - pageNumber, + pageNumber,id, searchString ); return resp.data; diff --git a/src/hooks/usePurchase.jsx b/src/hooks/usePurchase.jsx index 2cd4fc7f..aa535b58 100644 --- a/src/hooks/usePurchase.jsx +++ b/src/hooks/usePurchase.jsx @@ -62,3 +62,23 @@ export const useCreatePurchaseInvoice = (onSuccessCallback) => { }, }); }; + +export const useUpdatePurchaseInvoice = (onSuccessCallback) => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: async ({purchaseId,payload}) => PurchaseRepository.UpdatePurchase(purchaseId, payload), + onSuccess: (data, variables) => { + showToast("Purchase Invoice Updated successfully", "success"); + if (onSuccessCallback) onSuccessCallback(); + }, + onError: (error) => { + showToast( + error?.response?.data?.message || + error.message || + "Failed to create invoice", + "error" + ); + }, + }); +}; diff --git a/src/pages/purchase/PurchasePage.jsx b/src/pages/purchase/PurchasePage.jsx index 95c00523..8b3c5036 100644 --- a/src/pages/purchase/PurchasePage.jsx +++ b/src/pages/purchase/PurchasePage.jsx @@ -18,7 +18,10 @@ export const usePurchaseContext = () => { }; const PurchasePage = () => { const [searchText, setSearchText] = useState(""); - const [addePurchase, setAddedPurchase] = useState(false); + const [managePurchase, setManagePurchase] = useState({ + isOpen: false, + purchaseId: null, + }); const [viewPurchaseState, setViewPurchase] = useState({ isOpen: false, purchaseId: null, @@ -26,8 +29,8 @@ const PurchasePage = () => { const contextValue = { setViewPurchase, + setManagePurchase, }; - console.log(ViewPurchase); return (
    @@ -56,7 +59,12 @@ const PurchasePage = () => { @@ -65,20 +73,33 @@ const PurchasePage = () => {
    - {addePurchase && ( + {managePurchase.isOpen && ( setAddedPurchase(false)} + closeModal={() => + setManagePurchase({ + isOpen: false, + purchaseId: null, + }) + } > - setAddedPurchase(false)} /> + + setManagePurchase({ + isOpen: false, + purchaseId: null, + }) + } + purchaseId={managePurchase.purchaseId} + /> )} {viewPurchaseState.isOpen && ( setViewPurchase({ isOpen: false, purchaseId: null }) } diff --git a/src/repositories/OrganizationRespository.jsx b/src/repositories/OrganizationRespository.jsx index ab9121ff..9198f464 100644 --- a/src/repositories/OrganizationRespository.jsx +++ b/src/repositories/OrganizationRespository.jsx @@ -41,9 +41,11 @@ const OrganizationRepository = { return api.get(url); }, - getGlobalOrganization: (pageSize, pageNumber, searchString) => + getGlobalOrganization: (pageSize, pageNumber, searchString, id) => api.get( - `/api/Organization/list/basic?pageSize=${pageSize}&pageNumber=${pageNumber}&searchString=${searchString}` + `/api/Organization/list/basic?pageSize=${pageSize}&pageNumber=${pageNumber}${ + id ? `&id=${id}` : "" + }&searchString=${searchString}` ), }; diff --git a/src/repositories/PurchaseRepository.jsx b/src/repositories/PurchaseRepository.jsx index de4a033e..e95f9a1d 100644 --- a/src/repositories/PurchaseRepository.jsx +++ b/src/repositories/PurchaseRepository.jsx @@ -10,6 +10,10 @@ export const PurchaseRepository = { GetPurchase: (id) => api.get(`/api/PurchaseInvoice/details/${id}`), UpdatePurchase: (id, data) => api.patch(`/api/PurchaseInvoice/edit/${id}`, data), + GetDeliveryChallan: (purchaseInvoiceId) => + api.get(`/api/PurchaseInvoice/delivery-challan/list/${purchaseInvoiceId}`), + addDelievryChallan: (data) => + api.post(`/api/PurchaseInvoice/delivery-challan/create`, data), }; // const filterPayload = JSON.stringify({