diff --git a/src/Pages/BookingScreen/Components/OtherConponents/Reprint/ReprintPDFDataShare.jsx b/src/Pages/BookingScreen/Components/OtherConponents/Reprint/ReprintPDFDataShare.jsx
index d36f282..fb98ef1 100644
--- a/src/Pages/BookingScreen/Components/OtherConponents/Reprint/ReprintPDFDataShare.jsx
+++ b/src/Pages/BookingScreen/Components/OtherConponents/Reprint/ReprintPDFDataShare.jsx
@@ -12,6 +12,7 @@ import { uploadImage } from "../../../../../Features/upload/upload";
import { SelfBookingEmailSendLink } from "../../../../../Features/ConfigMasterPage/ConfigMasterPage";
import { Messages } from "../../../../../Components/Notifications/Messages";
const { RangePicker } = DatePicker;
+import dayjs from "dayjs";
const uploadApiUrl = import.meta.env.ENV_IMAGE_UPLOAD_API_URL;
const ReprintPDFDataShare = ({ printDatas, printerTemplateStyle, SettingDataSelector, open = false, onClose = () => { } }) => {
@@ -40,7 +41,9 @@ const ReprintPDFDataShare = ({ printDatas, printerTemplateStyle, SettingDataSele
fetchData(dateStrings);
}
};
-
+const disabledDate = (current) => {
+ return current && current > dayjs().endOf("day");
+};
const fetchData = async (dates = dateStrings) => {
setIsFetching(true);
try {
@@ -184,8 +187,9 @@ Thank you for choosing us!`;
diff --git a/src/Pages/Product/ExcelUpload.jsx b/src/Pages/Product/ExcelUpload.jsx
index 367bd07..18e7388 100644
--- a/src/Pages/Product/ExcelUpload.jsx
+++ b/src/Pages/Product/ExcelUpload.jsx
@@ -606,6 +606,8 @@ const ProductExcel = ({
const [loading, setLoading] = useState(false);
const [message, setMessage] = useState(false);
const [Datas, setDatas] = useState();
+ console.log(Datas, 'Datas32323232');
+
const [currentPage, setCurrentPage] = useState(1);
const [MappingOpen, setMappingOpen] = useState(false);
const [fieldMapping, setFieldMapping] = useState({});
@@ -843,6 +845,7 @@ const ProductExcel = ({
};
const handleFileUpload = (e) => {
+
const file = e.target.files[0];
const reader = new FileReader();
@@ -957,15 +960,28 @@ const ProductExcel = ({
const rows = nonEmptyRows.slice(1);
const dateFields = [
- 'Available From',
- 'Available To',
'Manufacture Date',
'Expire Date',
'Stock Date',
];
function convertToDisplayFormat(dateString) {
+ if (!dateString) return '';
+ // Handle DD/MM/YY or DD/MM/YYYY (from Excel dateNF format)
+ const slashParts = String(dateString).split('/');
+ if (slashParts.length === 3) {
+ const [d, m, y] = slashParts;
+ const fullYear = y.length === 2 ? '20' + y : y;
+ return `${d.padStart(2,'0')}-${m.padStart(2,'0')}-${fullYear}`;
+ }
+ // Handle DD-MM-YYYY already in correct format
+ const dashParts = String(dateString).split('-');
+ if (dashParts.length === 3 && dashParts[2].length === 4) {
+ return dateString; // already DD-MM-YYYY
+ }
+ // Fallback: try native Date parse (YYYY-MM-DD etc)
const date = new Date(dateString);
+ if (isNaN(date.getTime())) return '';
const day = date.getDate().toString().padStart(2, '0');
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const year = date.getFullYear().toString();
@@ -999,6 +1015,12 @@ const ProductExcel = ({
item['Product Varient Name'] === undefined
? 'Variant 1'
: item['Product Varient Name'],
+ 'Manufacture Date':
+ item['Manufacture Date'] == 'NaN-NaN-NaN' ? '' : item['Manufacture Date'],
+ 'Expire Date':
+ item['Expire Date'] == 'NaN-NaN-NaN' ? '' : item['Expire Date'],
+ 'Available From':
+ item['Available From'] == 'NaN-NaN-NaN' ? '' : item['Available From'],
'Available To':
item['Available To'] == 'NaN-NaN-NaN' ? '' : item['Available To'],
ProdId: item['ProdId'] || null,
@@ -1061,9 +1083,9 @@ const ProductExcel = ({
};
const updateImageUrl = (url, index, key) => {
+
const newData1 = [...Datas];
newData1[key] = { ...newData1[key], Productimage: url };
-
setDatas(newData1);
setExcelData(newData1);
};
@@ -1078,7 +1100,7 @@ const ProductExcel = ({
if (selectedImageIndex != null && selectedImageIndex != undefined) {
try {
- if (selectedImage.image !== undefined) {
+ if (selectedImage?.image !== undefined) {
const response = await fetch(selectedImage.image);
const datas = await response.blob();
const metadata = {
@@ -1296,13 +1318,7 @@ const ProductExcel = ({
validation: {
type: 'list',
allowBlank: true,
- formulae: [
- '"' +
- (typeof CategoryNames !== 'undefined'
- ? CategoryNames.join(',')
- : 'Sample Category') +
- '"',
- ],
+ formulae: [`Sheet2!$B$2:$B$${(CategoryNames?.length || 0) + 1}`],
},
sampleValue: sampleData?.category || 'Sample Category',
headerColor: 'FF2929',
@@ -1315,7 +1331,7 @@ const ProductExcel = ({
...headerStyle,
font: { bold: true, color: { argb: '#000000' } },
},
- validation: null,
+ validation: null, // set dynamically per row below
sampleValue: sampleData?.subCategory || 'Sample Sub Category',
headerColor: '52c41a',
},
@@ -1327,7 +1343,7 @@ const ProductExcel = ({
...headerStyle,
font: { bold: true, color: { argb: '#000000' } },
},
- validation: null,
+ validation: null, // set dynamically per row below
sampleValue: sampleData?.brand || 'Sample Brand',
headerColor: '52c41a',
},
@@ -1439,20 +1455,8 @@ const ProductExcel = ({
...headerStyle,
font: { bold: true, color: { argb: '#000000' } },
},
- validation: {
- type: 'list',
- allowBlank: true,
- formulae: [
- '"' +
- (typeof TaxDatas !== 'undefined'
- ? TaxDatas.map((item) =>
- item.replace(/,/g, '').replace('-', '-').trim()
- ).join(',')
- : 'NIL - 0%') +
- '"',
- ],
- },
- sampleValue: 'NIL - 0%',
+ validation: null, // set via Sheet2 range reference below
+ sampleValue: sampleData?.tax || 'NIL - 0%',
headerColor: '52c41a',
},
AutoGenerateQr: {
@@ -1501,7 +1505,7 @@ const ProductExcel = ({
},
OnePiecePrice: {
header: 'OnePiece Price',
- key: 'StockAvailable',
+ key: 'OnePiecePrice',
width: 20,
style: {
...headerStyle,
@@ -1520,7 +1524,7 @@ const ProductExcel = ({
},
AutoGenOnePieceQr: {
header: 'Auto Generate One Piece Qrcode',
- key: 'StockDate',
+ key: 'AutoGenOnePieceQr',
width: 30,
style: {
...headerStyle,
@@ -1536,7 +1540,7 @@ const ProductExcel = ({
},
AutoGenOnePieceQrNum: {
header: 'Auto Generate One Piece Qrcode Number',
- key: 'StockDate',
+ key: 'AutoGenOnePieceQrNum',
width: 40,
style: {
...headerStyle,
@@ -1620,27 +1624,31 @@ const ProductExcel = ({
},
AvailableFrom: {
header: 'Available From',
- key: 'AvailableFrom TIME',
+ key: 'AvailableFrom',
width: 20,
style: {
...headerStyle,
font: { bold: true, color: { argb: '#000000' } },
+ numFmt: '@',
},
validation: null,
- sampleValue: new Date(),
+ sampleValue: '08:00:00',
headerColor: '52c41a',
+ isTimeField: true,
},
AvailableTo: {
header: 'Available To',
- key: 'AvailableTo TIME',
+ key: 'AvailableTo',
width: 20,
style: {
...headerStyle,
font: { bold: true, color: { argb: '#000000' } },
+ numFmt: '@',
},
validation: null,
- sampleValue: new Date(),
+ sampleValue: '22:00:00',
headerColor: '52c41a',
+ isTimeField: true,
},
};
@@ -1772,11 +1780,26 @@ const ProductExcel = ({
};
});
- // Add sample data in row 2
-
+ // Add sample data in row 2 — time fields forced to text format
selectedColumns.forEach((config, index) => {
- const columnLetter = getExcelColumnLetter(index + 1); // ✅ FIXED
- worksheet.getCell(`${columnLetter}2`).value = config.sampleValue;
+ const columnLetter = getExcelColumnLetter(index + 1);
+ const cell = worksheet.getCell(`${columnLetter}2`);
+ if (config.isTimeField) {
+ cell.numFmt = '@';
+ cell.value = String(config.sampleValue);
+ } else {
+ cell.value = config.sampleValue;
+ }
+ });
+
+ // Force text format on all data rows for time fields
+ selectedColumns.forEach((config, index) => {
+ if (config.isTimeField) {
+ const columnLetter = getExcelColumnLetter(index + 1);
+ for (let r = 2; r <= 1002; r++) {
+ worksheet.getCell(`${columnLetter}${r}`).numFmt = '@';
+ }
+ }
});
// Add validation to columns
@@ -1803,29 +1826,42 @@ const ProductExcel = ({
}
});
+// // Now set protection for all rows
+// // First, unlock ALL cells in the worksheet
+// for (let rowNum = 1; rowNum <= worksheet.rowCount; rowNum++) {
+// const row = worksheet.getRow(rowNum);
+// row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
+// const config = selectedColumns[colNumber - 1];
+// cell.protection = { locked: config?.locked || false };
+// });
+// }
+
+// // Then lock ONLY the header row (row 1) and sample row (row 2)
+// worksheet.getRow(1).eachCell({ includeEmpty: true }, (cell) => {
+// cell.protection = { locked: true };
+// });
+
+// worksheet.getRow(2).eachCell({ includeEmpty: true }, (cell) => {
+// cell.protection = { locked: true };
+// });
// Add empty rows for data entry
for (let i = 1; i <= 1000; i++) {
worksheet.addRow({});
}
- // Now set protection for all rows
- // First, unlock ALL cells in the worksheet
- for (let rowNum = 1; rowNum <= worksheet.rowCount; rowNum++) {
- const row = worksheet.getRow(rowNum);
- row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
- const config = selectedColumns[colNumber - 1];
- cell.protection = { locked: config?.locked || false };
- });
+ // Explicitly unlock all data-entry cells (rows 3+) for every column
+ for (let rowNum = 3; rowNum <= worksheet.rowCount; rowNum++) {
+ for (let colNum = 1; colNum <= selectedColumns.length; colNum++) {
+ const config = selectedColumns[colNum - 1];
+ worksheet.getCell(rowNum, colNum).protection = { locked: config?.locked || false };
+ }
}
- // Then lock ONLY the header row (row 1) and sample row (row 2)
- worksheet.getRow(1).eachCell({ includeEmpty: true }, (cell) => {
- cell.protection = { locked: true };
- });
-
- worksheet.getRow(2).eachCell({ includeEmpty: true }, (cell) => {
- cell.protection = { locked: true };
- });
+ // Lock header row (row 1) and sample row (row 2)
+ for (let colNum = 1; colNum <= selectedColumns.length; colNum++) {
+ worksheet.getCell(1, colNum).protection = { locked: true };
+ worksheet.getCell(2, colNum).protection = { locked: true };
+ }
// Protect the worksheet
await worksheet.protect('', {
@@ -2149,6 +2185,139 @@ const ProductExcel = ({
});
}
+ // Write TaxDatas into Sheet2 column N for range-based dropdown (avoids 255-char limit)
+ if (typeof TaxDatas !== 'undefined' && TaxDatas?.length > 0) {
+ TaxDatas.forEach((taxItem, idx) => {
+ worksheet1.getCell(`N${idx + 2}`).value = taxItem.replace(/,/g, '').trim();
+ });
+ }
+
+ // Apply Tax validation using Sheet2 column N range
+ const taxColIndex = selectedColumns.findIndex((c) => c.key === 'TaxId') + 1;
+ if (taxColIndex > 0 && TaxDatas?.length > 0) {
+ for (let rowNumber = 3; rowNumber <= 1002; rowNumber++) {
+ worksheet.getCell(rowNumber, taxColIndex).dataValidation = {
+ type: 'list',
+ allowBlank: true,
+ formulae: [`Sheet2!$N$2:$N$${TaxDatas.length + 1}`],
+ showErrorMessage: false,
+ };
+ }
+ }
+
+ // ── Dynamic SubCategory dropdown per Category ──────────────────────
+ // Build a map: categoryName → [subcat names]
+ const catSubcatMap = {};
+ if (CategoryNames && SubCatData && Subcatnumfid) {
+ CategoryNames.forEach((catName, catIdx) => {
+ const catId = CategoryId?.[catIdx];
+ const subcats = SubCatData.filter(
+ (_, sIdx) => Subcatnumfid[sIdx] == catId
+ );
+ catSubcatMap[catName] = subcats;
+ });
+ }
+
+ // Write each category's subcats into Sheet2 starting at column O (col 15)
+ // Row 1 = category name header, rows 2+ = subcat names
+ const catSubcatStartCol = 15; // column O
+ const catNameToColLetter = {};
+
+ if (CategoryNames) {
+ CategoryNames.forEach((catName, catIdx) => {
+ const colIndex = catSubcatStartCol + catIdx;
+ const colLetter = getExcelColumnLetter(colIndex);
+ catNameToColLetter[catName] = colLetter;
+
+ // Write header (category name)
+ worksheet1.getCell(`${colLetter}1`).value = catName;
+
+ // Write subcats for this category
+ const subcats = catSubcatMap[catName] || [];
+ subcats.forEach((subcat, sIdx) => {
+ worksheet1.getCell(`${colLetter}${sIdx + 2}`).value = subcat;
+ });
+
+ // Define a named range for this category's subcats
+ const safeName = catName.replace(/[^A-Za-z0-9_]/g, '_');
+ const rangeRef = subcats.length > 0
+ ? `Sheet2!$${colLetter}$2:$${colLetter}$${subcats.length + 1}`
+ : `Sheet2!$${colLetter}$2:$${colLetter}$2`;
+
+ workbook.definedNames.add(rangeRef, safeName);
+ });
+ }
+
+ // Find which column index ProdCat and ProdSubCat are in Sheet1
+ const catColIndex = selectedColumns.findIndex((c) => c.key === 'ProdCat') + 1;
+ const subCatColIndex = selectedColumns.findIndex((c) => c.key === 'ProdSubCat') + 1;
+
+ if (catColIndex > 0 && subCatColIndex > 0) {
+ const catColLetter = getExcelColumnLetter(catColIndex);
+
+ for (let rowNumber = 3; rowNumber <= 1002; rowNumber++) {
+ const cell = worksheet.getCell(rowNumber, subCatColIndex);
+ cell.dataValidation = {
+ type: 'list',
+ allowBlank: true,
+ formulae: [`INDIRECT(SUBSTITUTE(${catColLetter}${rowNumber}," ","_"))`],
+ showErrorMessage: false,
+ };
+ }
+ }
+
+ // ── Dynamic Brand dropdown per SubCategory ────────────────────────
+ // Build a map: subcatName → [brand names] using Allbranddatanumfid (parent subcat ID)
+ const subcatBrandMap = {};
+ if (SubCatData && Allbranddata && Allbranddatanumfid) {
+ SubCatData.forEach((subcatName, sIdx) => {
+ const subcatId = SubcatId?.[sIdx];
+ const brands = Allbranddata.filter(
+ (_, bIdx) => Allbranddatanumfid[bIdx] == subcatId
+ );
+ subcatBrandMap[subcatName] = brands;
+ });
+ }
+
+ // Write each subcat's brands into Sheet2 starting after the category columns
+ const brandStartCol = catSubcatStartCol + (CategoryNames?.length || 0) + 1;
+
+ if (SubCatData) {
+ SubCatData.forEach((subcatName, sIdx) => {
+ const colIndex = brandStartCol + sIdx;
+ const colLetter = getExcelColumnLetter(colIndex);
+
+ worksheet1.getCell(`${colLetter}1`).value = `B_${subcatName}`;
+
+ const brands = subcatBrandMap[subcatName] || [];
+ brands.forEach((brand, bIdx) => {
+ worksheet1.getCell(`${colLetter}${bIdx + 2}`).value = brand;
+ });
+
+ const safeName = `B_${subcatName.replace(/[^A-Za-z0-9_]/g, '_')}`;
+ const rangeRef = brands.length > 0
+ ? `Sheet2!$${colLetter}$2:$${colLetter}$${brands.length + 1}`
+ : `Sheet2!$${colLetter}$2:$${colLetter}$2`;
+ workbook.definedNames.add(rangeRef, safeName);
+ });
+ }
+
+ // Apply INDIRECT brand validation based on selected SubCategory
+ const brandColIndex = selectedColumns.findIndex((c) => c.key === 'Brand') + 1;
+ if (subCatColIndex > 0 && brandColIndex > 0) {
+ const subCatColLetter = getExcelColumnLetter(subCatColIndex);
+ for (let rowNumber = 3; rowNumber <= 1002; rowNumber++) {
+ const cell = worksheet.getCell(rowNumber, brandColIndex);
+ cell.dataValidation = {
+ type: 'list',
+ allowBlank: true,
+ formulae: [`INDIRECT("B_"&SUBSTITUTE(${subCatColLetter}${rowNumber}," ","_"))`],
+ showErrorMessage: false,
+ };
+ }
+ }
+ // ─────────────────────────────────────────────────────────────────────
+
// Original complex logic for column C (SUBCAT DATAS)
worksheet1
.getColumn('C')
@@ -2527,7 +2696,7 @@ const ProductExcel = ({
updateImageUrl(url, index)}
+ updateImageUrl={(url) => updateImageUrl(url, index, record.key)}
// ImageLink={record.Productimage || ""}
ImageLink={
onlineImage
diff --git a/src/Pages/Product/ProductForm.jsx b/src/Pages/Product/ProductForm.jsx
index b312e56..f1cf7a1 100644
--- a/src/Pages/Product/ProductForm.jsx
+++ b/src/Pages/Product/ProductForm.jsx
@@ -629,6 +629,10 @@ const ProductForm = ({ formType }) => {
}, [editstate?.Rack, RackData]);
useEffect(() => {
+ // Auto-fill "Variant X" only when we are adding a new variant.
+ // When editing, another effect will populate the full data.
+ if (!openVariant || variantEdit) return;
+
let variantAddData11 = [...variantPriceData];
if (variantAddData11?.length > 0) {
const lastAddProdVariantName11 =
@@ -677,7 +681,32 @@ const ProductForm = ({ formType }) => {
ProdVariantName: `Variant ${parseInt(variantAddData11?.length) + parseInt(2)}`,
});
}
- }, [openVariant]);
+ }, [openVariant, variantEdit, variantPriceData]);
+
+ useEffect(() => {
+ // Populate edit values only after the variant form is mounted.
+ if (!openVariant || !variantEdit) return;
+ if (
+ variantEditIndex === undefined ||
+ variantEditIndex === null ||
+ !variantPriceData?.length
+ ) {
+ return;
+ }
+
+ const row = variantPriceData?.[variantEditIndex];
+ if (!row) return;
+
+ formVariantRef?.current?.setFieldsValue({
+ ProdVariantName: row?.ProdVariantName,
+ AmountOfPiece: row?.OnePcsPrice,
+ MRP: row?.MRP,
+ SellPrice: row?.SellPrice,
+ WhSalePrice: row?.WhSalePrice,
+ OfferPrice: row?.OfferPrice,
+ SpecialPrice: row?.SpecialPrice,
+ });
+ }, [openVariant, variantEdit, variantEditIndex, variantPriceData]);
const onComplete = useCallback(() => {
setMessageData(null);
@@ -1573,28 +1602,7 @@ const ProductForm = ({ formType }) => {
};
const variantActionsFormatter = (row, index) => {
- if (StockOpen == 'Y') {
- formVariantRef?.current?.setFieldsValue({
- ProdVariantName: row?.ProdVariantName,
- AmountOfPiece: row?.OnePcsPrice,
- MRP: row?.MRP,
- SellPrice: row?.SellPrice,
- WhSalePrice: row?.WhSalePrice,
- OfferPrice: row?.OfferPrice,
- SpecialPrice: row?.SpecialPrice,
- });
- } else {
- formVariantRef?.current?.setFieldsValue({
- ProdVariantName: row?.ProdVariantName,
- AmountOfPiece: row?.OnePcsPrice,
- MRP: row?.MRP,
- SellPrice: row?.SellPrice,
- WhSalePrice: row?.WhSalePrice,
- OfferPrice: row?.OfferPrice,
- SpecialPrice: row?.SpecialPrice,
- });
- }
-
+ setOpenVariant(true);
setVariantEdit(true);
setVariantEditIndex(index);
};