diff --git a/src/App.jsx b/src/App.jsx index f746608..9d5c4da 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -8,7 +8,7 @@ import SelfBooking from './Pages/SelfBooking/SelfBooking.jsx'; import { isMobile, isIOS } from 'react-device-detect'; import { routesConfig } from './routesConfig'; import { GlobalItemCard } from './Features/BookingScreen/BookingData/BookingData.js'; -import { clearSession, getSession } from './Services/Others.js'; +import { clearSession, getSession, sessionStore } from './Services/Others.js'; const KisokSelBooking = lazy( () => import('./Pages/SelfBooking/KisokSelBooking') @@ -27,9 +27,10 @@ import useSessionManager from './useSessionManager.js'; import ExtendSubscriptionModal from './Pages/ExtentedModal/ExtendSubscriptionModal.jsx'; import devtools from 'devtools-detect'; import { useDevToolsDetection } from './utils/useDevToolsDetection.js'; +import { Capacitor } from '@capacitor/core'; -const isCapacitor = () => !!window.Capacitor?.isNativePlatform?.(); - +// const isCapacitor = () => !!window.Capacitor?.isNativePlatform?.(); +const isCapacitor = () => Capacitor.isNativePlatform(); // ✅ Define your home/exit pages here const HOME_PAGES = [ '/app-page/home', // android minimize @@ -55,7 +56,7 @@ const AppRoutes = () => { const [devToolsOpen, setDevToolsOpen] = useState(false); // ✅ Flag to prevent stack push when back button navigates const isBackNav = useRef(false); - + console.log(isCapacitor(), 'Is Capacitor'); // ✅ Build navigation stack useEffect(() => { // Skip pushing to stack when back button caused this navigation @@ -70,13 +71,14 @@ const AppRoutes = () => { // Don't track login pages if (LOGIN_PAGES.some((p) => path.includes(p))) return; - const raw = sessionStorage.getItem('navStack'); + const raw = getSession('navStack'); + console.log('🎯 Current path:', path); let stack = raw ? JSON.parse(raw) : []; if (stack.length === 0 || stack[stack.length - 1] !== path) { stack.push(path); if (stack.length > 50) stack = stack.slice(-50); - sessionStorage.setItem('navStack', JSON.stringify(stack)); + sessionStore('navStack', JSON.stringify(stack)); console.log('📍 Stack:', stack); } } catch (e) { } @@ -90,7 +92,7 @@ const AppRoutes = () => { const currentPath = location.pathname; const SessionId = getSession('SessionId'); - + console.log('SessionId:', SessionId, 'CurrentPath:', currentPath) // 🟢 If session exists → allow navigation if (SessionId) { console.log('Browser back allowed'); @@ -112,65 +114,53 @@ const AppRoutes = () => { }, [location.pathname]); // ✅ Android — Capacitor back button - useEffect(() => { - if (!isCapacitor()) return; + useEffect(() => { + if (!isCapacitor()) return; - const handler = async () => { - try { - const currentPath = location.pathname + (location.search || ''); - console.log('🔙 Back pressed:', currentPath); + const handler = async () => { + try { + const currentPath = window.location.pathname + window.location.search; // Bug 2 fix - const raw = sessionStorage.getItem('navStack'); - let stack = raw ? JSON.parse(raw) : []; + const raw = getSession('navStack'); + let stack = raw ? JSON.parse(raw) : []; - // Remove current path from stack if it's at the end - while (stack.length && stack[stack.length - 1] === currentPath) { - stack.pop(); - } - - // If there are pages in history, go back to previous page - if (stack.length > 0) { - const previous = stack[stack.length - 1]; - sessionStorage.setItem('navStack', JSON.stringify(stack)); - isBackNav.current = true; - navigate(previous); - console.log('Navigate to previous:', previous); - return; - } - - // Stack is empty - check where we are - // 🏠 Home page → minimize - if (HOME_PAGES?.some((p) => currentPath?.includes(p))) { - console.log('Home page & empty stack → minimizing app'); - await CapacitorApp.minimizeApp(); - return; - } - - // 🚪 Login page → minimize - if (LOGIN_PAGES?.some((p) => currentPath?.includes(p))) { - console.log('Login page & empty stack → minimizing app'); - await CapacitorApp.minimizeApp(); - return; - } - - // Anywhere else with empty stack → go to home - const home = '/app-page/home'; - sessionStorage.setItem('navStack', JSON.stringify([home])); - isBackNav.current = true; - navigate(home); - console.log('Empty stack, navigate to home'); - } catch (e) { - console.error('Back handler error:', e); - await CapacitorApp.minimizeApp(); + while (stack.length && stack[stack.length - 1] === currentPath) { + stack.pop(); } - }; - const listener = CapacitorApp.addListener('backButton', handler); + if (stack.length > 0) { + const previous = stack[stack.length - 1]; + sessionStore('navStack', JSON.stringify(stack)); + isBackNav.current = true; // Bug 3 fix — BEFORE navigate + navigate(previous); + return; + } - return () => { - listener.remove(); - }; - }, [navigate, location.pathname, location.search]); + if (HOME_PAGES?.some((p) => currentPath?.includes(p))) { + await CapacitorApp.minimizeApp(); + return; + } + + if (LOGIN_PAGES?.some((p) => currentPath?.includes(p))) { + await CapacitorApp.minimizeApp(); + return; + } + + const home = '/app-page/home'; + isBackNav.current = true; // Bug 3 fix here too + sessionStore('navStack', JSON.stringify([home])); + navigate(home); + } catch (e) { + console.error('Back handler error:', e); + await CapacitorApp.minimizeApp(); + } + }; + + const listenerPromise = CapacitorApp.addListener('backButton', handler); // Bug 1 fix + return () => { + listenerPromise.then(({ remove }) => remove()); + }; +}, [navigate,location.pathname, location.search]); // mohan // useEffect(() => { // if (isMobile || isIOS) { @@ -211,27 +201,27 @@ const AppRoutes = () => { // return () => clearInterval(checkDevTools); // }, [devToolsOpen]); - const isBlocked = useDevToolsDetection(() => { - // optional: log, notify, etc. - console.warn('DevTools detected'); - }); + // const isBlocked = useDevToolsDetection(() => { + // // optional: log, notify, etc. + // console.warn('DevTools detected'); + // }); - if (isBlocked) { - return ( -
-

- DevTools detected. Please close it to continue. -

-
- ); - } + // if (isBlocked) { + // return ( + //
+ //

+ // DevTools detected. Please close it to continue. + //

