- {newTenantConfig
- .filter((step) => step.name.toLowerCase() !== "congratulation")
- .map((step, index) => {
- const isActive = activeTab === index;
- const isCompleted = completedTabs.includes(index);
+ {/* Header */}
+
+ {stepsConfig.map((step, index) => {
+ const isActive = activeTab === index;
+ const isCompleted = completedTabs.includes(index);
- return (
-
-
-
+
+
+ {index < stepsConfig.length - 1 && (
+
+ )}
+
+ );
+ })}
+
+ {/* Content */}
diff --git a/src/components/purchase/PurchasePartyDetails.jsx b/src/components/purchase/PurchasePartyDetails.jsx
index d7b63533..4870d38a 100644
--- a/src/components/purchase/PurchasePartyDetails.jsx
+++ b/src/components/purchase/PurchasePartyDetails.jsx
@@ -1,31 +1,232 @@
import React from "react";
-import { useAppFormContext } from "../../hooks/appHooks/useAppForm";
+import { AppFormController, useAppFormContext } from "../../hooks/appHooks/useAppForm";
+import Label from "../common/Label";
+import DatePicker from "../common/DatePicker";
+import {
+ SelectFieldSearch,
+ SelectProjectField,
+} from "../common/Forms/SelectFieldServerSide";
+import { useOrganization, useOrganizationsList } from "../../hooks/useOrganization";
+import { ITEMS_PER_PAGE } from "../../utils/constants";
-const PurchasePartyDetails = ({ onNext }) => {
+const PurchasePartyDetails = () => {
const {
register,
control,
- trigger,
+ setValue,
+ watch,
formState: { errors },
} = useAppFormContext();
- const handleNext = async () => {
- const valid = await trigger([
- "title",
- "projectId",
- "organizationId",
- "supplier",
- "billingAddress",
- "shippingAddress",
- "purchaseOrderNumber",
- "purchaseOrderDate",
- "porformaInvoiceNo",
- ]);
- if (valid) {
- onNext();
- }
- };
- return
;
+
+ return (
+
+ {/* Title */}
+
+
+
+
+
+ {errors?.title && (
+
{errors.title.message}
+ )}
+
+
+ {/* Project ID */}
+
+
+ setValue("projectId", val, {
+ shouldDirty: true,
+ shouldValidate: true,
+ })
+ }
+ errors={errors}
+ />
+
+
+ {/* Organization */}
+
+
+ {/* Supplier */}
+
+
+
+
+
+ {errors?.supplierId && (
+
{errors.supplierId.message}
+ )}
+
+
+ {/* Billing Address */}
+
+
+
+
+
+ {errors?.billingAddress && (
+
{errors.billingAddress.message}
+ )}
+
+
+
+
+
+
+
+ {errors?.shippingAddress && (
+
{errors.shippingAddress.message}
+ )}
+
+
+ {/* Purchase Order Number */}
+
+
+
+
+
+ {errors?.purchaseOrderNumber && (
+
+ {errors.purchaseOrderNumber.message}
+
+ )}
+
+
+ {/* Purchase Order Date */}
+
+
+
+
+
+ {errors?.purchaseOrderDate && (
+
{errors.purchaseOrderDate.message}
+ )}
+
+
+ {/* Proforma Invoice */}
+
+
+
+
+ {errors?.proformaInvoiceNumber && (
+
+ {errors.proformaInvoiceNumber.message}
+
+ )}
+
+
+
+
+
+ {errors?.proformaInvoiceAmountt && (
+
+ {errors.proformaInvoiceAmount.message}
+
+ )}
+
+
+
+
+
+
+ {errors?.proformaInvoiceDate && (
+
+ {errors.proformaInvoiceDate.message}
+
+ )}
+
+
+ );
};
export default PurchasePartyDetails;
diff --git a/src/components/purchase/PurchasePaymentDetails.jsx b/src/components/purchase/PurchasePaymentDetails.jsx
index fde938d4..c626ac8b 100644
--- a/src/components/purchase/PurchasePaymentDetails.jsx
+++ b/src/components/purchase/PurchasePaymentDetails.jsx
@@ -1,11 +1,143 @@
-import React from 'react'
+import React from "react";
+import Label from "../common/Label";
+import { useAppFormContext } from "../../hooks/appHooks/useAppForm";
+import DatePicker from "../common/DatePicker";
const PurchasePaymentDetails = () => {
- return (
-
-
-
- )
-}
+ const {
+ register,
+ watch,
+ setValue,control,
+ formState: { errors },
+ } = useAppFormContext();
-export default PurchasePaymentDetails
+ const baseAmount = watch("baseAmount");
+ const taxAmount = watch("taxAmount");
+
+ React.useEffect(() => {
+ const base = parseFloat(baseAmount) || 0;
+ const tax = parseFloat(taxAmount) || 0;
+
+ if (base || tax) {
+ setValue("totalAmount", (base + tax).toFixed(2));
+ }
+ }, [baseAmount, taxAmount, setValue]);
+
+ return (
+
+ {/* Base Amount */}
+
+
+
+
+
+ {errors?.baseAmount && (
+
+ {errors.baseAmount.message}
+
+ )}
+
+
+ {/* Tax Amount */}
+
+
+
+
+
+ {errors?.taxAmount && (
+
+ {errors.taxAmount.message}
+
+ )}
+
+
+ {/* Total Amount */}
+
+
+
+
+
+ {errors?.totalAmount && (
+
+ {errors.totalAmount.message}
+
+ )}
+
+
+ {/* Transport Charges */}
+
+
+
+
+
+ {errors?.transportCharges && (
+
+ {errors.transportCharges.message}
+
+ )}
+
+
+ {/* Payment Due Date */}
+
+
+
+
+
+
+ {errors?.paymentDueDate && (
+
+ {errors.paymentDueDate.message}
+
+ )}
+
+
+
+
+
+
+
+ {errors?.description && (
+
+ {errors.description.message}
+
+ )}
+
+
+ );
+};
+
+export default PurchasePaymentDetails;
diff --git a/src/components/purchase/PurchaseSchema.jsx b/src/components/purchase/PurchaseSchema.jsx
index 04a5dc02..64ba0883 100644
--- a/src/components/purchase/PurchaseSchema.jsx
+++ b/src/components/purchase/PurchaseSchema.jsx
@@ -1,4 +1,5 @@
import { z } from "zod";
+import { normalizeAllowedContentTypes } from "../../utils/appUtils";
export const AttachmentSchema = (allowedContentType, maxSizeAllowedInMB) => {
const allowedTypes = normalizeAllowedContentTypes(allowedContentType);
@@ -6,6 +7,10 @@ export const AttachmentSchema = (allowedContentType, maxSizeAllowedInMB) => {
return z.object({
fileName: z.string().min(1, { message: "File name is required" }),
base64Data: z.string().min(1, { message: "File data is required" }),
+ invoiceAttachmentTypeId: z
+ .string()
+ .min(1, { message: "File data is required" }),
+
contentType: z
.string()
.min(1, { message: "MIME type is required" })
@@ -15,6 +20,7 @@ export const AttachmentSchema = (allowedContentType, maxSizeAllowedInMB) => {
message: `File type must be one of: ${allowedTypes.join(", ")}`,
}
),
+
fileSize: z
.number()
.int()
@@ -23,6 +29,7 @@ export const AttachmentSchema = (allowedContentType, maxSizeAllowedInMB) => {
(maxSizeAllowedInMB ?? 25) * 1024 * 1024,
`fileSize must be ≤ ${maxSizeAllowedInMB ?? 25}MB`
),
+
description: z.string().optional().default(""),
isActive: z.boolean(),
});
@@ -34,27 +41,32 @@ export const PurchaseSchema = z.object({
organizationId: z.string().min(1, { message: "Organization is required" }),
billingAddress: z.string().min(1, { message: "Address is required" }),
shippingAddress: z.string().min(1, { message: "Address is required" }),
+
purchaseOrderNumber: z.string().nullable(),
- purchaseOrderDate: z.string().nullable(),
- supplier: z.string().min(1, { message: "Supplier is required" }),
- porformaInvoiceNo: z.string().nullable(),
- // Supplier Details
+ purchaseOrderDate: z.coerce.date().nullable(),
- invoiceNo: z.string().min(1, { message: "Invoice No is required" }),
- invoiceDate: z.string().min(1, { message: "Date is required" }),
- ewayBillNo: z.string().min(1, { message: "E-Way Bill No is required" }),
- ewayBillDate: z.string().min(1, { message: "E-Way Bill Date is required" }),
- irnNo: z.string().min(1, { message: "IRN is required" }),
- ackDate: z.string().min(1, { message: "Date is required" }),
- ackNo: z.string().min(1, { message: "acknowledgement No is required" }),
+ supplierId: z.string().min(1, { message: "Supplier is required" }),
+
+ proformaInvoiceNumber: z.string().nullable(),
+ proformaInvoiceDate: z.coerce.date().nullable(),
+ proformaInvoiceAmount: z.string().nullable(),
+
+ invoiceNumber: z.string().nullable(),
+ invoiceDate: z.coerce.date().nullable(),
+ eWayBillNumber: z.string().nullable(),
+ eWayBillDate: z.coerce.date().nullable(),
+ invoiceReferenceNumber: z.string().nullable(),
+ acknowledgmentDate: z.coerce.date().nullable(),
+ acknowledgmentNumber: z.string().nullable(),
- // Payment Detail
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" }),
- paymentDueDate: z.string().nullable(),
- TransportCharges: z.string().nullable(),
- description: z.string().min(1, { message: "description is required" }),
+ paymentDueDate: z.coerce.date().nullable(),
+ transportCharges: z.string().nullable(),
+ description: z.string().min(1, { message: "Description is required" }),
+
+ attachments: z.array(AttachmentSchema([], 25)).optional(),
});
// deliveryChallanNo: z
@@ -64,30 +76,36 @@ export const PurchaseSchema = z.object({
// shippingAddress: z.string().min(1, { message: "Delevery Date is required" }),
export const defaultPurchaseValue = {
- title: null,
- projectId: null,
- organizationId: null,
- billingAddress: null,
- shippingAddress: null,
+ title: "",
+ projectId: "",
+ organizationId: "",
+ billingAddress: "",
+ shippingAddress: "",
purchaseOrderNumber: null,
purchaseOrderDate: null,
- supplier: null,
- porformaInvoiceNo: null,
- invoiceNo: null,
+ supplierId: "",
+
+ proformaInvoiceNumber: null,
+ proformaInvoiceDate: null,
+ proformaInvoiceAmount: null,
+
+ invoiceNumber: null,
invoiceDate: null,
- ewayBillNo: null,
- ewayBillDate: null,
- irnNo: null,
- ackDate: null,
- ackNo: null,
+ eWayBillNumber: null,
+ eWayBillDate: null,
+ invoiceReferenceNumber: null,
+ acknowledgmentNumber: null,
+ acknowledgmentDate: null,
- baseAmount: null,
- taxAmount: null,
- totalAmount: null,
+ baseAmount: "",
+ taxAmount: "",
+ totalAmount: "",
paymentDueDate: null,
- TransportCharges: null,
- description: null,
+ transportCharges: null,
+ description: "",
+
+ attachments: [],
};
export const getStepFields = (stepIndex) => {
@@ -96,28 +114,29 @@ export const getStepFields = (stepIndex) => {
"title",
"projectId",
"organizationId",
- "supplier",
+ "supplierId",
"billingAddress",
"shippingAddress",
"purchaseOrderNumber",
"purchaseOrderDate",
- "porformaInvoiceNo",
+ "proformaInvoiceNumber",
+ "proformaInvoiceDate",
+ "proformaInvoiceAmount",
],
1: [
- "invoiceNo",
+ "invoiceNumber",
"invoiceDate",
- "ewayBillNo",
- "ewayBillDate",
- "irnNo",
- "ackNo",
- "taxId",
- "ackDate",
+ "eWayBillNumber",
+ "eWayBillDate",
+ "invoiceReferenceNumber",
+ "acknowledgmentNumber",
+ "acknowledgmentDate",
],
2: [
"baseAmount",
"taxAmount",
"totalAmount",
- "TransportCharges",
+ "transportCharges",
"paymentDueDate",
"description",
],
diff --git a/src/components/purchase/PurchaseTansportDetails.jsx b/src/components/purchase/PurchaseTansportDetails.jsx
deleted file mode 100644
index 483845e6..00000000
--- a/src/components/purchase/PurchaseTansportDetails.jsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import React from 'react'
-
-const PurchaseTansportDetails = () => {
- return (
-
-
-
- )
-}
-
-export default PurchaseTansportDetails
diff --git a/src/components/purchase/PurchaseTransportDetails.jsx b/src/components/purchase/PurchaseTransportDetails.jsx
new file mode 100644
index 00000000..b3237594
--- /dev/null
+++ b/src/components/purchase/PurchaseTransportDetails.jsx
@@ -0,0 +1,131 @@
+import React from "react";
+import { useAppFormContext } from "../../hooks/appHooks/useAppForm";
+import DatePicker from "../common/DatePicker";
+import Label from "../common/Label";
+
+const PurchaseTransportDetails = () => {
+ const {
+ register,control,
+ formState: { errors },
+ } = useAppFormContext();
+
+ return (
+
+ {/* Invoice Number */}
+
+
+
+
+
+ {errors?.invoiceNumber && (
+
+ {errors.invoiceNumber.message}
+
+ )}
+
+
+ {/* Invoice Date */}
+
+
+
+
+
+
+ {errors?.invoiceDate && (
+
+ {errors.invoiceDate.message}
+
+ )}
+
+
+ {/* E-Way Bill Number */}
+
+
+
+
+
+ {errors?.eWayBillNumber && (
+
+ {errors.eWayBillNumber.message}
+
+ )}
+
+
+ {/* E-Way Bill Date */}
+
+
+
+
+
+
+ {errors?.eWayBillDate && (
+
+ {errors.eWayBillDate.message}
+
+ )}
+
+
+ {/* Invoice Reference Number */}
+
+
+
+
+
+ {errors?.invoiceReferenceNumber && (
+
+ {errors.invoiceReferenceNumber.message}
+
+ )}
+
+
+ {/* Acknowledgment Number */}
+
+
+
+
+
+ {errors?.acknowledgmentNumber && (
+
+ {errors.acknowledgmentNumber.message}
+
+ )}
+
+
+
+
+
+
+
+ {errors?.acknowledgmentDate && (
+
+ {errors.acknowledgmentDate.message}
+
+ )}
+
+
+ );
+};
+
+export default PurchaseTransportDetails;