added updation invoice
This commit is contained in:
parent
528255c2bd
commit
1b3e090211
@ -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: <PurchasePartyDetails />,
|
||||
component: <PurchasePartyDetails purchase={data} />,
|
||||
},
|
||||
{
|
||||
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()
|
||||
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 }) => {
|
||||
|
||||
<span className="bs-stepper-label">
|
||||
<span className="bs-stepper-title">{step.name}</span>
|
||||
<span className="bs-stepper-subtitle">{step.subtitle}</span>
|
||||
<span className="bs-stepper-subtitle">
|
||||
{step.subtitle}
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
@ -112,7 +168,23 @@ const ManagePurchase = ({ onClose }) => {
|
||||
{/* Content */}
|
||||
<div className="bs-stepper-content py-2">
|
||||
<AppFormProvider {...purchaseOrder}>
|
||||
<form onSubmit={purchaseOrder.handleSubmit(onSubmit)}>
|
||||
<form
|
||||
onKeyDown={(e) => {
|
||||
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}
|
||||
|
||||
<div className="d-flex justify-content-between mt-4">
|
||||
@ -124,21 +196,27 @@ const ManagePurchase = ({ onClose }) => {
|
||||
>
|
||||
Previous
|
||||
</button>
|
||||
<di>
|
||||
|
||||
<div>
|
||||
{activeTab < stepsConfig.length - 1 ? (
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-sm btn-primary"
|
||||
onClick={handleNext}
|
||||
disabled={isPending || isUpdating}
|
||||
>
|
||||
Next <i className="bx bx-sm bx-right-arrow"></i>
|
||||
</button>
|
||||
) : (
|
||||
<button type="submit" className="btn btn-sm btn-primary">
|
||||
{isPending ? "Please Wait" : "SUbmit"}
|
||||
<button
|
||||
type="submit"
|
||||
className="btn btn-sm btn-primary"
|
||||
disabled={isPending || isUpdating}
|
||||
>
|
||||
{isPending || isUpdating ? "Please Wait" : "Submit"}
|
||||
</button>
|
||||
)}
|
||||
</di>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</AppFormProvider>
|
||||
@ -148,3 +226,4 @@ const ManagePurchase = ({ onClose }) => {
|
||||
};
|
||||
|
||||
export default ManagePurchase;
|
||||
|
||||
|
||||
@ -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 }) => {
|
||||
})
|
||||
}
|
||||
>
|
||||
<i className="bx bx-eye me-2"></i>
|
||||
<i className="bx bx-show me-2"></i>
|
||||
<span className="align-left">view</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a className="dropdown-item cursor-pointer">
|
||||
<i className="bx bx-trash me-2"></i>
|
||||
<span className="align-left">Add</span>
|
||||
<a
|
||||
className="dropdown-item cursor-pointer"
|
||||
onClick={() =>
|
||||
setManagePurchase({
|
||||
isOpen: true,
|
||||
purchaseId: item.id,
|
||||
})
|
||||
}
|
||||
>
|
||||
<i className="bx bx-edit me-2"></i>
|
||||
<span className="align-left">Edit</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
|
||||
@ -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
|
||||
/>
|
||||
|
||||
|
||||
@ -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: "",
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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"
|
||||
);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@ -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 (
|
||||
<PurchaseContext.Provider value={contextValue}>
|
||||
<div className="container-fluid">
|
||||
@ -56,7 +59,12 @@ const PurchasePage = () => {
|
||||
<di className="col-6 text-end">
|
||||
<button
|
||||
className="btn btn-sm btn-primary"
|
||||
onClick={() => setAddedPurchase(true)}
|
||||
onClick={() =>
|
||||
setManagePurchase({
|
||||
isOpen: true,
|
||||
purchaseId: null,
|
||||
})
|
||||
}
|
||||
>
|
||||
<i className="bx bx-plus-circle me-2"></i>Add
|
||||
</button>
|
||||
@ -65,20 +73,33 @@ const PurchasePage = () => {
|
||||
</div>
|
||||
|
||||
<PurchaseList searchString={searchText} />
|
||||
{addePurchase && (
|
||||
{managePurchase.isOpen && (
|
||||
<GlobalModel
|
||||
isOpen={addePurchase}
|
||||
isOpen={managePurchase.isOpen}
|
||||
size="lg"
|
||||
closeModal={() => setAddedPurchase(false)}
|
||||
closeModal={() =>
|
||||
setManagePurchase({
|
||||
isOpen: false,
|
||||
purchaseId: null,
|
||||
})
|
||||
}
|
||||
>
|
||||
<ManagePurchase onClose={() => setAddedPurchase(false)} />
|
||||
<ManagePurchase
|
||||
onClose={() =>
|
||||
setManagePurchase({
|
||||
isOpen: false,
|
||||
purchaseId: null,
|
||||
})
|
||||
}
|
||||
purchaseId={managePurchase.purchaseId}
|
||||
/>
|
||||
</GlobalModel>
|
||||
)}
|
||||
|
||||
{viewPurchaseState.isOpen && (
|
||||
<GlobalModel
|
||||
isOpen={viewPurchaseState.isOpen}
|
||||
size="lg"
|
||||
size="xl"
|
||||
closeModal={() =>
|
||||
setViewPurchase({ isOpen: false, purchaseId: null })
|
||||
}
|
||||
|
||||
@ -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}`
|
||||
),
|
||||
};
|
||||
|
||||
|
||||
@ -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({
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user