diff --git a/capacitor.config.json b/capacitor.config.json
new file mode 100644
index 0000000..2a7f3c4
--- /dev/null
+++ b/capacitor.config.json
@@ -0,0 +1,10 @@
+{
+ "appId": "com.example.app",
+ "appName": "PozoApp",
+ "webDir": "dist",
+ "plugins": {
+ "StatusBar": {
+ "overlay": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index b880d73..51320e1 100644
--- a/package.json
+++ b/package.json
@@ -12,10 +12,14 @@
},
"dependencies": {
"@ant-design/plots": "^2.6.8",
+ "@capacitor-community/file-opener": "^8.0.0",
"@capacitor-community/speech-recognition": "^7.0.1",
"@capacitor-mlkit/barcode-scanning": "^8.0.1",
+ "@capacitor/android": "^8.3.0",
"@capacitor/app": "^8.0.1",
- "@capacitor/core": "^8.1.0",
+ "@capacitor/cli": "^8.3.0",
+ "@capacitor/core": "^8.3.0",
+ "@capacitor/filesystem": "^8.1.2",
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0",
"@emotion/react": "^11.11.4",
@@ -27,6 +31,7 @@
"@tanstack/react-query-devtools": "^5.91.1",
"@tanstack/react-virtual": "^3.13.18",
"@types/node": "^25.5.0",
+ "@vitejs/plugin-legacy": "^8.0.1",
"@zxing/library": "^0.21.3",
"antd": "^5.17.4",
"antd-img-crop": "^4.22.0",
@@ -92,7 +97,7 @@
"eslint-plugin-react-refresh": "^0.4.7",
"prettier": "^3.5.3",
"rollup-plugin-obfuscator": "^1.1.0",
- "sass": "^1.77.2",
+ "sass": "^1.98.0",
"terser": "^5.31.3",
"vite": "^8.0.0",
"vite-plugin-obfuscator": "^1.0.5",
diff --git a/src/Pages/CommonMaster/ConfigExcelUpload.jsx b/src/Pages/CommonMaster/ConfigExcelUpload.jsx
index fefcbd2..5c2a590 100644
--- a/src/Pages/CommonMaster/ConfigExcelUpload.jsx
+++ b/src/Pages/CommonMaster/ConfigExcelUpload.jsx
@@ -16,6 +16,7 @@ import { RadioGrpButton } from '../../Components/Forms/RadioGroup.jsx';
import { AiFillDelete } from 'react-icons/ai';
import upldimg from '../../Images/upldimg.png';
import { FiDelete, FiDownload } from 'react-icons/fi';
+import { downloadFile } from '../../utils/downloadFile.js';
const allowedExcelTypes = [
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', // .xlsx
'application/vnd.ms-excel', // .xls
@@ -328,10 +329,17 @@ const ConfigExcel = ({ handleSubmit, CategoryNames, SubCatData }) => {
window.navigator.msSaveOrOpenBlob(blob, filename);
} else {
// For other browsers
- const downloadLink = document.createElement('a');
- downloadLink.href = window.URL.createObjectURL(blob);
- downloadLink.download = filename;
- downloadLink.click();
+ downloadFile(
+ buffer,
+ "CategoryDatas.xlsx",
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+ (success) => {
+ if (!success) {
+ console.error("error occured while downloading")
+ }
+ }
+ );
+
}
}
};
@@ -415,10 +423,17 @@ const ConfigExcel = ({ handleSubmit, CategoryNames, SubCatData }) => {
window.navigator.msSaveOrOpenBlob(blob, filename);
} else {
// For other browsers
- const downloadLink = document.createElement('a');
- downloadLink.href = window.URL.createObjectURL(blob);
- downloadLink.download = filename;
- downloadLink.click();
+
+ downloadFile(
+ buffer,
+ "SubcatagoryDatas.xlsx",
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+ (success) => {
+ if (!success) {
+ console.error("Failed to download the file. Please try again.")
+ }
+ }
+ );
}
}
};
@@ -529,10 +544,17 @@ const ConfigExcel = ({ handleSubmit, CategoryNames, SubCatData }) => {
window.navigator.msSaveOrOpenBlob(blob, filename);
} else {
// For other browsers
- const downloadLink = document.createElement('a');
- downloadLink.href = window.URL.createObjectURL(blob);
- downloadLink.download = filename;
- downloadLink.click();
+ downloadFile(
+ buffer,
+ "BrandDatas.xlsx",
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+ (success) => {
+ if (!success) {
+ console.error("Failed to download the file. Please try again.")
+
+ }
+ }
+ );
}
}
};
@@ -673,7 +695,7 @@ const ConfigExcel = ({ handleSubmit, CategoryNames, SubCatData }) => {
...record,
...values,
});
- } catch (errInfo) {}
+ } catch (errInfo) { }
};
let childNode = children;
diff --git a/src/Pages/Product/ExcelUpload.jsx b/src/Pages/Product/ExcelUpload.jsx
index 08040aa..bf78ecc 100644
--- a/src/Pages/Product/ExcelUpload.jsx
+++ b/src/Pages/Product/ExcelUpload.jsx
@@ -4,18 +4,18 @@ import { useDispatch, useSelector } from 'react-redux';
import ExcelJS from 'exceljs';
import { Table, Form, Input, Tooltip, Modal, Select } from 'antd';
import {
- emptyExcelData,
- excelDataSelector,
- excelFileSelector,
- excelFileErrorSelector,
- fileInputRefSelector,
- uploadExcel,
+ emptyExcelData,
+ excelDataSelector,
+ excelFileSelector,
+ excelFileErrorSelector,
+ fileInputRefSelector,
+ uploadExcel,
} from '../../Features/ExcelUploadPage/ExcelUploadPage.js';
import {
- getProductData,
- onlineimages,
- postFieldSetup,
- getFieldSetupData,
+ getProductData,
+ onlineimages,
+ postFieldSetup,
+ getFieldSetupData,
} from '../../Features/ProductPage/ProductPage.js';
import Imageupload from '../../Components/Forms/Upload.jsx';
import { BiSolidFileExport } from 'react-icons/bi';
@@ -32,9 +32,9 @@ import { getSession } from '../../Services/Others.js';
import { ArrowRightOutlined, CloseCircleOutlined } from '@ant-design/icons';
import stringSimilarity from 'string-similarity';
import {
- getCommonAppPreference,
- ApplicationPreferences,
- getApplicationDetails,
+ getCommonAppPreference,
+ ApplicationPreferences,
+ getApplicationDetails,
} from '../../Features/BrachLogin/BranchLogin.js';
import { MdOutlineAppRegistration } from 'react-icons/md';
import FormHeader from '../PageComponents/FormHeader.jsx';
@@ -43,517 +43,502 @@ import Buttons from '../../Components/Forms/Buttons.jsx';
import { IoClose } from 'react-icons/io5';
import { Messages } from '../../Components/Notifications/Messages.jsx';
import useWhyDidYouUpdate from '../../Services/findrerender.js';
+import { downloadFile } from '../../utils/downloadFile.js';
const getApplicationSampleData = (appName) => {
- const sampleDataMap = {
- Restaurant: {
- productName: 'Chicken Biryani',
- quantity: 1,
- uom: 'PLT',
- salesPrice: 250,
- mrp: 280,
- category: 'Non-Vegetarian',
- subCategory: 'Biryani',
- brand: 'Chef Special',
- variantName: 'Large',
- tax: 'CGST+SGST - 5%',
- hsn: '21069030',
- additionalSamples: [
- {
- productName: 'Masala Dosa',
- quantity: 1,
- uom: 'PLT',
- salesPrice: 120,
- category: 'Vegetarian',
- subCategory: 'South Indian',
+ const sampleDataMap = {
+ Restaurant: {
+ productName: 'Chicken Biryani',
+ quantity: 1,
+ uom: 'PLT',
+ salesPrice: 250,
+ mrp: 280,
+ category: 'Non-Vegetarian',
+ subCategory: 'Biryani',
+ brand: 'Chef Special',
+ variantName: 'Large',
+ tax: 'CGST+SGST - 5%',
+ hsn: '21069030',
+ additionalSamples: [
+ {
+ productName: 'Masala Dosa',
+ quantity: 1,
+ uom: 'PLT',
+ salesPrice: 120,
+ category: 'Vegetarian',
+ subCategory: 'South Indian',
+ },
+ {
+ productName: 'Paneer Butter Masala',
+ quantity: 1,
+ uom: 'PLT',
+ salesPrice: 200,
+ category: 'Vegetarian',
+ subCategory: 'North Indian',
+ },
+ ],
},
- {
- productName: 'Paneer Butter Masala',
- quantity: 1,
- uom: 'PLT',
- salesPrice: 200,
- category: 'Vegetarian',
- subCategory: 'North Indian',
+ Bakery: {
+ productName: 'Chocolate Cake',
+ quantity: 1,
+ uom: 'PCS',
+ salesPrice: 500,
+ mrp: 550,
+ category: 'Cakes',
+ subCategory: 'Birthday Cakes',
+ brand: 'Fresh Bakes',
+ variantName: '1 Kg',
+ tax: 'CGST+SGST - 5%',
+ hsn: '19053100',
+ additionalSamples: [
+ {
+ productName: 'Croissant',
+ quantity: 1,
+ uom: 'PCS',
+ salesPrice: 45,
+ category: 'Pastries',
+ subCategory: 'French Pastries',
+ },
+ {
+ productName: 'Whole Wheat Bread',
+ quantity: 1,
+ uom: 'LOAF',
+ salesPrice: 35,
+ category: 'Breads',
+ subCategory: 'Wheat Breads',
+ },
+ ],
},
- ],
- },
- Bakery: {
- productName: 'Chocolate Cake',
- quantity: 1,
- uom: 'PCS',
- salesPrice: 500,
- mrp: 550,
- category: 'Cakes',
- subCategory: 'Birthday Cakes',
- brand: 'Fresh Bakes',
- variantName: '1 Kg',
- tax: 'CGST+SGST - 5%',
- hsn: '19053100',
- additionalSamples: [
- {
- productName: 'Croissant',
- quantity: 1,
- uom: 'PCS',
- salesPrice: 45,
- category: 'Pastries',
- subCategory: 'French Pastries',
+ 'Electrical, Electronics and Computers': {
+ productName: 'LED Bulb 9W',
+ quantity: 1,
+ uom: 'PCS',
+ salesPrice: 120,
+ mrp: 150,
+ category: 'Lighting',
+ subCategory: 'LED Bulbs',
+ brand: 'Philips',
+ variantName: 'Cool White',
+ tax: 'CGST+SGST - 18%',
+ hsn: '85395000',
+ additionalSamples: [
+ {
+ productName: 'Mobile Charger',
+ quantity: 1,
+ uom: 'PCS',
+ salesPrice: 299,
+ category: 'Mobile Accessories',
+ subCategory: 'Chargers',
+ },
+ {
+ productName: 'Extension Board 4 Socket',
+ quantity: 1,
+ uom: 'PCS',
+ salesPrice: 350,
+ category: 'Electrical Accessories',
+ subCategory: 'Power Strips',
+ },
+ ],
},
- {
- productName: 'Whole Wheat Bread',
- quantity: 1,
- uom: 'LOAF',
- salesPrice: 35,
- category: 'Breads',
- subCategory: 'Wheat Breads',
+ 'Mobile Phone and Accessories': {
+ productName: 'Smartphone Screen Guard',
+ quantity: 1,
+ uom: 'PCS',
+ salesPrice: 199,
+ mrp: 299,
+ category: 'Screen Protection',
+ subCategory: 'Tempered Glass',
+ brand: 'TechGuard',
+ variantName: 'iPhone 14',
+ tax: 'CGST+SGST - 18%',
+ hsn: '70071900',
+ additionalSamples: [
+ {
+ productName: 'Phone Case',
+ quantity: 1,
+ uom: 'PCS',
+ salesPrice: 149,
+ category: 'Protection',
+ subCategory: 'Back Covers',
+ },
+ {
+ productName: 'Wireless Earbuds',
+ quantity: 1,
+ uom: 'PAIR',
+ salesPrice: 1599,
+ category: 'Audio',
+ subCategory: 'Bluetooth Earphones',
+ },
+ ],
},
- ],
- },
- 'Electrical, Electronics and Computers': {
- productName: 'LED Bulb 9W',
- quantity: 1,
- uom: 'PCS',
- salesPrice: 120,
- mrp: 150,
- category: 'Lighting',
- subCategory: 'LED Bulbs',
- brand: 'Philips',
- variantName: 'Cool White',
- tax: 'CGST+SGST - 18%',
- hsn: '85395000',
- additionalSamples: [
- {
- productName: 'Mobile Charger',
- quantity: 1,
- uom: 'PCS',
- salesPrice: 299,
- category: 'Mobile Accessories',
- subCategory: 'Chargers',
+ Grocery: {
+ productName: 'Basmati Rice',
+ quantity: 1,
+ uom: 'KG',
+ salesPrice: 85,
+ mrp: 90,
+ category: 'Food Grains',
+ subCategory: 'Rice',
+ brand: 'India Gate',
+ variantName: '1 Kg Pack',
+ tax: 'NIL - 0%',
+ hsn: '10063020',
+ additionalSamples: [
+ {
+ productName: 'Toor Dal',
+ quantity: 1,
+ uom: 'KG',
+ salesPrice: 120,
+ category: 'Pulses',
+ subCategory: 'Arhar Dal',
+ },
+ {
+ productName: 'Refined Oil',
+ quantity: 1,
+ uom: 'LITER',
+ salesPrice: 110,
+ category: 'Cooking Oil',
+ subCategory: 'Sunflower Oil',
+ },
+ ],
},
- {
- productName: 'Extension Board 4 Socket',
- quantity: 1,
- uom: 'PCS',
- salesPrice: 350,
- category: 'Electrical Accessories',
- subCategory: 'Power Strips',
+ 'Departmental Stores': {
+ productName: 'Shampoo',
+ quantity: 1,
+ uom: 'BTL',
+ salesPrice: 180,
+ mrp: 200,
+ category: 'Personal Care',
+ subCategory: 'Hair Care',
+ brand: 'Head & Shoulders',
+ variantName: '200ml',
+ tax: 'CGST+SGST - 18%',
+ hsn: '33051000',
+ additionalSamples: [
+ {
+ productName: 'Toothpaste',
+ quantity: 1,
+ uom: 'TUBE',
+ salesPrice: 45,
+ category: 'Oral Care',
+ subCategory: 'Toothpaste',
+ },
+ {
+ productName: 'Laundry Detergent',
+ quantity: 1,
+ uom: 'KG',
+ salesPrice: 85,
+ category: 'Household',
+ subCategory: 'Washing Powder',
+ },
+ ],
},
- ],
- },
- 'Mobile Phone and Accessories': {
- productName: 'Smartphone Screen Guard',
- quantity: 1,
- uom: 'PCS',
- salesPrice: 199,
- mrp: 299,
- category: 'Screen Protection',
- subCategory: 'Tempered Glass',
- brand: 'TechGuard',
- variantName: 'iPhone 14',
- tax: 'CGST+SGST - 18%',
- hsn: '70071900',
- additionalSamples: [
- {
- productName: 'Phone Case',
- quantity: 1,
- uom: 'PCS',
- salesPrice: 149,
- category: 'Protection',
- subCategory: 'Back Covers',
+ Jewellery: {
+ productName: 'Gold Ring',
+ quantity: 1,
+ uom: 'PCS',
+ salesPrice: 25000,
+ mrp: 26000,
+ category: 'Gold Jewellery',
+ subCategory: 'Rings',
+ brand: 'Tanishq',
+ variantName: '22K Gold',
+ tax: 'CGST+SGST - 3%',
+ hsn: '71131900',
+ additionalSamples: [
+ {
+ productName: 'Silver Earrings',
+ quantity: 1,
+ uom: 'PAIR',
+ salesPrice: 1200,
+ category: 'Silver Jewellery',
+ subCategory: 'Earrings',
+ },
+ {
+ productName: 'Diamond Pendant',
+ quantity: 1,
+ uom: 'PCS',
+ salesPrice: 15000,
+ category: 'Diamond Jewellery',
+ subCategory: 'Pendants',
+ },
+ ],
},
- {
- productName: 'Wireless Earbuds',
- quantity: 1,
- uom: 'PAIR',
- salesPrice: 1599,
- category: 'Audio',
- subCategory: 'Bluetooth Earphones',
+ 'Lifestyle and Fashion': {
+ productName: 'Cotton T-Shirt',
+ quantity: 1,
+ uom: 'PCS',
+ salesPrice: 499,
+ mrp: 599,
+ category: 'Apparel',
+ subCategory: 'T-Shirts',
+ brand: 'Nike',
+ variantName: 'Medium',
+ tax: 'CGST+SGST - 5%',
+ hsn: '61091000',
+ additionalSamples: [
+ {
+ productName: 'Jeans',
+ quantity: 1,
+ uom: 'PCS',
+ salesPrice: 1299,
+ category: 'Bottoms',
+ subCategory: 'Denim',
+ },
+ {
+ productName: 'Sneakers',
+ quantity: 1,
+ uom: 'PAIR',
+ salesPrice: 2499,
+ category: 'Footwear',
+ subCategory: 'Casual Shoes',
+ },
+ ],
},
- ],
- },
- Grocery: {
- productName: 'Basmati Rice',
- quantity: 1,
- uom: 'KG',
- salesPrice: 85,
- mrp: 90,
- category: 'Food Grains',
- subCategory: 'Rice',
- brand: 'India Gate',
- variantName: '1 Kg Pack',
- tax: 'NIL - 0%',
- hsn: '10063020',
- additionalSamples: [
- {
- productName: 'Toor Dal',
- quantity: 1,
- uom: 'KG',
- salesPrice: 120,
- category: 'Pulses',
- subCategory: 'Arhar Dal',
+ 'Salon, Spa and Beauty Parlour': {
+ productName: 'Hair Cut Service',
+ quantity: 1,
+ uom: 'SERVICE',
+ salesPrice: 300,
+ mrp: 350,
+ category: 'Hair Services',
+ subCategory: 'Cutting',
+ brand: 'Premium Salon',
+ variantName: 'Regular Cut',
+ tax: 'CGST+SGST - 18%',
+ hsn: '99820000',
+ additionalSamples: [
+ {
+ productName: 'Facial Treatment',
+ quantity: 1,
+ uom: 'SERVICE',
+ salesPrice: 800,
+ category: 'Skin Care',
+ subCategory: 'Facial',
+ },
+ {
+ productName: 'Hair Color',
+ quantity: 1,
+ uom: 'SERVICE',
+ salesPrice: 1200,
+ category: 'Hair Services',
+ subCategory: 'Coloring',
+ },
+ ],
},
- {
- productName: 'Refined Oil',
- quantity: 1,
- uom: 'LITER',
- salesPrice: 110,
- category: 'Cooking Oil',
- subCategory: 'Sunflower Oil',
+ Stationery: {
+ productName: 'A4 Paper Pack',
+ quantity: 1,
+ uom: 'PACK',
+ salesPrice: 280,
+ mrp: 300,
+ category: 'Paper Products',
+ subCategory: 'Copy Paper',
+ brand: 'JK Copier',
+ variantName: '500 Sheets',
+ tax: 'CGST+SGST - 12%',
+ hsn: '48025510',
+ additionalSamples: [
+ {
+ productName: 'Ball Pen',
+ quantity: 1,
+ uom: 'PCS',
+ salesPrice: 15,
+ category: 'Writing Instruments',
+ subCategory: 'Pens',
+ },
+ {
+ productName: 'Notebook',
+ quantity: 1,
+ uom: 'PCS',
+ salesPrice: 45,
+ category: 'Books & Notebooks',
+ subCategory: 'Exercise Books',
+ },
+ ],
},
- ],
- },
- 'Departmental Stores': {
- productName: 'Shampoo',
- quantity: 1,
- uom: 'BTL',
- salesPrice: 180,
- mrp: 200,
- category: 'Personal Care',
- subCategory: 'Hair Care',
- brand: 'Head & Shoulders',
- variantName: '200ml',
- tax: 'CGST+SGST - 18%',
- hsn: '33051000',
- additionalSamples: [
- {
- productName: 'Toothpaste',
- quantity: 1,
- uom: 'TUBE',
- salesPrice: 45,
- category: 'Oral Care',
- subCategory: 'Toothpaste',
+ Pharmacy: {
+ productName: 'Paracetamol 500mg',
+ quantity: 1,
+ uom: 'STRIP',
+ salesPrice: 12,
+ mrp: 15,
+ category: 'Medicines',
+ subCategory: 'Fever & Pain',
+ brand: 'Crocin',
+ variantName: '10 Tablets',
+ tax: 'CGST+SGST - 12%',
+ hsn: '30049099',
+ additionalSamples: [
+ {
+ productName: 'Hand Sanitizer',
+ quantity: 1,
+ uom: 'BTL',
+ salesPrice: 65,
+ category: 'Healthcare',
+ subCategory: 'Sanitizers',
+ },
+ {
+ productName: 'Bandage Roll',
+ quantity: 1,
+ uom: 'PCS',
+ salesPrice: 25,
+ category: 'Medical Supplies',
+ subCategory: 'First Aid',
+ },
+ ],
},
- {
- productName: 'Laundry Detergent',
- quantity: 1,
- uom: 'KG',
- salesPrice: 85,
- category: 'Household',
- subCategory: 'Washing Powder',
+ Furniture: {
+ productName: 'Wooden Dining Table',
+ quantity: 1,
+ uom: 'PCS',
+ salesPrice: 15000,
+ mrp: 18000,
+ category: 'Dining Furniture',
+ subCategory: 'Dining Tables',
+ brand: 'Royal Oak',
+ variantName: '6 Seater',
+ tax: 'CGST+SGST - 12%',
+ hsn: '94036090',
+ additionalSamples: [
+ {
+ productName: 'Office Chair',
+ quantity: 1,
+ uom: 'PCS',
+ salesPrice: 5500,
+ category: 'Office Furniture',
+ subCategory: 'Chairs',
+ },
+ {
+ productName: 'Queen Size Bed',
+ quantity: 1,
+ uom: 'PCS',
+ salesPrice: 12000,
+ category: 'Bedroom Furniture',
+ subCategory: 'Beds',
+ },
+ ],
},
- ],
- },
- Jewellery: {
- productName: 'Gold Ring',
- quantity: 1,
- uom: 'PCS',
- salesPrice: 25000,
- mrp: 26000,
- category: 'Gold Jewellery',
- subCategory: 'Rings',
- brand: 'Tanishq',
- variantName: '22K Gold',
- tax: 'CGST+SGST - 3%',
- hsn: '71131900',
- additionalSamples: [
- {
- productName: 'Silver Earrings',
- quantity: 1,
- uom: 'PAIR',
- salesPrice: 1200,
- category: 'Silver Jewellery',
- subCategory: 'Earrings',
+ Fruits: {
+ productName: 'Fresh Apples',
+ quantity: 1,
+ uom: 'KG',
+ salesPrice: 180,
+ mrp: 200,
+ category: 'Fresh Fruits',
+ subCategory: 'Seasonal Fruits',
+ brand: 'Farm Fresh',
+ variantName: 'Kashmiri Apple',
+ tax: 'NIL - 0%',
+ hsn: '08081000',
+ additionalSamples: [
+ {
+ productName: 'Bananas',
+ quantity: 1,
+ uom: 'DOZEN',
+ salesPrice: 60,
+ category: 'Fresh Fruits',
+ subCategory: 'Tropical Fruits',
+ },
+ {
+ productName: 'Orange Juice',
+ quantity: 1,
+ uom: 'LITER',
+ salesPrice: 120,
+ category: 'Fruit Juices',
+ subCategory: 'Fresh Juice',
+ },
+ ],
},
- {
- productName: 'Diamond Pendant',
- quantity: 1,
- uom: 'PCS',
- salesPrice: 15000,
- category: 'Diamond Jewellery',
- subCategory: 'Pendants',
+ Textiles: {
+ productName: 'Cotton Fabric',
+ quantity: 1,
+ uom: 'METER',
+ salesPrice: 85,
+ mrp: 100,
+ category: 'Fabric',
+ subCategory: 'Cotton Fabric',
+ brand: 'Raymond',
+ variantName: 'Plain White',
+ tax: 'CGST+SGST - 5%',
+ hsn: '52081900',
+ additionalSamples: [
+ {
+ productName: 'Silk Saree',
+ quantity: 1,
+ uom: 'PCS',
+ salesPrice: 2500,
+ category: 'Ready Made',
+ subCategory: 'Sarees',
+ },
+ {
+ productName: 'Woolen Shawl',
+ quantity: 1,
+ uom: 'PCS',
+ salesPrice: 800,
+ category: 'Accessories',
+ subCategory: 'Shawls',
+ },
+ ],
},
- ],
- },
- 'Lifestyle and Fashion': {
- productName: 'Cotton T-Shirt',
- quantity: 1,
- uom: 'PCS',
- salesPrice: 499,
- mrp: 599,
- category: 'Apparel',
- subCategory: 'T-Shirts',
- brand: 'Nike',
- variantName: 'Medium',
- tax: 'CGST+SGST - 5%',
- hsn: '61091000',
- additionalSamples: [
- {
- productName: 'Jeans',
- quantity: 1,
- uom: 'PCS',
- salesPrice: 1299,
- category: 'Bottoms',
- subCategory: 'Denim',
+ 'Computer Sales Shop': {
+ productName: 'Gaming Laptop',
+ quantity: 1,
+ uom: 'PCS',
+ salesPrice: 55000,
+ mrp: 60000,
+ category: 'Laptops',
+ subCategory: 'Gaming Laptops',
+ brand: 'ASUS',
+ variantName: 'ROG Strix G15',
+ tax: 'CGST+SGST - 18%',
+ hsn: '84713000',
+ additionalSamples: [
+ {
+ productName: 'Wireless Mouse',
+ quantity: 1,
+ uom: 'PCS',
+ salesPrice: 1200,
+ category: 'Computer Accessories',
+ subCategory: 'Mouse',
+ },
+ {
+ productName: 'SSD 500GB',
+ quantity: 1,
+ uom: 'PCS',
+ salesPrice: 4500,
+ category: 'Storage',
+ subCategory: 'Solid State Drive',
+ },
+ ],
},
- {
- productName: 'Sneakers',
- quantity: 1,
- uom: 'PAIR',
- salesPrice: 2499,
- category: 'Footwear',
- subCategory: 'Casual Shoes',
- },
- ],
- },
- 'Salon, Spa and Beauty Parlour': {
- productName: 'Hair Cut Service',
- quantity: 1,
- uom: 'SERVICE',
- salesPrice: 300,
- mrp: 350,
- category: 'Hair Services',
- subCategory: 'Cutting',
- brand: 'Premium Salon',
- variantName: 'Regular Cut',
- tax: 'CGST+SGST - 18%',
- hsn: '99820000',
- additionalSamples: [
- {
- productName: 'Facial Treatment',
- quantity: 1,
- uom: 'SERVICE',
- salesPrice: 800,
- category: 'Skin Care',
- subCategory: 'Facial',
- },
- {
- productName: 'Hair Color',
- quantity: 1,
- uom: 'SERVICE',
- salesPrice: 1200,
- category: 'Hair Services',
- subCategory: 'Coloring',
- },
- ],
- },
- Stationery: {
- productName: 'A4 Paper Pack',
- quantity: 1,
- uom: 'PACK',
- salesPrice: 280,
- mrp: 300,
- category: 'Paper Products',
- subCategory: 'Copy Paper',
- brand: 'JK Copier',
- variantName: '500 Sheets',
- tax: 'CGST+SGST - 12%',
- hsn: '48025510',
- additionalSamples: [
- {
- productName: 'Ball Pen',
- quantity: 1,
- uom: 'PCS',
- salesPrice: 15,
- category: 'Writing Instruments',
- subCategory: 'Pens',
- },
- {
- productName: 'Notebook',
- quantity: 1,
- uom: 'PCS',
- salesPrice: 45,
- category: 'Books & Notebooks',
- subCategory: 'Exercise Books',
- },
- ],
- },
- Pharmacy: {
- productName: 'Paracetamol 500mg',
- quantity: 1,
- uom: 'STRIP',
- salesPrice: 12,
- mrp: 15,
- category: 'Medicines',
- subCategory: 'Fever & Pain',
- brand: 'Crocin',
- variantName: '10 Tablets',
- tax: 'CGST+SGST - 12%',
- hsn: '30049099',
- additionalSamples: [
- {
- productName: 'Hand Sanitizer',
- quantity: 1,
- uom: 'BTL',
- salesPrice: 65,
- category: 'Healthcare',
- subCategory: 'Sanitizers',
- },
- {
- productName: 'Bandage Roll',
- quantity: 1,
- uom: 'PCS',
- salesPrice: 25,
- category: 'Medical Supplies',
- subCategory: 'First Aid',
- },
- ],
- },
- Furniture: {
- productName: 'Wooden Dining Table',
- quantity: 1,
- uom: 'PCS',
- salesPrice: 15000,
- mrp: 18000,
- category: 'Dining Furniture',
- subCategory: 'Dining Tables',
- brand: 'Royal Oak',
- variantName: '6 Seater',
- tax: 'CGST+SGST - 12%',
- hsn: '94036090',
- additionalSamples: [
- {
- productName: 'Office Chair',
- quantity: 1,
- uom: 'PCS',
- salesPrice: 5500,
- category: 'Office Furniture',
- subCategory: 'Chairs',
- },
- {
- productName: 'Queen Size Bed',
- quantity: 1,
- uom: 'PCS',
- salesPrice: 12000,
- category: 'Bedroom Furniture',
- subCategory: 'Beds',
- },
- ],
- },
- Fruits: {
- productName: 'Fresh Apples',
- quantity: 1,
- uom: 'KG',
- salesPrice: 180,
- mrp: 200,
- category: 'Fresh Fruits',
- subCategory: 'Seasonal Fruits',
- brand: 'Farm Fresh',
- variantName: 'Kashmiri Apple',
- tax: 'NIL - 0%',
- hsn: '08081000',
- additionalSamples: [
- {
- productName: 'Bananas',
- quantity: 1,
- uom: 'DOZEN',
- salesPrice: 60,
- category: 'Fresh Fruits',
- subCategory: 'Tropical Fruits',
- },
- {
- productName: 'Orange Juice',
- quantity: 1,
- uom: 'LITER',
- salesPrice: 120,
- category: 'Fruit Juices',
- subCategory: 'Fresh Juice',
- },
- ],
- },
- Textiles: {
- productName: 'Cotton Fabric',
- quantity: 1,
- uom: 'METER',
- salesPrice: 85,
- mrp: 100,
- category: 'Fabric',
- subCategory: 'Cotton Fabric',
- brand: 'Raymond',
- variantName: 'Plain White',
- tax: 'CGST+SGST - 5%',
- hsn: '52081900',
- additionalSamples: [
- {
- productName: 'Silk Saree',
- quantity: 1,
- uom: 'PCS',
- salesPrice: 2500,
- category: 'Ready Made',
- subCategory: 'Sarees',
- },
- {
- productName: 'Woolen Shawl',
- quantity: 1,
- uom: 'PCS',
- salesPrice: 800,
- category: 'Accessories',
- subCategory: 'Shawls',
- },
- ],
- },
- 'Computer Sales Shop': {
- productName: 'Gaming Laptop',
- quantity: 1,
- uom: 'PCS',
- salesPrice: 55000,
- mrp: 60000,
- category: 'Laptops',
- subCategory: 'Gaming Laptops',
- brand: 'ASUS',
- variantName: 'ROG Strix G15',
- tax: 'CGST+SGST - 18%',
- hsn: '84713000',
- additionalSamples: [
- {
- productName: 'Wireless Mouse',
- quantity: 1,
- uom: 'PCS',
- salesPrice: 1200,
- category: 'Computer Accessories',
- subCategory: 'Mouse',
- },
- {
- productName: 'SSD 500GB',
- quantity: 1,
- uom: 'PCS',
- salesPrice: 4500,
- category: 'Storage',
- subCategory: 'Solid State Drive',
- },
- ],
- },
- };
+ };
- // Return sample data for the specified app, or generic data if not found
- return (
- sampleDataMap[appName] || {
- productName: 'Sample Product Name',
- quantity: 1,
- uom: 'PCS',
- salesPrice: 100,
- mrp: 100,
- category: 'Sample Category',
- subCategory: 'Sample Sub Category',
- brand: 'Sample Brand',
- variantName: 'Sample Variant Name',
- tax: 'NIL - 0%',
- hsn: '12345678',
- additionalSamples: [],
- }
- );
+ // Return sample data for the specified app, or generic data if not found
+ return (
+ sampleDataMap[appName] || {
+ productName: 'Sample Product Name',
+ quantity: 1,
+ uom: 'PCS',
+ salesPrice: 100,
+ mrp: 100,
+ category: 'Sample Category',
+ subCategory: 'Sample Sub Category',
+ brand: 'Sample Brand',
+ variantName: 'Sample Variant Name',
+ tax: 'NIL - 0%',
+ hsn: '12345678',
+ additionalSamples: [],
+ }
+ );
};
const allowedExcelTypes = [
- 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', // .xlsx
- 'application/vnd.ms-excel', // .xls
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', // .xlsx
+ 'application/vnd.ms-excel', // .xls
];
const ProductExcel = ({
- handleSubmit,
- CategoryId,
- CategoryNames,
- SubcatId,
- SubCatData,
- AllBrandId,
- Allbranddata,
- Allbranddatanumfid,
- Subcatnumfid,
- Unit,
- TaxDatas,
- SuplierNames,
- CategoryName1,
- Catconfigid,
-}) => {
- useWhyDidYouUpdate('ProductExcel', {
handleSubmit,
CategoryId,
CategoryNames,
@@ -568,2833 +553,2871 @@ const ProductExcel = ({
SuplierNames,
CategoryName1,
Catconfigid,
- });
- const dispatch = useDispatch();
- const formRef = useRef(null);
- const CompId = getSession('CompId');
- const BranchId = getSession('BranchId');
- const AppId = getSession('AppId');
- const UserId = getSession('UserId');
+}) => {
+ useWhyDidYouUpdate('ProductExcel', {
+ handleSubmit,
+ CategoryId,
+ CategoryNames,
+ SubcatId,
+ SubCatData,
+ AllBrandId,
+ Allbranddata,
+ Allbranddatanumfid,
+ Subcatnumfid,
+ Unit,
+ TaxDatas,
+ SuplierNames,
+ CategoryName1,
+ Catconfigid,
+ });
+ const dispatch = useDispatch();
+ const formRef = useRef(null);
+ const CompId = getSession('CompId');
+ const BranchId = getSession('BranchId');
+ const AppId = getSession('AppId');
+ const UserId = getSession('UserId');
- const fileInputRef = useRef(fileInputRefSelector);
- const excelData = useSelector(excelDataSelector);
- const excelFile = useSelector(excelFileSelector);
- const excelFileError = useSelector(excelFileErrorSelector);
- const ApplicationPreferenceData = useSelector(ApplicationPreferences);
- const productBulkUploadCatId = ApplicationPreferenceData?.find(
- (p) => p?.PreferredCatName?.toLowerCase() === 'product bulk upload'
- )?.PreferredCatId;
+ const fileInputRef = useRef(fileInputRefSelector);
+ const excelData = useSelector(excelDataSelector);
+ const excelFile = useSelector(excelFileSelector);
+ const excelFileError = useSelector(excelFileErrorSelector);
+ const ApplicationPreferenceData = useSelector(ApplicationPreferences);
+ const productBulkUploadCatId = ApplicationPreferenceData?.find(
+ (p) => p?.PreferredCatName?.toLowerCase() === 'product bulk upload'
+ )?.PreferredCatId;
- const [appName, setAppName] = useState(null);
- const [messageType, setMessageType] = useState(null);
- const [messageData, setMessageData] = useState(null);
- const [selectedFields, setSelectedFields] = useState([]);
- const [tableFieldPreferences, setTableFieldPreferences] = useState([]);
- const [worksheet, setWorksheet] = useState(null);
- const [worksheet1, setWorksheet1] = useState(null);
- const [editdelete, seteditdelete] = useState('');
- const [fieldSetup, setFieldSetup] = useState(false);
- const [selectedImageIndex, setSelectedImageIndex] = useState(null);
- const [selectedProductName, setSelectedProductName] = useState(null);
- const [imagedata, setimagedata] = useState();
- const [selectedImage, setSelectedImage] = useState(null);
- const [imageopen, setimageOpen] = useState();
- const [onlineImage, setOnlineImage] = useState(null);
- const [loading, setLoading] = useState(false);
- const [message, setMessage] = useState(false);
- const [Datas, setDatas] = useState();
- const [currentPage, setCurrentPage] = useState(1);
- const [MappingOpen, setMappingOpen] = useState(false);
- const [fieldMapping, setFieldMapping] = useState({});
- const [headers, setHeaders] = useState([]);
- const [UploadedRawData, setUploadedRawData] = useState([]);
- const [ExcelData, setExcelData] = useState([]);
- const [originalUploadedRawData, setOriginalUploadedRawData] = useState([]);
- const [FieldValues, setFieldValues] = useState([]);
- const [OrginalData, setOrginalData] = useState([]);
- const handleTableChange = (pagination, filters, sorter) => {
- setCurrentPage(pagination.current);
- };
+ const [appName, setAppName] = useState(null);
+ const [messageType, setMessageType] = useState(null);
+ const [messageData, setMessageData] = useState(null);
+ const [selectedFields, setSelectedFields] = useState([]);
+ const [tableFieldPreferences, setTableFieldPreferences] = useState([]);
+ const [worksheet, setWorksheet] = useState(null);
+ const [worksheet1, setWorksheet1] = useState(null);
+ const [editdelete, seteditdelete] = useState('');
+ const [fieldSetup, setFieldSetup] = useState(false);
+ const [selectedImageIndex, setSelectedImageIndex] = useState(null);
+ const [selectedProductName, setSelectedProductName] = useState(null);
+ const [imagedata, setimagedata] = useState();
+ const [selectedImage, setSelectedImage] = useState(null);
+ const [imageopen, setimageOpen] = useState();
+ const [onlineImage, setOnlineImage] = useState(null);
+ const [loading, setLoading] = useState(false);
+ const [message, setMessage] = useState(false);
+ const [Datas, setDatas] = useState();
+ const [currentPage, setCurrentPage] = useState(1);
+ const [MappingOpen, setMappingOpen] = useState(false);
+ const [fieldMapping, setFieldMapping] = useState({});
+ const [headers, setHeaders] = useState([]);
+ const [UploadedRawData, setUploadedRawData] = useState([]);
+ const [ExcelData, setExcelData] = useState([]);
+ const [originalUploadedRawData, setOriginalUploadedRawData] = useState([]);
+ const [FieldValues, setFieldValues] = useState([]);
+ const [OrginalData, setOrginalData] = useState([]);
+ const handleTableChange = (pagination, filters, sorter) => {
+ setCurrentPage(pagination.current);
+ };
- console.log(tableFieldPreferences, 'tableFieldPreferences');
- useEffect(() => {
- if (excelData && excelData?.length > 0) {
- let ExecelToJsConvertion = [];
- let slicedData = excelData?.slice(1);
- let filteredData = slicedData?.filter(
- (item) => item?.[item?.length - 1]?.trim() !== 'sample row'
- );
- filteredData?.map((item, index) => {
- ExecelToJsConvertion.push({
- key: index,
- ProductName: item?.['0'],
- Quantity: item?.['1'],
- UOM: item?.['2'],
- SellPrice: item?.['3'],
- Category: item?.['4'],
- SubCategory: item?.['5'],
- Brand: item?.['6'],
- ProductVariantName: item?.['7'] ? item?.['7'] : 'Variant 1',
- MRP: item?.['8'],
- WhSalePrice: item?.['9'],
- StockAvailable: item?.['10'] ? item?.['10'] : 'No',
- TokenAvailable: item?.['11'] ? item?.['11'] : 'No',
- ProductType: item?.['12'],
- Tax: item?.['13'],
- AutoGenerateQrcode: item?.['14'],
- AddQrCode: item?.['15'],
- OnePeiceAvailable: item?.['16'] ? item?.['16'] : 'No',
- OnePeicePrice: item?.['17'],
- AutoGenerateOnePieceQrcode: item?.['18'] ? item?.['18'] : 'No',
- AutoGenerateOnePieceQrcodeNumber: item?.['19'],
- CESS: item?.['20'],
- HSN: item?.['21'],
- PartNumber: item?.['22'],
- Rack: item?.['23'],
- ManufactureDate: item?.['24'],
- ExpireDate: item?.['25'],
- AvailableFrom: item?.['26'] ? item?.['26'] : '',
- AvailableTo: item?.['27'] ? item?.['27'] : '',
- Productimage: '',
- });
- });
+ console.log(tableFieldPreferences, 'tableFieldPreferences');
+ useEffect(() => {
+ if (excelData && excelData?.length > 0) {
+ let ExecelToJsConvertion = [];
+ let slicedData = excelData?.slice(1);
+ let filteredData = slicedData?.filter(
+ (item) => item?.[item?.length - 1]?.trim() !== 'sample row'
+ );
+ filteredData?.map((item, index) => {
+ ExecelToJsConvertion.push({
+ key: index,
+ ProductName: item?.['0'],
+ Quantity: item?.['1'],
+ UOM: item?.['2'],
+ SellPrice: item?.['3'],
+ Category: item?.['4'],
+ SubCategory: item?.['5'],
+ Brand: item?.['6'],
+ ProductVariantName: item?.['7'] ? item?.['7'] : 'Variant 1',
+ MRP: item?.['8'],
+ WhSalePrice: item?.['9'],
+ StockAvailable: item?.['10'] ? item?.['10'] : 'No',
+ TokenAvailable: item?.['11'] ? item?.['11'] : 'No',
+ ProductType: item?.['12'],
+ Tax: item?.['13'],
+ AutoGenerateQrcode: item?.['14'],
+ AddQrCode: item?.['15'],
+ OnePeiceAvailable: item?.['16'] ? item?.['16'] : 'No',
+ OnePeicePrice: item?.['17'],
+ AutoGenerateOnePieceQrcode: item?.['18'] ? item?.['18'] : 'No',
+ AutoGenerateOnePieceQrcodeNumber: item?.['19'],
+ CESS: item?.['20'],
+ HSN: item?.['21'],
+ PartNumber: item?.['22'],
+ Rack: item?.['23'],
+ ManufactureDate: item?.['24'],
+ ExpireDate: item?.['25'],
+ AvailableFrom: item?.['26'] ? item?.['26'] : '',
+ AvailableTo: item?.['27'] ? item?.['27'] : '',
+ Productimage: '',
+ });
+ });
- setDatas(ExecelToJsConvertion);
- // setExcelData(ExecelToJsConvertion);
- // setOriginalUploadedRawData(ExecelToJsConvertion);
- const style = document.createElement('style');
- style.type = 'text/css';
- style.innerHTML = `
+ setDatas(ExecelToJsConvertion);
+ // setExcelData(ExecelToJsConvertion);
+ // setOriginalUploadedRawData(ExecelToJsConvertion);
+ const style = document.createElement('style');
+ style.type = 'text/css';
+ style.innerHTML = `
.viewerExcelupload::-webkit-scrollbar {
display: block !important;
}
`;
- document.head.appendChild(style);
+ document.head.appendChild(style);
- return () => {
- document.head.removeChild(style);
- };
- }
- }, [excelData]);
-
- useEffect(() => {
- const fetchData = async () => {
- if (AppId) {
- const response = await dispatch(
- getApplicationDetails({ AppId })
- )?.unwrap();
- setAppName(response?.data?.data?.[0]?.AppName);
- }
- };
- fetchData();
- }, [AppId]);
-
- useEffect(() => {
- // Call handleSubmit when Datas is updated
- if (Datas) {
- handleSubmit(Datas);
- }
- }, [Datas, handleSubmit]);
-
- // Automatically update preview data on mapping change
- const mandatoryFields = [
- 'ProductName',
- 'Quantity',
- 'UOM',
- 'SellPrice',
- 'Category',
- ];
- useEffect(() => {
- if (UploadedRawData.length > 0) {
- const updatedMappedData = UploadedRawData.map((row, index) => {
- const newRow = { key: index };
- newRow['isModified'] = row?.isModified;
-
- // โ
Process mandatory fields (retain value even if unmapped)
- mandatoryFields.forEach((field) => {
- const mappedHeader = fieldMapping[field];
-
- if (mappedHeader && row[mappedHeader] !== undefined) {
- newRow[field] = row[mappedHeader];
- } else {
- // Fallback: try original headers (case-insensitive, whitespace-insensitive)
- const fallbackHeader = headers.find(
- (header) =>
- header?.toLowerCase().replace(/\s+/g, '') ===
- field.toLowerCase().replace(/\s+/g, '')
- );
-
- if (fallbackHeader && row[fallbackHeader] !== undefined) {
- newRow[field] = row[fallbackHeader];
- } else {
- // Preserve existing value if present
- newRow[field] = ExcelData?.[index]?.[field] ?? '';
- }
- }
- });
-
- // โ
Process non-mandatory mapped fields
- Object.entries(fieldMapping).forEach(([field, header]) => {
- if (!mandatoryFields.includes(field)) {
- newRow[field] = headers.includes(header) ? (row[header] ?? '') : '';
- }
- });
-
- // โ
Clean up unmapped columns
- headers.forEach((header) => {
- const isMapped = Object.values(fieldMapping).includes(header);
- const mappedField = Object.keys(fieldMapping).find(
- (key) => fieldMapping[key] === header
- );
- const isMandatory = mandatoryFields.includes(mappedField);
-
- if (!isMapped && !(header in newRow)) {
- newRow[header] = isMandatory ? (row[header] ?? '') : '';
- }
- });
- return newRow;
- });
-
- setExcelData(updatedMappedData);
- setDatas(updatedMappedData);
- }
- }, [fieldMapping, UploadedRawData, headers]);
-
- useEffect(() => {
- if (AppId && BranchId && CompId) {
- handleExportBulkdata();
- }
- }, [AppId, BranchId, CompId]);
-
- useEffect(() => {
- getFieldSetup();
- }, [productBulkUploadCatId]);
-
- const getFieldSetup = async () => {
- try {
- const response = await dispatch(
- getFieldSetupData({
- AppId,
- CompId,
- BranchId,
- categoryId: productBulkUploadCatId,
- Type: 'EB',
- })
- ).unwrap();
- if (response?.data?.statusCode === 1) {
- console.log(response?.data?.data?.[0]?.ConfigDtl, 'Field Setup Data');
- setSelectedFields(
- response?.data?.data?.[0]?.ConfigDtl?.filter(
- (c) => c.ConfigId && c.Access === 'Y'
- )?.map((c) => c.ConfigId) || []
- );
- setTableFieldPreferences(
- response?.data?.data?.[0]?.ConfigDtl?.map((c) => ({
- value: c.ConfigId,
- label: c.ConfigName,
- access: c.Access,
- })) || []
- );
- setFieldValues(response?.data?.data?.[0]?.ConfigDtl);
- } else {
- setMessageType('error');
- setMessageData('Failed to fetch field setup');
- }
- } catch (error) {
- console.error('Error fetching field setup:', error);
- }
- };
-
- const handleFileUpload = (e) => {
- const file = e.target.files[0];
- const reader = new FileReader();
-
- if (file) {
- const isAllowed = allowedExcelTypes?.includes(file.type);
- if (!isAllowed) {
- Modal.error({
- title: 'Invalid File Type',
- content: 'Only Excel files (.xls, .xlsx) are allowed.',
- });
- handleCancelData();
- } else {
- reader.readAsDataURL(file);
- uploadAndProcessExcel(file);
- }
- } else {
- dispatch(emptyExcelData());
- }
- };
-
- const handleClick = () => {
- // Programmatically trigger the file input click event
- fileInputRef.current.click();
- };
- const getFieldValue = (product, field) => {
- const aliasField = FIELD_ALIAS[field];
- return normalize(product[field] ?? product[aliasField]);
- };
- const normalize = (value) => {
- // Empty / invalid values
- if (
- value === undefined ||
- value === null ||
- value === '' ||
- value === 'NaN-NaN-NaN'
- ) {
- return '';
- }
-
- // Y / N flags
- if (value === 'Y') return true;
- if (value === 'N') return false;
-
- // Numbers (handles "150", 150, "0")
- if (
- typeof value === 'number' ||
- (typeof value === 'string' &&
- value.trim() !== '' &&
- !Number.isNaN(Number(value)))
- ) {
- return Number(value);
- }
-
- // Default string
- return String(value).trim();
- };
- const hashProduct = (product) =>
- COMPARE_FIELDS.map((field) => getFieldValue(product, field)).join('ยง');
- function findModifiedProducts(originalData, updatedData) {
- if (!originalData?.length || !updatedData?.length) return [];
-
- const originalHashMap = new Map();
-
- for (const product of originalData) {
- if (!product.ProdId) continue;
- originalHashMap.set(product.ProdId, hashProduct(product));
- }
-
- // Step 2: Compare updated products
- const modifiedProducts = [];
-
- for (const product of updatedData) {
- if (!product.ProdId) continue;
-
- const originalHash = originalHashMap.get(product.ProdId);
- if (!originalHash) continue; // new product, not modified
-
- const updatedHash = hashProduct(product);
-
- if (originalHash !== updatedHash) {
- modifiedProducts.push(product);
- }
- }
-
- return modifiedProducts;
- }
- const FIELD_ALIAS = {
- 'Product Variant Name': 'Product Varient Name',
- };
-
- const uploadAndProcessExcel = (file) => {
- const reader = new FileReader();
-
- reader.onload = async (e) => {
- const buffer = e.target.result;
-
- const workbook = new ExcelJS.Workbook();
- await workbook.xlsx.load(buffer);
-
- const worksheet = workbook.worksheets[0];
-
- // ๐ฅ convert to same format as xlsx (array of arrays)
- const jsonData = [];
- worksheet.eachRow((row) => {
- const rowValues = row.values.slice(1); // remove first empty index
- jsonData.push(rowValues);
- });
-
- const nonEmptyRows = jsonData.filter((row) =>
- row.some((cell) => cell !== '' && cell !== null && cell !== undefined)
- );
-
- const header = nonEmptyRows[0];
- const rows = nonEmptyRows.slice(1);
-
- const dateFields = [
- 'Available From',
- 'Available To',
- 'Manufacture Date',
- 'Expire Date',
- 'Stock Date',
- ];
-
- function convertToDisplayFormat(dateString) {
- if (!dateString) return '';
-
- const date = new Date(dateString);
- if (isNaN(date)) return dateString;
-
- const day = date.getDate().toString().padStart(2, '0');
- const month = (date.getMonth() + 1).toString().padStart(2, '0');
- const year = date.getFullYear().toString();
- return `${day}-${month}-${year}`;
- }
-
- const formattedData = rows.map((row) => {
- let rowData = header.reduce((acc, col, columnIndex) => {
- if (dateFields?.includes(col)) {
- acc[col] = convertToDisplayFormat(row[columnIndex]);
- } else {
- acc[col] = row[columnIndex];
- }
- return acc;
- }, {});
- return rowData;
- });
-
- if (jsonData.length > 0) {
- const extractedHeaders = Object.keys(formattedData[0] || {});
-
- const filteredData = formattedData.filter(
- (item) => !Object.values(item)?.includes('sample row')
- );
-
- const updatedData = filteredData.map((item) => ({
- ...item,
- 'Product Varient Name':
- item['Product Varient Name'] === undefined
- ? 'Variant 1'
- : item['Product Varient Name'],
- 'Available To':
- item['Available To'] == 'NaN-NaN-NaN' ? '' : item['Available To'],
- ProdId: item['ProdId'] || null,
- }));
-
- const modifiedProducts = findModifiedProducts(OrginalData, updatedData);
- const modifiedIds = new Set(modifiedProducts.map((p) => p.ProdId));
- const originalIds = new Set(OrginalData?.map((p) => p.ProdId) || []);
-
- const markedData = updatedData
- .map((item) => ({
- ...item,
- isModified:
- modifiedIds.has(item.ProdId) || !originalIds.has(item.ProdId),
- }))
- .sort((a, b) => b.isModified - a.isModified);
-
- setUploadedRawData(markedData);
-
- setHeaders(extractedHeaders);
- autoMapFields(extractedHeaders);
-
- dispatch(uploadExcel({ file, jsonData: nonEmptyRows }));
-
- setWorksheet(worksheet);
- setDatas([]);
- setExcelData([]);
- }
-
- // โ ๏ธ keep your original flow (no break)
- dispatch(uploadExcel({ file, jsonData: nonEmptyRows }));
- setWorksheet(worksheet);
- setWorksheet1(worksheet1);
- setDatas(formattedData);
- };
-
- reader.readAsArrayBuffer(file);
- };
-
- // const uploadAndProcessExcel = (file) => {
- // const reader = new FileReader();
-
- // reader.onload = (e) => {
- // const data = new Uint8Array(e.target.result);
-
- // const workbook = read(data, { type: 'array' });
- // const worksheet = workbook.Sheets[workbook.SheetNames[0]];
-
- // const jsonData = utils.sheet_to_json(worksheet, {
- // header: 1,
- // raw: false,
- // dateNF: 'DD/MM/YY',
- // });
-
- // const nonEmptyRows = jsonData.filter((row) =>
- // row.some((cell) => cell !== '')
- // );
-
- // const header = nonEmptyRows[0];
- // const rows = nonEmptyRows.slice(1);
-
- // const dateFields = [
- // 'Available From',
- // 'Available To',
- // 'Manufacture Date',
- // 'Expire Date',
- // 'Stock Date',
- // ];
-
- // function convertToDisplayFormat(dateString) {
- // const date = new Date(dateString);
- // const day = date.getDate().toString().padStart(2, '0');
- // const month = (date.getMonth() + 1).toString().padStart(2, '0');
- // const year = date.getFullYear().toString();
- // return `${day}-${month}-${year}`;
- // }
-
- // const formattedData = rows.map((row) => {
- // let rowData = header.reduce((acc, col, columnIndex) => {
- // if (dateFields?.includes(col)) {
- // acc[col] = convertToDisplayFormat(row[columnIndex]);
- // } else {
- // acc[col] = row[columnIndex];
- // }
- // return acc;
- // }, {});
-
- // return rowData;
- // });
-
- // if (jsonData.length > 0) {
- // const extractedHeaders = Object.keys(formattedData[0]);
-
- // const filteredData = formattedData.filter(
- // (item) => !Object.values(item)?.includes('sample row')
- // );
-
- // // โ
Add default variant name if missing
- // const updatedData = filteredData.map((item) => ({
- // ...item,
- // 'Product Varient Name':
- // item['Product Varient Name'] === undefined
- // ? 'Variant 1'
- // : item['Product Varient Name'],
- // 'Available To':
- // item['Available To'] == 'NaN-NaN-NaN' ? '' : item['Available To'],
- // ProdId: item['ProdId'] || null,
- // }));
-
- // // Detect modified products
-
- // const modifiedProducts = findModifiedProducts(OrginalData, updatedData);
- // const modifiedIds = new Set(modifiedProducts.map((p) => p.ProdId));
- // const originalIds = new Set(OrginalData?.map((p) => p.ProdId) || []);
- // const markedData = updatedData
- // .map((item) => ({
- // ...item,
- // isModified:
- // modifiedIds.has(item.ProdId) || !originalIds.has(item.ProdId),
- // }))
- // .sort((a, b) => b.isModified - a.isModified);
- // setUploadedRawData(markedData);
- // console.log(modifiedProducts, 'modifiedProducts');
-
- // // โ
Set only once with final data
- // setHeaders(extractedHeaders);
-
- // autoMapFields(extractedHeaders);
- // dispatch(uploadExcel({ file, jsonData: nonEmptyRows }));
- // setWorksheet(worksheet);
- // setDatas([]); // Clear mapped state initially
- // setExcelData([]);
- // }
-
- // // setMappingOpen(true);
- // dispatch(uploadExcel({ file, jsonData: nonEmptyRows }));
- // setWorksheet(worksheet);
- // setWorksheet1(worksheet1);
- // setDatas(formattedData); // Update Datas state here
- // // setExcelData(formattedData);
- // };
-
- // reader.readAsArrayBuffer(file);
- // };
-
- useEffect(() => {
- imagecall();
- addOnlineImage();
- Fielddatas();
- }, []);
-
- const imagecall = async (ProdName) => {
- if (selectedProductName !== null) {
- let response = await dispatch(onlineimages(ProdName)).unwrap();
- setimagedata(response?.data?.data);
- }
- };
-
- const addOnlineImage = (item, index) => {
- item?.ProductName && setimageOpen(true);
- imagecall(item?.ProductName);
- setSelectedProductName(item?.ProductName);
- setSelectedImageIndex(index);
- };
-
- const updateImageUrl = (url, index, key) => {
- const newData1 = [...Datas];
- newData1[key] = { ...newData1[key], Productimage: url };
-
- setDatas(newData1);
- setExcelData(newData1);
- };
-
- const handleimage = () => {
- setimageOpen(false);
- setSelectedImageIndex(null);
- };
-
- const submitimage = async () => {
- const pageNo = currentPage * 10 + selectedImageIndex - 10;
-
- if (selectedImageIndex != null && selectedImageIndex != undefined) {
- try {
- if (selectedImage?.image !== undefined) {
- const response = await fetch(selectedImage.image);
- const datas = await response.blob();
- const metadata = {
- type: 'image/jpeg',
- };
-
- const file = new File([datas], 'image.jpg', metadata);
-
- const uploadImgData = await dispatch(uploadImage(file)).unwrap();
-
- if (uploadImgData?.data?.status == 1) {
- let tempData = Datas;
- const selectedIndex = tempData.findIndex(
- (_, index) => index === pageNo
- );
-
- if (selectedIndex !== -1) {
- tempData[selectedIndex].Productimage = uploadImgData?.data?.image;
- }
- setDatas(tempData);
- setExcelData(tempData);
- }
- }
- } finally {
- handleimage();
- }
- }
- };
-
- const fieldOrder = [
- 'Product Name',
- 'Quantity',
- 'UOM',
- 'Sales Price',
- 'MRP',
- 'WholeSale Price',
- 'Category',
- 'Sub Category',
- 'Brand',
- 'Product Variant Name',
- 'Stock Available',
- 'Token Available',
- 'Product Type',
- 'Tax',
- 'Auto Generate QRCode',
- 'Add Qr Code',
- 'One Piece Available',
- 'OnePiece Price',
- 'Auto Generate One Piece Qrcode',
- 'Auto Generate One Piece Qrcode Number',
- 'CESS',
- 'HSN',
- 'Part Number',
- 'Rack',
- 'Manufacture Date',
- 'Expire Date',
- 'Available From',
- 'Available To',
- ];
-
- const sortPreferredFields = (fields) => {
- const fieldMap = {};
- fields.forEach((field) => {
- fieldMap[field.ConfigName] = field;
- });
-
- const sorted = [];
-
- fieldOrder.forEach((name) => {
- if (fieldMap[name] && fieldMap[name].Access === 'Y') {
- sorted.push(fieldMap[name]);
- }
- });
-
- return sorted;
- };
-
- // Usage inside your Fielddatas
- const Fielddatas = async () => {
- const res = await dispatch(getCommonAppPreference(AppId)).unwrap();
-
- const productbulkUploadCatId =
- res?.data?.data?.[0]?.PreferenceDetails?.find(
- (p) => p?.PreferredCatName?.toLowerCase() === 'product bulk upload'
- )?.PreferredCatId;
-
- const response = await dispatch(
- getFieldSetupData({
- AppId,
- CompId,
- BranchId,
- categoryId: productbulkUploadCatId,
- Type: 'EB',
- })
- ).unwrap();
-
- const productBulkUploadFields = response?.data?.data?.[0]?.ConfigDtl || [];
- const sortedFields = sortPreferredFields(productBulkUploadFields);
-
- setFieldValues(sortedFields);
- };
-
- const handleDownload = async () => {
- const workbook = new ExcelJS.Workbook();
- const worksheet = workbook.addWorksheet('Sheet1');
- const worksheet1 = workbook.addWorksheet('Sheet2');
-
- const headerStyle = {
- font: { bold: true },
- border: {
- top: { style: 'thin' },
- left: { style: 'thin' },
- bottom: { style: 'thin' },
- right: { style: 'thin' },
- },
- alignment: { horizontal: 'center', vertical: 'middle' },
- };
-
- // Define all possible field configurations
- const sampleData = getApplicationSampleData(appName);
- console.log(sampleData, 'sampleData');
- const fieldConfigs = {
- ProdId: {
- header: 'ProdId',
- key: 'ProdId',
- width: 15,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- validation: null,
- sampleValue: '',
- headerColor: 'D3D3D3',
- locked: true,
- },
- ProdName: {
- header: 'Product Name',
- key: 'ProdName',
- width: 20,
- Height: 20,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- validation: null,
- sampleValue: sampleData?.productName || 'Sample Product Name',
- headerColor: 'FF2929',
- },
- Size: {
- header: 'Quantity',
- key: 'Size',
- width: 10,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- validation: {
- type: 'custom',
- allowBlank: true,
- formulae: ['ISNUMBER({COLUMN}{ROW})'],
- showErrorMessage: true,
- errorTitle: 'Validation Error',
- error: 'Please enter a Number.',
- },
- sampleValue: sampleData?.quantity || 1,
- headerColor: 'FF2929',
- },
- UOM: {
- header: 'UOM',
- key: 'UOM',
- width: 10,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- validation: {
- type: 'list',
- allowBlank: true,
- formulae: [
- '"' +
- (typeof Unit !== 'undefined' ? Unit.join(',') : 'KGS,PCS,LITER') +
- '"',
- ],
- },
- sampleValue: sampleData?.uom || 'KGS',
- headerColor: 'FF2929',
- },
- SellPrice: {
- header: 'Sales Price',
- key: 'SellPrice',
- width: 15,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- validation: {
- type: 'custom',
- allowBlank: true,
- formulae: ['ISNUMBER({COLUMN}{ROW})'],
- showErrorMessage: true,
- errorTitle: 'Validation Error',
- error: 'Please enter a Number.',
- },
- sampleValue: sampleData?.salesPrice || 100,
- headerColor: 'FF2929',
- },
- ProdCat: {
- header: 'Category',
- key: 'ProdCat',
- width: 20,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- validation: {
- type: 'list',
- allowBlank: true,
- formulae: [`Sheet2!$B$2:$B$${(CategoryNames?.length || 0) + 1}`],
- },
- sampleValue: sampleData?.category || 'Sample Category',
- headerColor: 'FF2929',
- },
- ProdSubCat: {
- header: 'Sub Category',
- key: 'ProdSubCat',
- width: 20,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- validation: null, // set dynamically per row below
- sampleValue: sampleData?.subCategory || 'Sample Sub Category',
- headerColor: '52c41a',
- },
- Brand: {
- header: 'Brand',
- key: 'Brand',
- width: 20,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- validation: null, // set dynamically per row below
- sampleValue: sampleData?.brand || 'Sample Brand',
- headerColor: '52c41a',
- },
- ProdVarientName: {
- header: 'Product Variant Name',
- key: 'ProdVarientName',
- width: 20,
- Height: 20,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- validation: null,
- sampleValue: sampleData?.variantName || 'Sample Variant Name',
- headerColor: '52c41a',
- },
- MRP: {
- header: 'MRP',
- key: 'MRP',
- width: 10,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- validation: {
- type: 'custom',
- allowBlank: true,
- formulae: ['ISNUMBER({COLUMN}{ROW})'],
- showErrorMessage: true,
- errorTitle: 'Validation Error',
- error: 'Please enter a Number.',
- },
- sampleValue: sampleData?.mrp || 100,
- headerColor: '52c41a',
- },
- WhSalePrice: {
- header: 'WholeSale Price',
- key: 'WhSalePrice',
- width: 15,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- validation: {
- type: 'custom',
- allowBlank: true,
- formulae: ['ISNUMBER({COLUMN}{ROW})'],
- showErrorMessage: true,
- errorTitle: 'Validation Error',
- error: 'Please enter a Number.',
- },
- sampleValue: 100,
- headerColor: '52c41a',
- },
-
- StockAvailable: {
- header: 'Stock Available',
- key: 'StockAvailable',
- width: 20,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- validation: {
- type: 'list',
- allowBlank: true,
- formulae: ['"Yes,No"'],
- },
- sampleValue: 'Choose Yes or No',
- headerColor: '52c41a',
- },
- OfferPrice: {
- header: 'Token Available',
- key: 'OfferPrice',
- width: 15,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- validation: {
- type: 'list',
- allowBlank: true,
- formulae: ['"Yes,No"'],
- },
- sampleValue: 'Choose Yes or No',
- headerColor: '52c41a',
- },
- Supplier: {
- header: 'Product Type',
- key: 'Supplier',
- width: 20,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- validation: {
- type: 'list',
- allowBlank: true,
- formulae: ['"Product"'],
- },
- sampleValue: 'Product',
- headerColor: '52c41a',
- },
- TaxId: {
- header: 'Tax',
- key: 'TaxId',
- width: 20,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- validation: null, // set via Sheet2 range reference below
- sampleValue: sampleData?.tax || 'NIL - 0%',
- headerColor: '52c41a',
- },
- AutoGenerateQr: {
- header: 'Auto Generate Qrcode',
- key: 'AutoGenerateQr',
- width: 20,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- validation: {
- type: 'list',
- allowBlank: true,
- formulae: ['"Yes,No"'],
- },
- sampleValue: 'Choose Yes or No',
- headerColor: '52c41a',
- },
- AddQrCode: {
- header: 'Add Qr Code',
- key: 'AddQrCode',
- width: 20,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- validation: null,
- sampleValue: 'Sample Qr eg:12345',
- headerColor: '52c41a',
- },
- SpecialPrice: {
- header: 'One Piece Available',
- key: 'SpecialPrice',
- width: 20,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- validation: {
- type: 'list',
- allowBlank: true,
- formulae: ['"Yes,No"'],
- },
- sampleValue: 'Choose Yes or No',
- headerColor: '52c41a',
- },
- OnePiecePrice: {
- header: 'OnePiece Price',
- key: 'OnePiecePrice',
- width: 20,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- validation: {
- type: 'custom',
- allowBlank: true,
- formulae: ['ISNUMBER({COLUMN}{ROW})'],
- showErrorMessage: true,
- errorTitle: 'Validation Error',
- error: 'Please enter a Number.',
- },
- sampleValue: 'OnePiecePrice',
- headerColor: '52c41a',
- },
- AutoGenOnePieceQr: {
- header: 'Auto Generate One Piece Qrcode',
- key: 'AutoGenOnePieceQr',
- width: 30,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- validation: {
- type: 'list',
- allowBlank: true,
- formulae: ['"Yes,No"'],
- },
- sampleValue: 'Choose Yes or No',
- headerColor: '52c41a',
- },
- AutoGenOnePieceQrNum: {
- header: 'Auto Generate One Piece Qrcode Number',
- key: 'AutoGenOnePieceQrNum',
- width: 40,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- validation: null,
- sampleValue: 'Qr Number eg:ABC123',
- headerColor: '52c41a',
- },
- CESS: {
- header: 'CESS',
- key: 'CESS',
- width: 20,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- validation: null,
- sampleValue: 'Cess eg:0.5',
- headerColor: '52c41a',
- },
- HSNCode: {
- header: 'HSN',
- key: 'HSNCode',
- width: 20,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- validation: null,
- sampleValue: 'Hsn Number eg:100190',
- headerColor: '52c41a',
- },
- PartNumber: {
- header: 'Part Number',
- key: 'PartNumber',
- width: 20,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- validation: null,
- sampleValue: 'Part Number eg:1234-5678',
- headerColor: '52c41a',
- },
- Rack: {
- header: 'Rack',
- key: 'Rack',
- width: 20,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- validation: null,
- sampleValue: 'Rack Number eg:2200302',
- headerColor: '52c41a',
- },
- ManufDate: {
- header: 'Manufacture Date',
- key: 'ManufDate DATETIME',
- width: 20,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- validation: null,
- sampleValue: new Date(),
- headerColor: '52c41a',
- },
- ExpDate: {
- header: 'Expire Date',
- key: 'ExpDate DATETIME',
- width: 20,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- validation: null,
- sampleValue: new Date(),
- headerColor: '52c41a',
- },
- AvailableFrom: {
- header: 'Available From',
- key: 'AvailableFrom',
- width: 20,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- numFmt: '@',
- },
- validation: null,
- sampleValue: '08:00:00',
- headerColor: '52c41a',
- isTimeField: true,
- },
- AvailableTo: {
- header: 'Available To',
- key: 'AvailableTo',
- width: 20,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- numFmt: '@',
- },
- validation: null,
- sampleValue: '22:00:00',
- headerColor: '52c41a',
- isTimeField: true,
- },
- };
-
- function getExcelColumnLetter(colIndex) {
- let temp = '';
- let letter = '';
- while (colIndex > 0) {
- temp = (colIndex - 1) % 26;
- letter = String.fromCharCode(temp + 65) + letter;
- colIndex = Math.floor((colIndex - temp - 1) / 26);
- }
- return letter;
- }
-
- const mandatoryFields = ['ProdName', 'Size', 'UOM', 'SellPrice', 'ProdCat'];
-
- const apiToInternalFieldMap = {
- 'Product Name': 'ProdName',
- Quantity: 'Size',
- UOM: 'UOM',
- 'Sales Price': 'SellPrice',
- MRP: 'MRP',
- 'WholeSale Price': 'WhSalePrice',
- Category: 'ProdCat',
- 'Sub Category': 'ProdSubCat',
- Brand: 'Brand',
- 'Product Variant Name': 'ProdVarientName',
- 'Token Available': 'OfferPrice',
- 'Stock Available': 'StockAvailable',
- Tax: 'TaxId',
- 'Auto Generate QRCode': 'AutoGenerateQr',
- 'Add Qr Code': 'AddQrCode',
- 'One Piece Available': 'SpecialPrice',
- 'OnePiece Price': 'OnePiecePrice',
- 'Auto Generate One Piece Qrcode': 'AutoGenOnePieceQr',
- 'Auto Generate One Piece Qrcode Number': 'AutoGenOnePieceQrNum',
- CESS: 'CESS',
- HSN: 'HSNCode',
- 'Part Number': 'PartNumber',
- Rack: 'Rack',
- 'Manufacture Date': 'ManufDate',
- 'Expire Date': 'ExpDate',
- 'Available From': 'AvailableFrom',
- 'Available To': 'AvailableTo',
- 'Product Type': 'Supplier',
- };
-
- // Define dependent relationships
- const dependentFieldMap = {
- 'Auto Generate QRCode': 'Add Qr Code',
- 'One Piece Available': 'OnePiece Price',
- 'Auto Generate One Piece Qrcode': 'Auto Generate One Piece Qrcode Number',
- };
-
- // Step 1: Sort preferred fields
- const sortedPreferredFields = sortPreferredFields(FieldValues); // Your existing sort function
-
- // Step 2: Convert API names to internal keys while skipping dependent fields initially
- const preferredFieldKeys = [];
- const preferredFieldSet = new Set();
-
- sortedPreferredFields.forEach((field) => {
- const fieldName = field.ConfigName;
- const status = field.Access;
-
- // Skip dependent fields for now
- if (Object.values(dependentFieldMap).includes(fieldName)) return;
-
- if (status === 'Y') {
- const internalKey = apiToInternalFieldMap[fieldName];
- if (internalKey) {
- preferredFieldKeys.push(internalKey);
- preferredFieldSet.add(fieldName);
- }
-
- // If this field has a dependent field, and it's enabled, add dependent too
- const dependentFieldName = dependentFieldMap[fieldName];
- if (dependentFieldName) {
- const dependentInternalKey =
- apiToInternalFieldMap[dependentFieldName];
- if (dependentInternalKey) {
- preferredFieldKeys.push(dependentInternalKey);
- }
- }
- }
- });
-
- // Step 3: Merge Mandatory + Preferred (no duplicates)
- const finalFieldKeys = [
- ...mandatoryFields,
- ...preferredFieldKeys.filter((key) => !mandatoryFields.includes(key)),
- ];
-
- // Step 4: Map to ExcelJS column configs
- const selectedColumns = finalFieldKeys
- .map((fieldKey) => {
- const config = fieldConfigs[fieldKey];
- if (!config) {
- console.warn(`Field configuration not found for: ${fieldKey}`);
- return null;
- }
- return config;
- })
- .filter(Boolean);
-
- selectedColumns.push({
- header: '__isSampleRow',
- key: '__isSampleRow',
- width: 10, // width can be any value
- style: { font: { size: 1 }, alignment: { horizontal: 'left' } },
- sampleValue: 'sample row', // Mark sample row
- headerColor: 'FFFFFF',
- });
-
- worksheet.columns = selectedColumns;
-
- worksheet.getColumn(selectedColumns.length).hidden = true;
-
- selectedColumns.forEach((config, index) => {
- const columnLetter = getExcelColumnLetter(index + 1); // โ
FIXED
- const headerCell = worksheet.getCell(`${columnLetter}1`);
- headerCell.style = {
- ...config.style,
- fill: {
- type: 'pattern',
- pattern: 'solid',
- fgColor: { argb: config.headerColor },
- },
- };
- });
-
- // Add sample data in row 2 โ time fields forced to text format
- selectedColumns.forEach((config, index) => {
- 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
-
- selectedColumns.forEach((config, colIndex) => {
- if (config.validation) {
- const colNumber = colIndex + 1; // Excel is 1-based
- const columnLetter = getExcelColumnLetter(colNumber); // โ
FIXED
-
- for (let rowNumber = 2; rowNumber <= 1001; rowNumber++) {
- const cell = worksheet.getCell(rowNumber, colNumber); // โ
Use (row, col) instead of letter
- let validation = { ...config.validation };
-
- if (validation.formulae) {
- validation.formulae = validation.formulae.map((formula) =>
- formula
- .replace('{COLUMN}', columnLetter)
- .replace('{ROW}', rowNumber.toString())
- );
- }
-
- cell.dataValidation = validation;
- }
- }
- });
-
- // // 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({});
- }
-
- // 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,
- };
- }
- }
-
- // 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('', {
- selectLockedCells: true, // Allow selecting locked cells (header/sample)
- selectUnlockedCells: true, // Allow selecting unlocked cells (data rows)
- formatCells: false,
- formatColumns: false,
- formatRows: false,
- insertColumns: false,
- insertRows: false,
- deleteColumns: false,
- deleteRows: false,
- });
-
- // Configure Sheet2 with all original columns and functionality
- worksheet1.columns = [
- {
- header: 'Category Id',
- key: 'CategoryId',
- width: 15,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- },
- {
- header: 'Category Name',
- key: 'Category',
- width: 30,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- },
- {
- header: 'SUBCAT DATAS OF PARTICULAR CATEGORY',
- key: 'SDPC',
- width: 180,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- },
- {
- header: 'SUBCAT ID',
- key: 'SubcayID',
- width: 10,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- },
- {
- header: 'Sub Category name',
- key: 'SubCategory',
- width: 25,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- },
- {
- header: '',
- key: '',
- width: 5,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- },
- {
- header: 'SUBCAT NUMFID',
- key: 'SubcatnumfId',
- width: 20,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- },
- {
- header: '',
- key: 'smallIcon',
- width: 5,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- },
- {
- header: 'Brand ID',
- key: 'BrandId',
- width: 20,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- },
- {
- header: 'Brand Name',
- key: 'Brandname',
- width: 20,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- },
- {
- header: 'Brand NumfId',
- key: 'BrandnumfId',
- width: 20,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- },
- {
- header: '',
- key: 'smallIcon',
- width: 5,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- },
- {
- header: 'Brand Details',
- key: 'Branddetails',
- width: 150,
- style: {
- ...headerStyle,
- font: { bold: true, color: { argb: '#000000' } },
- },
- },
- ];
-
- // Add data to Sheet2
- for (let i = 1; i <= 100; i++) {
- worksheet1.addRow({
- CategoryId: '',
- Category: '',
- SDPC: '',
- SubcayID: '',
- SubCategory: '',
- SubcatnumfId: '',
- BrandId: '',
- Brandname: '',
- BrandnumfId: '',
- Branddetails: '',
- });
- }
-
- // All the original dropdown and validation logic for Sheet2
- const dropdownOptions = {
- Option1: ['Yes', 'No'],
- Option2: ['Product'],
- Option3: ['ValueX', 'ValueY', 'ValueZ'],
- };
-
- const selectedOptionA = 'Option1';
- const selectedOptionB = 'Option2';
-
- // Create category and brand data maps (original logic)
- const categoryDataMap = {};
- if (typeof CategoryId !== 'undefined') {
- CategoryId.forEach((categoryId, index) => {
- categoryDataMap[categoryId] =
- typeof SubCatData !== 'undefined' ? SubCatData[index] : '';
- });
- }
-
- const BrandDataMap = {};
- if (typeof AllBrandId !== 'undefined') {
- AllBrandId.forEach((AllBrandId, index) => {
- BrandDataMap[AllBrandId] =
- typeof SubCatData !== 'undefined' ? SubCatData[index] : '';
- });
- }
-
- // Apply all original Sheet2 validations and logic
- if (typeof CategoryId !== 'undefined') {
- worksheet1
- .getColumn('A')
- .eachCell({ includeEmpty: true }, function (cell, rowNumber) {
- if (rowNumber > 1) {
- const dynamicValidValues = '"' + CategoryId.join(',') + '"';
- const defaultCategoryId = CategoryId[rowNumber - 2];
- cell.value = defaultCategoryId;
-
- cell.dataValidation = {
- type: 'list',
- allowBlank: true,
- formulae: [dynamicValidValues],
+ return () => {
+ document.head.removeChild(style);
};
- }
- });
- }
-
- if (typeof CategoryNames !== 'undefined') {
- worksheet1
- .getColumn('B')
- .eachCell({ includeEmpty: true }, function (cell, rowNumber) {
- if (rowNumber > 1) {
- const dynamicValidValues = '"' + CategoryNames.join(',') + '"';
- const defaultCategoryName = CategoryNames[rowNumber - 2];
- cell.value = defaultCategoryName;
-
- cell.dataValidation = {
- type: 'list',
- allowBlank: true,
- formulae: [dynamicValidValues],
- };
- }
- });
- }
-
- if (typeof SubcatId !== 'undefined') {
- worksheet1
- .getColumn('D')
- .eachCell({ includeEmpty: true }, function (cell, rowNumber) {
- if (rowNumber > 1) {
- const dynamicValidValues = '"' + SubcatId.join(',') + '"';
- const defaultCategorysubName = SubcatId[rowNumber - 2];
- cell.value = defaultCategorysubName;
-
- cell.dataValidation = {
- type: 'list',
- allowBlank: true,
- formulae: [dynamicValidValues],
- };
- }
- });
- }
-
- if (typeof SubCatData !== 'undefined') {
- worksheet1
- .getColumn('E')
- .eachCell({ includeEmpty: true }, function (cell, rowNumber) {
- if (rowNumber > 1) {
- const dynamicValidValues = '"' + SubCatData.join(',') + '"';
- const defaultCategorysubName = SubCatData[rowNumber - 2];
- cell.value = defaultCategorysubName;
-
- cell.dataValidation = {
- type: 'list',
- allowBlank: true,
- formulae: [dynamicValidValues],
- };
- }
- });
- }
-
- if (typeof Subcatnumfid !== 'undefined') {
- worksheet1
- .getColumn('G')
- .eachCell({ includeEmpty: true }, function (cell, rowNumber) {
- if (rowNumber > 1) {
- const dynamicValidValues = '"' + Subcatnumfid.join(',') + '"';
- const defaultCategorysubName = Subcatnumfid[rowNumber - 2];
- cell.value = defaultCategorysubName;
-
- cell.dataValidation = {
- type: 'list',
- allowBlank: true,
- formulae: [dynamicValidValues],
- };
- }
- });
- }
-
- if (typeof AllBrandId !== 'undefined') {
- worksheet1
- .getColumn('I')
- .eachCell({ includeEmpty: true }, function (cell, rowNumber) {
- if (rowNumber > 1) {
- const dynamicValidValues = '"' + AllBrandId.join(',') + '"';
- const defaultCategorysubName = AllBrandId[rowNumber - 2];
- cell.value = defaultCategorysubName;
-
- cell.dataValidation = {
- type: 'list',
- allowBlank: true,
- formulae: [dynamicValidValues],
- };
- }
- });
- }
-
- if (typeof Allbranddata !== 'undefined') {
- worksheet1
- .getColumn('J')
- .eachCell({ includeEmpty: true }, function (cell, rowNumber) {
- if (rowNumber > 1) {
- const dynamicValidValues = '"' + Allbranddata.join(',') + '"';
- const defaultCategorysubName = Allbranddata[rowNumber - 2];
- cell.value = defaultCategorysubName;
-
- cell.dataValidation = {
- type: 'list',
- allowBlank: true,
- formulae: [dynamicValidValues],
- };
- }
- });
- }
-
- if (typeof Allbranddatanumfid !== 'undefined') {
- worksheet1
- .getColumn('K')
- .eachCell({ includeEmpty: true }, function (cell, rowNumber) {
- if (rowNumber > 1) {
- const dynamicValidValues = '"' + Allbranddatanumfid.join(',') + '"';
- const defaultCategorysubName = Allbranddatanumfid[rowNumber - 2];
- cell.value = defaultCategorysubName;
-
- cell.dataValidation = {
- type: 'list',
- allowBlank: true,
- formulae: [dynamicValidValues],
- };
- }
- });
- }
-
- // 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')
- .eachCell({ includeEmpty: true }, function (cell, rowNumber) {
- if (rowNumber > 1) {
- const categoryId = worksheet1.getCell(`A${rowNumber}`).value;
- if (categoryId !== null) {
- const uniqueSubCategoryData = new Set();
- const matchedData = [];
-
- worksheet1
- .getColumn('G')
- .eachCell(
- { includeEmpty: true },
- function (subCatCell, subCatRowNumber) {
- if (subCatRowNumber > 1 && subCatCell.value === categoryId) {
- const subCategoryName = worksheet1.getCell(
- `E${subCatRowNumber}`
- ).value;
- const subCatId = worksheet1.getCell(
- `D${subCatRowNumber}`
- ).value;
-
- const fullSubCategoryName = `${subCatId} - ${subCategoryName}`;
-
- uniqueSubCategoryData.add({
- subCategoryId: subCatId,
- subCategoryName: subCategoryName,
- });
-
- const subCatData = categoryDataMap[categoryId]
- ? categoryDataMap[categoryId].subCatData
- : null;
-
- const data = {
- subCategoryId: subCatId,
- subCategoryName: subCategoryName,
- subCatData: subCatData,
- };
- matchedData.push(data);
- }
- }
- );
-
- cell.value = JSON.stringify(Array.from(uniqueSubCategoryData));
- }
}
- });
-
- // Original complex logic for column M (Brand Details)
- worksheet1
- .getColumn('M')
- .eachCell({ includeEmpty: true }, function (cell, rowNumber) {
- if (rowNumber > 1) {
- const SubcatId = worksheet1.getCell(`D${rowNumber}`).value;
- if (SubcatId !== null) {
- const uniqueSubCategoryData = new Set();
- const matchedData = [];
-
- worksheet1
- .getColumn('K')
- .eachCell(
- { includeEmpty: true },
- function (BrandCell, BrandRowNumber) {
- if (BrandRowNumber > 1 && BrandCell.value === SubcatId) {
- const BrandName = worksheet1.getCell(
- `J${BrandRowNumber}`
- ).value;
- const BrandId = worksheet1.getCell(
- `I${BrandRowNumber}`
- ).value;
-
- const fullSubCategoryName = `${BrandId} - ${BrandName}`;
-
- uniqueSubCategoryData.add({
- BrandId: BrandId,
- BrandName: BrandName,
- });
-
- const BrandData = BrandDataMap[SubcatId]
- ? BrandDataMap[SubcatId].BrandData
- : null;
-
- const data = {
- BrandId: BrandId,
- BrandName: BrandName,
- BrandData: BrandData,
- };
- matchedData.push(data);
- }
- }
- );
-
- cell.value = JSON.stringify(Array.from(uniqueSubCategoryData));
- }
- }
- });
-
- // Generate and download the file
- const buffer = await workbook.xlsx.writeBuffer();
- const blob = new Blob([buffer], {
- type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
- });
- const filename = 'Product Data.xlsx';
-
- if (typeof window !== 'undefined') {
- if (window.navigator && window.navigator.msSaveOrOpenBlob) {
- window.navigator.msSaveOrOpenBlob(blob, filename);
- } else {
- const downloadLink = document.createElement('a');
- downloadLink.href = window.URL.createObjectURL(blob);
- downloadLink.download = filename;
- downloadLink.click();
- }
- }
- };
-
- // Usage examples:
- // Download only specific fields:
- // handleDownload(['ProdName', 'Size']); // Only Product Name and Quantity
- // handleDownload(['ProdName', 'Size', 'UOM', 'SellPrice']); // Multiple fields
- // handleDownload(['ProdName', 'Size', 'UOM', 'SellPrice', 'ProdCat', 'Brand']); // More fields
-
- // Available field names:
- // 'ProdName', 'Size', 'UOM', 'SellPrice', 'ProdCat', 'ProdSubCat', 'Brand',
- // 'ProdVarientName', 'MRP', 'StockAvailable', 'OfferPrice', 'Supplier', 'TaxId',
- // 'AutoGenerateQr', 'AddQrCode', 'SpecialPrice', 'OnePiecePrice', 'AutoGenOnePieceQr',
- // 'AutoGenOnePieceQrNum', 'CESS', 'HSNCode', 'PartNumber', 'Rack', 'ManufDate',
- // 'ExpDate', 'AvailableFrom', 'AvailableTo'
- const handleFileSubmit = (e) => {
- e.preventDefault();
- if (excelFile === null) {
- excelFileError('Please select an Excel file.');
- } else {
- handleSubmit(Datas);
- }
- };
-
- const handleFieldSetup = () => {
- setFieldSetup(true);
- };
-
- const handleFieldSetupSubmit = async () => {
- const postData = {
- AppId: AppId,
- CompId: CompId,
- BranchId: BranchId,
- Type: 'EB',
- FormType: 'Product',
- TypeId: productBulkUploadCatId,
- ConfigDtl: selectedFields?.map((field) => ({
- ConfigId: field,
- Access: 'Y',
- })),
- CreatedBy: UserId,
- };
-
- const response = await dispatch(postFieldSetup(postData))?.unwrap();
-
- if (response?.data?.statusCode === 1) {
- setMessageType('success');
- setMessageData(response?.data?.response);
- setFieldSetup(false);
- await getFieldSetup();
- } else {
- setMessageType('error');
- setMessageData('Failed to set up fields');
- }
- };
-
- const handleFieldSelect = (value) => {
- setSelectedFields((prev) => {
- if (prev.includes(value)) {
- return prev;
- }
- return [value, ...prev];
- });
- };
-
- const handleFieldRemove = (id) => {
- setSelectedFields((prev) => prev.filter((field) => field !== id));
- };
-
- const handleCancelData = () => {
- dispatch(emptyExcelData());
- if (fileInputRef.current) {
- fileInputRef.current.value = '';
- }
- };
-
- const columns = [
- {
- title: 'Product Name',
- dataIndex: 'ProductName',
- key: 'ProductName',
- editable: true,
- },
- {
- title: 'Qty',
- dataIndex: 'Quantity',
- key: 'Quantity',
- editable: true,
- },
- {
- title: 'UOM',
- dataIndex: 'UOM',
- key: 'UOM',
- editable: true,
- },
- {
- title: 'Sales Price',
- dataIndex: 'SellPrice',
- key: 'SellPrice',
- editable: true,
- },
- {
- title: 'Category',
- dataIndex: 'Category',
- key: 'Category',
- editable: true,
- },
- {
- title: 'Sub Category',
- dataIndex: 'SubCategory',
- key: 'SubCategory',
- editable: true,
- },
- {
- title: 'Brand',
- dataIndex: 'Brand',
- key: 'Brand',
- editable: true,
- },
- {
- title: 'Variant Name',
- dataIndex: 'ProductVariantName',
- key: 'ProductVariantName',
- editable: true,
- },
- {
- title: 'MRP',
- dataIndex: 'MRP',
- key: 'MRP',
- editable: true,
- },
- {
- title: 'WholeSale Price',
- dataIndex: 'WhSalePrice',
- key: 'WhSalePrice',
- editable: true,
- },
- {
- title: 'Auto Qrcode',
- dataIndex: 'AutoGenerateQrcode',
- key: 'AutoGenerateQrcode',
- editable: true,
- },
- {
- title: 'Add QrCode',
- dataIndex: 'AddQrCode',
- key: 'AddQrCode',
- editable: true,
- },
- {
- title: 'Stock Available',
- dataIndex: 'StockAvailable',
- key: 'StockAvailable',
- editable: true,
- },
- {
- title: 'Token Available',
- dataIndex: 'TokenAvailable',
- key: 'TokenAvailable',
- editable: true,
- },
- {
- title: 'One Piece Available',
- dataIndex: 'OnePieceAvailable',
- key: 'OnePieceAvailable',
- editable: true,
- },
- {
- title: 'One Piece Price',
- dataIndex: 'OnePiecePrice',
- key: 'OnePiecePrice',
- editable: true,
- },
- {
- title: 'Auto Gen One Piece Qr',
- dataIndex: 'AutoGenerateOnePieceQrcode',
- key: 'AutoGenerateOnePieceQrcode',
- editable: true,
- },
- {
- title: 'Auto Gen One Piece Qr No',
- dataIndex: 'AutoGenerateOnePieceQrcodeNumber',
- key: 'AutoGenerateOnePieceQrcodeNumber',
- editable: true,
- },
- {
- title: 'Product Type',
- dataIndex: 'ProductType',
- key: 'ProductType',
- editable: true,
- },
- {
- title: 'Tax',
- dataIndex: 'Tax',
- key: 'Tax',
- editable: true,
- },
- {
- title: 'Cess',
- dataIndex: 'CESS',
- key: 'CESS',
- editable: true,
- },
- {
- title: 'HSN',
- dataIndex: 'HSN',
- key: 'HSN',
- editable: true,
- },
- {
- title: 'Part Number',
- dataIndex: 'PartNumber',
- key: 'PartNumber',
- editable: true,
- },
- {
- title: 'Rack',
- dataIndex: 'Rack',
- key: 'Rack',
- editable: true,
- },
- {
- title: 'Mfg Date',
- dataIndex: 'ManufactureDate',
- key: 'ManufactureDate',
- editable: true,
- },
- {
- title: 'Exp Date',
- dataIndex: 'ExpireDate',
- key: 'ExpireDate',
- editable: true,
- },
- {
- title: 'Avl From',
- dataIndex: 'AvailableFrom',
- key: 'AvailableFrom',
- editable: true,
- },
- {
- title: 'Avl To',
- dataIndex: 'AvailableTo',
- key: 'AvailableTo',
- editable: true,
- },
- {
- title: 'Image',
- dataIndex: 'Productimage',
- key: 'Productimage',
- render: (ProdImage, record, index) => {
- const Img = ProdImage;
- return (
- <>
- {Img ? (
-
- ) : (
- <>
-