+ //
+ // ); + // } if (extendModel) { return ( { const DineinDefault = useSelector(GlobalDineinDefault); const [collapse, setCollapse] = useState(false); + const [isLandscape, setIsLandscape] = useState( + window.matchMedia('(orientation: landscape)').matches + ); + useEffect(() => { + const handleResize = () => { + setIsLandscape(window.matchMedia('(orientation: landscape)').matches); + }; + + window.addEventListener('resize', handleResize); + return () => window.removeEventListener('resize', handleResize); + }, []); + useEffect(() => { const handleResize = () => { setCollapse(window.innerWidth < 768); @@ -368,7 +380,10 @@ const SideMenuPozo = ({ items = [] }) => {
{ let encryptedLoginType = getSession('LoginType') - console.log( - 'encryptedLoginType', - encryptedLoginType, - TokendecryptedValuesFun(encryptedMobileno) - ); - + // let Mobileno = encryptedUserId && encryptedLoginType != "Kiosk" ? TokendecryptedValuesFun(encryptedMobileno) : '1000000001'; let Mobileno = encryptedUserId ? encryptedMobileno diff --git a/src/Features/BookingScreen/BookingData/BookingData.js b/src/Features/BookingScreen/BookingData/BookingData.js index 1e02bcc..3706e29 100644 --- a/src/Features/BookingScreen/BookingData/BookingData.js +++ b/src/Features/BookingScreen/BookingData/BookingData.js @@ -1416,6 +1416,13 @@ export const getOtherServiceTicket = createAsyncThunk( } } ); +// post /cancelPayment +export const PostCancelPayment = createAsyncThunk( + 'BookingData/cancelPayment', + async (postData) => { + return await axiosRetailInstanceData.post(`/cancelPayment`, postData); + } +); export const PostBlockSlots = createAsyncThunk( 'BookingData/PostBlockSlots', async (postData) => { @@ -1444,6 +1451,7 @@ export const getPaymentStatusForBusinessUPI = createAsyncThunk( } ); + export const getCurrentOrderid = createAsyncThunk( 'BookingData/getcurrentorderid', @@ -2160,15 +2168,15 @@ const BookingData = createSlice({ state.getmultipleSearchDatas = []; } }); - builder.addCase(getAppSubscriptionDate.fulfilled, (state, action) => { - if (action?.payload?.data?.statusCode === 1) { - state.AppExpDateData = - action?.payload?.data?.data?.[0]|| {}; - } else { - state.AppExpDateData = {}; - } + builder.addCase(getAppSubscriptionDate.fulfilled, (state, action) => { + if (action?.payload?.data?.statusCode === 1) { + state.AppExpDateData = + action?.payload?.data?.data?.[0] || {}; + } else { + state.AppExpDateData = {}; + } }); - + }, }); diff --git a/src/Pages/Automated Reorder/AutomatedReorder.scss b/src/Pages/Automated Reorder/AutomatedReorder.scss index 083b4a9..903a74f 100644 --- a/src/Pages/Automated Reorder/AutomatedReorder.scss +++ b/src/Pages/Automated Reorder/AutomatedReorder.scss @@ -3,7 +3,7 @@ height: 90vh; overflow: auto; scrollbar-width: thin; - font-family: 'Poppins'; + font-family: "Poppins"; .automated-reorder-content { padding-top: 18px; @@ -51,4 +51,12 @@ padding: 6px !important; } } -} \ No newline at end of file +} + +.automated-reorder-list-content { + .eyeopenShow { + display: flex; + align-items: center; + justify-content: center; + } +} diff --git a/src/Pages/Automated Reorder/AutomatedReorderList.jsx b/src/Pages/Automated Reorder/AutomatedReorderList.jsx index 91d43bc..db7e7db 100644 --- a/src/Pages/Automated Reorder/AutomatedReorderList.jsx +++ b/src/Pages/Automated Reorder/AutomatedReorderList.jsx @@ -1,345 +1,359 @@ -import { useCallback, useEffect, useState } from "react"; -import { useDispatch } from "react-redux"; -import { getSession } from "../../Services/Others"; -import { changeBreadCrumb, getEmpAccess } from "../../Features/AppPage/CenterPage"; -import { Messages } from "../../Components/Notifications/Messages"; -import { Tables } from "../../Components/Tables/Table"; -import FormHeader from "../PageComponents/FormHeader"; -import Search from "../../Components/Forms/Search"; -import Buttons from "../../Components/Forms/Buttons"; +import { useCallback, useEffect, useState } from 'react'; +import { useDispatch } from 'react-redux'; +import { getSession } from '../../Services/Others'; import { - EditFilled, - DeleteFilled, - PlusOutlined, - ReloadOutlined, + changeBreadCrumb, + getEmpAccess, +} from '../../Features/AppPage/CenterPage'; +import { Messages } from '../../Components/Notifications/Messages'; +import { Tables } from '../../Components/Tables/Table'; +import FormHeader from '../PageComponents/FormHeader'; +import Search from '../../Components/Forms/Search'; +import Buttons from '../../Components/Forms/Buttons'; +import { + EditFilled, + DeleteFilled, + PlusOutlined, + ReloadOutlined, } from '@ant-design/icons'; -import { useLocation, useNavigate } from "react-router-dom"; -import { Space, Tooltip } from "antd"; -import { deleteAutomatedReorder, getAutomatedReorderList } from "../../Features/PurchaseOrder/PurchaseOrder"; -import { DefaultModal } from "../../Components/Modal/DefaultModal"; -import { FaRegEye } from "react-icons/fa"; -import { render } from "react-dom"; -import { useAuth } from "../../AuthContext"; -import "./AutomatedReorder.scss"; +import { useLocation, useNavigate } from 'react-router-dom'; +import { Space, Tooltip } from 'antd'; +import { + deleteAutomatedReorder, + getAutomatedReorderList, +} from '../../Features/PurchaseOrder/PurchaseOrder'; +import { DefaultModal } from '../../Components/Modal/DefaultModal'; +import { FaRegEye } from 'react-icons/fa'; +import { render } from 'react-dom'; +import { useAuth } from '../../AuthContext'; +import './AutomatedReorder.scss'; const subDirectory = import.meta.env.BASE_URL; const items = [ - { - name: 'Home', - link: `${subDirectory}app-page/home`, - }, - { - name: 'Automated Reorder', - link: `${subDirectory}setting/automated-reorder`, - }, + { + name: 'Home', + link: `${subDirectory}app-page/home`, + }, + { + name: 'Automated Reorder', + link: `${subDirectory}setting/automated-reorder`, + }, ]; - - const AutomatedReorderList = () => { - const dispatch = useDispatch(); - const navigate = useNavigate(); - const location = useLocation(); - const state = location?.state; - const { SadminuserAccess } = useAuth(); - let SAAccessCommonMaster = SadminuserAccess?.find( - (e) => e?.MenuName === 'Product Receipt' + const dispatch = useDispatch(); + const navigate = useNavigate(); + const location = useLocation(); + const state = location?.state; + const { SadminuserAccess } = useAuth(); + let SAAccessCommonMaster = SadminuserAccess?.find( + (e) => e?.MenuName === 'Product Receipt' + ); + + const AppId = getSession('AppId'); + const CompId = getSession('CompId'); + const BranchId = getSession('BranchId'); + const UserId = getSession('UserId'); + const UserType = getSession('UserType'); + const [empData, setEmpData] = useState(); + const [addnewAccess, setaddnewAccess] = useState(true); + + const [messageType, setMessageType] = useState(null); + const [messageData, setMessageData] = useState(null); + const [supplierModalOpen, setSupplierModalOpen] = useState(false); + const [supplierRecords, setSupplierRecords] = useState([]); + const [supplierRecordIndex, setSupplierRecordIndex] = useState(null); + const [page, setPage] = useState(1); + + const [searchedText, setSearchedText] = useState(''); + const [tableData, setTableData] = useState([]); + + const columns = [ + { + title: 'SL.NO', + dataIndex: 'SLNO', + key: 'SLNO', + width: '10%', + render: (_, record, index) => index + 1, + align: 'center', + }, + { + title: 'Product Name', + dataIndex: 'ProdName', + key: 'ProdName', + render: (_, record) => `${record.ProdName} (${record.UOMName})`, + }, + { + title: 'Supplier', + dataIndex: 'Supplier', + key: 'Supplier', + align: 'center', + render: (_, record, index) => ( + //
+ +
+ { + setSupplierModalOpen(true); + setSupplierRecords(record.SupplierDetails); + setSupplierRecordIndex(index); + }} + /> +
+
+ ), + }, + { + title: 'Order Type', + dataIndex: 'OrderType', + key: 'OrderType', + render: (_, record, index) => + record.OrderType === 'E' ? 'End of Day (EOD)' : 'Immediate', + }, + { + title: 'Confirmation Type', + dataIndex: 'OrderProcessing', + key: 'OrderProcessing', + render: (_, record, index) => + record.OrderProcessing === 'Y' ? 'Need Confirmation' : 'Auto', + }, + { + title: 'Reorder Quantity', + dataIndex: 'OrderQty', + key: 'OrderQty', + align: 'center', + }, + { + title: 'Action', + dataIndex: 'Action', + key: 'Action', + width: '100px', + align: 'center', + render: (_, record, index) => + record.ActiveStatus === 'A' ? ( +
+ handleEdit(record)} + /> + handleActiveAndDeactive(record)} + /> +
+ ) : ( + handleActiveAndDeactive(record)} + /> + ), + }, + ]; + + const supplierColumns = [ + { + title: 'SL.NO', + dataIndex: 'SLNO', + key: 'SLNO', + width: '10%', + render: (_, record, index) => index + 1, + }, + { + title: 'Supplier Name', + dataIndex: 'SuppName', + key: 'SuppName', + width: '20%', + }, + ]; + + useEffect(() => { + try { + if (AppId && CompId && BranchId) { + dispatch(changeBreadCrumb({ items: items })); + fetchData(); + if (state?.Notify) { + setMessageType(state?.Notify.messageType); + setMessageData(state?.Notify.messageData); + } + } + } catch (error) { + console.error(error, 'error: changeBreadCrumb'); + } + }, [AppId, CompId, BranchId]); + + useEffect(() => { + if (UserType === 'Employee') { + fetchApi(); + } + }, [UserType]); + + useEffect(() => { + let hasAccess = false; + + if (UserType === 'Admin' || UserType === 'Super Admin') { + hasAccess = true; + } else if (UserType === 'Employee') { + hasAccess = empData?.AddAccess === 'Y'; + } else if (UserType === 'Super Admin User') { + hasAccess = SAAccessCommonMaster?.AddAccess === 'Y'; + } + + setaddnewAccess(!hasAccess); + }, [empData, SAAccessCommonMaster, UserType]); + + const fetchApi = async () => { + let data = { + CompId: CompId, + BranchId: BranchId, + AppId: AppId, + EmpId: UserId, + }; + let response = await dispatch(getEmpAccess(data)).unwrap(); + let datas = response?.data?.data?.[0]?.EmpAccessDetails?.filter( + (item) => item.ConfigName === 'Automated Reorder' ); + setEmpData(datas?.[0]); + }; - const AppId = getSession('AppId'); - const CompId = getSession('CompId'); - const BranchId = getSession('BranchId'); - const UserId = getSession('UserId'); - const UserType = getSession('UserType'); - const [empData, setEmpData] = useState(); - const [addnewAccess, setaddnewAccess] = useState(true); - - const [messageType, setMessageType] = useState(null); - const [messageData, setMessageData] = useState(null); - const [supplierModalOpen, setSupplierModalOpen] = useState(false); - const [supplierRecords, setSupplierRecords] = useState([]); - const [supplierRecordIndex, setSupplierRecordIndex] = useState(null); - const [page, setPage] = useState(1); - - - const [searchedText, setSearchedText] = useState(''); - const [tableData, setTableData] = useState([]); - - const columns = [ - { - title: 'SL.NO', - dataIndex: 'SLNO', - key: 'SLNO', - width: '10%', - render: (_, record, index) => index + 1, - align: 'center', - }, - { - title: 'Product Name', - dataIndex: 'ProdName', - key: 'ProdName', - render: (_, record) => ( - `${record.ProdName} (${record.UOMName})` - ) - }, - { - title: 'Supplier', - dataIndex: 'Supplier', - key: 'Supplier', - align: 'center', - render: (_, record, index) => ( - //
- -
- { - setSupplierModalOpen(true); - setSupplierRecords(record.SupplierDetails); - setSupplierRecordIndex(index); - }} - /> -
-
- ), - }, - { - title: 'Order Type', - dataIndex: 'OrderType', - key: 'OrderType', - render: (_, record, index) => ( - record.OrderType === 'E' ? 'End of Day (EOD)' : 'Immediate' - ) - }, - { - title: 'Confirmation Type', - dataIndex: 'OrderProcessing', - key: 'OrderProcessing', - render: (_, record, index) => ( - record.OrderProcessing === 'Y' ? 'Need Confirmation' : 'Auto' - ) - }, - { - title: 'Reorder Quantity', - dataIndex: 'OrderQty', - key: 'OrderQty', - align: 'center', - }, - { - title: 'Action', - dataIndex: 'Action', - key: 'Action', - width: '100px', - align: 'center', - render: (_, record, index) => ( - - record.ActiveStatus === 'A' ? ( -
- handleEdit(record)} - /> - handleActiveAndDeactive(record)} - /> -
- ) : ( - handleActiveAndDeactive(record)} - /> - ) - ), - }, - ]; - - const supplierColumns = [ - { - title: 'SL.NO', - dataIndex: 'SLNO', - key: 'SLNO', - width: '10%', - render: (_, record, index) => index + 1 - }, - { - title: 'Supplier Name', - dataIndex: 'SuppName', - key: 'SuppName', - width: '20%', - } - ]; - - useEffect(() => { - try { - if (AppId && CompId && BranchId) { - dispatch(changeBreadCrumb({ items: items })); - fetchData() - if (state?.Notify) { - setMessageType(state?.Notify.messageType); - setMessageData(state?.Notify.messageData); - } - } - } catch (error) { - console.error(error, 'error: changeBreadCrumb'); - } - }, [AppId, CompId, BranchId]); - - useEffect(() => { - if (UserType === 'Employee') { - fetchApi(); - } - }, [UserType]); - - useEffect(() => { - let hasAccess = false; - - if (UserType === 'Admin' || UserType === 'Super Admin') { - hasAccess = true; - } else if (UserType === 'Employee') { - hasAccess = empData?.AddAccess === 'Y'; - } else if (UserType === 'Super Admin User') { - hasAccess = SAAccessCommonMaster?.AddAccess === 'Y'; - } - - setaddnewAccess(!hasAccess); - }, [empData, SAAccessCommonMaster, UserType]); - - const fetchApi = async () => { - let data = { - CompId: CompId, - BranchId: BranchId, - AppId: AppId, - EmpId: UserId, - }; - let response = await dispatch(getEmpAccess(data)).unwrap(); - let datas = response?.data?.data?.[0]?.EmpAccessDetails?.filter( - (item) => item.ConfigName === 'Automated Reorder' - ); - setEmpData(datas?.[0]); - }; - - const fetchData = async () => { - try { - const res = await dispatch(getAutomatedReorderList({ AppId, CompId, BranchId }))?.unwrap(); - if (res?.data?.statusCode === 1 && res?.data?.data?.length > 0) { - setTableData(res?.data?.data) - } else { - setTableData([]) - } - } catch (error) { - console.error(error, 'error: getAutomatedReorderList'); - } + const fetchData = async () => { + try { + const res = await dispatch( + getAutomatedReorderList({ AppId, CompId, BranchId }) + )?.unwrap(); + if (res?.data?.statusCode === 1 && res?.data?.data?.length > 0) { + setTableData(res?.data?.data); + } else { + setTableData([]); + } + } catch (error) { + console.error(error, 'error: getAutomatedReorderList'); } + }; - const onSearch = (value) => { - setSearchedText(value); - }; - const onSearchChange = (e) => { - setSearchedText(e?.target?.value); - }; + const onSearch = (value) => { + setSearchedText(value); + }; + const onSearchChange = (e) => { + setSearchedText(e?.target?.value); + }; - const handleAdd = () => { - navigate(`${subDirectory}setting/automated-reorder/new`); + const handleAdd = () => { + navigate(`${subDirectory}setting/automated-reorder/new`); + }; + + const handleEdit = (record) => { + navigate(`${subDirectory}setting/automated-reorder/update`, { + state: { + editstate: record, + }, + }); + }; + const handleActiveAndDeactive = async (record) => { + const res = await dispatch( + deleteAutomatedReorder({ + UniqueId: record?.UniqueId, + UpdatedBy: UserId, + ActiveStatus: record?.ActiveStatus === 'A' ? 'D' : 'A', + }) + )?.unwrap(); + if (res?.data?.statusCode === 1) { + setMessageType('success'); + setMessageData( + record?.ActiveStatus === 'A' + ? 'Deactivated Successfully' + : 'Activated Successfully' + ); + fetchData(); + } else { + setMessageType('error'); + setMessageData(res?.data?.message); } + }; - const handleEdit = (record) => { - navigate(`${subDirectory}setting/automated-reorder/update`, { - state: { - editstate: record, - } - }); - } - const handleActiveAndDeactive = async (record) => { - const res = await dispatch(deleteAutomatedReorder({ UniqueId: record?.UniqueId, UpdatedBy: UserId, ActiveStatus: record?.ActiveStatus === 'A' ? 'D' : 'A' }))?.unwrap(); - if (res?.data?.statusCode === 1) { - setMessageType('success'); - setMessageData(record?.ActiveStatus === 'A' ? 'Deactivated Successfully' : 'Activated Successfully'); - fetchData(); - } else { - setMessageType('error'); - setMessageData(res?.data?.message); - } - } + const onComplete = useCallback(() => { + setMessageType(null); + setMessageData(null); + }, []); + const handlePageChange = (current) => { + setPage(current); + }; - const onComplete = useCallback(() => { - setMessageType(null); - setMessageData(null); - }, []); - const handlePageChange = (current) => { - setPage(current); - }; - - return ( -
- -
-
-
-
- -
-
-
- -
- } - /> -
-
-
-
- -
+ return ( +
+ +
+
+
+
+
- { - setSupplierModalOpen(false); - setSupplierRecords(null); - setSupplierRecordIndex(null); - }} - children={ -
- -
- } - /> -
- ) -} +
+
+ +
+ } + /> +
+
+
+
+ +
+
+ { + setSupplierModalOpen(false); + setSupplierRecords(null); + setSupplierRecordIndex(null); + }} + children={ +
+ +
+ } + /> + + ); +}; -export default AutomatedReorderList \ No newline at end of file +export default AutomatedReorderList; diff --git a/src/Pages/BookingScreen/Components/BSBillingTables/BSBillingEditQuantity/BSBillingEditQuantity.jsx b/src/Pages/BookingScreen/Components/BSBillingTables/BSBillingEditQuantity/BSBillingEditQuantity.jsx index 9c84e49..b0ea151 100644 --- a/src/Pages/BookingScreen/Components/BSBillingTables/BSBillingEditQuantity/BSBillingEditQuantity.jsx +++ b/src/Pages/BookingScreen/Components/BSBillingTables/BSBillingEditQuantity/BSBillingEditQuantity.jsx @@ -54,7 +54,7 @@ const BSBillingEditQuantity = (props) => { const quantityInputRef = useRef(null); const priceChangeInputRef = useRef(null); const reductionInputRef = useRef(null); - const { setIndex = () => {} } = props; + const { setIndex = () => { } } = props; const [disableSubmitButton, setDisableSubmitButton] = useState(false); console.log(disableSubmitButton, 'disableSubmitButton'); @@ -522,7 +522,15 @@ const BSBillingEditQuantity = (props) => { cartItem?.InwardDtlId === editedProduct?.InwardDtlId && cartItem?.OrderRate === editedProduct?.OrderRate && cartItem?.BookingTypeName === editedProduct?.BookingTypeName && - !cartItem?.SalesId + !cartItem?.SalesId && ((cartItem?.OfferModeType && cartItem?.OfferMode === 'B' + ? true + : cartItem?.OfferMode !== 'B') && + cartItem?.OfferMode !== 'P' && + cartItem?.OfferMode !== 'C' && + cartItem?.OfferMode !== 'O' && + cartItem?.OfferMode !== 'L' + ? true + : cartItem?.Offer === 0) ); // changing for one piece stock checking const isItemInCartfilter = CartOrderDetails?.filter( @@ -530,7 +538,15 @@ const BSBillingEditQuantity = (props) => { cartItem?.ProdId === editedProduct?.ProdId && cartItem?.InwardDtlId === editedProduct?.InwardDtlId && cartItem?.OrderRate !== editedProduct?.OrderRate && - !cartItem?.SalesId + !cartItem?.SalesId && ((cartItem?.OfferModeType && cartItem?.OfferMode === 'B' + ? true + : cartItem?.OfferMode !== 'B') && + cartItem?.OfferMode !== 'P' && + cartItem?.OfferMode !== 'C' && + cartItem?.OfferMode !== 'O' && + cartItem?.OfferMode !== 'L' + ? true + : cartItem?.Offer === 0) ); const isItemInCartHold = CartOrderDetails?.find( @@ -538,7 +554,15 @@ const BSBillingEditQuantity = (props) => { cartItem?.ProdId === editedProduct?.ProdId && cartItem?.InwardDtlId === editedProduct.InwardDtlId && cartItem?.OrderRate === editedProduct?.OrderRate && - cartItem?.BookingTypeName === editedProduct?.BookingTypeName + cartItem?.BookingTypeName === editedProduct?.BookingTypeName && ((cartItem?.OfferModeType && cartItem?.OfferMode === 'B' + ? true + : cartItem?.OfferMode !== 'B') && + cartItem?.OfferMode !== 'P' && + cartItem?.OfferMode !== 'C' && + cartItem?.OfferMode !== 'O' && + cartItem?.OfferMode !== 'L' + ? true + : cartItem?.Offer === 0) ); // check if the item is already in the cart const isItemInCartHoldfilter = CartOrderDetails?.filter( (cartItem) => @@ -547,7 +571,15 @@ const BSBillingEditQuantity = (props) => { !( (cartItem?.OrderRate === editedProduct?.OrderRate) // && cartItem?.BookingTypeName === editedProduct?.BookingTypeName - ) + ) && ((cartItem?.OfferModeType && cartItem?.OfferMode === 'B' + ? true + : cartItem?.OfferMode !== 'B') && + cartItem?.OfferMode !== 'P' && + cartItem?.OfferMode !== 'C' && + cartItem?.OfferMode !== 'O' && + cartItem?.OfferMode !== 'L' + ? true + : cartItem?.Offer === 0) ); if ( @@ -809,7 +841,7 @@ const BSBillingEditQuantity = (props) => { return ( cartItem?.InwardDtlId === editedProduct?.InwardDtlId && cartItem?.OfferMessage?.[0]?.OfferId === - editedProduct?.OfferMessage?.[0]?.OfferId && + editedProduct?.OfferMessage?.[0]?.OfferId && cartItem?.OfferMode === editedProduct?.OfferMode && cartItem?.BookingTypeName !== editedProduct?.BookingTypeName ); @@ -943,7 +975,7 @@ const BSBillingEditQuantity = (props) => { cartItem?.InwardDtlId === editedProduct?.InwardDtlId && cartItem?.OrderRate === editedProduct?.OrderRate && cartItem?.BookingTypeName !== - editedProduct?.BookingTypeName && + editedProduct?.BookingTypeName && !cartItem?.OfferMode && cartItem?.Offer === 0 ); @@ -957,7 +989,7 @@ const BSBillingEditQuantity = (props) => { cartItem?.InwardDtlId === editedProduct?.InwardDtlId && cartItem?.OrderRate === editedProduct?.OrderRate && cartItem?.BookingTypeName !== - editedProduct?.BookingTypeName && + editedProduct?.BookingTypeName && cartItem?.OfferMode === editedProduct?.OfferMode && cartItem?.Offer > 0 ); @@ -1090,7 +1122,7 @@ const BSBillingEditQuantity = (props) => { ) ) && product?.OfferId === - editedProduct?.OfferMessage?.[0]?.OfferId && + editedProduct?.OfferMessage?.[0]?.OfferId && product?.OfferMode === editedProduct?.OfferMode ) { const freeQty = @@ -1123,7 +1155,7 @@ const BSBillingEditQuantity = (props) => { // Also check main offer conditions const isMatchingOffer = offerProduct?.OfferId === - editedProduct?.OfferMessage?.[0]?.OfferId && + editedProduct?.OfferMessage?.[0]?.OfferId && offerProduct?.OfferMode === editedProduct?.OfferMode; if (hasMatchingFreeProduct && isMatchingOffer) { @@ -1206,7 +1238,7 @@ const BSBillingEditQuantity = (props) => { ) ) && product?.OfferId === - editedProduct?.OfferMessage?.[0]?.OfferId && + editedProduct?.OfferMessage?.[0]?.OfferId && product?.OfferMode === editedProduct?.OfferMode ) { return { @@ -1236,7 +1268,7 @@ const BSBillingEditQuantity = (props) => { // Also check main offer conditions const isMatchingOffer = offerProduct?.OfferId === - editedProduct?.OfferMessage?.[0]?.OfferId && + editedProduct?.OfferMessage?.[0]?.OfferId && offerProduct?.OfferMode === editedProduct?.OfferMode; if (hasMatchingFreeProduct && isMatchingOffer) { @@ -1423,7 +1455,7 @@ const BSBillingEditQuantity = (props) => { // Also check main offer conditions const isMatchingOffer = offerProduct?.OfferId === - editedProduct?.OfferMessage?.[0]?.OfferId && + editedProduct?.OfferMessage?.[0]?.OfferId && offerProduct?.OfferMode === editedProduct?.OfferMode; if (hasMatchingFreeProduct && isMatchingOffer) { @@ -1525,7 +1557,7 @@ const BSBillingEditQuantity = (props) => { // Also check main offer conditions const isMatchingOffer = offerProduct?.OfferId === - editedProduct?.OfferMessage?.[0]?.OfferId && + editedProduct?.OfferMessage?.[0]?.OfferId && offerProduct?.OfferMode === editedProduct?.OfferMode; if (hasMatchingFreeProduct && isMatchingOffer) { @@ -1679,7 +1711,7 @@ const BSBillingEditQuantity = (props) => { ) && cartItem?.Offer && isFreeProductApplicable?.OfferId === - cartItem?.OfferMessage?.[0]?.OfferId + cartItem?.OfferMessage?.[0]?.OfferId ); } ); @@ -1968,11 +2000,11 @@ const BSBillingEditQuantity = (props) => { product?.ProdId === editedProduct?.ProdId && product?.InwardDtlId === editedProduct?.InwardDtlId && product?.OfferId === - (sameBookingTypeProduct?.OfferMessage?.[0]?.OfferId || - otherBookingTypeProduct?.OfferMessage?.[0]?.OfferId) && + (sameBookingTypeProduct?.OfferMessage?.[0]?.OfferId || + otherBookingTypeProduct?.OfferMessage?.[0]?.OfferId) && product?.OfferMode === - (sameBookingTypeProduct?.OfferMode || - otherBookingTypeProduct?.OfferMode) + (sameBookingTypeProduct?.OfferMode || + otherBookingTypeProduct?.OfferMode) ) { return { ...product, @@ -2006,11 +2038,11 @@ const BSBillingEditQuantity = (props) => { // Also check main offer conditions const isMatchingOffer = offerProduct?.OfferId === - (sameBookingTypeProduct?.OfferMessage?.[0]?.OfferId || - otherBookingTypeProduct?.OfferMessage?.[0]?.OfferId) && + (sameBookingTypeProduct?.OfferMessage?.[0]?.OfferId || + otherBookingTypeProduct?.OfferMessage?.[0]?.OfferId) && offerProduct?.OfferMode === - (sameBookingTypeProduct?.OfferMode || - otherBookingTypeProduct?.OfferMode); + (sameBookingTypeProduct?.OfferMode || + otherBookingTypeProduct?.OfferMode); if (hasMatchingFreeProduct && isMatchingOffer) { // Get loyalty points from the matching free product @@ -2151,7 +2183,7 @@ const BSBillingEditQuantity = (props) => { cartItem?.Offer > 0 && isFreeProductApplicable?.OfferMode === cartItem?.OfferMode && isFreeProductApplicable?.OfferId === - cartItem?.OfferMessage?.[0]?.OfferId + cartItem?.OfferMessage?.[0]?.OfferId ); } ); @@ -2254,11 +2286,11 @@ const BSBillingEditQuantity = (props) => { if ( cartItem.ProdId === otherBookingTypeProduct.ProdId && cartItem.InwardDtlId === - otherBookingTypeProduct.InwardDtlId && + otherBookingTypeProduct.InwardDtlId && cartItem.BookingTypeName === - otherBookingTypeProduct.BookingTypeName && + otherBookingTypeProduct.BookingTypeName && cartItem.OrderRate === - otherBookingTypeProduct.OrderRate && + otherBookingTypeProduct.OrderRate && cartItem.OfferMode && cartItem.Offer > 0 ) { @@ -2329,12 +2361,12 @@ const BSBillingEditQuantity = (props) => { product?.ProdId === editedProduct?.ProdId && product?.InwardDtlId === editedProduct?.InwardDtlId && product?.OfferId === - (sameBookingTypeFreeProduct?.OfferMessage?.[0]?.OfferId || - otherBookingTypeFreeProduct?.OfferMessage?.[0] - ?.OfferId) && + (sameBookingTypeFreeProduct?.OfferMessage?.[0]?.OfferId || + otherBookingTypeFreeProduct?.OfferMessage?.[0] + ?.OfferId) && product?.OfferMode === - (sameBookingTypeFreeProduct?.OfferMode || - otherBookingTypeFreeProduct?.OfferMode) + (sameBookingTypeFreeProduct?.OfferMode || + otherBookingTypeFreeProduct?.OfferMode) ) { return { ...product, @@ -2368,13 +2400,13 @@ const BSBillingEditQuantity = (props) => { // Also check main offer conditions const isMatchingOffer = offerProduct?.OfferId === - (sameBookingTypeFreeProduct?.OfferMessage?.[0] - ?.OfferId || - otherBookingTypeFreeProduct?.OfferMessage?.[0] - ?.OfferId) && + (sameBookingTypeFreeProduct?.OfferMessage?.[0] + ?.OfferId || + otherBookingTypeFreeProduct?.OfferMessage?.[0] + ?.OfferId) && offerProduct?.OfferMode === - (sameBookingTypeFreeProduct?.OfferMode || - otherBookingTypeFreeProduct?.OfferMode); + (sameBookingTypeFreeProduct?.OfferMode || + otherBookingTypeFreeProduct?.OfferMode); if (hasMatchingFreeProduct && isMatchingOffer) { // Get loyalty points from the matching free product @@ -2456,11 +2488,11 @@ const BSBillingEditQuantity = (props) => { if ( cartItem.ProdId === sameBookingTypeProduct.ProdId && cartItem.InwardDtlId === - sameBookingTypeProduct.InwardDtlId && + sameBookingTypeProduct.InwardDtlId && cartItem.BookingTypeName === - sameBookingTypeProduct.BookingTypeName && + sameBookingTypeProduct.BookingTypeName && cartItem.OrderRate === - sameBookingTypeProduct.OrderRate && + sameBookingTypeProduct.OrderRate && cartItem.OfferMode && cartItem.Offer > 0 ) { @@ -2513,11 +2545,11 @@ const BSBillingEditQuantity = (props) => { if ( cartItem.ProdId === sameBookingTypeProduct.ProdId && cartItem.InwardDtlId === - sameBookingTypeProduct.InwardDtlId && + sameBookingTypeProduct.InwardDtlId && cartItem.BookingTypeName === - sameBookingTypeProduct.BookingTypeName && + sameBookingTypeProduct.BookingTypeName && cartItem.OrderRate === - sameBookingTypeProduct.OrderRate && + sameBookingTypeProduct.OrderRate && cartItem.OfferMode && cartItem.Offer > 0 ) { @@ -2606,11 +2638,11 @@ const BSBillingEditQuantity = (props) => { if ( cartItem.ProdId === otherBookingTypeProduct.ProdId && cartItem?.InwardDtlId === - otherBookingTypeProduct.InwardDtlId && + otherBookingTypeProduct.InwardDtlId && cartItem?.BookingTypeName === - otherBookingTypeProduct.BookingTypeName && + otherBookingTypeProduct.BookingTypeName && cartItem?.OrderRate === - otherBookingTypeProduct.OrderRate && + otherBookingTypeProduct.OrderRate && cartItem?.OfferMode && cartItem?.Offer > 0 ) { @@ -2639,11 +2671,11 @@ const BSBillingEditQuantity = (props) => { if ( cartItem.ProdId === otherBookingTypeProduct.ProdId && cartItem.InwardDtlId === - otherBookingTypeProduct.InwardDtlId && + otherBookingTypeProduct.InwardDtlId && cartItem.BookingTypeName === - otherBookingTypeProduct.BookingTypeName && + otherBookingTypeProduct.BookingTypeName && cartItem.OrderRate === - otherBookingTypeProduct.OrderRate && + otherBookingTypeProduct.OrderRate && cartItem.OfferMode && cartItem.Offer > 0 ) { @@ -2673,11 +2705,11 @@ const BSBillingEditQuantity = (props) => { if ( cartItem.ProdId === otherBookingTypeProduct.ProdId && cartItem.InwardDtlId === - otherBookingTypeProduct.InwardDtlId && + otherBookingTypeProduct.InwardDtlId && cartItem.BookingTypeName === - otherBookingTypeProduct.BookingTypeName && + otherBookingTypeProduct.BookingTypeName && cartItem.OrderRate === - otherBookingTypeProduct.OrderRate && + otherBookingTypeProduct.OrderRate && cartItem.OfferMode && cartItem.Offer > 0 ) { @@ -2776,12 +2808,12 @@ const BSBillingEditQuantity = (props) => { product?.ProdId === editedProduct?.ProdId && product?.InwardDtlId === editedProduct?.InwardDtlId && product?.OfferId === - (sameBookingTypeFreeProduct?.OfferMessage?.[0]?.OfferId || - otherBookingTypeFreeProduct?.OfferMessage?.[0] - ?.OfferId) && + (sameBookingTypeFreeProduct?.OfferMessage?.[0]?.OfferId || + otherBookingTypeFreeProduct?.OfferMessage?.[0] + ?.OfferId) && product?.OfferMode === - (sameBookingTypeFreeProduct?.OfferMode || - otherBookingTypeFreeProduct?.OfferMode) + (sameBookingTypeFreeProduct?.OfferMode || + otherBookingTypeFreeProduct?.OfferMode) ) { return { ...product, @@ -2815,12 +2847,12 @@ const BSBillingEditQuantity = (props) => { // Also check main offer conditions const isMatchingOffer = offerProduct?.OfferId === - (sameBookingTypeProduct?.OfferMessage?.[0]?.OfferId || - otherBookingTypeProduct?.OfferMessage?.[0] - ?.OfferId) && + (sameBookingTypeProduct?.OfferMessage?.[0]?.OfferId || + otherBookingTypeProduct?.OfferMessage?.[0] + ?.OfferId) && offerProduct?.OfferMode === - (sameBookingTypeProduct?.OfferMode || - otherBookingTypeProduct?.OfferMode); + (sameBookingTypeProduct?.OfferMode || + otherBookingTypeProduct?.OfferMode); if (hasMatchingFreeProduct && isMatchingOffer) { // Get loyalty points from the matching free product @@ -2899,11 +2931,11 @@ const BSBillingEditQuantity = (props) => { if ( cartItem.ProdId === sameBookingTypeProduct.ProdId && cartItem.InwardDtlId === - sameBookingTypeProduct.InwardDtlId && + sameBookingTypeProduct.InwardDtlId && cartItem.BookingTypeName === - sameBookingTypeProduct.BookingTypeName && + sameBookingTypeProduct.BookingTypeName && cartItem.OrderRate === - sameBookingTypeProduct.OrderRate && + sameBookingTypeProduct.OrderRate && cartItem.OfferMode && cartItem.Offer > 0 ) { @@ -2962,11 +2994,11 @@ const BSBillingEditQuantity = (props) => { if ( cartItem.ProdId === otherBookingTypeProduct.ProdId && cartItem.InwardDtlId === - otherBookingTypeProduct.InwardDtlId && + otherBookingTypeProduct.InwardDtlId && cartItem.BookingTypeName === - otherBookingTypeProduct.BookingTypeName && + otherBookingTypeProduct.BookingTypeName && cartItem.OrderRate === - otherBookingTypeProduct.OrderRate && + otherBookingTypeProduct.OrderRate && cartItem.OfferMode && cartItem.Offer > 0 ) { @@ -3038,12 +3070,12 @@ const BSBillingEditQuantity = (props) => { product?.ProdId === editedProduct?.ProdId && product?.InwardDtlId === editedProduct?.InwardDtlId && product?.OfferId === - (sameBookingTypeFreeProduct?.OfferMessage?.[0]?.OfferId || - otherBookingTypeFreeProduct?.OfferMessage?.[0] - ?.OfferId) && + (sameBookingTypeFreeProduct?.OfferMessage?.[0]?.OfferId || + otherBookingTypeFreeProduct?.OfferMessage?.[0] + ?.OfferId) && product?.OfferMode === - (sameBookingTypeFreeProduct?.OfferMode || - otherBookingTypeFreeProduct?.OfferMode) + (sameBookingTypeFreeProduct?.OfferMode || + otherBookingTypeFreeProduct?.OfferMode) ) { return { ...product, @@ -3077,12 +3109,12 @@ const BSBillingEditQuantity = (props) => { // Also check main offer conditions const isMatchingOffer = offerProduct?.OfferId === - (sameBookingTypeProduct?.OfferMessage?.[0]?.OfferId || - otherBookingTypeProduct?.OfferMessage?.[0] - ?.OfferId) && + (sameBookingTypeProduct?.OfferMessage?.[0]?.OfferId || + otherBookingTypeProduct?.OfferMessage?.[0] + ?.OfferId) && offerProduct?.OfferMode === - (sameBookingTypeProduct?.OfferMode || - otherBookingTypeProduct?.OfferMode); + (sameBookingTypeProduct?.OfferMode || + otherBookingTypeProduct?.OfferMode); if (hasMatchingFreeProduct && isMatchingOffer) { // Get loyalty points from the matching free product @@ -3217,21 +3249,21 @@ const BSBillingEditQuantity = (props) => { }), ...(!offerApply && itemDiscountPrice > 0 ? { - DiscountAmt: safeRound(itemDiscountPrice * fixedQty), - DiscountType: - itemDiscountPercentageSelection === 'Fixed' ? 'F' : 'P', - DiscountValue: - itemDiscountPercentageSelection === 'Fixed' - ? itemDiscountPrice * fixedQty - : ((itemDiscountPrice * fixedQty) / - (newPrice > 0 ? newPrice : editedProduct?.OrderRate)) * - 100, - } + DiscountAmt: safeRound(itemDiscountPrice * fixedQty), + DiscountType: + itemDiscountPercentageSelection === 'Fixed' ? 'F' : 'P', + DiscountValue: + itemDiscountPercentageSelection === 'Fixed' + ? itemDiscountPrice * fixedQty + : ((itemDiscountPrice * fixedQty) / + (newPrice > 0 ? newPrice : editedProduct?.OrderRate)) * + 100, + } : { - DiscountAmt: null, - DiscountType: null, - DiscountValue: null, - }), + DiscountAmt: null, + DiscountType: null, + DiscountValue: null, + }), }; if (hasOffer) { @@ -3256,17 +3288,17 @@ const BSBillingEditQuantity = (props) => { changeOrderCardDetails( CartOrderDetails?.map((i) => i?.InwardDtlId == updatedProduct?.InwardDtlId && - i?.BookingTypeName == updatedProduct?.BookingTypeName && - i?.localId === updatedProduct?.localId + i?.BookingTypeName == updatedProduct?.BookingTypeName && + i?.localId === updatedProduct?.localId ? { - ...updatedProduct, - Offer: 0, - OfferType: - updatedProduct?.Type === 'C' - ? updatedProduct?.OfferType - : null, - OfferMessage: null, - } + ...updatedProduct, + Offer: 0, + OfferType: + updatedProduct?.Type === 'C' + ? updatedProduct?.OfferType + : null, + OfferMessage: null, + } : i ) ) @@ -3302,10 +3334,10 @@ const BSBillingEditQuantity = (props) => { ((c?.OfferModeType && c?.OfferMode === 'B' ? true : c?.OfferMode !== 'B') && - c?.OfferMode !== 'P' && - c?.OfferMode !== 'C' && - c?.OfferMode !== 'O' && - c?.OfferMode !== 'L' + c?.OfferMode !== 'P' && + c?.OfferMode !== 'C' && + c?.OfferMode !== 'O' && + c?.OfferMode !== 'L' ? true : c?.Offer === 0); @@ -4040,14 +4072,14 @@ const BSBillingEditQuantity = (props) => {
{((RadioBtnSelection == 'Price' && disableSubmitButton) || RadioBtnSelection == 'Quantity') && ( - } - > - )} + } + > + )}
diff --git a/src/Pages/BookingScreen/Components/BSBillingTables/BSBillingTable1/BST1Payment.jsx b/src/Pages/BookingScreen/Components/BSBillingTables/BSBillingTable1/BST1Payment.jsx index 07327ae..5ca4c63 100644 --- a/src/Pages/BookingScreen/Components/BSBillingTables/BSBillingTable1/BST1Payment.jsx +++ b/src/Pages/BookingScreen/Components/BSBillingTables/BSBillingTable1/BST1Payment.jsx @@ -127,6 +127,7 @@ import { changeSearchedData, GlobalSelectedCustDisable, GlobalOrderStatus, + PostCancelPayment, } from '../../../../../Features/BookingScreen/BookingData/BookingData'; import FeaturesFunctionalities from '../../BookingFunctionality/FeaturesFunctionalities'; import { @@ -944,7 +945,7 @@ export default function BST1Payment() { const selectedStyle = stylesMap[ - printerTemplateStyle == undefined ? 'Style 13' : printerTemplateStyle + printerTemplateStyle == undefined ? 'Style 13' : printerTemplateStyle ]; if (selectedStyle) { @@ -1392,6 +1393,15 @@ export default function BST1Payment() { : AddBookingDetails(BookingType, true); } }; + // PostCancelPayment + const CancelPayment = async () => { + const response = await dispatch(PostCancelPayment({OrderId: businessUPIOrderId})).unwrap() + if (response?.data?.statusCode) { + ClearAllGlobalStateDatas(); + CustomerDisplay(); + setBusinessUPI(false); + } + } const financialYearError = async () => { setMessageType('error'); setMessageData('Financial Year-Based Sales Not Yet Started'); @@ -2069,15 +2079,15 @@ export default function BST1Payment() { OrderStatus: 'O', OrderType: BookingType === 'Dine In' || - BookingTypeBoth || - Estimation?.SettingValue == 'N' + BookingTypeBoth || + Estimation?.SettingValue == 'N' ? 'S' : GlobEstBooking === 'OvrAllEst' ? 'E' : GlobEstBooking === 'ParEst' ? GlobProdwisedata?.includes( - a.InwardDtlId + ' ' + a?.BookingTypeName - ) + a.InwardDtlId + ' ' + a?.BookingTypeName + ) ? 'E' : 'S' : 'S', @@ -2170,7 +2180,7 @@ export default function BST1Payment() { : Paybtnnameselected?.toLowerCase() === 'credit' ? 'S' : Paybtnnameselected?.toLowerCase() === 'upi' && - SelectedUPIPayOption?.toLowerCase() === 'default' + SelectedUPIPayOption?.toLowerCase() === 'default' ? 'S' : 'P', OrderDtlDetails: @@ -2187,9 +2197,9 @@ export default function BST1Payment() { ? globalTipAmount === 0 ? SelectedTableDetails : SelectedTableDetails?.map((item) => ({ - ...item, - TipsAmount: globalTipAmount, - })) + ...item, + TipsAmount: globalTipAmount, + })) : null, SalesPaymentType: 'normal', @@ -2205,8 +2215,8 @@ export default function BST1Payment() { ? PaymentgatewayUPI?.[0]?.ModeId : SelectedUPIPayOption?.toLowerCase() === 'business' ? BusinessPayOption?.find( - (busupi) => busupi?.ModeId === UpiId - )?.ModeId + (busupi) => busupi?.ModeId === UpiId + )?.ModeId : paybtnselected : paybtnselected ? paybtnselected @@ -2219,15 +2229,15 @@ export default function BST1Payment() { salesBillEdit && currentOrderNetAmount < previousNetAmount ? null : Paybtnnameselected?.toLowerCase() === 'upi' && - SelectedUPIPayOption?.toLowerCase() === 'business' + SelectedUPIPayOption?.toLowerCase() === 'business' ? BusinessPayOption?.find((busupi) => busupi?.ModeId === UpiId) - ?.MerchantId + ?.MerchantId : null, PaymentOptionType: salesBillEdit && - currentOrderNetAmount < previousNetAmount && - (refundPaySelectedName?.toLowerCase() === 'cash' || - refundPaySelectedName?.toLowerCase() === 'credit') + currentOrderNetAmount < previousNetAmount && + (refundPaySelectedName?.toLowerCase() === 'cash' || + refundPaySelectedName?.toLowerCase() === 'credit') ? 'PC' : Paybtnnameselected?.toLowerCase() === 'cash' ? 'PC' @@ -2247,29 +2257,29 @@ export default function BST1Payment() { ? null : SelectedUPIPayOption?.toLowerCase() === 'default' ? PaymentUpiOptions?.find((upipay) => upipay?.UPIId === UpiId) - ?.UPIDetailId + ?.UPIDetailId : SelectedUPIPayOption?.toLowerCase() === 'business' ? BusinessPayOption?.find( - (busupi) => busupi?.ModeId === UpiId - )?.MerchantUPIId + (busupi) => busupi?.ModeId === UpiId + )?.MerchantUPIId : null, AccountDtl: salesBillEdit && currentOrderNetAmount < previousNetAmount ? [] : Paybtnnameselected?.toLowerCase() === 'upi' && - SelectedUPIPayOption?.toLowerCase() === 'default' + SelectedUPIPayOption?.toLowerCase() === 'default' ? useOptions?.[0]?.PaymentDetails?.Payatthecounter?.find( - (upipay) => upipay?.UPIId === UpiId - ) + (upipay) => upipay?.UPIId === UpiId + ) : (Paybtnnameselected?.toLowerCase() === 'upi' && - SelectedUPIPayOption?.toLowerCase() === 'pd') || - (Paybtnnameselected?.toLowerCase() === 'card' && - SelectedCardOption?.toLowerCase() === 'pd') + SelectedUPIPayOption?.toLowerCase() === 'pd') || + (Paybtnnameselected?.toLowerCase() === 'card' && + SelectedCardOption?.toLowerCase() === 'pd') ? useOptions?.[0]?.PaymentDetails?.PaymentDevice : (Paybtnnameselected?.toLowerCase() === 'upi' && - SelectedUPIPayOption?.toLowerCase() === 'pg') || - (Paybtnnameselected?.toLowerCase() === 'card' && - SelectedCardOption?.toLowerCase() === 'pg') + SelectedUPIPayOption?.toLowerCase() === 'pg') || + (Paybtnnameselected?.toLowerCase() === 'card' && + SelectedCardOption?.toLowerCase() === 'pg') ? useOptions?.[0]?.PaymentDetails?.PaymentGateway : [], PaymentStatus: @@ -2280,13 +2290,13 @@ export default function BST1Payment() { : Paybtnnameselected?.toLowerCase() === 'credit' ? 'S' : Paybtnnameselected?.toLowerCase() === 'upi' && - SelectedUPIPayOption?.toLowerCase() === 'default' + SelectedUPIPayOption?.toLowerCase() === 'default' ? 'S' : 'P', Debit: salesBillEdit && - currentOrderNetAmount < previousNetAmount && - refundPaySelectedName?.toLowerCase() === 'credit' + currentOrderNetAmount < previousNetAmount && + refundPaySelectedName?.toLowerCase() === 'credit' ? Math.round(previousNetAmount - currentOrderNetAmount) : 0, Credit: salesBillEdit @@ -2362,14 +2372,14 @@ export default function BST1Payment() { setMessageType('success'); setMessageData( response?.data?.response + - ' ' + - (response?.data?.OrderDetails?.length > 0 - ? response?.data?.OrderId && - extractLastNumberOrderId( - response?.data?.OrderId, - response?.data?.OrderDetails?.[0]?.FYStatus - ) - : '') + ' ' + + (response?.data?.OrderDetails?.length > 0 + ? response?.data?.OrderId && + extractLastNumberOrderId( + response?.data?.OrderId, + response?.data?.OrderDetails?.[0]?.FYStatus + ) + : '') ); response?.data?.OrderDetails?.length > 0 && setPrintOrderDetails([response?.data]); @@ -2526,14 +2536,14 @@ export default function BST1Payment() { setMessageType('success'); setMessageData( response?.data?.response + - ' ' + - (response?.data?.OrderDetails?.length > 0 - ? response?.data?.OrderId && - extractLastNumberOrderId( - response?.data?.OrderId, - response?.data?.OrderDetails?.[0]?.FYStatus - ) - : '') + ' ' + + (response?.data?.OrderDetails?.length > 0 + ? response?.data?.OrderId && + extractLastNumberOrderId( + response?.data?.OrderId, + response?.data?.OrderDetails?.[0]?.FYStatus + ) + : '') ); response?.data?.OrderDetails?.length > 0 && setPrintOrderDetails([response?.data]); @@ -2634,14 +2644,14 @@ export default function BST1Payment() { } setMessageData( response?.data?.response + - ' ' + - (response?.data?.OrderDetails?.length > 0 - ? response?.data?.OrderId && - extractLastNumberOrderId( - response?.data?.OrderId, - response?.data?.OrderDetails?.[0]?.FYStatus - ) - : '') + ' ' + + (response?.data?.OrderDetails?.length > 0 + ? response?.data?.OrderId && + extractLastNumberOrderId( + response?.data?.OrderId, + response?.data?.OrderDetails?.[0]?.FYStatus + ) + : '') ); if (response?.data?.OrderDetails?.length > 0) { setPrintOrderDetails([response?.data]); @@ -2816,14 +2826,14 @@ export default function BST1Payment() { setMessageType('success'); setMessageData( bookingpaymentupdate?.data?.response + - ' ' + - (bookingpaymentupdate?.data?.OrderDetails?.length > 0 - ? bookingpaymentupdate?.data?.OrderId && - extractLastNumberOrderId( - bookingpaymentupdate?.data?.OrderId, - bookingpaymentupdate?.data?.OrderDetail?.[0]?.FYStatus - ) - : '') + ' ' + + (bookingpaymentupdate?.data?.OrderDetails?.length > 0 + ? bookingpaymentupdate?.data?.OrderId && + extractLastNumberOrderId( + bookingpaymentupdate?.data?.OrderId, + bookingpaymentupdate?.data?.OrderDetail?.[0]?.FYStatus + ) + : '') ); bookingpaymentupdate?.data?.OrderDetails?.length > 0 && setPrintOrderDetails([bookingpaymentupdate?.data]); @@ -2841,7 +2851,7 @@ export default function BST1Payment() { if ( Date.now() - startTime > useOptions?.[0]?.PDConfigDetails?.[0]?.AutoCancelDurationInMinutes * - 60000 + 60000 ) { // 60,000 ms = 1 minute @@ -3650,29 +3660,29 @@ export default function BST1Payment() { {tableOptions.find( (item) => item.OptionName === 'AddCustomer' ) && ( -
- +
+ - - {' '} - - -
- )} + + {' '} + + +
+ )}
@@ -3735,31 +3745,31 @@ export default function BST1Payment() { (BookingType === 'Dine In' || BookingTypeBoth || CheckOrderType?.length > 0) && - !unpaidFlow && - OrderStatus + !unpaidFlow && + OrderStatus ? 'none' : 'auto', opacity: (BookingType === 'Dine In' || BookingTypeBoth || CheckOrderType?.length > 0) && - !unpaidFlow && - OrderStatus + !unpaidFlow && + OrderStatus ? 0.5 : 1, }} > {paybtns?.length > 0 && - currentOrderNetAmount >= previousNetAmount ? ( + currentOrderNetAmount >= previousNetAmount ? ( paybtns?.map((payment) => (
)} {/* DragItem */} diff --git a/src/Pages/BookingScreen/Components/MainPage/MainPage.jsx b/src/Pages/BookingScreen/Components/MainPage/MainPage.jsx index 92a4d81..6bc3574 100644 --- a/src/Pages/BookingScreen/Components/MainPage/MainPage.jsx +++ b/src/Pages/BookingScreen/Components/MainPage/MainPage.jsx @@ -1,7 +1,11 @@ import { useEffect, useRef, useState } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { Button, Carousel, Skeleton } from 'antd'; -import { ArrowRightOutlined, LeftOutlined, RightOutlined } from '@ant-design/icons'; +import { + ArrowRightOutlined, + LeftOutlined, + RightOutlined, +} from '@ant-design/icons'; import SelectionComponent from './SelectionComponent'; import PreviewLayout1 from '../PreviewLayouts/PreviewLayout1'; import PreviewLayout2 from '../PreviewLayouts/PreviewLayout2'; @@ -10,19 +14,30 @@ import PreViewLayout4 from '../PreviewLayouts/PreViewLayout4'; import PreviewLayout5 from '../PreviewLayouts/PreviewLayout5'; import PreViewLayout6 from '../PreviewLayouts/PreViewLayout6'; import ComboLayout1 from '../PreviewLayouts/ComboLayout1'; -import { changeActiveTheme, changeOthersTheme, changeSelectedTheme, changeThemeCreation, getOthersTemplate, getPreviewData, getTemplate, GlobalActiveTheme, GlobalDefaultTheme, GlobalOthersTheme, GlobalSelectedTheme } from '../../../../Features/ThemeChange/ThemeChange'; +import { + changeActiveTheme, + changeOthersTheme, + changeSelectedTheme, + changeThemeCreation, + getOthersTemplate, + getPreviewData, + getTemplate, + GlobalActiveTheme, + GlobalDefaultTheme, + GlobalOthersTheme, + GlobalSelectedTheme, +} from '../../../../Features/ThemeChange/ThemeChange'; import '../../../../Styles/BookingScreen/Components/SelectionComponent/MainPage.scss'; import { HiOutlineSquares2X2, HiSquaresPlus } from 'react-icons/hi2'; import { getSession } from '../../../../Services/Others'; import Buttons from '../../../../Components/Forms/Buttons'; import { BiSkipNext, BiSkipPrevious } from 'react-icons/bi'; -import { MdOutlineDisplaySettings } from "react-icons/md"; +import { MdOutlineDisplaySettings } from 'react-icons/md'; import { useAuth } from '../../../../AuthContext'; import { getEmpAccess } from '../../../../Features/AppPage/CenterPage'; - const BookingSelectionPage = (props) => { - const { SadminuserAccess } = useAuth(); + const { SadminuserAccess } = useAuth(); let SAAccessCommonMaster = SadminuserAccess?.find( (e) => e?.MenuName === 'Sales Screen' ); @@ -39,16 +54,16 @@ const BookingSelectionPage = (props) => { // const [activeTheme, setActiveTheme] = useState( // 'default' // ); - const activeTheme = useSelector(GlobalActiveTheme) - const SelectedTheme = useSelector(GlobalSelectedTheme) + const activeTheme = useSelector(GlobalActiveTheme); + const SelectedTheme = useSelector(GlobalSelectedTheme); - const mergedThemes = DefaultThemes.concat(OthersTheme) + const mergedThemes = DefaultThemes.concat(OthersTheme); const [currentSlide, setCurrentSlide] = useState(0); - console.log(SelectedTheme, "currentSlide") + console.log(SelectedTheme, 'currentSlide'); const [OthersCount, setOthersCount] = useState(1); const [isNext, isSetNext] = useState(true); - const [empData, setEmpData] = useState(); - const [addnewAccess, setaddnewAccess] = useState(true); + const [empData, setEmpData] = useState(); + const [addnewAccess, setaddnewAccess] = useState(true); const rightIsLastSlide = currentSlide === mergedThemes.length - 1; const leftIsFirstSlide = currentSlide === 0 && OthersCount > 1; const [pendingSlide, setPendingSlide] = useState(null); @@ -68,50 +83,50 @@ const BookingSelectionPage = (props) => { : useSelector(getPreviewData); console.log(previewData, 'previewDatapreviewData'); useEffect(() => { - GetOthersTemplate() + GetOthersTemplate(); // gettemplatedetail() - }, []) - useEffect(() => { - if (UserType === 'Employee') { - fetchApi(); - } - }, [UserType]); - - useEffect(() => { - let hasAccess = false; - - if (UserType === 'Admin' || UserType === 'Super Admin') { - hasAccess = true; - } else if (UserType === 'Employee') { - hasAccess = empData?.AddAccess === 'Y'; - } else if (UserType === 'Super Admin User') { - hasAccess = SAAccessCommonMaster?.AddAccess === 'Y'; - } - - setaddnewAccess(!hasAccess); - }, [empData, SAAccessCommonMaster, UserType]); - - const fetchApi = async () => { - let data = { - CompId: CompId, - BranchId: BranchId, - AppId: AppId, - EmpId: UserId, - }; - let response = await dispatch(getEmpAccess(data)).unwrap(); - let datas = response?.data?.data?.[0]?.EmpAccessDetails?.filter( - (item) => item.ConfigName === 'Sales Screen' - ); - setEmpData(datas?.[0]); + }, []); + useEffect(() => { + if (UserType === 'Employee') { + fetchApi(); + } + }, [UserType]); + + useEffect(() => { + let hasAccess = false; + + if (UserType === 'Admin' || UserType === 'Super Admin') { + hasAccess = true; + } else if (UserType === 'Employee') { + hasAccess = empData?.AddAccess === 'Y'; + } else if (UserType === 'Super Admin User') { + hasAccess = SAAccessCommonMaster?.AddAccess === 'Y'; + } + + setaddnewAccess(!hasAccess); + }, [empData, SAAccessCommonMaster, UserType]); + + const fetchApi = async () => { + let data = { + CompId: CompId, + BranchId: BranchId, + AppId: AppId, + EmpId: UserId, }; - + let response = await dispatch(getEmpAccess(data)).unwrap(); + let datas = response?.data?.data?.[0]?.EmpAccessDetails?.filter( + (item) => item.ConfigName === 'Sales Screen' + ); + setEmpData(datas?.[0]); + }; + const gettemplatedetail = async () => { let tempdetail = await dispatch( getTemplate({ CompId: CompId, BranchId: BranchId, AppId: AppId }) ).unwrap(); if (tempdetail?.data?.statusCode == 1) { - dispatch(changeActiveTheme("customised")); + dispatch(changeActiveTheme('customised')); } }; @@ -149,7 +164,12 @@ const BookingSelectionPage = (props) => { setCurrentSlide(pendingSlide); let seltheme = updatedThemes[pendingSlide]; dispatch(changeThemeCreation({ formtype: 'edit', editdata: seltheme })); - dispatch(changeSelectedTheme({ ThemeId: seltheme?.TemplatePreferenceId, ThemeName: seltheme?.ThemeName })); + dispatch( + changeSelectedTheme({ + ThemeId: seltheme?.TemplatePreferenceId, + ThemeName: seltheme?.ThemeName, + }) + ); } setPendingSlide(null); // Reset } @@ -180,7 +200,7 @@ const BookingSelectionPage = (props) => { // // } // }; // const RightOnclick = async () => { - // // let Allthemes = + // // let Allthemes = // // alert('Right Clicked'); // const newIndex = (currentSlide + 1) % mergedThemes.length; // carouselRef.current.goTo(newIndex); @@ -205,7 +225,12 @@ const BookingSelectionPage = (props) => { setCurrentSlide(newIndex); let seltheme = mergedThemes[newIndex]; dispatch(changeThemeCreation({ formtype: 'edit', editdata: seltheme })); - dispatch(changeSelectedTheme({ ThemeId: seltheme?.TemplatePreferenceId, ThemeName: seltheme?.ThemeName })); + dispatch( + changeSelectedTheme({ + ThemeId: seltheme?.TemplatePreferenceId, + ThemeName: seltheme?.ThemeName, + }) + ); } }; @@ -214,12 +239,18 @@ const BookingSelectionPage = (props) => { await GetLessTemplate(); setPendingSlide(DefaultThemes.concat(OthersTheme).length - 1); // Ask to jump to last slide after fetch } else { - const newIndex = (currentSlide - 1 + mergedThemes.length) % mergedThemes.length; + const newIndex = + (currentSlide - 1 + mergedThemes.length) % mergedThemes.length; carouselRef.current.goTo(newIndex); setCurrentSlide(newIndex); let seltheme = mergedThemes[newIndex]; dispatch(changeThemeCreation({ formtype: 'edit', editdata: seltheme })); - dispatch(changeSelectedTheme({ ThemeId: seltheme?.TemplatePreferenceId, ThemeName: seltheme?.ThemeName })); + dispatch( + changeSelectedTheme({ + ThemeId: seltheme?.TemplatePreferenceId, + ThemeName: seltheme?.ThemeName, + }) + ); } }; const CustomisedthemeSelection = async (seltheme) => { @@ -236,16 +267,25 @@ const BookingSelectionPage = (props) => { } } else { if (Object.keys(DefaultThemes)?.length > 0) { - dispatch(changeSelectedTheme({ ThemeId: DefaultThemes?.[0]?.TemplatePreferenceId, ThemeName: DefaultThemes?.[0]?.ThemeName })); + dispatch( + changeSelectedTheme({ + ThemeId: DefaultThemes?.[0]?.TemplatePreferenceId, + ThemeName: DefaultThemes?.[0]?.ThemeName, + }) + ); // settemplateData(DefaultThemes?.[0]); - dispatch(changeThemeCreation({ formtype: 'edit', editdata: DefaultThemes?.[0] })); + dispatch( + changeThemeCreation({ + formtype: 'edit', + editdata: DefaultThemes?.[0], + }) + ); } else { dispatch(changeSelectedTheme({})); dispatch(changeThemeCreation({ formtype: 'new' })); - } } - } + }; const handlesubmit = () => { const PostData = {}; @@ -256,7 +296,7 @@ const BookingSelectionPage = (props) => { PostData['ColorId'] = colorFilteredArray; PostData['FontId'] = fontFilteredArray; PostData['CreatedBy'] = UserId; - } + }; const GetOthersTemplate = async () => { let OtherTemp = await dispatch( getOthersTemplate({ pagenumber: OthersCount }) @@ -266,7 +306,7 @@ const BookingSelectionPage = (props) => { ...temp, ThemeName: `Theme ${index + 1 + OthersCount * 10 - 10}`, })); - dispatch(changeOthersTheme(withname)) + dispatch(changeOthersTheme(withname)); } else { } }; @@ -288,8 +328,7 @@ const BookingSelectionPage = (props) => { ...temp, ThemeName: `Theme ${index + 1 + (tempcount - 1) * 10}`, })); - dispatch(changeOthersTheme(withname)) - + dispatch(changeOthersTheme(withname)); } else { setMessageType('warning'); setMessageData('No more templates'); @@ -306,22 +345,24 @@ const BookingSelectionPage = (props) => { ...temp, ThemeName: `Theme ${index + 1 + (tempcount - 1) * 10}`, })); - dispatch(changeOthersTheme(withname)) + dispatch(changeOthersTheme(withname)); isSetNext(true); } else { } }; const clearOtherTemplate = async () => { - dispatch(changeOthersTheme([])) + dispatch(changeOthersTheme([])); setOthersCount(1); }; return ( -
- +

-

Sales Setup

+

+ {' '} + Sales Setup +

Customize your sales screen here

@@ -338,29 +379,24 @@ const BookingSelectionPage = (props) => { > Customized Theme
-
- {activeTheme === 'default' && + {activeTheme === 'default' && (
} />
- } + )}
-
- {activeTheme === 'default' ? +
+ {activeTheme === 'default' ? ( <> -
- +
)} -
- : + ) : ( <>
- {Object.keys(previewData)?.length > 0 ? ( renderPreviewLayout() @@ -436,16 +470,14 @@ const BookingSelectionPage = (props) => { )}
-
+
- } + )}
-
); }; - export default BookingSelectionPage; diff --git a/src/Pages/BookingScreen/Components/PreviewLayouts/PreviewLayout1.jsx b/src/Pages/BookingScreen/Components/PreviewLayouts/PreviewLayout1.jsx index c4b0844..f29e98b 100644 --- a/src/Pages/BookingScreen/Components/PreviewLayouts/PreviewLayout1.jsx +++ b/src/Pages/BookingScreen/Components/PreviewLayouts/PreviewLayout1.jsx @@ -118,7 +118,7 @@ const PreviewLayout1 = (props) => { )} />{' '}
-
+
{Preview1Data?.BookingLayout?.[1] && Preview1Data?.BookingBilling?.[0] != 'Billing1' && Preview1Data?.BookingBilling?.[0] != 'Billing2' && diff --git a/src/Pages/BookingScreen/Components/UtillComponents/BSNavBarFavItems.jsx b/src/Pages/BookingScreen/Components/UtillComponents/BSNavBarFavItems.jsx index 66277f6..d8ecb74 100644 --- a/src/Pages/BookingScreen/Components/UtillComponents/BSNavBarFavItems.jsx +++ b/src/Pages/BookingScreen/Components/UtillComponents/BSNavBarFavItems.jsx @@ -26,9 +26,14 @@ import { SlArrowDown } from 'react-icons/sl'; import { IoCloseSharp } from 'react-icons/io5'; import TooltipWrapper from '../../../../Components/Tooltip/Tooltip'; import { isMobile } from 'react-device-detect'; -import "./BSNavBarFavItems.scss" +import './BSNavBarFavItems.scss'; -const BSNavBarFavItems = ({ type, fill, drawerOpen = false }) => { +const BSNavBarFavItems = ({ + type, + fill, + drawerOpen = false, + setNavmenu = () => {}, +}) => { const [open, setOpen] = useState(false); const [favopen, setFavopen] = useState(false); const globalAllItemdata = useSelector(GlobalAllItemData); diff --git a/src/Pages/BookingScreen/Components/UtillComponents/BSNavBarFavItems.scss b/src/Pages/BookingScreen/Components/UtillComponents/BSNavBarFavItems.scss index 1e99ba9..3e6de51 100644 --- a/src/Pages/BookingScreen/Components/UtillComponents/BSNavBarFavItems.scss +++ b/src/Pages/BookingScreen/Components/UtillComponents/BSNavBarFavItems.scss @@ -85,13 +85,13 @@ .AddFavList { position: fixed; left: 0; - top: 17rem; + top: 15rem; width: 100vw !important; padding: 1rem 1rem !important; } .AddFavItemListCont { - height: 34vh; + height: 30vh; overflow: auto; } @@ -104,7 +104,7 @@ .AddFavList { position: fixed; left: 0; - top: 17rem; + top: 15rem; width: 100vw !important; padding: 1rem 1rem !important; } diff --git a/src/Pages/BookingScreen/Components/UtillComponents/PaymentGatewayEmbedded.jsx b/src/Pages/BookingScreen/Components/UtillComponents/PaymentGatewayEmbedded.jsx index a72f095..a8ec70a 100644 --- a/src/Pages/BookingScreen/Components/UtillComponents/PaymentGatewayEmbedded.jsx +++ b/src/Pages/BookingScreen/Components/UtillComponents/PaymentGatewayEmbedded.jsx @@ -1,6 +1,6 @@ import { useEffect, useRef, useState, useImperativeHandle, forwardRef } from 'react'; import { useDispatch } from 'react-redux'; -import { getPaymentStatusForBusinessUPI } from '../../../../Features/BookingScreen/BookingData/BookingData'; +import { getPaymentStatusForBusinessUPI, PostCancelPayment } from '../../../../Features/BookingScreen/BookingData/BookingData'; const PaymentGatewayEmbedded = forwardRef(({ orderId, @@ -65,6 +65,7 @@ const PaymentGatewayEmbedded = forwardRef(({ if (data.status === 'TIMEOUT') { // Stop polling and mark as timed out + dispatch(PostCancelPayment({OrderId: orderId})).unwrap() setTimedOut(true); setShowTimeout(true); if (intervalRef.current) { diff --git a/src/Pages/BookingScreen/LayoutSubCategoryFetcher.jsx b/src/Pages/BookingScreen/LayoutSubCategoryFetcher.jsx index ca47f77..7369e40 100644 --- a/src/Pages/BookingScreen/LayoutSubCategoryFetcher.jsx +++ b/src/Pages/BookingScreen/LayoutSubCategoryFetcher.jsx @@ -1,7 +1,9 @@ import { useEffect } from 'react'; import { useSelector, useDispatch, shallowEqual } from 'react-redux'; import { + ChangeSubcategoryData, getLayoutSubCategories, + GlobalisFavClicked, GlobalProductCategorie, } from '../../Features/BookingScreen/BookingData/BookingData'; import { getTemplateData } from '../../Features/ThemeChange/ThemeChange'; @@ -12,6 +14,7 @@ const LayoutSubCategoryFetcher = () => { const ProdCat = useSelector(GlobalProductCategorie, shallowEqual); const templateData = useSelector(getTemplateData, shallowEqual); + const favSelected = useSelector(GlobalisFavClicked); const CompId = getSession('CompId'); const BranchId = getSession('BranchId'); @@ -23,6 +26,11 @@ const LayoutSubCategoryFetcher = () => { const isCategory5 = templateData?.BookingCategory?.[0] === 'Category5'; const isLayout2 = templateData?.BookingLayout?.[0] === 'Layout2'; + if (favSelected) { + dispatch(ChangeSubcategoryData([])); + return + } + if (isCategory5 && isLayout2) { dispatch( getLayoutSubCategories({ @@ -37,6 +45,7 @@ const LayoutSubCategoryFetcher = () => { ProdCat, templateData?.BookingCategory?.[0], templateData?.BookingLayout?.[0], + favSelected ]); return null; // this component renders nothing diff --git a/src/Pages/BookingScreen/Template/BSLayout4/BSLayout4.jsx b/src/Pages/BookingScreen/Template/BSLayout4/BSLayout4.jsx index f43e5fc..2cb1cb5 100644 --- a/src/Pages/BookingScreen/Template/BSLayout4/BSLayout4.jsx +++ b/src/Pages/BookingScreen/Template/BSLayout4/BSLayout4.jsx @@ -5,22 +5,20 @@ import { Tooltip, Badge, Popconfirm } from 'antd'; import { isMobile } from 'react-device-detect'; import BookingCloseIcon from '../../Components/UtillComponents/BookingCloseIcon.jsx'; const BSNavbar1 = lazy(() => import('../../Components/BSNavbar/BSNavbar1')); - const CategoryHorizontal = lazy( +const CategoryHorizontal = lazy( () => import('../../Components/BSCategories/BSCategoryHorizontal') ); const BSItemCard = lazy( () => import('../../Components/BSItemCards/BSItemCard') ); - + const BSBillingTable2 = lazy( () => import('../../Components/BSBillingTables/BSBillingTable2/BSBillingTable2') ); -const BSBillingTable3 = lazy( - () => - import('../../Components/BSBillingTables/BSBillingTable3/BSBillingTable3overall') -); - + +import BSBillingTable3 from '../../Components/BSBillingTables/BSBillingTable3/BSBillingTable3overall'; + import { dynamicComponentProps } from '../DynamicComponentProps.js'; import { getTemplateData, @@ -95,16 +93,10 @@ const BSOtherServicesVerticalcat = lazy( () => import('../../Components/BSCategories/BSOtherServicesVerticalcat.jsx') ); - const SalesCountForStandard = lazy( () => import('../SalesCountForStandard.jsx') ); -const StandardTable = lazy( - () => - import('../../Components/BSBillingTables/StandardTable/StandardTable.jsx') -); - const ComboSalesBillTable = lazy( () => import('../../Components/BSBillingTables/ComboSalesBillTable/ComboSalesBillTable.jsx') diff --git a/src/Pages/CancelReschedule/SalesBillProductsReturn.jsx b/src/Pages/CancelReschedule/SalesBillProductsReturn.jsx index 7d450b4..86304cc 100644 --- a/src/Pages/CancelReschedule/SalesBillProductsReturn.jsx +++ b/src/Pages/CancelReschedule/SalesBillProductsReturn.jsx @@ -17,6 +17,7 @@ import { DatePicProd } from "../../Components/Forms/DatePickerProduct"; import { useNavigate } from "react-router-dom"; import { FaEye, FaPlus } from "react-icons/fa"; import { DefaultModal } from "../../Components/Modal/DefaultModal"; +import { IoEye } from "react-icons/io5"; const { RangePicker } = DatePicker; const SEARCH_OPTIONS = [ @@ -70,6 +71,8 @@ const SalesBillProductsReturn = () => { const [currentEditingItem, setCurrentEditingItem] = useState(null); const [modalDescription, setModalDescription] = useState(''); const [modalImageUrl, setModalImageUrl] = useState(''); + const [policyDeatilModal, setPolicyDeatilModal] = useState(false); + const [selectedPolicyDetails, setSelectedPolicyDetails] = useState(null); console.log(selectedItems, "selectedItemsselectedItemsselectedItems") @@ -77,7 +80,7 @@ const SalesBillProductsReturn = () => { navigateTo(`${subDirectory}setting/sales-bill-product-return/list`); }; const handleCheckboxChange = (item, checked) => { - const { ProdId, InwardDtlId, Type, SalesQty, Rate, TotalAmt, TaxAmt, SinglePc, ProdNameQty,IsWarrantyEligible } = item; + const { ProdId, InwardDtlId, Type, SalesQty, Rate, TotalAmt, TaxAmt, SinglePc, ProdNameQty, IsWarrantyEligible } = item; if (checked) { const data = { ProdId, @@ -108,7 +111,15 @@ const SalesBillProductsReturn = () => { const description = product?.Description || "" return { ReturnEligible: eligible, Description: description }; }; - + const handleOrdermodalCancel = () => { + setPolicyDeatilModal(false); + setSelectedPolicyDetails(null); + }; + const Viewdetails = (item) => { + const policy = policybasedprodcuts?.find(p => p.ProdId === item.ProdId) || null; + setSelectedPolicyDetails(policy); + setPolicyDeatilModal(true); + }; useEffect(() => { const fetchPaymentOptions = async () => { try { @@ -192,12 +203,11 @@ const SalesBillProductsReturn = () => { try { const res = await dispatch(getReturnBill(data)).unwrap(); - if (res?.data?.statusCode === 1) { const modifiedData = res?.data?.data?.map(item => { return { ...item, - productDetails: item?.productDetails.map(product => { + productDetails: item?.productDetails?.map(product => { return { ...product, ExchangeQty: 0, @@ -577,8 +587,9 @@ const SalesBillProductsReturn = () => { - + + @@ -597,17 +608,23 @@ const SalesBillProductsReturn = () => { disabled={!ReturnEligible} onChange={(e) => handleCheckboxChange(item, e.target.checked)} /> - {!ReturnEligible && ( + {/* {( - {/* */} - - {/* */} + Viewdetails(item)} + /> - )} + )} */} + @@ -634,11 +651,11 @@ const SalesBillProductsReturn = () => { - + {/* */} - {selectedItems.map((item, index) => { + {selectedItems?.map((item, index) => { return ( @@ -706,7 +723,7 @@ const SalesBillProductsReturn = () => { - + */} ); })} @@ -816,6 +833,43 @@ const SalesBillProductsReturn = () => { handleCancel={handleCancel} handleSubmit={handleModalSubmit} /> + + + {selectedPolicyDetails ? ( +
Select Sl.NoPolicy Details Product Name Sales-Qty Rate {index + 1} + Viewdetails(item)} + /> {item.ProdNameQty} {item.SalesQty} ₹{item.Rate}Sales-Qty Return-Qty MoreDetailsDetails
{index + 1} + {/* {item.description && (
{
🖼️
)} -
+ + {[ + ['Product Name', selectedPolicyDetails.ProdName], + ['Policy Name', selectedPolicyDetails.PolicyName], + ['Description', selectedPolicyDetails.Description], + ['Return Allowed', selectedPolicyDetails.IsReturnAllowed === 'Y' ? 'Yes' : 'No'], + ['Exchange Allowed', selectedPolicyDetails.IsExchangeAllowed === 'Y' ? 'Yes' : 'No'], + ['Return Window (Days)', selectedPolicyDetails.ReturnWindowDays], + ['Exchange Window (Days)', selectedPolicyDetails.ExchangeWindowDays], + ['Exchange Limit Count', selectedPolicyDetails.ExchangeLimitCount ?? 'N/A'], + ['Return Eligible', selectedPolicyDetails.ReturnEligible ? 'Yes' : 'No'], + // ['Effective From', selectedPolicyDetails.EffectiveFrom ? dayjs(selectedPolicyDetails.EffectiveFrom).format('DD-MM-YYYY') : 'N/A'], + // ['Effective To', selectedPolicyDetails.EffectiveTo ? dayjs(selectedPolicyDetails.EffectiveTo).format('DD-MM-YYYY') : 'N/A'], + ].map(([label, value]) => ( + + + + + ))} + +
{label}{value}
+ ) : ( +

No policy found for this product.

+ )} +
+ } + />
diff --git a/src/Pages/CustomerMaster/CustMasterList.jsx b/src/Pages/CustomerMaster/CustMasterList.jsx index cade722..b11113f 100644 --- a/src/Pages/CustomerMaster/CustMasterList.jsx +++ b/src/Pages/CustomerMaster/CustMasterList.jsx @@ -25,8 +25,7 @@ import { Messages } from '../../Components/Notifications/Messages'; import { DefaultModal } from '../../Components/Modal/DefaultModal.jsx'; import { useAuth } from '../../AuthContext.jsx'; import { getPreferenceData } from '../../Features/BookingScreen/BookingData/BookingData.js'; - -const subDirectory = import.meta.env.BASE_URL; +const subDirectory = import.meta.env.ENV_BASE_URL; const items = [ { @@ -71,7 +70,6 @@ const CustomerMaster = () => { const [addnewAccess, setaddnewAccess] = useState(true); const [allowDecimal, setAllowDecimal] = useState(false); - async function fetchData() { if (location?.state?.Notiffy) { setMessageType(location?.state?.Notiffy.messageType); @@ -155,13 +153,22 @@ const CustomerMaster = () => { } }; const getPreference = async () => { - const data = { AppId: AppId, CompId: CompId, BranchId: BranchId, UserId: UserId }; - const { data: res } = await dispatch(getPreferenceData(data)).unwrap() - const decimalSetting = res?.data?.[0]?.SettingDtlDetails?.find((setting) => setting?.SettingIdName?.toLowerCase() === "decimal" && setting?.SettingValue === 'Y'); + const data = { + AppId: AppId, + CompId: CompId, + BranchId: BranchId, + UserId: UserId, + }; + const { data: res } = await dispatch(getPreferenceData(data)).unwrap(); + const decimalSetting = res?.data?.[0]?.SettingDtlDetails?.find( + (setting) => + setting?.SettingIdName?.toLowerCase() === 'decimal' && + setting?.SettingValue === 'Y' + ); if (decimalSetting) { - setAllowDecimal(true) + setAllowDecimal(true); } - } + }; //Delete const statusFormatter = async (row) => { @@ -251,7 +258,8 @@ const CustomerMaster = () => { width: '100px', render: (text, row) => ( - {(row?.CustName ? (row?.CustName + ' ') : '') + (row?.CustShortName || "") || row?.CustMobile} + {(row?.CustName ? row?.CustName + ' ' : '') + + (row?.CustShortName || '') || row?.CustMobile} ), filteredValue: [searchedText], @@ -260,8 +268,12 @@ const CustomerMaster = () => { String(record.CustShortName) ?.toLowerCase() ?.includes(value?.toLowerCase()) || - String(record.CustName)?.toLowerCase()?.includes(value?.toLowerCase()) || - String(record.CustMobile)?.toLowerCase()?.includes(value?.toLowerCase()) + String(record.CustName) + ?.toLowerCase() + ?.includes(value?.toLowerCase()) || + String(record.CustMobile) + ?.toLowerCase() + ?.includes(value?.toLowerCase()) ); }, sorter: (a, b) => a?.CustName?.length - b?.CustName?.length, diff --git a/src/Pages/DashBoard/RetailDashboard.jsx b/src/Pages/DashBoard/RetailDashboard.jsx index 8b52761..f42080e 100644 --- a/src/Pages/DashBoard/RetailDashboard.jsx +++ b/src/Pages/DashBoard/RetailDashboard.jsx @@ -1775,11 +1775,6 @@ const RetailDashboard = () => { UserType === 'Super Admin' || UserType === 'Super Admin User' ) { - if (!document.fullscreenElement) { - document.documentElement.requestFullscreen().catch((err) => { - console.error('Error attempting to enable fullscreen:', err); - }); - } navigate(`${subDirectory}sales`); } }} diff --git a/src/Pages/Kiosk/Components/SelfBookingFooter.jsx b/src/Pages/Kiosk/Components/SelfBookingFooter.jsx index b67754e..2e924ef 100644 --- a/src/Pages/Kiosk/Components/SelfBookingFooter.jsx +++ b/src/Pages/Kiosk/Components/SelfBookingFooter.jsx @@ -1,5 +1,5 @@ import React, { useCallback, useEffect, useState } from 'react'; -import { Popconfirm, Drawer, Badge } from 'antd'; +import { Popconfirm, Drawer, Badge, Modal } from 'antd'; import { QuestionCircleOutlined } from '@ant-design/icons'; import { useDispatch, useSelector } from 'react-redux'; import { IoIosArrowForward } from 'react-icons/io'; @@ -43,7 +43,7 @@ import KioskPayment from '../Payment/KioskPaymentWithModal'; import { ApplicationPreferences } from '../../../Features/BrachLogin/BranchLogin'; import { FaAngleUp, FaCircleCheck } from 'react-icons/fa6'; import { FaAngleDown } from 'react-icons/fa'; -import { PostBookingData } from '../../../Features/BookingScreen/BookingData/BookingData'; +import { PostBookingData, PostCancelPayment } from '../../../Features/BookingScreen/BookingData/BookingData'; import { generateRandomKey, getSession, @@ -129,6 +129,7 @@ const selfKioskFooter = (props) => { const [chairInformation, setChairInformation] = useState(); const [TableINformation, setTableINformation] = useState(); const [paymentUrl, setpaymentUrl] = useState(null); + const [showCancelConfirm, setShowCancelConfirm] = useState(null); const [TransctionId, setTransctionId] = useState(null); const [paymentGatewayAccess, setPaymentGatewayAccess] = useState([]); // let chairInformation = getSession('table'); @@ -939,6 +940,15 @@ const selfKioskFooter = (props) => { setMessageType(null); }, []); + // PostCancelPayment + const CancelPayment = async () => { + const response = await dispatch(PostCancelPayment({OrderId: TransctionId})).unwrap() + if (response?.data?.statusCode) { + // setBusinessUPI(false); + setpaymentUrl(null) + } + } + return (
{
)} + {showCancelConfirm && ( + { + setShowCancelConfirm(false); + CancelPayment() + }} + onCancel={() => setShowCancelConfirm(false)} + okText="Yes" + cancelText="No" + > + Do you want to cancel the payment? + + )} ); }; diff --git a/src/Pages/Kiosk/Payment/KioskPaymentWithModal.jsx b/src/Pages/Kiosk/Payment/KioskPaymentWithModal.jsx index 3b6747c..7a40db2 100644 --- a/src/Pages/Kiosk/Payment/KioskPaymentWithModal.jsx +++ b/src/Pages/Kiosk/Payment/KioskPaymentWithModal.jsx @@ -61,6 +61,7 @@ import { import { getConfigType, getPreferenceData, + PostCancelPayment, PreferenceData, PutPendingPaymentList, } from '../../../Features/BookingScreen/BookingData/BookingData'; @@ -1092,6 +1093,15 @@ const KioskPayment = (props) => { }, 2000); } }; + // PostCancelPayment + const CancelPayment = async () => { + const response = await dispatch(PostCancelPayment({OrderId: businessUPIOrderId})).unwrap() + if (response?.data?.statusCode) { + ClearAllGlobalStateDatas(); + CustomerDisplay(); + setBusinessUPI(false); + } + } const handleDevice = async (paymentDetails, option) => { const paymentDeviceDetails = await dispatch( @@ -2342,6 +2352,7 @@ const KioskPayment = (props) => { handleCancel={() => setShowCancelConfirm(true)} footer={false} width={500} + destroyOnClose={true} children={ <> { } /> {showCancelConfirm && ( - { - paymentGatewayRef.current?.clearPolling(); - setBusinessUPI(false); - setShowCancelConfirm(false); - ClearAllGlobalStateDatas(); - }} - onCancel={() => setShowCancelConfirm(false)} - okText="Yes" - cancelText="No" - > - Do you want to cancel the payment? - + // { + // paymentGatewayRef.current?.clearPolling(); + // setBusinessUPI(false); + // setShowCancelConfirm(false); + // ClearAllGlobalStateDatas(); + // }} + // onCancel={() => setShowCancelConfirm(false)} + // okText="Yes" + // cancelText="No" + // > + // Do you want to cancel the payment? + // + { + setShowCancelConfirm(false); + CancelPayment() + }} + onCancel={() => setShowCancelConfirm(false)} + okText="Yes" + cancelText="No" + > + Do you want to cancel the payment? + )} ); diff --git a/src/Pages/OtherServices/OtherServicesForm.jsx b/src/Pages/OtherServices/OtherServicesForm.jsx index d6b4493..bd32f2f 100644 --- a/src/Pages/OtherServices/OtherServicesForm.jsx +++ b/src/Pages/OtherServices/OtherServicesForm.jsx @@ -49,7 +49,7 @@ const OtherServices = ({ formType }) => { const AppId = getSession('AppId'); const UserId = getSession('UserId'); - console.log(SelectedCategory, 'SelectedCategory'); + console.log(TaxData, 'TaxData'); const items = [ { name: 'Home', @@ -435,8 +435,8 @@ const OtherServices = ({ formType }) => { ({ - value: option.TaxId, - label: option.TaxIdName, + value: option?.TaxId, + label: `${option?.TaxIdName} - ${option?.TaxPercentage}%`, })), ]} label="Tax" diff --git a/src/Pages/Product/ExcelUpload.jsx b/src/Pages/Product/ExcelUpload.jsx index bf78ecc..10ef5e9 100644 --- a/src/Pages/Product/ExcelUpload.jsx +++ b/src/Pages/Product/ExcelUpload.jsx @@ -1,24 +1,22 @@ import React, { useState, useRef, useEffect, useContext } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -// import { read, utils } from 'xlsx'; 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'; import { CiExport } from 'react-icons/ci'; import { uploadImage } from '../../Features/upload/upload.js'; @@ -32,9 +30,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'; @@ -46,499 +44,515 @@ 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', - }, - { - productName: 'Paneer Butter Masala', - quantity: 1, - uom: 'PLT', - salesPrice: 200, - category: 'Vegetarian', - subCategory: 'North 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', }, - 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', - }, - ], + { + productName: 'Paneer Butter Masala', + quantity: 1, + uom: 'PLT', + salesPrice: 200, + category: 'Vegetarian', + subCategory: 'North Indian', }, - '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', - }, - ], + ], + }, + 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', }, - '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', - }, - ], + { + productName: 'Whole Wheat Bread', + quantity: 1, + uom: 'LOAF', + salesPrice: 35, + category: 'Breads', + subCategory: 'Wheat Breads', }, - 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', - }, - ], + ], + }, + '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', }, - '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', - }, - ], + { + productName: 'Extension Board 4 Socket', + quantity: 1, + uom: 'PCS', + salesPrice: 350, + category: 'Electrical Accessories', + subCategory: 'Power Strips', }, - 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', - }, - ], + ], + }, + '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', }, - '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', - }, - ], + { + productName: 'Wireless Earbuds', + quantity: 1, + uom: 'PAIR', + salesPrice: 1599, + category: 'Audio', + subCategory: 'Bluetooth Earphones', }, - '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', - }, - ], + ], + }, + 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', }, - 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', - }, - ], + { + productName: 'Refined Oil', + quantity: 1, + uom: 'LITER', + salesPrice: 110, + category: 'Cooking Oil', + subCategory: 'Sunflower Oil', }, - 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', - }, - ], + ], + }, + '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', }, - 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', - }, - ], + { + productName: 'Laundry Detergent', + quantity: 1, + uom: 'KG', + salesPrice: 85, + category: 'Household', + subCategory: 'Washing Powder', }, - 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', - }, - ], + ], + }, + 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', }, - 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', - }, - ], + { + productName: 'Diamond Pendant', + quantity: 1, + uom: 'PCS', + salesPrice: 15000, + category: 'Diamond Jewellery', + subCategory: 'Pendants', }, - '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', - }, - ], + ], + }, + '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', + }, + ], + }, + '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, @@ -553,3180 +567,3014 @@ const ProductExcel = ({ SuplierNames, CategoryName1, Catconfigid, -}) => { - 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 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'); - setDatas(ExecelToJsConvertion); - // setExcelData(ExecelToJsConvertion); - // setOriginalUploadedRawData(ExecelToJsConvertion); - const style = document.createElement('style'); - style.type = 'text/css'; - style.innerHTML = ` + useEffect(() => { + if (excelData && excelData?.length > 0) { + let ExecelToJsConvertion = []; + let slicedData = excelData?.slice(1); + let filteredData = slicedData?.filter((item) => { + const values = Object.values(item || {}); + const lastVal = values[values.length - 1]; + return typeof lastVal === 'string' + ? lastVal.trim() !== 'sample row' + : true; + }); + 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 = ` .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; + return () => { + document.head.removeChild(style); + }; } - const FIELD_ALIAS = { - 'Product Variant Name': 'Product Varient Name', + }, [excelData]); + + useEffect(() => { + const fetchData = async () => { + if (AppId) { + const response = await dispatch( + getApplicationDetails({ AppId }) + )?.unwrap(); + setAppName(response?.data?.data?.[0]?.AppName); + } }; + fetchData(); + }, [AppId]); - const uploadAndProcessExcel = (file) => { - const reader = new FileReader(); + useEffect(() => { + // Call handleSubmit when Datas is updated + if (Datas) { + handleSubmit(Datas); + } + }, [Datas, handleSubmit]); - reader.onload = async (e) => { - const buffer = e.target.result; + // 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; - const workbook = new ExcelJS.Workbook(); - await workbook.xlsx.load(buffer); + // ✅ Process mandatory fields (retain value even if unmapped) + mandatoryFields.forEach((field) => { + const mappedHeader = fieldMapping[field]; - 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) + 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, '') ); - 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}`; + if (fallbackHeader && row[fallbackHeader] !== undefined) { + newRow[field] = row[fallbackHeader]; + } else { + // Preserve existing value if present + newRow[field] = ExcelData?.[index]?.[field] ?? ''; } + } + }); - 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; - }); + // ✅ Process non-mandatory mapped fields + Object.entries(fieldMapping).forEach(([field, header]) => { + if (!mandatoryFields.includes(field)) { + newRow[field] = headers.includes(header) ? (row[header] ?? '') : ''; + } + }); - if (jsonData.length > 0) { - const extractedHeaders = Object.keys(formattedData[0] || {}); + // ✅ 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); - const filteredData = formattedData.filter( - (item) => !Object.values(item)?.includes('sample row') - ); + if (!isMapped && !(header in newRow)) { + newRow[header] = isMandatory ? (row[header] ?? '') : ''; + } + }); + return newRow; + }); - 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, - })); + setExcelData(updatedMappedData); + setDatas(updatedMappedData); + } + }, [fieldMapping, UploadedRawData, headers]); - const modifiedProducts = findModifiedProducts(OrginalData, updatedData); - const modifiedIds = new Set(modifiedProducts.map((p) => p.ProdId)); - const originalIds = new Set(OrginalData?.map((p) => p.ProdId) || []); + useEffect(() => { + if (AppId && BranchId && CompId) { + handleExportBulkdata(); + } + }, [AppId, BranchId, CompId]); - const markedData = updatedData - .map((item) => ({ - ...item, - isModified: - modifiedIds.has(item.ProdId) || !originalIds.has(item.ProdId), - })) - .sort((a, b) => b.isModified - a.isModified); + useEffect(() => { + getFieldSetup(); + }, [productBulkUploadCatId]); - setUploadedRawData(markedData); + 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); + } + }; - setHeaders(extractedHeaders); - autoMapFields(extractedHeaders); + const handleFileUpload = (e) => { + const file = e.target.files[0]; + const reader = new FileReader(); - dispatch(uploadExcel({ file, jsonData: nonEmptyRows })); + 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()); + } + }; - setWorksheet(worksheet); - setDatas([]); - setExcelData([]); - } + 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 ''; + } - // ⚠️ keep your original flow (no break) - dispatch(uploadExcel({ file, jsonData: nonEmptyRows })); - setWorksheet(worksheet); - setWorksheet1(worksheet1); - setDatas(formattedData); - }; + // Y / N flags + if (value === 'Y') return true; + if (value === 'N') return false; - reader.readAsArrayBuffer(file); - }; + // Numbers (handles "150", 150, "0") + if ( + typeof value === 'number' || + (typeof value === 'string' && + value.trim() !== '' && + !Number.isNaN(Number(value))) + ) { + return Number(value); + } - // const uploadAndProcessExcel = (file) => { - // const reader = new FileReader(); + // 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 []; - // reader.onload = (e) => { - // const data = new Uint8Array(e.target.result); + const originalHashMap = new Map(); - // const workbook = read(data, { type: 'array' }); - // const worksheet = workbook.Sheets[workbook.SheetNames[0]]; + for (const product of originalData) { + if (!product.ProdId) continue; + originalHashMap.set(product.ProdId, hashProduct(product)); + } - // const jsonData = utils.sheet_to_json(worksheet, { - // header: 1, - // raw: false, - // dateNF: 'DD/MM/YY', - // }); + // Step 2: Compare updated products + const modifiedProducts = []; - // const nonEmptyRows = jsonData.filter((row) => - // row.some((cell) => cell !== '') - // ); + for (const product of updatedData) { + if (!product.ProdId) continue; - // const header = nonEmptyRows[0]; - // const rows = nonEmptyRows.slice(1); + const originalHash = originalHashMap.get(product.ProdId); + if (!originalHash) continue; // new product, not modified - // const dateFields = [ - // 'Available From', - // 'Available To', - // 'Manufacture Date', - // 'Expire Date', - // 'Stock Date', - // ]; + const updatedHash = hashProduct(product); - // 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}`; - // } + if (originalHash !== updatedHash) { + modifiedProducts.push(product); + } + } - // 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 modifiedProducts; + } + const FIELD_ALIAS = { + 'Product Variant Name': 'Product Varient Name', + }; - // return rowData; - // }); + const uploadAndProcessExcel = (file) => { + const reader = new FileReader(); - // if (jsonData.length > 0) { - // const extractedHeaders = Object.keys(formattedData[0]); + reader.onload = async (e) => { + const buffer = e.target.result; - // const filteredData = formattedData.filter( - // (item) => !Object.values(item)?.includes('sample row') - // ); + const workbook = new ExcelJS.Workbook(); + await workbook.xlsx.load(buffer); - // // ✅ 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, - // })); + const worksheet = workbook.worksheets[0]; - // // Detect modified products + // 🔥 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 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'); + const nonEmptyRows = jsonData.filter((row) => + row.some((cell) => cell !== '' && cell !== null && cell !== undefined) + ); - // // ✅ Set only once with final data - // setHeaders(extractedHeaders); + const header = nonEmptyRows[0]; + const rows = nonEmptyRows.slice(1); - // 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', + const dateFields = [ 'Available From', 'Available To', - ]; + 'Manufacture Date', + 'Expire Date', + 'Stock Date', + ]; - const sortPreferredFields = (fields) => { - const fieldMap = {}; - fields.forEach((field) => { - fieldMap[field.ConfigName] = field; - }); + function convertToDisplayFormat(dateString) { + if (!dateString) return ''; - const sorted = []; + const date = new Date(dateString); + if (isNaN(date)) return dateString; - fieldOrder.forEach((name) => { - if (fieldMap[name] && fieldMap[name].Access === 'Y') { - sorted.push(fieldMap[name]); - } - }); + 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}`; + } - return sorted; + 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); }; - // Usage inside your Fielddatas - const Fielddatas = async () => { - const res = await dispatch(getCommonAppPreference(AppId)).unwrap(); + reader.readAsArrayBuffer(file); + }; - const productbulkUploadCatId = - res?.data?.data?.[0]?.PreferenceDetails?.find( - (p) => p?.PreferredCatName?.toLowerCase() === 'product bulk upload' - )?.PreferredCatId; + useEffect(() => { + imagecall(); + addOnlineImage(); + Fielddatas(); + }, []); - const response = await dispatch( - getFieldSetupData({ - AppId, - CompId, - BranchId, - categoryId: productbulkUploadCatId, - Type: 'EB', - }) - ).unwrap(); + const imagecall = async (ProdName) => { + if (selectedProductName !== null) { + let response = await dispatch(onlineimages(ProdName)).unwrap(); + setimagedata(response?.data?.data); + } + }; - const productBulkUploadFields = response?.data?.data?.[0]?.ConfigDtl || []; - const sortedFields = sortPreferredFields(productBulkUploadFields); + const addOnlineImage = (item, index) => { + item?.ProductName && setimageOpen(true); + imagecall(item?.ProductName); + setSelectedProductName(item?.ProductName); + setSelectedImageIndex(index); + }; - setFieldValues(sortedFields); + 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' }, }; - const handleDownload = async () => { - const workbook = new ExcelJS.Workbook(); - const worksheet = workbook.addWorksheet('Sheet1'); - const worksheet1 = workbook.addWorksheet('Sheet2'); + // 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', + }, - const headerStyle = { - font: { bold: true }, - border: { - top: { style: 'thin' }, - left: { style: 'thin' }, - bottom: { style: 'thin' }, - right: { style: 'thin' }, - }, - alignment: { horizontal: 'center', vertical: 'middle' }, - }; + 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, + }, + }; - // 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', - }, + 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; + } - 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, - }, - }; + const mandatoryFields = ['ProdName', 'Size', 'UOM', 'SellPrice', 'ProdCat']; - 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 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); } - const mandatoryFields = ['ProdName', 'Size', 'UOM', 'SellPrice', 'ProdCat']; + // 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); + } + } + } + }); - 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', + // 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; + } + } + }); + + // 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, }; + } + } - // 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', - }; + // 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 }; + } - // Step 1: Sort preferred fields - const sortedPreferredFields = sortPreferredFields(FieldValues); // Your existing sort function + // 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, + }); - // Step 2: Convert API names to internal keys while skipping dependent fields initially - const preferredFieldKeys = []; - const preferredFieldSet = new Set(); + // 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' } }, + }, + }, + ]; - sortedPreferredFields.forEach((field) => { - const fieldName = field.ConfigName; - const status = field.Access; + // Add data to Sheet2 + for (let i = 1; i <= 100; i++) { + worksheet1.addRow({ + CategoryId: '', + Category: '', + SDPC: '', + SubcayID: '', + SubCategory: '', + SubcatnumfId: '', + BrandId: '', + Brandname: '', + BrandnumfId: '', + Branddetails: '', + }); + } - // Skip dependent fields for now - if (Object.values(dependentFieldMap).includes(fieldName)) return; + // All the original dropdown and validation logic for Sheet2 + const dropdownOptions = { + Option1: ['Yes', 'No'], + Option2: ['Product'], + Option3: ['ValueX', 'ValueY', 'ValueZ'], + }; - if (status === 'Y') { - const internalKey = apiToInternalFieldMap[fieldName]; - if (internalKey) { - preferredFieldKeys.push(internalKey); - preferredFieldSet.add(fieldName); - } + const selectedOptionA = 'Option1'; + const selectedOptionB = 'Option2'; - // 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); - } - } - } - }); + // 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] : ''; + }); + } - // Step 3: Merge Mandatory + Preferred (no duplicates) - const finalFieldKeys = [ - ...mandatoryFields, - ...preferredFieldKeys.filter((key) => !mandatoryFields.includes(key)), - ]; + const BrandDataMap = {}; + if (typeof AllBrandId !== 'undefined') { + AllBrandId.forEach((AllBrandId, index) => { + BrandDataMap[AllBrandId] = + typeof SubCatData !== 'undefined' ? SubCatData[index] : ''; + }); + } - // 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); + // 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; - 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 }, - }, + cell.dataValidation = { + type: 'list', + allowBlank: true, + formulae: [dynamicValidValues], }; + } }); + } - // 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; - } + 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], + }; + } }); + } - // 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 = '@'; - } - } + 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], + }; + } }); + } - // Add validation to columns + 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; - 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; - } - } + cell.dataValidation = { + type: 'list', + allowBlank: true, + formulae: [dynamicValidValues], + }; + } }); + } - // // 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 }; - // }); - // } + 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; - // // 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, + cell.dataValidation = { + type: 'list', + allowBlank: true, + formulae: [dynamicValidValues], + }; + } }); + } - // 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' } }, - }, - }, - ]; + 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; - // Add data to Sheet2 - for (let i = 1; i <= 100; i++) { - worksheet1.addRow({ - CategoryId: '', - Category: '', - SDPC: '', - SubcayID: '', - SubCategory: '', - SubcatnumfId: '', - BrandId: '', - Brandname: '', - BrandnumfId: '', - Branddetails: '', - }); - } + cell.dataValidation = { + type: 'list', + allowBlank: true, + formulae: [dynamicValidValues], + }; + } + }); + } - // All the original dropdown and validation logic for Sheet2 - const dropdownOptions = { - Option1: ['Yes', 'No'], - Option2: ['Product'], - Option3: ['ValueX', 'ValueY', 'ValueZ'], + 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, }; + } + } - 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], - }; - } - }); - } - - 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(); - // } - // } - - const buffer = await workbook.xlsx.writeBuffer(); - - downloadFile( - buffer, - "Product Data.xlsx", - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", - (success) => { - if (success) { - console.log("File downloaded and opened successfully!"); - } else { - console.log("Failed to download/open file."); - } - } + // ── 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 = {}; - // 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 + if (CategoryNames) { + CategoryNames.forEach((catName, catIdx) => { + const colIndex = catSubcatStartCol + catIdx; + const colLetter = getExcelColumnLetter(colIndex); + catNameToColLetter[catName] = colLetter; - // 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); - } - }; + // Write header (category name) + worksheet1.getCell(`${colLetter}1`).value = catName; - 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]; + // Write subcats for this category + const subcats = catSubcatMap[catName] || []; + subcats.forEach((subcat, sIdx) => { + worksheet1.getCell(`${colLetter}${sIdx + 2}`).value = subcat; }); - }; - const handleFieldRemove = (id) => { - setSelectedFields((prev) => prev.filter((field) => field !== id)); - }; + // 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`; - const handleCancelData = () => { - dispatch(emptyExcelData()); - if (fileInputRef.current) { - fileInputRef.current.value = ''; - } - }; + workbook.definedNames.add(rangeRef, safeName); + }); + } - 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 ? ( - {record.Productimage} - ) : ( - <> -
- - updateImageUrl(url, index, record.key) - } - // ImageLink={record.Productimage || ""} - ImageLink={ - onlineImage - ? onlineImage - : record.Productimage - ? record.Productimage - : '' - } - listType="picture-card" - // onlineImage={onlineImage?onlineImage:""} - // ImageLink={record.Productimage } - // updateImageUrl={updateImageUrl} - // singleImage={true} - recordMaintainKey={record.key} - /> + // 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; - - addOnlineImage(record, index)} - /> - -
- - )} - - ); - }, - }, - ]; + if (catColIndex > 0 && subCatColIndex > 0) { + const catColLetter = getExcelColumnLetter(catColIndex); - const column = columns?.map((col) => { - if (!col.editable) { - return col; - } - - let onClickHandler = null; - - if (editdelete === 'Delete') { - onClickHandler = (record) => removeFromTable(record); - } - - return { - ...col, - onCell: (record) => ({ - record, - editable: col.editable, - dataIndex: col.dataIndex, - title: col.title, - handleSave, - onClick: () => onClickHandler(record), - }), + 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)); + } + } + }); + + const buffer = await workbook.xlsx.writeBuffer(); + + downloadFile( + buffer, + "Product Data.xlsx", + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + (success) => { + if (success) { + console.log("File downloaded and opened successfully!"); + } else { + console.log("Failed to download/open file."); + } + } + ); + + }; + + 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 EditableContext = React.createContext(null); + const handleFieldRemove = (id) => { + setSelectedFields((prev) => prev.filter((field) => field !== id)); + }; - const EditableRow = ({ index, dataIndex, ...props }) => { - const [form] = Form.useForm(); + 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 ( -
- - - -
- ); - }; - - const EditableCell = ({ - title, - editable, - children, - dataIndex, - record, - handleSave, - index, - ...restProps - }) => { - const [editing, setEditing] = useState(false); - const inputRef = useRef(null); - const form = useContext(EditableContext); - - useEffect(() => { - if (editing) { - inputRef?.current?.focus(); - } - }, [editing]); - - const toggleEdit = () => { - setEditing(!editing); - form.setFieldsValue({ - [dataIndex]: record[dataIndex], - }); - }; - - const save = async () => { - try { - const values = await form.validateFields(); - toggleEdit(); - handleSave({ - ...record, - ...values, - }); - } catch (errInfo) { } - }; - - let childNode = children; - - if (editable) { - childNode = editing ? ( - - - + <> + {Img ? ( + {record.Productimage} ) : ( -
- {children} -
- ); - } - - return {childNode}; - }; - - const components = { - body: { - row: EditableRow, - cell: EditableCell, - }, - }; - - const handleSave = (row) => { - const newDatas = [...Datas]; - - const item = newDatas.filter((item) => item.key === row.key); - - // const item = newDatas[index]; - const UpdatedData = { - ProductName: row?.ProductName, - ProductVariantName: row?.ProductVariantName - ? row?.ProductVariantName - : 'Variant 1', - Quantity: row?.Quantity, - UOM: row?.UOM, - MRP: row?.MRP, - isModified: true, - WhSalePrice: row?.WhSalePrice, - SellPrice: row?.SellPrice, - Category: row?.Category, - SubCategory: row?.SubCategory, - Brand: row?.Brand, - AutoGenerateQrcode: row?.AutoGenerateQrcode, - AddQrCode: row?.AddQrCode, - StockAvailable: row?.StockAvailable, - // NumberOfPieceInside:row?.NumberOfPieceInside, - TokenAvailable: row?.TokenAvailable, - OnePieceAvailable: row?.OnePieceAvailable, - OnePiecePrice: row?.OnePiecePrice, - AutoGenerateOnePieceQrcode: row?.AutoGenerateOnePieceQrcode, - AutoGenerateOnePieceQrcodeNumber: row?.AutoGenerateOnePieceQrcodeNumber, - ProductType: row?.ProductType, - Tax: row?.Tax, - CESS: row?.CESS, - HSN: row?.HSN, - PartNumber: row?.PartNumber, - Rack: row?.Rack, - ManufactureDate: row?.ManufactureDate, - ExpireDate: row?.ExpireDate, - AvailableFrom: row?.AvailableFrom, - AvailableTo: row?.AvailableTo, - Productimage: row?.Productimage, - key: row?.key, - }; - newDatas.splice(item?.[0]?.key, 1, { - ...item?.[0], - ...UpdatedData, - }); - setDatas(newDatas); - setExcelData(newDatas); - }; - - const handlechange22 = (index) => { - if (editdelete === 'Delete') { - seteditdelete(''); - } else { - seteditdelete('Delete'); - } - }; - - const removeFromTable = (record) => { - const indexToRemove = Datas.findIndex((item) => item.key === record.key); - - if (indexToRemove !== -1) { - const updatedDataSource = [...Datas]; - updatedDataSource.splice(indexToRemove, 1); - setDatas(updatedDataSource); - setExcelData(updatedDataSource); - } - }; - - const handleExportData = async () => { - setLoading(true); - let response = await dispatch( - getProductData({ CompId: CompId, BranchId: BranchId, AppId: AppId }) - ).unwrap(); - if (response?.data?.statusCode == 1 && response?.data?.data?.length > 0) { - const formattedData = response?.data?.data?.map((item) => { - return { - ProdId: item.ProdId, - 'Product Name': item.ProdName, - 'Product Variant Name': item.ProdVarientName, - Quantity: item.Size, - UOM: item.UomName, - MRP: item.MRP, - 'WholeSale Price': item.WhSalePrice, - 'Sales Price': item.SellPrice, - Category: item.CategoryName, - 'Sub Category': item.SubCategoryName, - Brand: item.BrandName, - 'Auto Generate Qrcode': item.AutoGenerateQr - ? item.AutoGenerateQr - : 'N', - 'Add Qr Code': item.QRCode, - 'Stock Available': item.StockAvailable ? item.StockAvailable : 'N', - 'Token Available': item.TokenAvailable ? item.TokenAvailable : 'N', - 'One Piece Available': item.OnePcsAvailable - ? item.OnePcsAvailable - : 'N', - 'One Piece Price': item.OnePcsPrice, - 'Auto Generate One Piece Qrcode': item.AutoGenerateSingleQr - ? item.AutoGenerateSingleQr - : 'N', - 'Auto Generate One Piece Qrcode Number': item.OnePcQR, - 'Product Type': item.ProdTypeName ? item.ProdTypeName : 'Product', - Tax: `${item.TaxName || 'NIL'} - ${item.TaxPercentage || 0}%`, - CESS: item.CESS, - HSN: item.HSNCode, - 'Part Number': item.PartNumber, - Rack: item.Rack, - 'Manufacture Date': null, - 'Expire Date': null, - 'Available From': - item.AvailableFrom != '00:00:00' ? item.AvailableFrom : null, - 'Available To': - item.AvailableTo != '00:00:00' ? item.AvailableTo : null, - }; - }); - - const workbook = new ExcelJS.Workbook(); - const worksheet = workbook.addWorksheet('Products'); - - worksheet.columns = Object.keys(formattedData[0]).map((key) => ({ - header: key, - key: key, - width: 20, - })); - - formattedData.forEach((row) => worksheet.addRow(row)); - - worksheet.eachRow((row, rowNumber) => { - row.eachCell((cell, colNumber) => { - cell.protection = { locked: colNumber === 1 }; - }); - }); - - await worksheet.protect('', { - selectLockedCells: true, - selectUnlockedCells: true, - }); - - // const buffer = await workbook.xlsx.writeBuffer(); - // const blob = new Blob([buffer], { - // type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - // }); - // const downloadLink = document.createElement('a'); - // downloadLink.href = window.URL.createObjectURL(blob); - // downloadLink.download = 'Product_Data.xlsx'; - // downloadLink.click(); - const buffer = await workbook.xlsx.writeBuffer(); - - downloadFile( - buffer, - "Product_Data.xlsx", - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" - ); - setLoading(false); - } else { - setLoading(false); - setMessage(true); - } - }; - - const handleExportBulkdata = async () => { - let response = await dispatch( - getProductData({ CompId: CompId, BranchId: BranchId, AppId: AppId }) - ).unwrap(); - if (response?.data?.statusCode == 1 && response?.data?.data?.length > 0) { - const formattedData = response?.data?.data?.map((item) => { - return { - ProdId: item.ProdId, - 'Product Name': item.ProdName, - 'Product Variant Name': item.ProdVarientName, - Quantity: item.Size, - UOM: item.UomName, - MRP: item.MRP, - 'WholeSale Price': item.WhSalePrice, - 'Sales Price': item.SellPrice, - Category: item.CategoryName, - 'Sub Category': item.SubCategoryName, - Brand: item.BrandName, - 'Auto Generate Qrcode': item.AutoGenerateQr - ? item.AutoGenerateQr - : 'N', - 'Add Qr Code': item.QRCode, - 'Stock Available': item.StockAvailable ? item.StockAvailable : 'N', - 'Token Available': item.TokenAvailable ? item.TokenAvailable : 'N', - 'One Piece Available': item.OnePcsAvailable - ? item.OnePcsAvailable - : 'N', - 'One Piece Price': item.OnePcsPrice, - 'Auto Generate One Piece Qrcode': item.AutoGenerateSingleQr - ? item.AutoGenerateSingleQr - : 'N', - 'Auto Generate One Piece Qrcode Number': item.OnePcQR, - 'Product Type': item.ProdTypeName ? item.ProdTypeName : 'Product', - Tax: `${item.TaxName || 'NIL'} - ${item.TaxPercentage || 0}%`, - CESS: item.CESS, - HSN: item.HSNCode, - 'Part Number': item.PartNumber, - Rack: item.Rack, - 'Manufacture Date': null, - 'Expire Date': null, - 'Available From': - item.AvailableFrom != '00:00:00' ? item.AvailableFrom : null, - 'Available To': - item.AvailableTo != '00:00:00' ? item.AvailableTo : null, - }; - }); - - setOrginalData(formattedData); - } - }; - - const requiredFields = [ - 'ProductName', - 'ProductVariantName', - 'Quantity', - 'UOM', - 'MRP', - 'SellPrice', - 'WhSalePrice', - 'Category', - 'SubCategory', - 'Brand', - 'StockAvailable', - 'TokenAvailable', - 'ProductType', - 'Tax', - 'AutoGenerateQrcode', - 'AddQrCode', - 'OnePieceAvailable', - 'OnePiecePrice', - 'AutoGenerateOnePieceQrcode', - 'AutoGenerateOnePieceQrcodeNumber', - 'CESS', - 'HSN', - 'PartNumber', - 'Rack', - 'ManufactureDate', - 'ExpireDate', - 'AvailableFrom', - 'AvailableTo', - ]; - - const enhancedColumns = column.map((col) => { - if (col.dataIndex === 'Productimage') return col; - - // Get all used fields *except* the current column (to allow remap) - const usedFields = Object.entries(fieldMapping) - .filter(([key]) => key !== col.dataIndex) - .map(([, value]) => value); - - // Fields left for dropdown (excluding already selected ones) - const availableHeaders = headers?.filter( - (h) => !usedFields?.includes(h) && h !== '__isSampleRow' - ); - - const isMapped = !!fieldMapping[col.dataIndex]; - - return { - ...col, - title: ( -
-
- {col.title} - {!isMapped && ( - Not mapped - )} -
- -
- - - {fieldMapping[col.dataIndex] && ( - { - setFieldMapping((prev) => { - const updated = { ...prev }; - delete updated[col.dataIndex]; - return updated; - }); - }} - className="SelectCancelicon" - style={{ - position: 'absolute', - right: '-17px', - top: '80%', - transform: 'translateY(-50%)', - color: 'red', - fontSize: 14, - cursor: 'pointer', - zIndex: 1, - }} - /> - )} -
-
- ), - render: (text, record, index) => { - const mappedField = fieldMapping[col.dataIndex]; - - if ( - mappedField && - originalUploadedRawData?.[index]?.[mappedField] !== undefined - ) { - return originalUploadedRawData[index][mappedField]; - } - - return record[col.dataIndex] !== undefined ? record[col.dataIndex] : ''; - }, - onCell: (record) => ({ - record, - editable: col.editable, - dataIndex: col.dataIndex, - title: col.title, - handleSave, - onClick: () => { - if (editdelete === 'Delete') { - removeFromTable(record); + <> +
+ + updateImageUrl(url, index, record.key) } - }, - }), + // ImageLink={record.Productimage || ""} + ImageLink={ + onlineImage + ? onlineImage + : record.Productimage + ? record.Productimage + : '' + } + listType="picture-card" + // onlineImage={onlineImage?onlineImage:""} + // ImageLink={record.Productimage } + // updateImageUrl={updateImageUrl} + // singleImage={true} + recordMaintainKey={record.key} + /> + + + addOnlineImage(record, index)} + /> + +
+ + )} + + ); + }, + }, + ]; + + const column = columns?.map((col) => { + if (!col.editable) { + return col; + } + + let onClickHandler = null; + + if (editdelete === 'Delete') { + onClickHandler = (record) => removeFromTable(record); + } + + return { + ...col, + onCell: (record) => ({ + record, + editable: col.editable, + dataIndex: col.dataIndex, + title: col.title, + handleSave, + onClick: () => onClickHandler(record), + }), + }; + }); + + const EditableContext = React.createContext(null); + + const EditableRow = ({ index, dataIndex, ...props }) => { + const [form] = Form.useForm(); + return ( +
+ + + +
+ ); + }; + + const EditableCell = ({ + title, + editable, + children, + dataIndex, + record, + handleSave, + index, + ...restProps + }) => { + const [editing, setEditing] = useState(false); + const inputRef = useRef(null); + const form = useContext(EditableContext); + + useEffect(() => { + if (editing) { + inputRef?.current?.focus(); + } + }, [editing]); + + const toggleEdit = () => { + setEditing(!editing); + form.setFieldsValue({ + [dataIndex]: record[dataIndex], + }); + }; + + const save = async () => { + try { + const values = await form.validateFields(); + toggleEdit(); + handleSave({ + ...record, + ...values, + }); + } catch (errInfo) {} + }; + + let childNode = children; + + if (editable) { + childNode = editing ? ( + + + + ) : ( +
+ {children} +
+ ); + } + + return {childNode}; + }; + + const components = { + body: { + row: EditableRow, + cell: EditableCell, + }, + }; + + const handleSave = (row) => { + const newDatas = [...Datas]; + + const item = newDatas.filter((item) => item.key === row.key); + + // const item = newDatas[index]; + const UpdatedData = { + ProductName: row?.ProductName, + ProductVariantName: row?.ProductVariantName + ? row?.ProductVariantName + : 'Variant 1', + Quantity: row?.Quantity, + UOM: row?.UOM, + MRP: row?.MRP, + isModified: true, + WhSalePrice: row?.WhSalePrice, + SellPrice: row?.SellPrice, + Category: row?.Category, + SubCategory: row?.SubCategory, + Brand: row?.Brand, + AutoGenerateQrcode: row?.AutoGenerateQrcode, + AddQrCode: row?.AddQrCode, + StockAvailable: row?.StockAvailable, + // NumberOfPieceInside:row?.NumberOfPieceInside, + TokenAvailable: row?.TokenAvailable, + OnePieceAvailable: row?.OnePieceAvailable, + OnePiecePrice: row?.OnePiecePrice, + AutoGenerateOnePieceQrcode: row?.AutoGenerateOnePieceQrcode, + AutoGenerateOnePieceQrcodeNumber: row?.AutoGenerateOnePieceQrcodeNumber, + ProductType: row?.ProductType, + Tax: row?.Tax, + CESS: row?.CESS, + HSN: row?.HSN, + PartNumber: row?.PartNumber, + Rack: row?.Rack, + ManufactureDate: row?.ManufactureDate, + ExpireDate: row?.ExpireDate, + AvailableFrom: row?.AvailableFrom, + AvailableTo: row?.AvailableTo, + Productimage: row?.Productimage, + key: row?.key, + }; + newDatas.splice(item?.[0]?.key, 1, { + ...item?.[0], + ...UpdatedData, + }); + setDatas(newDatas); + setExcelData(newDatas); + }; + + const handlechange22 = (index) => { + if (editdelete === 'Delete') { + seteditdelete(''); + } else { + seteditdelete('Delete'); + } + }; + + const removeFromTable = (record) => { + const indexToRemove = Datas.findIndex((item) => item.key === record.key); + + if (indexToRemove !== -1) { + const updatedDataSource = [...Datas]; + updatedDataSource.splice(indexToRemove, 1); + setDatas(updatedDataSource); + setExcelData(updatedDataSource); + } + }; + + const handleExportData = async () => { + setLoading(true); + let response = await dispatch( + getProductData({ CompId: CompId, BranchId: BranchId, AppId: AppId }) + ).unwrap(); + if (response?.data?.statusCode == 1 && response?.data?.data?.length > 0) { + const formattedData = response?.data?.data?.map((item) => { + return { + ProdId: item.ProdId, + 'Product Name': item.ProdName, + 'Product Variant Name': item.ProdVarientName, + Quantity: item.Size, + UOM: item.UomName, + MRP: item.MRP, + 'WholeSale Price': item.WhSalePrice, + 'Sales Price': item.SellPrice, + Category: item.CategoryName, + 'Sub Category': item.SubCategoryName, + Brand: item.BrandName, + 'Auto Generate Qrcode': item.AutoGenerateQr + ? item.AutoGenerateQr + : 'N', + 'Add Qr Code': item.QRCode, + 'Stock Available': item.StockAvailable ? item.StockAvailable : 'N', + 'Token Available': item.TokenAvailable ? item.TokenAvailable : 'N', + 'One Piece Available': item.OnePcsAvailable + ? item.OnePcsAvailable + : 'N', + 'One Piece Price': item.OnePcsPrice, + 'Auto Generate One Piece Qrcode': item.AutoGenerateSingleQr + ? item.AutoGenerateSingleQr + : 'N', + 'Auto Generate One Piece Qrcode Number': item.OnePcQR, + 'Product Type': item.ProdTypeName ? item.ProdTypeName : 'Product', + Tax: `${item.TaxName || 'NIL'} - ${item.TaxPercentage || 0}%`, + CESS: item.CESS, + HSN: item.HSNCode, + 'Part Number': item.PartNumber, + Rack: item.Rack, + 'Manufacture Date': null, + 'Expire Date': null, + 'Available From': + item.AvailableFrom != '00:00:00' ? item.AvailableFrom : null, + 'Available To': + item.AvailableTo != '00:00:00' ? item.AvailableTo : null, }; + }); + + const workbook = new ExcelJS.Workbook(); + const worksheet = workbook.addWorksheet('Products'); + + worksheet.columns = Object.keys(formattedData[0]).map((key) => ({ + header: key, + key: key, + width: 20, + })); + + formattedData.forEach((row) => worksheet.addRow(row)); + + worksheet.eachRow((row, rowNumber) => { + row.eachCell((cell, colNumber) => { + cell.protection = { locked: colNumber === 1 }; + }); + }); + + await worksheet.protect('', { + selectLockedCells: true, + selectUnlockedCells: true, + }); + + // const buffer = await workbook.xlsx.writeBuffer(); + // const blob = new Blob([buffer], { + // type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + // }); + // const downloadLink = document.createElement('a'); + // downloadLink.href = window.URL.createObjectURL(blob); + // downloadLink.download = 'Product_Data.xlsx'; + // downloadLink.click(); + const buffer = await workbook.xlsx.writeBuffer(); + + downloadFile( + buffer, + "Product_Data.xlsx", + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" + ); + setLoading(false); + } else { + setLoading(false); + setMessage(true); + } + }; + + const handleExportBulkdata = async () => { + let response = await dispatch( + getProductData({ CompId: CompId, BranchId: BranchId, AppId: AppId }) + ).unwrap(); + if (response?.data?.statusCode == 1 && response?.data?.data?.length > 0) { + const formattedData = response?.data?.data?.map((item) => { + return { + ProdId: item.ProdId, + 'Product Name': item.ProdName, + 'Product Variant Name': item.ProdVarientName, + Quantity: item.Size, + UOM: item.UomName, + MRP: item.MRP, + 'WholeSale Price': item.WhSalePrice, + 'Sales Price': item.SellPrice, + Category: item.CategoryName, + 'Sub Category': item.SubCategoryName, + Brand: item.BrandName, + 'Auto Generate Qrcode': item.AutoGenerateQr + ? item.AutoGenerateQr + : 'N', + 'Add Qr Code': item.QRCode, + 'Stock Available': item.StockAvailable ? item.StockAvailable : 'N', + 'Token Available': item.TokenAvailable ? item.TokenAvailable : 'N', + 'One Piece Available': item.OnePcsAvailable + ? item.OnePcsAvailable + : 'N', + 'One Piece Price': item.OnePcsPrice, + 'Auto Generate One Piece Qrcode': item.AutoGenerateSingleQr + ? item.AutoGenerateSingleQr + : 'N', + 'Auto Generate One Piece Qrcode Number': item.OnePcQR, + 'Product Type': item.ProdTypeName ? item.ProdTypeName : 'Product', + Tax: `${item.TaxName || 'NIL'} - ${item.TaxPercentage || 0}%`, + CESS: item.CESS, + HSN: item.HSNCode, + 'Part Number': item.PartNumber, + Rack: item.Rack, + 'Manufacture Date': null, + 'Expire Date': null, + 'Available From': + item.AvailableFrom != '00:00:00' ? item.AvailableFrom : null, + 'Available To': + item.AvailableTo != '00:00:00' ? item.AvailableTo : null, + }; + }); + + setOrginalData(formattedData); + } + }; + + const requiredFields = [ + 'ProductName', + 'ProductVariantName', + 'Quantity', + 'UOM', + 'MRP', + 'SellPrice', + 'WhSalePrice', + 'Category', + 'SubCategory', + 'Brand', + 'StockAvailable', + 'TokenAvailable', + 'ProductType', + 'Tax', + 'AutoGenerateQrcode', + 'AddQrCode', + 'OnePieceAvailable', + 'OnePiecePrice', + 'AutoGenerateOnePieceQrcode', + 'AutoGenerateOnePieceQrcodeNumber', + 'CESS', + 'HSN', + 'PartNumber', + 'Rack', + 'ManufactureDate', + 'ExpireDate', + 'AvailableFrom', + 'AvailableTo', + ]; + + const enhancedColumns = column.map((col) => { + if (col.dataIndex === 'Productimage') return col; + + // Get all used fields *except* the current column (to allow remap) + const usedFields = Object.entries(fieldMapping) + .filter(([key]) => key !== col.dataIndex) + .map(([, value]) => value); + + // Fields left for dropdown (excluding already selected ones) + const availableHeaders = headers?.filter( + (h) => !usedFields?.includes(h) && h !== '__isSampleRow' + ); + + const isMapped = !!fieldMapping[col.dataIndex]; + + return { + ...col, + title: ( +
+
+ + {col.title} + + {!isMapped && ( + + Not mapped + + )} +
+ +
+ + + {fieldMapping[col.dataIndex] && ( + { + setFieldMapping((prev) => { + const updated = { ...prev }; + delete updated[col.dataIndex]; + return updated; + }); + }} + className="SelectCancelicon" + style={{ + position: 'absolute', + right: '-17px', + top: '90%', + transform: 'translateY(-50%)', + color: 'red', + fontSize: 14, + cursor: 'pointer', + zIndex: 1, + }} + /> + )} +
+
+ ), + render: (text, record, index) => { + const mappedField = fieldMapping[col.dataIndex]; + + if ( + mappedField && + originalUploadedRawData?.[index]?.[mappedField] !== undefined + ) { + return originalUploadedRawData[index][mappedField]; + } + + return record[col.dataIndex] !== undefined ? record[col.dataIndex] : ''; + }, + onCell: (record) => ({ + record, + editable: col.editable, + dataIndex: col.dataIndex, + title: col.title, + handleSave, + onClick: () => { + if (editdelete === 'Delete') { + removeFromTable(record); + } + }, + }), + }; + }); + + const aliasMap = { + ProductName: ['product name', 'product', 'item', 'item name', 'prodname'], + ProductVariantName: [ + 'variant', + 'product variant', + 'variant name', + 'productvariant', + ], + Quantity: ['qty', 'quantity', 'qty size', 'quantitysize', 'qnt'], + UOM: ['uom', 'unit', 'unit of measure'], + MRP: ['mrp', 'mrp price', 'm.r.p'], + SellPrice: ['retail', 'retail price', 'sales price', 'selling price'], + WhSalePrice: ['wholesale', 'wholesale price', 'wholesaleprice'], + Category: ['category', 'product category', 'cat'], + SubCategory: ['subcategory', 'sub category', 'sub cat', 'sub-cat'], + Tax: ['tax', 'tax percent', 'gst', 'vat'], + CESS: ['cess'], + HSN: ['hsn', 'hsn code'], + Brand: ['brand', 'brand name'], + // Add more as needed... + }; + + const autoMapFields = (headers) => { + const updatedMapping = {}; + const cleanedHeaders = headers.map((h) => + h?.toLowerCase().replace(/\s+/g, '') + ); + + requiredFields.forEach((requiredField) => { + const cleanedField = requiredField?.toLowerCase(); + + // 1. Try exact match (cleaned) + const match = stringSimilarity.findBestMatch( + cleanedField, + cleanedHeaders + ); + const bestMatchIndex = match.bestMatchIndex; + const bestMatchScore = match.bestMatch.rating; + + if (bestMatchScore > 0.6) { + updatedMapping[requiredField] = headers[bestMatchIndex]; + return; + } + + // 2. Try alias match + const aliases = aliasMap[requiredField] || []; + const matchedHeader = headers.find((header) => + aliases.some( + (alias) => + header?.toLowerCase().replace(/\s+/g, '') === + alias.replace(/\s+/g, '') + ) + ); + + if (matchedHeader) { + updatedMapping[requiredField] = matchedHeader; + } }); - const aliasMap = { - ProductName: ['product name', 'product', 'item', 'item name', 'prodname'], - ProductVariantName: [ - 'variant', - 'product variant', - 'variant name', - 'productvariant', - ], - Quantity: ['qty', 'quantity', 'qty size', 'quantitysize', 'qnt'], - UOM: ['uom', 'unit', 'unit of measure'], - MRP: ['mrp', 'mrp price', 'm.r.p'], - SellPrice: ['retail', 'retail price', 'sales price', 'selling price'], - WhSalePrice: ['wholesale', 'wholesale price', 'wholesaleprice'], - Category: ['category', 'product category', 'cat'], - SubCategory: ['subcategory', 'sub category', 'sub cat', 'sub-cat'], - Tax: ['tax', 'tax percent', 'gst', 'vat'], - CESS: ['cess'], - HSN: ['hsn', 'hsn code'], - Brand: ['brand', 'brand name'], - // Add more as needed... - }; + setFieldMapping(updatedMapping); + }; - const autoMapFields = (headers) => { - const updatedMapping = {}; - const cleanedHeaders = headers.map((h) => - h?.toLowerCase().replace(/\s+/g, '') - ); + const COMPARE_FIELDS = [ + 'Product Name', + 'Quantity', + 'MRP', + 'Sales Price', + 'WholeSale Price', + 'Category', + 'Sub Category', + 'Brand', + 'Stock Available', + ]; - requiredFields.forEach((requiredField) => { - const cleanedField = requiredField?.toLowerCase(); + return ( +
+ { + setMessageData(null); + setMessageType(null); + }} + /> - // 1. Try exact match (cleaned) - const match = stringSimilarity.findBestMatch( - cleanedField, - cleanedHeaders - ); - const bestMatchIndex = match.bestMatchIndex; - const bestMatchScore = match.bestMatch.rating; - - if (bestMatchScore > 0.6) { - updatedMapping[requiredField] = headers[bestMatchIndex]; - return; - } - - // 2. Try alias match - const aliases = aliasMap[requiredField] || []; - const matchedHeader = headers.find((header) => - aliases.some( - (alias) => - header?.toLowerCase().replace(/\s+/g, '') === - alias.replace(/\s+/g, '') - ) - ); - - if (matchedHeader) { - updatedMapping[requiredField] = matchedHeader; - } - }); - - setFieldMapping(updatedMapping); - }; - - const COMPARE_FIELDS = [ - 'Product Name', - 'Quantity', - 'MRP', - 'Sales Price', - 'WholeSale Price', - 'Category', - 'Sub Category', - 'Brand', - 'Stock Available', - ]; - - return ( -
- { - setMessageData(null); - setMessageType(null); +
+
+
+
+

+ > + Upload Your Excel +

-
- -
-

- Upload Your Excel -

- -
- -
- -
-
-
handleExportData()} - > -
- -
-
- Export Excel -
-
- {/* {excelData?.length > 0 && excelData && -
setMappingOpen(true)}> -
- -
-
- Map Your Fields -
-
- } */} - {loading &&
Loading...
} - {message &&
No Data Found
} -
- - {excelData?.length > 0 && excelData && ( -
- - - -
- )} -
-
0 ? 'space-between' : 'flex-end', - width: '100%', - }} - > - {excelData?.length > 0 && ( -
-
-

- Modified -
-
-

- Not Modified -
-
- )} - - - - -
- - {(!excelData || excelData?.length === 0) && ( - <> -
-
- {/* */} - -
-
- - )} - - {excelFileError && ( -
- {excelFileError} -
- )} - -
- {excelData && excelData?.length > 0 ? ( - - record.isModified ? 'modified-row' : 'old-row' - } - >
- ) : ( -

- )} -
-
+
- {/* -
- - Download -
-
*/} + justifyContent: 'center', + padding: '5px 12px', + borderRadius: '4px', + }} + onClick={handleFieldSetup} + > + +
+ +
handleExportData()} + > +
+ +
+
+ Export Excel +
+
- {excelData && excelData?.length > 0 && ( - + {message && ( +
No Data Found
)}
- setFieldSetup(false)} - footer={false} - children={ -
-
- -
-
-
- - !selectedFields?.some((s) => s === p.value) - )} - /> - -
- {selectedFields - ?.map((id) => - tableFieldPreferences?.find((p) => p.value === id) - ) - .filter(Boolean) - .map((field) => ( -
-
{field.label}
-
handleFieldRemove(field.value)} - > - -
-
- ))} -
-
- } - htmlType={true} - /> -
-
-
-
- } - /> -
- -
- {imagedata?.map((item, index) => ( -
setSelectedImage(item)} - > - no image -
- ))} -
- - } - handleSubmit={submitimage} - handleCancel={handleimage} - >
+ {excelData?.length > 0 && excelData && ( +
+ + + +
+ )} +
+
0 ? 'space-between' : 'flex-end', + gap: '1rem', + }} + > + {excelData?.length > 0 && ( +
+
+

+ Modified +
+
+

+ Not Modified +
+
+ )} + + + +
+
- setMappingOpen(false)} - > - {requiredFields.map((field) => { - const usedHeaders = Object.entries(fieldMapping) - .filter(([key]) => key !== field) - .map(([, value]) => value); + {(!excelData || excelData?.length === 0) && ( + <> +
+
+ {/* */} + +
+
+ + )} - const availableHeaders = headers?.filter( - (header) => !usedHeaders?.includes(header) - ); - - return ( -
- - + {excelFileError && ( +
+ {excelFileError} +
+ )} + +
+
+ {excelData && excelData?.length > 0 ? ( + + record.isModified ? 'modified-row' : 'old-row' + } + >
+ ) : ( +

+ )} +
+
+ {excelData && excelData?.length > 0 && ( + + )} +
+ setFieldSetup(false)} + footer={false} + children={ +
+
+ +
+
+
+ + !selectedFields?.some((s) => s === p.value) + )} + /> + +
+ {selectedFields + ?.map((id) => + tableFieldPreferences?.find((p) => p.value === id) + ) + .filter(Boolean) + .map((field) => ( +
+
{field.label}
+
handleFieldRemove(field.value)} + > +
- ); - })} - -
- ); +
+ ))} +
+
+ } + htmlType={true} + /> +
+ +
+
+ } + /> + +
+ +
+ {imagedata?.map((item, index) => ( +
setSelectedImage(item)} + > + no image +
+ ))} +
+ + } + handleSubmit={submitimage} + handleCancel={handleimage} + >
+
+ + setMappingOpen(false)} + > + {requiredFields.map((field) => { + const usedHeaders = Object.entries(fieldMapping) + .filter(([key]) => key !== field) + .map(([, value]) => value); + + const availableHeaders = headers?.filter( + (header) => !usedHeaders?.includes(header) + ); + + return ( +
+ + +
+ ); + })} +
+
+ ); }; export default ProductExcel; diff --git a/src/Pages/Product/ProductList.jsx b/src/Pages/Product/ProductList.jsx index 98d0b0e..a2edd1c 100644 --- a/src/Pages/Product/ProductList.jsx +++ b/src/Pages/Product/ProductList.jsx @@ -2714,7 +2714,7 @@ const ProductList = () => { open={openExcel} title="Bulk Upload" footer={true} - width={excelDataValues?.length > 0 ? 2500 : 600} + width={excelDataValues?.length > 0 ? 2500 : 700} className={'bulkuploadmodal'} children={ <> diff --git a/src/Pages/RedirectApps.jsx b/src/Pages/RedirectApps.jsx index 5ec400c..5a4a76e 100644 --- a/src/Pages/RedirectApps.jsx +++ b/src/Pages/RedirectApps.jsx @@ -18,14 +18,14 @@ function RedirectApps() { const SessionId = encryptedValuesUrlFun(getSession('SessionId')); // const AuthToken = sessionStorage.getItem('auth'); - if (sessionStorage.getItem('BranchId') !== null) { + if (getSession('BranchId') !== null) { clearSession('BranchId'); } - if (sessionStorage.getItem('AppId') !== null) { + if (getSession('AppId') !== null) { clearSession('AppId'); } - if (sessionStorage.getItem('hasRefreshed') !== null) { - sessionStorage.removeItem('hasRefreshed'); + if (getSession('hasRefreshed') !== null) { + clearSession('hasRefreshed'); } const param = { MN: MobileNo, diff --git a/src/Pages/Reports/DateWiseReport/DateWiseReport.jsx b/src/Pages/Reports/DateWiseReport/DateWiseReport.jsx index c424dc6..a3fa7fa 100644 --- a/src/Pages/Reports/DateWiseReport/DateWiseReport.jsx +++ b/src/Pages/Reports/DateWiseReport/DateWiseReport.jsx @@ -41,6 +41,7 @@ const DateWiseReport = () => { getSession('AppType')?.toLowerCase() == 'wholesale' ? true : false; const [OrderFromDate, setOrderFromDate] = useState(); const [OrderToDate, setOrderToDate] = useState(); + const sessionuserid = getSession('UserId') const [UserId, setUserId] = useState( UserRole != 'Employee' ? 0 : getSession('UserId') ); @@ -63,7 +64,7 @@ const DateWiseReport = () => { setting?.SettingIdName?.toLowerCase() === 'mobilea4' && setting?.SettingValue === 'Y' ); - console.log(MobileA4Print, 'MobileA4PrintMobileA4Print'); + console.log(MobileA4Print,SettingDataSelector, 'MobileA4PrintMobileA4Print'); useEffect(() => { if (dataSource?.length > 0) { @@ -368,7 +369,7 @@ const DateWiseReport = () => { }, []); const getPreference = async () => { - const data = { AppId: AppId, CompId: CompId, BranchId: BranchId,UserId: UserId }; + const data = { AppId: AppId, CompId: CompId, BranchId: BranchId,UserId: sessionuserid }; const { data: res } = await dispatch(getPreferenceData(data)).unwrap(); const decimalSetting = res?.data?.[0]?.SettingDtlDetails?.find( (setting) => @@ -545,12 +546,12 @@ const DateWiseReport = () => { let TokenData = ''; let FooterPrint = ''; if (isMobile) { - if (MobileA4Print) { - ReportMobilePDFPrint({ - printId: 'RePrint', - printStyle: style, - }); - } else { + // if (MobileA4Print) { + // ReportMobilePDFPrint({ + // printId: 'RePrint', + // printStyle: style, + // }); + // } else { var textEncoded = encodeURI(receiptText); var TypeCheck = 'PrintReceipt'; var scheme = 'pozoprinter'; @@ -578,7 +579,7 @@ const DateWiseReport = () => { FooterPrint + 'HasFooterTextE' + ';end;'; - } + // } } else { await printDiv('RePrint', style); } diff --git a/src/Pages/Reports/ItemWiseReport/ItemWiseReport.jsx b/src/Pages/Reports/ItemWiseReport/ItemWiseReport.jsx index 8d6e824..03bb062 100644 --- a/src/Pages/Reports/ItemWiseReport/ItemWiseReport.jsx +++ b/src/Pages/Reports/ItemWiseReport/ItemWiseReport.jsx @@ -69,6 +69,7 @@ const ItemWiseReport = () => { const BranchId = getSession('BranchId'); const AppId = getSession('AppId'); const UserRole = getSession('UserType'); + const sessionuserid = getSession('UserId') const [UserId, setUserId] = useState( UserRole != 'Employee' ? 0 : getSession('UserId') ); @@ -79,7 +80,7 @@ const ItemWiseReport = () => { setting?.SettingIdName?.toLowerCase() === 'mobilea4' && setting?.SettingValue === 'Y' ); - + console.log(MobileA4Print,SettingDataSelector, 'MobileA4PrintMobileA4Print') useEffect(() => { getPreference(); }, []); @@ -210,7 +211,7 @@ const ItemWiseReport = () => { } }, [apiCall]); const getPreference = async () => { - const data = { AppId: AppId, CompId: CompId, BranchId: BranchId,UserId: UserId }; + const data = { AppId: AppId, CompId: CompId, BranchId: BranchId,UserId: sessionuserid }; const { data: res } = await dispatch(getPreferenceData(data)).unwrap(); const decimalSetting = res?.data?.[0]?.SettingDtlDetails?.find( (setting) => @@ -310,12 +311,12 @@ const ItemWiseReport = () => { }; const Print = async () => { if (isMobile) { - if (MobileA4Print) { - ReportMobilePDFPrint({ - printId: 'RePrint', - printStyle: style, - }); - } else { + // if (MobileA4Print) { + // ReportMobilePDFPrint({ + // printId: 'RePrint', + // printStyle: style, + // }); + // } else { let LogoImage = ''; let TokenData = ''; let FooterPrint = ''; @@ -346,7 +347,7 @@ const ItemWiseReport = () => { FooterPrint + 'HasFooterTextE' + ';end;'; - } + // } } else { await printDiv('RePrint', style); } diff --git a/src/Styles/BookingScreen/Components/BSBillingTables/BSBillingTable1/BSBPayment.scss b/src/Styles/BookingScreen/Components/BSBillingTables/BSBillingTable1/BSBPayment.scss index 9c2d2c5..c973f1b 100644 --- a/src/Styles/BookingScreen/Components/BSBillingTables/BSBillingTable1/BSBPayment.scss +++ b/src/Styles/BookingScreen/Components/BSBillingTables/BSBillingTable1/BSBPayment.scss @@ -4,6 +4,7 @@ flex-wrap: wrap; justify-content: center; gap: 10px; + margin-top: 4px; } .BST1-Payment-onlypay { diff --git a/src/Styles/BookingScreen/Components/BSItemCards/BSItemCard.scss b/src/Styles/BookingScreen/Components/BSItemCards/BSItemCard.scss index 3cc2a73..5f386db 100644 --- a/src/Styles/BookingScreen/Components/BSItemCards/BSItemCard.scss +++ b/src/Styles/BookingScreen/Components/BSItemCards/BSItemCard.scss @@ -78,7 +78,7 @@ } .BSItemCard-content { - padding: 1px 0; + padding: 3px 0; background-color: rgba(255, 255, 255, 0.8); position: absolute; display: flex; @@ -96,7 +96,8 @@ font-weight: 500; max-width: 130px; display: -webkit-box; - -webkit-line-clamp: 3; + -webkit-line-clamp: 2; + line-height: 1; -webkit-box-orient: vertical; overflow: hidden; } diff --git a/src/Styles/BookingScreen/Components/BSNavbar/BSNavbar1.scss b/src/Styles/BookingScreen/Components/BSNavbar/BSNavbar1.scss index 4972fdf..553088f 100644 --- a/src/Styles/BookingScreen/Components/BSNavbar/BSNavbar1.scss +++ b/src/Styles/BookingScreen/Components/BSNavbar/BSNavbar1.scss @@ -635,11 +635,10 @@ // .resNavbarMain { - width: 100vw; + width: max-content; + max-width: 250px; height: 100vh; - background-color: #00000056; position: fixed; - left: 0; top: 0; bottom: 0; right: 0; @@ -648,7 +647,7 @@ align-items: flex-start; justify-content: flex-end; overflow: visible; - backdrop-filter: blur(6px); + box-shadow: rgba(100, 100, 111, 0.2) 0px 7px 29px 0px; animation: fadeInRes 0.3s ease; &.closing { diff --git a/src/Styles/BookingScreen/Components/UtillComponents/BSNavBarDragItems.scss b/src/Styles/BookingScreen/Components/UtillComponents/BSNavBarDragItems.scss index f661693..6652c99 100644 --- a/src/Styles/BookingScreen/Components/UtillComponents/BSNavBarDragItems.scss +++ b/src/Styles/BookingScreen/Components/UtillComponents/BSNavBarDragItems.scss @@ -85,7 +85,7 @@ } .AddFavItemListCont { - height: 34vh; + height: 30vh; padding-bottom: 4rem; } } diff --git a/src/Styles/OverAllStyle/OverAllStyle.scss b/src/Styles/OverAllStyle/OverAllStyle.scss index 841b020..bfd5707 100644 --- a/src/Styles/OverAllStyle/OverAllStyle.scss +++ b/src/Styles/OverAllStyle/OverAllStyle.scss @@ -1721,3 +1721,17 @@ table { right: 2rem; } } + +.addVariant { + background: #23378a29; + color: #23378a; + padding: 12px 24px; + border: none; + font-family: "Poppins", sans-serif; + font-size: 14px; + font-weight: 500; + cursor: pointer; + border-radius: 6px; + outline: none; + height: max-content; +} diff --git a/src/Styles/Product/excel.scss b/src/Styles/Product/excel.scss index 00a9214..a964f20 100644 --- a/src/Styles/Product/excel.scss +++ b/src/Styles/Product/excel.scss @@ -8,12 +8,7 @@ font-weight: bold !important; } -// .viewerExcelupload table { -// // table-layout: auto !important; -// } - .viewerExcelupload::-webkit-scrollbar { - // display: block !important; width: 0rem; height: 0.5rem; } @@ -28,7 +23,7 @@ background-color: #1292ee; color: #fff; border-radius: 4px; - font-family: 'Poppins'; + font-family: "Poppins"; font-size: 16px; svg { @@ -48,6 +43,8 @@ .tableExcelUpload { .ant-table-cell { padding: 0 8px !important; + font-family: "Poppins"; + font-weight: 500 !important; } .ant-select-selection-placeholder { @@ -129,16 +126,16 @@ } .mdsheet { - width: 25px; - height: 25px; + width: 20px; + height: 20px; border: 1px solid #5bff73; background-color: #b3ffbf; border-radius: 4px; } .mdsheet2 { - width: 25px; + width: 20px; + height: 20px; border-radius: 4px; - height: 25px; background-color: #ffc7f8; border: 1px solid #ff74ec; } @@ -148,5 +145,88 @@ font-family: "Poppins"; font-size: 14px; font-weight: 500; + @media (max-width: 500px) { + font-size: 10px; + } } -} \ No newline at end of file +} + +.field-setup-selected-fields { + display: flex; + flex-wrap: wrap; + gap: 4px; + margin-bottom: 50px; + height: max-content; + max-height: 50vh; + overflow: auto; + + .selected-field { + display: flex; + align-items: center; + gap: 4px; + background: #0bad77; + padding: 6px 10px; + border-radius: 6px; + font-size: 13px; + font-weight: 600; + color: #fff; + + .close-icon { + display: flex; + align-items: center; + cursor: pointer; + + > svg { + color: #ffffffff !important; + } + } + } +} + +.HeadingUploadExl { + display: flex; + align-items: center; + justify-content: space-between; + gap: 1rem; + width: 50%; + @media (max-width: 950px) { + width: 100%; + } +} +.download-linkMain { + display: flex; + align-items: center; + gap: 1rem; + justify-content: space-between; + margin-bottom: 10px; + @media (max-width: 950px) { + flex-wrap: wrap; + } +} + +.download-link { + width: 50%; + justify-content: space-between; + align-items: center; + @media (max-width: 950px) { + width: 100%; + } +} + +.viewerExcelupload { + .ant-select-selection-item { + margin-top: 0 !important ; + padding-top: 0 !important; + } +} + +.download-link span { + font-size: 12px; + font-weight: 400; +} +.imgUpldr { + display: flex; + flex-direction: column; + align-items: center; + gap: 2px; +} diff --git a/src/Styles/Tablebooking/TableBooking.scss b/src/Styles/Tablebooking/TableBooking.scss index 2c80958..58f6e93 100644 --- a/src/Styles/Tablebooking/TableBooking.scss +++ b/src/Styles/Tablebooking/TableBooking.scss @@ -705,7 +705,7 @@ color: #fff; top: 0; } -.optionnew:selection { +.optionnew::selection { background-color: #ff4d4f; } .ovrly-icos { diff --git a/src/utils/useDevToolsDetection.js b/src/utils/useDevToolsDetection.js deleted file mode 100644 index 51265e0..0000000 --- a/src/utils/useDevToolsDetection.js +++ /dev/null @@ -1,86 +0,0 @@ -const DevToolsDetector = { - checkWindowSize() { - const threshold = 160; - return ( - window.outerWidth - window.innerWidth > threshold || - window.outerHeight - window.innerHeight > threshold - ); - }, - - checkConsole() { - let detected = false; - const element = new Image(); - Object.defineProperty(element, 'id', { - get: () => { detected = true; } - }); - console.log('%c', element); - console.clear(); - return detected; - }, - - checkDebugger() { - if (import.meta.env.DEV) return false; - const start = performance.now(); - // eslint-disable-next-line no-debugger - debugger; - const end = performance.now(); - return end - start > 100; - }, - - checkToString() { - let detected = false; - const div = document.createElement('div'); - Object.defineProperty(div, 'id', { - get: function () { - detected = true; - return 'id'; - } - }); - console.log(div); - console.clear(); - return detected; - }, - - detect() { - return ( - this.checkWindowSize() || - this.checkConsole() || - this.checkDebugger() || - this.checkToString() - ); - } -}; - -export default DevToolsDetector; - - - -import { useEffect, useState } from 'react'; - -const isMobileOrIOS = () => - /iPhone|iPad|iPod|Android/i.test(navigator.userAgent); - -export const useDevToolsDetection = (onDetected) => { - const [isBlocked, setIsBlocked] = useState(false); - - useEffect(() => { - if (isMobileOrIOS()) return; - - const interval = setInterval(() => { - const detected = DevToolsDetector.detect(); - - if (detected && !isBlocked) { - setIsBlocked(true); - onDetected?.(); - } else if (!detected && isBlocked) { - setIsBlocked(false); - clearInterval(interval); - setTimeout(() => window.location.reload(), 100); - } - }, 1000); - - return () => clearInterval(interval); - }, [isBlocked]); - - return isBlocked; -}; \ No newline at end of file