added organization api and successfuly created invoice

This commit is contained in:
pramod.mahajan 2025-11-26 15:16:58 +05:30
parent 82c1dc4b8e
commit 998284f398
10 changed files with 258 additions and 264 deletions

View File

@ -202,7 +202,7 @@ export const SelectProjectField = ({
isAllProject = false,
disabled,
className,
errors
errors,
}) => {
const [searchText, setSearchText] = useState("");
const debounce = useDebounce(searchText, 300);
@ -304,12 +304,11 @@ export const SelectProjectField = ({
{displayText}
</span>
</button>
{errors?.projectId && (
<div className="danger-text">{errors.projectId.message}</div>
)}
{/* DROPDOWN */}
{errors?.projectId && (
<div className="danger-text">{errors.projectId.message}</div>
)}
{open && (
<ul
className="dropdown-menu w-100 shadow-sm show animate__fadeIn h-64 overflow-auto rounded"
@ -332,6 +331,7 @@ export const SelectProjectField = ({
placeholder="Search..."
/>
</div>
<div className="overflow-auto px-1" style={{ maxHeight: "200px" }}>
{isLoading && (
<li className="dropdown-item text-muted text-center">Loading...</li>
@ -364,6 +364,7 @@ export const SelectProjectField = ({
</li>
);
})}
</div>
</ul>
)}
</div>
@ -372,7 +373,7 @@ export const SelectProjectField = ({
export const SelectFieldSearch = ({
label = "Select",
placeholder = "Select ",
placeholder = "Select",
required = false,
value = null,
onChange,
@ -383,7 +384,7 @@ export const SelectFieldSearch = ({
isMultiple = false,
hookParams,
useFetchHook,
errors=null,
errors = null,
}) => {
const [searchText, setSearchText] = useState("");
const debounce = useDebounce(searchText, 300);
@ -393,108 +394,75 @@ export const SelectFieldSearch = ({
const [open, setOpen] = useState(false);
const dropdownRef = useRef(null);
const getDisplayName = (entity) => {
if (!entity) return "";
return `${entity[labelKey] || ""}`.trim();
};
const getDisplayName = (entity) =>
entity ? `${entity[labelKey] || ""}`.trim() : "";
/** -----------------------------
* SELECTED OPTION (SINGLE)
* ----------------------------- */
/** ----------------------------- SELECTED OPTION ----------------------------- */
let selectedSingle = null;
if (!isMultiple) {
if (isFullObject && value) selectedSingle = value;
else if (!isFullObject && value)
selectedSingle = options.find((o) => o[valueKey] === value);
}
/** -----------------------------
* SELECTED OPTION (MULTIPLE)
* ----------------------------- */
let selectedList = [];
if (isMultiple && Array.isArray(value)) {
if (isFullObject) selectedList = value;
else {
selectedList = options.filter((opt) => value.includes(opt[valueKey]));
}
selectedList = isFullObject
? value
: options.filter((opt) => value.includes(opt[valueKey]));
}
/** Main button label */
const displayText = !isMultiple
? getDisplayName(selectedSingle) || placeholder
: selectedList.length > 0
: selectedList.length
? selectedList.map((e) => getDisplayName(e)).join(", ")
: placeholder;
/** -----------------------------
* HANDLE OUTSIDE CLICK
* ----------------------------- */
/** ----------------------------- OUTSIDE CLICK ----------------------------- */
useEffect(() => {
const handleClickOutside = (e) => {
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
if (dropdownRef.current && !dropdownRef.current.contains(e.target))
setOpen(false);
}
};
document.addEventListener("mousedown", handleClickOutside);
return () => document.removeEventListener("mousedown", handleClickOutside);
}, []);
// MERGED OPTIONS TO ENSURE SELECTED VALUE APPEARS EVEN IF NOT IN SEARCH RESULT
const [mergedOptions, setMergedOptions] = useState([]);
/** ----------------------------- MERGED OPTIONS ----------------------------- */
const [mergedOptions, setMergedOptions] = useState(options);
useEffect(() => {
let finalList = [...options];
if (!isMultiple && value && !isFullObject) {
// already selected option inside options?
const exists = options.some((o) => o[valueKey] === value);
// if selected item not found, try to get from props (value) as fallback
if (!exists && typeof value === "object") {
finalList.unshift(value);
}
if (!isMultiple && value && !isFullObject && typeof value === "object") {
const exists = options.some((o) => o[valueKey] === value[valueKey]);
if (!exists) finalList.unshift(value);
}
if (isMultiple && Array.isArray(value)) {
value.forEach((val) => {
const id = isFullObject ? val[valueKey] : val;
const exists = options.some((o) => o[valueKey] === id);
if (!exists && typeof val === "object") {
finalList.unshift(val);
}
if (!exists && typeof val === "object") finalList.unshift(val);
});
}
setMergedOptions(finalList);
}, [options, value]);
// Only update if different to avoid infinite loop
const oldKeys = mergedOptions.map((o) => o[valueKey]).join(",");
const newKeys = finalList.map((o) => o[valueKey]).join(",");
if (oldKeys !== newKeys) setMergedOptions(finalList);
}, [options, value, isMultiple, isFullObject, valueKey, mergedOptions]);
/** -----------------------------
* HANDLE SELECT
* ----------------------------- */
/** ----------------------------- HANDLE SELECT ----------------------------- */
const handleSelect = (option) => {
if (!isMultiple) {
// SINGLE SELECT
if (isFullObject) onChange(option);
else onChange(option[valueKey]);
onChange(isFullObject ? option : option[valueKey]);
} else {
// MULTIPLE SELECT
let updated = [];
const exists = selectedList.some((e) => e[valueKey] === option[valueKey]);
if (exists) {
// remove
updated = selectedList.filter((e) => e[valueKey] !== option[valueKey]);
} else {
// add
updated = [...selectedList, option];
}
if (isFullObject) onChange(updated);
else onChange(updated.map((x) => x[valueKey]));
const updated = exists
? selectedList.filter((e) => e[valueKey] !== option[valueKey])
: [...selectedList, option];
onChange(isFullObject ? updated : updated.map((x) => x[valueKey]));
}
};
@ -506,10 +474,9 @@ export const SelectFieldSearch = ({
</Label>
)}
{/* MAIN BUTTON */}
<button
type="button"
className={`select2-icons form-select d-flex align-items-center justify-content-between ${
className={`select2-icons form-select d-flex align-items-center justify-content-between ${
open ? "show" : ""
}`}
disabled={disabled}
@ -519,21 +486,18 @@ export const SelectFieldSearch = ({
{displayText}
</span>
</button>
{errors && (
<div className="danger-text">{errors.message}</div>
)}
{/* DROPDOWN */}
{errors && <div className="danger-text">{errors.message}</div>}
{open && (
<ul
className="dropdown-menu w-100 shadow-sm show animate__fadeIn h-64 overflow-auto rounded overflow-x-hidden"
className="dropdown-menu w-100 shadow-sm show animate__fadeIn h-64 overflow-auto rounded rounded-top-0 overflow-x-hidden"
style={{
position: "absolute",
top: "100%",
left: 0,
zIndex: 1050,
marginTop: "2px",
borderRadius: "0.375rem",
marginTop: "1px",
overflow: "hidden",
}}
>
@ -547,36 +511,40 @@ export const SelectFieldSearch = ({
disabled={disabled}
/>
</div>
<div className="overflow-auto px-1" style={{ maxHeight: "200px" }}>
{isLoading && (
<li className="dropdown-item text-muted text-center">
Loading...
</li>
)}
{!isLoading && mergedOptions.length === 0 && (
<li className="dropdown-item text-muted text-center">
No results found
</li>
)}
{isLoading && (
<li className="dropdown-item text-muted text-center">Loading...</li>
)}
{!isLoading &&
mergedOptions.map((option) => {
const isActive = isMultiple
? selectedList.some((x) => x[valueKey] === option[valueKey])
: selectedSingle &&
selectedSingle[valueKey] === option[valueKey];
{!isLoading && options.length === 0 && (
<li className="dropdown-item text-muted text-center">
No results found
</li>
)}
{!isLoading &&
options.map((option) => {
const isActive = isMultiple
? selectedList.some((x) => x[valueKey] === option[valueKey])
: selectedSingle &&
selectedSingle[valueKey] === option[valueKey];
return (
<li key={option[valueKey]}>
<button
type="button"
className={`dropdown-item ${isActive ? "active" : ""}`}
onClick={() => handleSelect(option)}
>
{getDisplayName(option)}
</button>
</li>
);
})}
return (
<li key={option[valueKey]}>
<button
type="button"
className={`dropdown-item rounded ${
isActive ? "active" : ""
}`}
onClick={() => handleSelect(option)}
>
{getDisplayName(option)}
</button>
</li>
);
})}
</div>
</ul>
)}
</div>

View File

@ -9,29 +9,30 @@ import {
import PurchasePartyDetails from "./PurchasePartyDetails";
import PurchaseTransportDetails from "./PurchaseTransportDetails";
import PurchasePaymentDetails from "./PurchasePaymentDetails";
import { useCreatePurchaseInvoice } from "../../hooks/usePurchase";
const ManagePurchase = () => {
const ManagePurchase = ({ onClose }) => {
const [activeTab, setActiveTab] = useState(0);
const [completedTabs, setCompletedTabs] = useState([]);
const stepsConfig = [
{
name: "Contact Info",
name: "Party Details",
icon: "bx bx-user bx-md",
subtitle: "Provide Contact Details",
subtitle: "Supplier & project information",
component: <PurchasePartyDetails />,
},
{
name: "Organization",
icon: "bx bx-buildings bx-md",
subtitle: "Organization Details",
component: <PurchaseTransportDetails/>,
name: "Invoice & Transport",
icon: "bx bx-receipt bx-md",
subtitle: "Invoice, eWay bill & transport info",
component: <PurchaseTransportDetails />,
},
{
name: "Subscription",
icon: "bx bx-star bx-md",
subtitle: "Payment & Financials",
component: <PurchasePaymentDetails/>,
name: "Payment Details",
icon: "bx bx-credit-card bx-md",
subtitle: "Amount, tax & due date",
component: <PurchasePaymentDetails />,
},
];
@ -55,8 +56,14 @@ const ManagePurchase = () => {
setActiveTab((prev) => Math.max(prev - 1, 0));
};
const { mutate: CreateInvoice, isPending } = useCreatePurchaseInvoice(() => {
onClose?.();
});
const onSubmit = (formData) => {
console.log("PURCHASE DATA:", formData);
let payload = formData;
CreateInvoice(payload);
};
return (
@ -88,9 +95,7 @@ const ManagePurchase = () => {
<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,26 +117,27 @@ const ManagePurchase = () => {
<div className="d-flex justify-content-between mt-4">
<button
type="button"
className="btn btn-outline-secondary"
className="btn btn-sm btn-outline-secondary"
onClick={handlePrev}
disabled={activeTab === 0}
>
Previous
</button>
{activeTab < stepsConfig.length - 1 ? (
<button
type="button"
className="btn btn-sm btn-primary"
onClick={handleNext}
>
Next
</button>
) : (
<button type="submit" className="btn btn-sm btn-primary">
Submit
</button>
)}
<di>
{activeTab < stepsConfig.length - 1 ? (
<button
type="button"
className="btn btn-sm btn-primary"
onClick={handleNext}
>
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>
)}
</di>
</div>
</form>
</AppFormProvider>

View File

@ -6,7 +6,7 @@ import {
SelectFieldSearch,
SelectProjectField,
} from "../common/Forms/SelectFieldServerSide";
import { useOrganization, useOrganizationsList } from "../../hooks/useOrganization";
import { useGlobaleOrganizations, useOrganization, useOrganizationsList } from "../../hooks/useOrganization";
import { ITEMS_PER_PAGE } from "../../utils/constants";
const PurchasePartyDetails = () => {
@ -82,7 +82,7 @@ const PurchasePartyDetails = () => {
onChange={field.onChange}
valueKey="id"
labelKey="name"
useFetchHook={useOrganizationsList}
useFetchHook={useGlobaleOrganizations}
hookParams={[ITEMS_PER_PAGE,1]}
errors={errors?.organizationId}
/>
@ -93,15 +93,25 @@ const PurchasePartyDetails = () => {
{/* Supplier */}
<div className="col-12 col-md-6">
<Label htmlFor="supplierId" required>
Supplier
</Label>
<input
id="supplierId"
type="text"
className={`form-control form-control-md `}
{...register("supplierId")}
<AppFormController
name="supplierId"
control={control}
render={({ field }) => (
<SelectFieldSearch
label="Supplier"
placeholder="Select Organization"
required
value={field.value}
onChange={field.onChange}
valueKey="id"
labelKey="name"
useFetchHook={useGlobaleOrganizations}
hookParams={[ITEMS_PER_PAGE,1]}
errors={errors?.organizationId}
/>
)}
/>
{errors?.supplierId && (

View File

@ -1,20 +1,24 @@
import React from "react";
import React, { useEffect } from "react";
import Label from "../common/Label";
import { useAppFormContext } from "../../hooks/appHooks/useAppForm";
import DatePicker from "../common/DatePicker";
import { useInvoiceAttachmentTypes } from "../../hooks/masterHook/useMaster";
const PurchasePaymentDetails = () => {
const { data, isLoading, error, isError } = useInvoiceAttachmentTypes();
console.log(data);
const {
register,
watch,
setValue,control,
setValue,
control,
formState: { errors },
} = useAppFormContext();
const baseAmount = watch("baseAmount");
const taxAmount = watch("taxAmount");
React.useEffect(() => {
useEffect(() => {
const base = parseFloat(baseAmount) || 0;
const tax = parseFloat(taxAmount) || 0;
@ -25,7 +29,6 @@ const PurchasePaymentDetails = () => {
return (
<div className="row g-2 text-start">
{/* Base Amount */}
<div className="col-12 col-md-4">
<Label htmlFor="baseAmount" required>
Base Amount
@ -45,7 +48,6 @@ const PurchasePaymentDetails = () => {
)}
</div>
{/* Tax Amount */}
<div className="col-12 col-md-4">
<Label htmlFor="taxAmount" required>
Tax Amount
@ -65,7 +67,6 @@ const PurchasePaymentDetails = () => {
)}
</div>
{/* Total Amount */}
<div className="col-12 col-md-4">
<Label htmlFor="totalAmount" required>
Total Amount
@ -86,7 +87,6 @@ const PurchasePaymentDetails = () => {
)}
</div>
{/* Transport Charges */}
<div className="col-12 col-md-6">
<Label htmlFor="transportCharges">Transport Charges</Label>
@ -104,12 +104,14 @@ const PurchasePaymentDetails = () => {
)}
</div>
{/* Payment Due Date */}
<div className="col-12 col-md-6">
<Label htmlFor="paymentDueDate">Payment Due Date</Label>
<DatePicker name={"paymentDueDate"} control={control} className="w-full"/>
<DatePicker
name={"paymentDueDate"}
control={control}
className="w-full"
/>
{errors?.paymentDueDate && (
<div className="small danger-text mt-1">

View File

@ -10,16 +10,25 @@ import {
} from "@tanstack/react-query";
import showToast from "../../services/toastService";
export const useRecurringStatus = ()=>{
export const useInvoiceAttachmentTypes = () => {
return useQuery({
queryKey:["RecurringStatus"],
queryFn:async()=>{
queryKey: ["invoiceAttachmentType"],
queryFn: async () => {
const resp = await MasterRespository.getInvoiceAttachmentTypes();
return resp.data;
},
});
};
export const useRecurringStatus = () => {
return useQuery({
queryKey: ["RecurringStatus"],
queryFn: async () => {
const resp = await MasterRespository.getRecurringStatus();
return resp.data
}
})
}
return resp.data;
},
});
};
export const useCurrencies = () => {
return useQuery({
queryKey: ["currencies"],
@ -31,10 +40,10 @@ export const useCurrencies = () => {
};
export const usePaymentAjustmentHead = (isActive) => {
return useQuery({
queryKey: ["paymentType",isActive],
queryFn: async () => await MasterRespository.getPaymentAdjustmentHead(isActive),
return useQuery({
queryKey: ["paymentType", isActive],
queryFn: async () =>
await MasterRespository.getPaymentAdjustmentHead(isActive),
});
};
@ -296,26 +305,26 @@ export const useOrganizationType = () => {
});
};
export const useJobStatus=(statusId,projectId)=>{
export const useJobStatus = (statusId, projectId) => {
return useQuery({
queryKey:["Job_Staus",statusId,projectId],
queryFn:async()=>{
const resp = await MasterRespository.getJobStatus(statusId,projectId);
queryKey: ["Job_Staus", statusId, projectId],
queryFn: async () => {
const resp = await MasterRespository.getJobStatus(statusId, projectId);
return resp.data;
},
enabled:!!statusId && !!projectId
})
}
enabled: !!statusId && !!projectId,
});
};
export const useTeamRole=()=>{
export const useTeamRole = () => {
return useQuery({
queryKey:["Team_Role"],
queryFn:async()=>{
queryKey: ["Team_Role"],
queryFn: async () => {
const resp = await MasterRespository.getTeamRole();
return resp.data;
}
})
}
},
});
};
//#region ==Get Masters==
const fetchMasterData = async (masterType) => {
switch (masterType) {
@ -405,8 +414,6 @@ const useMaster = () => {
export default useMaster;
//#endregion
// ================================Mutation====================================
//#region Job Role
@ -456,10 +463,6 @@ export const useCreateJobRole = (onSuccessCallback) => {
};
//#endregion Job Role
//#region Application Role
export const useCreateApplicationRole = (onSuccessCallback) => {
const queryClient = useQueryClient();
@ -505,10 +508,6 @@ export const useUpdateApplicationRole = (onSuccessCallback) => {
};
//#endregion
//#region Create work Category
export const useCreateWorkCategory = (onSuccessCallback) => {
const queryClient = useQueryClient();
@ -554,11 +553,6 @@ export const useUpdateWorkCategory = (onSuccessCallback) => {
};
//#endregion
//#region Contact Category
export const useCreateContactCategory = (onSuccessCallback) => {
@ -609,10 +603,6 @@ export const useUpdateContactCategory = (onSuccessCallback) => {
//#endregion
//#region Contact Tag
export const useCreateContactTag = (onSuccessCallback) => {
@ -659,10 +649,6 @@ export const useUpdateContactTag = (onSuccessCallback) => {
};
//#endregion
//#region Expense Category
export const useCreateExpenseCategory = (onSuccessCallback) => {
const queryClient = useQueryClient();
@ -689,7 +675,10 @@ export const useUpdateExpenseCategory = (onSuccessCallback) => {
return useMutation({
mutationFn: async ({ id, payload }) => {
const response = await MasterRespository.updateExpenseCategory(id, payload);
const response = await MasterRespository.updateExpenseCategory(
id,
payload
);
return response.data;
},
onSuccess: (data, variables) => {
@ -708,11 +697,6 @@ export const useUpdateExpenseCategory = (onSuccessCallback) => {
//#endregion
//#region Payment Mode
export const useCreatePaymentMode = (onSuccessCallback) => {
@ -759,10 +743,6 @@ export const useUpdatePaymentMode = (onSuccessCallback) => {
//#endregion
// Services-------------------------------
// export const useCreateService = (onSuccessCallback) => {
@ -844,10 +824,6 @@ export const useUpdateService = (onSuccessCallback) => {
//#endregion
//#region Activity Grouph
export const useCreateActivityGroup = (onSuccessCallback) => {
@ -912,10 +888,6 @@ export const useUpdateActivityGroup = (onSuccessCallback) => {
//#endregion
//#region Activities
export const useCreateActivity = (onSuccessCallback) => {
const queryClient = useQueryClient();
@ -970,11 +942,6 @@ export const useUpdateActivity = (onSuccessCallback) => {
//#endregion
//#region Expense Status
export const useCreateExpenseStatus = (onSuccessCallback) => {
const queryClient = useQueryClient();
@ -1018,10 +985,6 @@ export const useUpdateExpenseStatus = (onSuccessCallback) => {
};
//#endregion
//#region Document-Category
export const useCreateDocumentCatgory = (onSuccessCallback) => {
const queryClient = useQueryClient();
@ -1068,11 +1031,6 @@ export const useUpdateDocumentCategory = (onSuccessCallback) => {
};
//#endregion
//#region Document-Type
export const useCreateDocumentType = (onSuccessCallback) => {
const queryClient = useQueryClient();
@ -1117,10 +1075,6 @@ export const useUpdateDocumentType = (onSuccessCallback) => {
};
//#endregion
//#region Payment Adjustment Head
export const useCreatePaymentAjustmentHead = (onSuccessCallback) => {
const queryClient = useQueryClient();
@ -1147,7 +1101,10 @@ export const useUpdatePaymentAjustmentHead = (onSuccessCallback) => {
return useMutation({
mutationFn: async ({ id, payload }) => {
const resp = await MasterRespository.updatePaymentAjustmentHead(id, payload);
const resp = await MasterRespository.updatePaymentAjustmentHead(
id,
payload
);
return resp.data;
},
onSuccess: (data) => {
@ -1164,10 +1121,6 @@ export const useUpdatePaymentAjustmentHead = (onSuccessCallback) => {
};
//#endregion
//#region ==Delete Master==
export const useDeleteMasterItem = () => {
const queryClient = useQueryClient();
@ -1203,8 +1156,6 @@ export const useDeleteMasterItem = () => {
//#endregion
export const useDeleteServiceGroup = () => {
const queryClient = useQueryClient();

View File

@ -24,7 +24,9 @@ export const useOrganizationModal = () => {
dispatch(
openOrgModal({
isOpen: true,
orgData: options.hasOwnProperty("orgData") ? options.orgData : orgData,
orgData: options.hasOwnProperty("orgData")
? options.orgData
: orgData,
startStep: options.startStep ?? startStep ?? 1,
prevStep: options.prevStep ?? prevStep ?? 1,
flowType: options.flowType ?? flowType ?? "default",
@ -37,16 +39,30 @@ export const useOrganizationModal = () => {
// ================================Query=============================================================
export const useOrganization=(id)=>{
return useQuery({
queryKey:["organization",id],
queryFn:async()=> {
const resp = await await OrganizationRepository.getOrganizaion(id);
return resp.data
},
enabled:!!id
})
}
export const useGlobaleOrganizations = (pageSize, pageNumber, searchString) => {
return useQuery({
queryKey: ["global_organization",pageSize, pageNumber, searchString],
queryFn: async () => {
const resp = await OrganizationRepository.getGlobalOrganization(
pageSize,
pageNumber,
searchString
);
return resp.data;
},
});
};
export const useOrganization = (id) => {
return useQuery({
queryKey: ["organization", id],
queryFn: async () => {
const resp = await await OrganizationRepository.getOrganizaion(id);
return resp.data;
},
enabled: !!id,
});
};
export const useOrganizationBySPRID = (sprid) => {
return useQuery({
queryKey: ["organization by", sprid],
@ -101,7 +117,7 @@ export const useOrganizationEmployees = (
organizationId,
searchString
),
enabled: !!projectId ,
enabled: !!projectId,
});
};
@ -138,10 +154,10 @@ export const useAssignOrgToProject = (onSuccessCallback) => {
useClient.invalidateQueries({
queryKey: ["projectAssignedOrganiztions"],
});
useClient.invalidateQueries({
useClient.invalidateQueries({
queryKey: ["projectAssignedOrganiztionsName"],
});
useClient.invalidateQueries({
queryKey: ["projectAssignedServices", projectId],
});
@ -181,12 +197,14 @@ export const useAssignOrgToTenant = (onSuccessCallback) => {
export const useUpdateOrganization = (onSuccessCallback) => {
const useClient = useQueryClient();
return useMutation({
mutationFn: async ({orgId,payload}) =>
await OrganizationRepository.updateOrganizaion(orgId,payload),
mutationFn: async ({ orgId, payload }) =>
await OrganizationRepository.updateOrganizaion(orgId, payload),
onSuccess: (_, variables) => {
useClient.invalidateQueries({ queryKey: ["organizationList"] });
useClient.invalidateQueries({ queryKey: ["projectAssignedOrganiztionsName"] });
useClient.invalidateQueries({
queryKey: ["projectAssignedOrganiztionsName"],
});
showToast("Organization Updated successfully", "success");
if (onSuccessCallback) onSuccessCallback();
},

25
src/hooks/usePurchase.jsx Normal file
View File

@ -0,0 +1,25 @@
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { PurchaseRepository } from "../repositories/PurchaseRepository";
export const useCreatePurchaseInvoice = (onSuccessCallback) => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (payload) =>
await PurchaseRepository.CreatePurchase(payload),
onSuccess: (data, variables) => {
showToast("Purchase Invoice Created successfully", "success");
if (onSuccessCallback) onSuccessCallback();
},
onError: (error) => {
showToast(
error?.response?.data?.message ||
error.message ||
"Failed to create invoice",
"error"
);
},
});
};

View File

@ -157,4 +157,7 @@ export const MasterRespository = {
),
getTeamRole: () => api.get(`/api/Master/team-roles/list`),
getInvoiceAttachmentTypes:()=>api.get("/api/Master/invoice-attachment-type/list")
};

View File

@ -2,8 +2,9 @@ import { api } from "../utils/axiosClient";
const OrganizationRepository = {
createOrganization: (data) => api.post("/api/Organization/create", data),
updateOrganizaion:(id,data)=>api.put(`/api/Organization/edit/${id}`,data),
getOrganizaion:(id)=>api.get(`/api/Organization/details/${id}`),
updateOrganizaion: (id, data) =>
api.put(`/api/Organization/edit/${id}`, data),
getOrganizaion: (id) => api.get(`/api/Organization/details/${id}`),
getOrganizationList: (pageSize, pageNumber, active, sprid, searchString) => {
return api.get(
`/api/Organization/list?pageSize=${pageSize}&pageNumber=${pageNumber}&active=${active}&${
@ -39,6 +40,11 @@ const OrganizationRepository = {
return api.get(url);
},
getGlobalOrganization: (pageSize, pageNumber, searchString) =>
api.get(
`/api/Organization/list/basic?pageSize=${pageSize}&pageNumber=${pageNumber}&searchString=${searchString}`
),
};
export default OrganizationRepository;

View File

@ -0,0 +1,5 @@
import { api } from "../utils/axiosClient";
export const PurchaseRepository = {
CreatePurchase: (data) => api.post("/api/PurchaseInvoice/create", data),
};