import { useEffect, useRef, useState, useCallback, lazy } from 'react'; import { shallowEqual, useDispatch, useSelector } from 'react-redux'; import moment from 'moment'; import { BiBarcodeReader } from 'react-icons/bi'; import { GoTriangleRight } from 'react-icons/go'; import { FiSearch } from 'react-icons/fi'; import defaultimage from '../../../../Images/defaultItemImg.png'; import { Form, AutoComplete } from 'antd'; import { CloseSquareFilled } from '@ant-design/icons'; import '../../../../Styles/BookingScreen/Template/BSLayout7/BSC1Search.scss'; import { changeSearchedData, ChangeNewQrProduct, getProductsearch, GlobalOrderCardDetails, changeOrderCardDetails, GlobalBookingType, GlobalWSProduct, GlobalSearchData, GlobalNewQrProduct, changeHoldOrderDtl, changePreviousOrderLength, Globalcombofocus, GlobalfocusStatusCustMouse, GlobalSelCustId, GlobalPrintStatus, changeCombofocus, GlobalCompoPaymentIconStatus, GlobalReorderHoldDetails, GlobalWeightScalePort, GlobalWeightScaleWeight, changeothersdata, GlobalCreditFocus, GlobalBookingTypeBoth, GlobalOrderType, GlobalReorderProductDetails, GlobalCompoPreOrderDtlStatus, GlobalDropDownStatus, GlobalPreOrderSearchStatus, GlobalFocusKioskPay, PreferenceData, GlobalFeatAddOnData, GlobalSelectedDatas, getConfigType, GlobalGetmultipleSearchDatas, } from '../../../../Features/BookingScreen/BookingData/BookingData'; import { changepreOrderList, GlobalPreOrderList, GlobalPreOrderAdditem, GlobalpreOrderOpen, } from '../../../../Features/BookingScreen/PreOrder/PreOrder.js'; import { Messages } from '../../../../Components/Notifications/Messages'; import FormHeader from '../../../PageComponents/FormHeader'; import { DefaultModal } from '../../../../Components/Modal/DefaultModal'; import { Tables } from '../../../../Components/Tables/Table'; const FeaturesFunctionalities = lazy( () => import('../BookingFunctionality/FeaturesFunctionalities') ); import { isMobile } from 'react-device-detect'; import { getTemplateData, StoredSessionData, } from '../../../../Features/ThemeChange/ThemeChange.js'; import { v4 as uuidv4 } from 'uuid'; import { changeFreeProductForLoyalty, ChangeFreeProductList, ChangeFullFreeProductList, changeFullOfferAppliedProducts, ChangeOfferAppliedProducts, changeOfferAppliedProductsForLoyalty, changeTriggerOfferFree, getOfferinBooking, GlobalFreeProdList, GlobalOfferAppliedProducts, GlobalTriggerOfferFree, RemoveOfferAppliedProduct, } from '../../../../Features/Offer/Offernew/BookingOffernew.js'; import { Global_PromoCodeOffers } from '../../../../Features/Offer/Offer.js'; import { validateOffers } from '../BSItemCards/ValidateOffer.jsx'; import { useSaleswiseOfferWatcher } from '../BSItemCards/SalesWiseOffer.jsx'; import { calculateOverAllQtyLimit } from '../../../../utils/calculations.js'; import BarCodeScan from '../../../../Services/BarCodeScan.jsx'; const ExpireConfirmModal = lazy( () => import('../BookingFunctionality/ExpireConfirmModal.jsx') ); const BarcodeScanner = lazy( () => import('../UtillComponents/BarcodeScanner.jsx') ); const BSNavBarWeightScale = lazy( () => import('../UtillComponents/BSNavBarWeightScale.jsx') ); export default function BSC1Search(props) { const dispatch = useDispatch(); const searchPromiseRef = useRef(null); const debounceTimerRef = useRef(null); const SessionData = useSelector(StoredSessionData); const BranchId = SessionData?.BranchId; const AppId = SessionData?.AppId; const CompId = SessionData?.CompId; const formRef = useRef(); const triggerOfferFree = useSelector(GlobalTriggerOfferFree); const Globalfocus = useSelector(Globalcombofocus); const preOrder = useSelector(GlobalpreOrderOpen, shallowEqual); const GlobalPreOrderData = useSelector(GlobalPreOrderList); const CartOrderDetails = useSelector(GlobalOrderCardDetails); const BookingTypeBoth = useSelector(GlobalBookingTypeBoth); const BookingType = useSelector(GlobalBookingType); const WSProductdata = useSelector(GlobalWSProduct); const ProductSearch = useSelector(GlobalSearchData); const GetmultipleSearchDatas = useSelector( GlobalGetmultipleSearchDatas, shallowEqual ); const SelectedDatas = useSelector(GlobalSelectedDatas, shallowEqual); const NewQrProductData = useSelector(GlobalNewQrProduct); const ReportholdData = useSelector(GlobalReorderHoldDetails); const WeightScalePort = useSelector(GlobalWeightScalePort); const ReorderProductData = useSelector(GlobalReorderProductDetails); const WeightScaleWeight = useSelector(GlobalWeightScaleWeight); const PreOrderSearchStatus = useSelector(GlobalPreOrderSearchStatus); const KioskFocusStatus = useSelector(GlobalFocusKioskPay); const FeatureAddonData = useSelector(GlobalFeatAddOnData); useSaleswiseOfferWatcher(); const preferenceDatas = useSelector(PreferenceData); const overAllLimitPreferenece = preferenceDatas?.[0]?.[ 'SettingDtlDetails' ]?.find( (item) => item.SettingIdName?.toLowerCase() === 'overalllimit' && item?.SettingValue === 'Y' ); const itemWiseLimitPreferenece = preferenceDatas?.[0]?.[ 'SettingDtlDetails' ]?.find( (item) => item.SettingIdName?.toLowerCase() === 'itemwiselimit' && item?.SettingValue === 'Y' ); const maxQtyLimit = itemWiseLimitPreferenece?.SettingCount || overAllLimitPreferenece?.SettingCount || null; const preferenceOffer = preferenceDatas?.[0]?.['SettingDtlDetails']?.find( (item) => item.SettingIdName === 'Offer' )?.SettingValue === 'Y'; const templateData = useSelector(getTemplateData, shallowEqual); console.log(CartOrderDetails, 'templateData'); const OfferCheckedInSetup = templateData?.BookingNavbar?.[1].some( (item) => item?.OptionName == 'Offer' ) || templateData?.BookingCombo1?.[1]?.some( (item) => item?.OptionName == 'Offer' ); const BSComboData = props?.hasOwnProperty('data') ? props['data'] : null; const [messageType, setMessageType] = useState(null); const [messageData, setMessageData] = useState(null); const [qtydata, setQtydata] = useState(); const [modelQty, setModelQty] = useState(false); const [modelstock, setModelstock] = useState(false); const [ModalVarient, setModalVarient] = useState(false); const [QtyIndex, setQtyIndex] = useState(0); const [repeatedModel, setRepeatedModel] = useState(false); const [VarientIndex, setVarientIndex] = useState(0); const [ProductList, setProductList] = useState([]); const [addFirst, setAddFirst] = useState(false); const [ConfigDataList, setConfigDataList] = useState([]); const [SelectedProduct, setSelectedProduct] = useState({}); const [prodexpir, setProdexpir] = useState(false); const [Item, setItem] = useState(); const [VarItem, setVarItem] = useState(); const [StockItem, setStockItem] = useState(); const [StockPreferenceDetail, setStockPreferenceDetail] = useState(); const [QuickAdd, setQuickAdd] = useState(false); const inputRef = useRef(null); const containerRef = useRef(null); // QR code tracking const [lastScannedQr, setLastScannedQr] = useState(null); const [currentSessionQr, setCurrentSessionQr] = useState(null); const focusStatusCustMouse = useSelector(GlobalfocusStatusCustMouse); const CompoPaymentIconStatus = useSelector(GlobalCompoPaymentIconStatus); const CompoPreOrderDtlStatus = useSelector(GlobalCompoPreOrderDtlStatus); const DropDownStatus = useSelector(GlobalDropDownStatus); const CustChangeDropDown = useSelector(GlobalSelCustId); const printStatus = useSelector(GlobalPrintStatus); const [screenWidth, setScreenWidth] = useState(window.innerWidth); const [preFocus, setpreFocus] = useState(false); const OrderType = useSelector(GlobalOrderType); const [autoCompleteVisible, setAutoCompleteVisible] = useState( preFocus && screenWidth > 768 && OrderType != 'Failed' ? true : false ); const CreditFocus = useSelector(GlobalCreditFocus); const [onePeiceFlow, setOnePeiceFlow] = useState(false); const PreOrderAdditem = useSelector(GlobalPreOrderAdditem); const offerAppliedProducts = useSelector( GlobalOfferAppliedProducts, shallowEqual ); const FreeProdList = useSelector(GlobalFreeProdList); const OverAllproductBasedOfferDatas = useSelector( (state) => state?.BookingOFferNew?.OverAllProductBasedProducts, shallowEqual ); const TakAwayId = ConfigDataList?.find( (a) => a?.ConfigName === 'TakeAway' )?.ConfigId; console.log(TakAwayId, 'TakAwayId'); const DineinId = ConfigDataList?.find( (a) => a?.ConfigName === 'Dine In' )?.ConfigId; const PromoCodeOffersDatas = useSelector( Global_PromoCodeOffers, shallowEqual ); // const [FeatureAddonData, setFeatureAddonData] = useState([]); const [openScanner, setOpenScanner] = useState(false); const scannerRef = useRef(); const updateScreenSize = () => { setScreenWidth(window.innerWidth); }; const [ExpiredProduct, setExpiredProduct] = useState(); const isSelectingRef = useRef(false); const [expireModal, setExpireModal] = useState({ open: false, title: '', onOk: null, onCancel: null, }); const openExpireModal = ({ title, onOk, onCancel }) => { setExpireModal({ open: true, title, onOk, onCancel, }); }; const closeExpireModal = () => { setExpireModal((prev) => ({ ...prev, open: false })); }; //dhana useEffect(() => { const handleKeyPress = (event) => { if (event.shiftKey && event.code === 'KeyS') { if ( document.activeElement.tagName !== 'INPUT' && document.activeElement.tagName !== 'TEXTAREA' ) { event.preventDefault(); inputRef?.current?.focus(); } } }; const handleClickOutside = (event) => { if ( containerRef.current && !containerRef.current.contains(event.target) ) { inputRef?.current?.blur(); } }; window.addEventListener('keydown', handleKeyPress); document.addEventListener('mousedown', handleClickOutside); return () => { window.removeEventListener('keydown', handleKeyPress); document.removeEventListener('mousedown', handleClickOutside); }; }, []); //dhana async function getOffers() { await dispatch( getOfferinBooking({ AppId: AppId, CompId: CompId, BranchId: BranchId }) ).unwrap(); } useEffect(() => { getOffers(); }, []); useEffect(() => { focusPreferenceData(); }, []); useEffect(() => { if (ConfigDataList?.length === 0) { getBookingTypeId(); } }, []); useEffect(() => { const first = preferenceDatas?.[0]?.['SettingDtlDetails']?.find( (item) => item.SettingIdName === 'BillItemsOrder' )?.SettingValue === 'Y'; setAddFirst(first); }, [preferenceDatas]); useEffect(() => { if ( triggerOfferFree && CartOrderDetails?.length > 0 && FreeProdList?.length > 0 ) { let { ModifiedData, UpdatedFreeProdList, AppliedOffers } = handleLoyaltyFreeProducts(CartOrderDetails, FreeProdList); dispatch(changeOrderCardDetails(ModifiedData)); dispatch(ChangeFullFreeProductList(UpdatedFreeProdList)); dispatch(changeFullOfferAppliedProducts(AppliedOffers)); dispatch(changeTriggerOfferFree(false)); } }, [triggerOfferFree]); useEffect(() => { updateScreenSize(); window.addEventListener('resize', updateScreenSize); return () => { window.removeEventListener('resize', updateScreenSize); }; }, []); useEffect(() => { if (preFocus && screenWidth < 768) { setAutoCompleteVisible(true); } }, [screenWidth]); useEffect(() => { preFocus && screenWidth > 768 && inputRef?.current?.focus(); }, [CustChangeDropDown]); useEffect(() => { if (CreditFocus) { setAutoCompleteVisible(false); } else { preFocus && screenWidth > 768 && setAutoCompleteVisible(true); } }, [CreditFocus]); useEffect(() => { if (PreOrderSearchStatus) { setAutoCompleteVisible(false); } else { preFocus && screenWidth > 768 && setAutoCompleteVisible(true); } }, [PreOrderSearchStatus]); useEffect(() => { preFocus && screenWidth > 768 && setAutoCompleteVisible(true); preFocus && screenWidth > 768 && inputRef?.current?.focus(); }, [printStatus]); useEffect(() => { if ( QuickAdd || CompoPaymentIconStatus || focusStatusCustMouse || modelQty || modelstock || ModalVarient || KioskFocusStatus ) { setAutoCompleteVisible(false); } else { preFocus && screenWidth > 768 && setAutoCompleteVisible(true); preFocus && screenWidth > 768 && inputRef?.current?.focus(); } }, [ QuickAdd, CompoPaymentIconStatus, focusStatusCustMouse, modelQty, modelstock, ModalVarient, KioskFocusStatus, ]); useEffect(() => { if (!CompoPreOrderDtlStatus && !DropDownStatus) { preFocus && screenWidth > 768 && setAutoCompleteVisible(true); preFocus && screenWidth > 768 && inputRef?.current?.focus(); } else { setAutoCompleteVisible(false); } }, [CompoPreOrderDtlStatus]); useEffect(() => { preFocus && screenWidth > 768 && inputRef?.current?.focus(); }, [CartOrderDetails]); useEffect(() => { setAutoCompleteVisible(Globalfocus ? false : true); if (!Globalfocus) { preFocus && screenWidth > 768 && inputRef?.current?.focus(); } }, [Globalfocus]); useEffect(() => { if (!preFocus) { setAutoCompleteVisible(false); } else { setAutoCompleteVisible(true); } }, [preFocus]); useEffect(() => { const handleDocumentClick = (event) => { if ( containerRef.current && event.target !== inputRef?.current && !isDescendant(containerRef?.current, event?.target) && autoCompleteVisible && !Globalfocus && !QuickAdd && screenWidth > 768 && preFocus && !CreditFocus && !CompoPreOrderDtlStatus && !focusStatusCustMouse && !KioskFocusStatus ) { inputRef?.current?.focus(); } }; document.addEventListener('click', handleDocumentClick); return () => { document.removeEventListener('click', handleDocumentClick); }; }, [ inputRef, Globalfocus, autoCompleteVisible, QuickAdd, screenWidth, preFocus, CreditFocus, CompoPreOrderDtlStatus, CartOrderDetails, KioskFocusStatus, ]); useEffect(() => { if (autoCompleteVisible) { dispatch(changeCombofocus(false)); preFocus && screenWidth > 768 && inputRef?.current?.focus(); } }, [autoCompleteVisible]); useEffect(() => { if (autoCompleteVisible) { preFocus && screenWidth > 768 && inputRef?.current?.focus(); } }, [autoCompleteVisible]); useEffect(() => { getPreferenceStock(); }, []); useEffect(() => { if (Object.keys(NewQrProductData)?.length > 0) { let addQrProductData = { ...NewQrProductData }; addQrProductData['OrderRate'] = addQrProductData['SellPrice']; addQrProductData['OrderQty'] = addQrProductData['Quantity']; addQrProductData['BookingTypeName'] = BookingType; AddOrderDetails(addQrProductData); } }, [NewQrProductData]); useEffect(() => { if (Object.keys(SelectedProduct)?.length > 0) { ProductSelected(SelectedProduct); } }, [SelectedProduct]); function handleLoyaltyFreeProducts(orderCardDtls, freeProdDtls) { if (!freeProdDtls || freeProdDtls.length === 0) { return { ModifiedData: orderCardDtls, UpdatedFreeProdList: freeProdDtls, AppliedOffers: [], }; } const updatedFreeProdList = JSON.parse(JSON.stringify(freeProdDtls)); // deep copy const AppliedOffers = []; let ModifiedData = []; let processedItems = new Set(); // Track processed items // Helper function to create applied offer object function createAppliedOffer( freeProduct, usedQty, inwardDtlId, orderRate, bookingType ) { const stockDetail = freeProduct.ProdVariantDetails?.[0]?.StockDetails?.[0]; return { OfferId: freeProduct.OfferId, OfferAmount: usedQty * orderRate, OfferMode: freeProduct.OfferMode, ActualOfferAmount: usedQty * orderRate, OfferValue: usedQty * orderRate, TableName: freeProduct.TableName || 'LoyaltyPointsNew', TableUniqueName: freeProduct.TableUniqueName || 'FreeProduct', TableUniqueId: '', ActualFreeQty: usedQty, Detail: [], OfferCode: '', CustId: freeProduct.CustId || '', UsedCount: (stockDetail?.ProdLoyaltyPoint || 0) * usedQty, AppliesTo: '', BookingType: bookingType === 'Dine In' ? 'DineinId' : 'TakAwayId', FreeProductsList: { FreeProdId: freeProduct.FreeProdId, FreeQty: usedQty, FreeProdName: freeProduct.FreeProdName, ProdVariantDetails: [ { FreeProdVariantName: freeProduct.FreeProdVariantName, StockDetails: [ { ProdOfferId: stockDetail?.ProdOfferId || '', FreeInwardDtlId: inwardDtlId, ActiveStatus: 'A', ProdLoyaltyPoint: stockDetail?.ProdLoyaltyPoint || '', }, ], }, ], }, ProdId: '', SinglePc: 'N', StockAvailable: 'N', ProdVariantName: '', Type: '', InwardDtlId: '', ProdCat: '', HalfPrice: 'N', MinQty: '', }; } // First, handle existing paid products that can be converted to free updatedFreeProdList.forEach((freeProduct) => { if (freeProduct.RemainingQty > 0) { // Find matching paid products by InwardDtlId const matchingPaidItems = orderCardDtls.filter( (item) => freeProduct.ProdVariantDetails?.some((variant) => variant.StockDetails?.some( (stock) => stock.FreeInwardDtlId === item.InwardDtlId ) ) && (!item.Offer || item.Offer === 0) && !item.OfferType && !item.OfferMode && !processedItems.has(item.localId) && item?.SinglePc !== 'Y' ); matchingPaidItems.forEach((paidItem) => { const remainingFreeQty = freeProduct.RemainingQty; if (remainingFreeQty <= 0) return; if (paidItem.OrderQty === remainingFreeQty) { // Remove paid item and convert entire quantity to free const freeItem = { ...paidItem, Offer: paidItem.OrderQty * paidItem.OrderRate, OfferType: freeProduct.OfferMode, OfferMode: freeProduct.OfferMode, OfferMessage: [ { OfferId: freeProduct.OfferId, FreeQty: paidItem.OrderQty, FreeProdId: freeProduct.FreeProdId, FreeProdName: freeProduct.FreeProdName, }, ], localId: paidItem.localId + '_converted_free', }; ModifiedData.push(freeItem); // Update free product usage freeProduct.FreeQty = (freeProduct.FreeQty || 0) + paidItem.OrderQty; freeProduct.RemainingQty -= paidItem.OrderQty; // Create applied offer AppliedOffers.push( createAppliedOffer( freeProduct, paidItem.OrderQty, paidItem.InwardDtlId, paidItem.OrderRate, paidItem.BookingTypeName ) ); processedItems.add(paidItem.localId); } else if (paidItem.OrderQty > remainingFreeQty) { // Split: convert available free qty to free, keep excess as paid const freeQty = remainingFreeQty; const paidQty = paidItem.OrderQty - remainingFreeQty; // Create free item const freeItem = { ...paidItem, OrderQty: freeQty, TotalAmt: freeQty * paidItem.OrderRate, TaxAmt: ( (freeQty * paidItem.OrderRate * paidItem.TaxPercentage) / 100 ).toFixed(2), WithoutTaxRate: freeQty * paidItem.OrderRate - (freeQty * paidItem.OrderRate * paidItem.TaxPercentage) / 100, Offer: freeQty * paidItem.OrderRate, OfferType: freeProduct.OfferMode, OfferMode: freeProduct.OfferMode, OfferMessage: [ { OfferId: freeProduct.OfferId, FreeQty: freeQty, FreeProdId: freeProduct.FreeProdId, FreeProdName: freeProduct.FreeProdName, }, ], localId: paidItem.localId + '_free_part', }; // Create updated paid item with reduced quantity const updatedPaidItem = { ...paidItem, OrderQty: paidQty, TotalAmt: paidQty * paidItem.OrderRate, TaxAmt: ( (paidQty * paidItem.OrderRate * paidItem.TaxPercentage) / 100 ).toFixed(2), WithoutTaxRate: paidQty * paidItem.OrderRate - (paidQty * paidItem.OrderRate * paidItem.TaxPercentage) / 100, localId: paidItem.localId + '_paid_part', }; ModifiedData.push(freeItem); ModifiedData.push(updatedPaidItem); // Update free product usage freeProduct.FreeQty = (freeProduct.FreeQty || 0) + freeQty; freeProduct.RemainingQty -= freeQty; // Create applied offer AppliedOffers.push( createAppliedOffer( freeProduct, freeQty, paidItem.InwardDtlId, paidItem.OrderRate, paidItem.BookingTypeName ) ); processedItems.add(paidItem.localId); } }); } }); // Process remaining cart items orderCardDtls.forEach((item) => { // Skip if already processed if (processedItems.has(item.localId)) { return; } // Check if item is currently marked as free (has OfferType/OfferMode and Offer > 0) const isCurrentlyFree = item.Offer > 0 && (item.OfferType || item.OfferMode); if (isCurrentlyFree) { // Find matching free product by InwardDtlId const matchingFreeProduct = updatedFreeProdList.find((freeProd) => freeProd.ProdVariantDetails?.some((variant) => variant.StockDetails?.some( (stock) => stock.FreeInwardDtlId === item.InwardDtlId ) ) ); if (matchingFreeProduct) { const availableFreeQty = matchingFreeProduct.OverAllFreeQty || 0; if (item.OrderQty > availableFreeQty) { // Split: Keep available free qty as free, convert excess to paid const excessQty = item.OrderQty - availableFreeQty; // Create free portion (if any free qty available) if (availableFreeQty > 0) { const freeItem = { ...item, OrderQty: availableFreeQty, TotalAmt: availableFreeQty * item.OrderRate, TaxAmt: ( (availableFreeQty * item.OrderRate * item.TaxPercentage) / 100 ).toFixed(2), WithoutTaxRate: availableFreeQty * item.OrderRate - (availableFreeQty * item.OrderRate * item.TaxPercentage) / 100, Offer: availableFreeQty * item.OrderRate, }; ModifiedData.push(freeItem); // Create applied offer AppliedOffers.push( createAppliedOffer( matchingFreeProduct, availableFreeQty, item.InwardDtlId, item.OrderRate, item.BookingTypeName ) ); } // Handle excess quantity - look for existing paid item in original cart const existingPaidItem = orderCardDtls.find( (cartItem) => cartItem.InwardDtlId === item.InwardDtlId && cartItem.localId !== item.localId && (!cartItem.Offer || cartItem.Offer === 0) && !cartItem.OfferType && !cartItem.OfferMode ); if ( existingPaidItem && !processedItems.has(existingPaidItem.localId) ) { // Merge excess with existing paid item const mergedPaidItem = { ...existingPaidItem, OrderQty: existingPaidItem.OrderQty + excessQty, TotalAmt: (existingPaidItem.OrderQty + excessQty) * item.OrderRate, TaxAmt: ( ((existingPaidItem.OrderQty + excessQty) * item.OrderRate * item.TaxPercentage) / 100 ).toFixed(2), WithoutTaxRate: (existingPaidItem.OrderQty + excessQty) * item.OrderRate - ((existingPaidItem.OrderQty + excessQty) * item.OrderRate * item.TaxPercentage) / 100, }; ModifiedData.push(mergedPaidItem); processedItems.add(existingPaidItem.localId); // Mark as processed } else { // Create new paid item for excess quantity const paidItem = { ...item, OrderQty: excessQty, TotalAmt: excessQty * item.OrderRate, TaxAmt: ( (excessQty * item.OrderRate * item.TaxPercentage) / 100 ).toFixed(2), WithoutTaxRate: excessQty * item.OrderRate - (excessQty * item.OrderRate * item.TaxPercentage) / 100, Offer: 0, OfferType: undefined, OfferMode: undefined, OfferMessage: undefined, localId: item.localId + '_paid', }; ModifiedData.push(paidItem); } } else if (availableFreeQty > 0) { // All quantity can remain free const isAlreadyExists = ModifiedData?.findIndex( (data) => data?.OfferMode === item?.OfferMode && data?.InwardDtlId === item?.InwardDtlId && data?.ProdId === item?.ProdId && data?.OfferMessage?.[0]?.OfferId === item?.OfferMessage?.[0]?.OfferId ); if (isAlreadyExists !== -1) { // Merge with existing free item ModifiedData[isAlreadyExists] = { ...ModifiedData[isAlreadyExists], OrderQty: ModifiedData[isAlreadyExists].OrderQty + item.OrderQty, TotalAmt: (ModifiedData[isAlreadyExists].OrderQty + item.OrderQty) * item.OrderRate, TaxAmt: ( ((ModifiedData[isAlreadyExists].OrderQty + item.OrderQty) * item.OrderRate * item.TaxPercentage) / 100 ).toFixed(2), WithoutTaxRate: (ModifiedData[isAlreadyExists].OrderQty + item.OrderQty) * item.OrderRate - ((ModifiedData[isAlreadyExists].OrderQty + item.OrderQty) * item.OrderRate * item.TaxPercentage) / 100, Offer: (ModifiedData[isAlreadyExists].OrderQty + item.OrderQty) * item.OrderRate, }; } else { // Create new free item const newFreeItem = { ...item, TotalAmt: item.OrderQty * item.OrderRate, TaxAmt: ( (item.OrderQty * item.OrderRate * item.TaxPercentage) / 100 ).toFixed(2), WithoutTaxRate: item.OrderQty * item.OrderRate - (item.OrderQty * item.OrderRate * item.TaxPercentage) / 100, Offer: item.OrderQty * item.OrderRate, }; ModifiedData.push(newFreeItem); } const appliedOfferAlreadyExists = AppliedOffers.findIndex( (offer) => offer?.FreeProductsList?.FreeProdId === matchingFreeProduct?.FreeProdId && offer?.TableName === matchingFreeProduct?.TableName && offer?.TableUniqueName === matchingFreeProduct?.TableUniqueName && offer?.OfferId === matchingFreeProduct?.OfferId && offer?.OfferMode === matchingFreeProduct?.OfferMode && offer?.FreeProductsList?.ProdVariantDetails?.[0] ?.StockDetails?.[0]?.FreeInwardDtlId === item?.InwardDtlId ); if (appliedOfferAlreadyExists !== -1) { AppliedOffers[appliedOfferAlreadyExists] = { ...AppliedOffers[appliedOfferAlreadyExists], ActualOfferAmount: AppliedOffers[appliedOfferAlreadyExists].ActualOfferAmount + item.OrderQty * item.OrderRate, ActualFreeQty: AppliedOffers[appliedOfferAlreadyExists].ActualFreeQty + item.OrderQty, OfferAmount: (AppliedOffers[appliedOfferAlreadyExists].ActualFreeQty + item.OrderQty) * item.OrderRate, OfferValue: (AppliedOffers[appliedOfferAlreadyExists].ActualFreeQty + item.OrderQty) * item.OrderRate, UsedCount: (matchingFreeProduct?.ProdVariantDetails?.[0] ?.StockDetails?.[0]?.ProdLoyaltyPoint || 0) * (AppliedOffers[appliedOfferAlreadyExists].ActualFreeQty + item.OrderQty), FreeProductsList: { ...AppliedOffers[appliedOfferAlreadyExists].FreeProductsList, FreeQty: AppliedOffers[appliedOfferAlreadyExists].FreeProductsList .FreeQty + item.OrderQty, }, }; } else { // Create applied offer AppliedOffers.push( createAppliedOffer( matchingFreeProduct, item.OrderQty, item.InwardDtlId, item.OrderRate, item.BookingTypeName ) ); } } else { // No free quantity available, convert to paid const paidItem = { ...item, Offer: 0, OfferType: undefined, OfferMode: undefined, OfferMessage: undefined, TotalAmt: item.OrderQty * item.OrderRate, TaxAmt: ( (item.OrderQty * item.OrderRate * item.TaxPercentage) / 100 ).toFixed(2), WithoutTaxRate: item.OrderQty * item.OrderRate - (item.OrderQty * item.OrderRate * item.TaxPercentage) / 100, }; ModifiedData.push(paidItem); } } else { // No matching free product found, convert to paid const paidItem = { ...item, Offer: 0, OfferType: undefined, OfferMode: undefined, OfferMessage: undefined, }; ModifiedData.push(paidItem); } } else { // Item is not currently free, check if it can become free const matchingFreeProduct = updatedFreeProdList.find( (freeProd) => freeProd.ProdVariantDetails?.some((variant) => variant.StockDetails?.some( (stock) => stock.FreeInwardDtlId === item.InwardDtlId ) ) && freeProd.RemainingQty > 0 ); if (matchingFreeProduct) { const availableFreeQty = Math.min( item.OrderQty, matchingFreeProduct.RemainingQty ); if (availableFreeQty > 0) { // Create free item for available free quantity const freeItem = { ...item, OrderQty: availableFreeQty, TotalAmt: availableFreeQty * item.OrderRate, TaxAmt: ( (availableFreeQty * item.OrderRate * item.TaxPercentage) / 100 ).toFixed(2), WithoutTaxRate: availableFreeQty * item.OrderRate - (availableFreeQty * item.OrderRate * item.TaxPercentage) / 100, Offer: availableFreeQty * item.OrderRate, OfferType: matchingFreeProduct.OfferMode, OfferMode: matchingFreeProduct.OfferMode, OfferMessage: [ { OfferId: matchingFreeProduct.OfferId, FreeQty: availableFreeQty, FreeProdId: matchingFreeProduct.FreeProdId, FreeProdName: matchingFreeProduct.FreeProdName, }, ], localId: item.localId + '_free', }; ModifiedData.push(freeItem); // Update free product usage matchingFreeProduct.FreeQty = (matchingFreeProduct.FreeQty || 0) + availableFreeQty; matchingFreeProduct.RemainingQty -= availableFreeQty; // Create applied offer AppliedOffers.push( createAppliedOffer( matchingFreeProduct, availableFreeQty, item.InwardDtlId, item.OrderRate, item.BookingTypeName ) ); // If there's remaining paid quantity if (item.OrderQty > availableFreeQty) { const paidQty = item.OrderQty - availableFreeQty; const paidItem = { ...item, OrderQty: paidQty, TotalAmt: paidQty * item.OrderRate, TaxAmt: ( (paidQty * item.OrderRate * item.TaxPercentage) / 100 ).toFixed(2), WithoutTaxRate: paidQty * item.OrderRate - (paidQty * item.OrderRate * item.TaxPercentage) / 100, }; ModifiedData.push(paidItem); } } else { // No free quantity available, keep as paid ModifiedData.push(item); } } else { // No matching free product or no remaining free quantity ModifiedData.push(item); } } processedItems.add(item.localId); }); return { ModifiedData, UpdatedFreeProdList: updatedFreeProdList, AppliedOffers, }; } function safeRound(amountStr) { if (amountStr == null) return '0.00'; const cleaned = String(amountStr).replace(/[^0-9.-]+/g, ''); const num = Number(cleaned); return isNaN(num) ? '0.00' : num.toFixed(2); } const focusPreferenceData = async () => { const filteredDatas = preferenceDatas?.[0]?.SettingDtlDetails?.filter( (item) => item.SettingIdName === 'SearchFocus' && item.SettingValue === 'N' ); console.log('focusPreferenceData', filteredDatas); filteredDatas?.length > 0 ? setpreFocus(false) : setpreFocus(true); }; const isDescendant = (parent, child) => { let node = child.parentNode; while (node !== null) { if (node === parent) { return true; } node = node.parentNode; } return false; }; const handleFocus = () => { preFocus && screenWidth > 768 && setAutoCompleteVisible(true); }; const OnfocusTrue = () => { preFocus && screenWidth > 768 && setAutoCompleteVisible(true); preFocus && screenWidth > 768 && inputRef?.current?.focus(); }; const stopScannerFromParent = () => { if (scannerRef.current) { scannerRef?.current?.stopScanner(); // Call stopScanner from the child component } }; const handleQrcode = () => { setOpenScanner((prev) => !prev); if (!openScanner && scannerRef.current) { scannerRef.current.reinitializeCamera(); // Call the function to reinitialize the camera } }; const getBookingTypeId = async () => { let tempconfigdata = await dispatch( getConfigType({ TypeName: 'Booking Type' }) ).unwrap(); if (tempconfigdata?.data?.statusCode == 1) { setConfigDataList(tempconfigdata?.data?.data); let configdata = tempconfigdata?.data?.data; let checkName = BookingTypeBoth ? 'DineIn,TakeAway' : BookingType; let filterconfigdata = configdata?.find( (a) => a?.ConfigName === checkName ); // setSelectedBookingType(filterconfigdata?.ConfigId); } }; const handleQrData = async (value, err) => { if (err && err?.error) { setMessageData(err?.error); setMessageType('error'); } // await searchdata(value); setOpenScanner(false); // Close the modal after scanning stopScannerFromParent(); }; const ProductNameOnChange = (data) => { if (isSelectingRef.current) { isSelectingRef.current = false; setProductList([]); return; // ⛔ skip search logic } if (debounceTimerRef.current) { clearTimeout(debounceTimerRef.current); } debounceTimerRef.current = setTimeout(async () => { if (searchPromiseRef.current) { searchPromiseRef.current.abort(); } await dispatch(changeSearchedData(data)); // If same QR as current session, just add quantity if (currentSessionQr === data) { if (lastScannedQr) { const updatedProduct = { ...lastScannedQr, OrderQty: (lastScannedQr.OrderQty || 1) + 1, Quantity: (lastScannedQr.Quantity || 1) + 1, }; ProductSelected(updatedProduct); } // clear input after handling repeated scan formRef.current?.resetFields(['ItemName']); setProductList([]); return; } try { // 🚀 Call API for new session QR code searchPromiseRef.current = dispatch( getProductsearch({ CompId, BranchId, AppId, ProdName: data, }) ); const ProductListNew = await searchPromiseRef.current.unwrap(); if (ProductListNew?.statusCode === 1) { const ApiSearchData = ProductListNew?.data?.[0]; if ( ApiSearchData?.QrBasedSearch === 'Y' || ApiSearchData?.OnePcQRBased === 'Y' ) { setCurrentSessionQr(data); setLastScannedQr(ApiSearchData); ProductSelected(ApiSearchData); // clear input once a QR-based product is selected formRef.current?.resetFields(['ItemName']); setProductList([]); setQuickAdd(false); } else if (!ApiSearchData.ProdId && ApiSearchData?.AppId == 0) { setQuickAdd(true); } else { setProductList(ProductListNew?.data); } } else if (data?.length > 5) { setQuickAdd(true); } else { setProductList(null); } } catch (error) { // ❌ Ignore abort errors if (error?.name !== 'AbortError' && error?.name !== 'CanceledError') { console.error('Search error:', error); } } }, 400); // 👈 debounce delay }; const getPreferenceStock = async () => { const PreferenceStckDtl = preferenceDatas?.[0]?.SettingDtlDetails; const StockPreference = PreferenceStckDtl?.find( (item) => item.SettingIdName === 'StockSelection' ); setStockPreferenceDetail(StockPreference); const expiredDate = PreferenceStckDtl?.find( (item) => item.SettingIdName === 'ExpiredSelection' )?.SettingValue === 'Y'; setExpiredProduct(expiredDate); }; function removeDefaultVariantStock(data) { return { ...data, ProductDetail: (data.ProductDetail || []).map((product) => { // Only act when StockAvailable === 'Y' if (product.StockAvailable !== 'Y') { return product; } return { ...product, ProdVariantDetails: (product.ProdVariantDetails || []).map( (variant) => { const hasDefaultVariant = (variant.StockDetails || []).some( (stock) => stock.DefaultVariant === 'Y' ); // If no DefaultVariant exists, return as-is if (!hasDefaultVariant) { return variant; } return { ...variant, StockDetails: variant.StockDetails.filter( (stock) => stock.DefaultVariant !== 'Y' ), }; } ), }; }), }; } const ProductOnSelect = async (data) => { isSelectingRef.current = true; let ProdNamedata = ProductList?.find((item) => item.ProdName === data); const removedDefault = removeDefaultVariantStock(ProdNamedata); setSelectedProduct(removedDefault); formRef.current.resetFields(['ItemName']); }; const ProductSelected = (item) => { if (item.OverAllExpStatus == 'Y') { // setexpModel(true); openExpireModal({ title: 'Product Expires', onOk: () => expFun(Item), }); setItem(item); } else { setQtydata(item); let count = item?.ProductDetail?.length; if (count > 1) { Quantity(); } else { setQtyIndex(0); SingleQuantity(item, onePeiceFlow); // SingleQuantity(item, item?.OnePcQRBased == 'Y'); } } }; const returnQtyCount = (ProdId, item, orderDetails) => { if (onePeiceFlow) { let ItemQuantity = item?.ProdVariantDetails?.reduce( (accumulator, card) => { return accumulator + parseInt(card.OverAllPcs || 0); }, 0 ); let SelectedProduct = ReorderProductData?.filter( (a) => a?.ProdId === ProdId ); let totalSelectedProductQty = SelectedProduct?.reduce( (accumulator, card) => { return ( accumulator + parseInt( card?.StockAvailable === 'Y' ? card.SinglePc !== 'Y' ? card.OrderQty * card.NoOfPcs : card.OrderQty : 0 ) ); }, 0 ); let getCurrentProdDtl = orderDetails?.filter((a) => a?.ProdId === ProdId); let totalOrderQty = getCurrentProdDtl?.reduce((accumulator, card) => { return ( accumulator + parseInt( card?.StockAvailable === 'Y' ? card.SinglePc !== 'Y' ? card.OrderQty * card.NoOfPcs : card.OrderQty : 0 ) ); }, 0); let OverallProdQty = totalOrderQty - totalSelectedProductQty; if ( parseInt(ItemQuantity) > parseInt( Object.keys(ReportholdData)?.length > 0 && totalOrderQty ? OverallProdQty : getCurrentProdDtl ? totalOrderQty : 0 ) ) { let count = parseInt(ItemQuantity) - parseInt( Object.keys(ReportholdData)?.length > 0 && totalOrderQty ? OverallProdQty : getCurrentProdDtl ? totalOrderQty : 0 ); return parseInt(count); } else { let count = 0; return count; } } else { let ItemQuantity = item?.ProdVariantDetails?.reduce( (accumulator, card) => { return accumulator + parseInt(card.OverAllQty || 0); }, 0 ); let SelectedProduct = ReorderProductData?.filter( (a) => a?.ProdId === ProdId ); let totalSelectedProductQty = SelectedProduct?.reduce( (accumulator, card) => { return ( accumulator + parseInt( card?.StockAvailable === 'Y' ? card.SinglePc !== 'Y' ? card.OrderQty : card.OverAllPcs % card.NoOfPcs >= card.OrderQty ? 0 : card.OrderQty % card.NoOfPcs === 0 ? Math.floor(card.OrderQty / card.NoOfPcs) : Math.floor(card.OrderQty / card.NoOfPcs) + 1 : 0 ) ); }, 0 ); let getCurrentProdDtl = orderDetails?.filter((a) => a?.ProdId === ProdId); let totalOrderQty = getCurrentProdDtl?.reduce((accumulator, card) => { return ( accumulator + parseInt( card?.StockAvailable === 'Y' ? card.SinglePc !== 'Y' ? card.OrderQty : card.OverAllPcs % card.NoOfPcs >= card.OrderQty ? 0 : card.OrderQty % card.NoOfPcs === 0 ? Math.floor(card.OrderQty / card.NoOfPcs) : Math.floor(card.OrderQty / card.NoOfPcs) + 1 : 0 ) ); }, 0); let OverallProdQty = totalOrderQty - totalSelectedProductQty; if ( parseInt(ItemQuantity) > parseInt( Object.keys(ReportholdData)?.length > 0 && totalOrderQty ? OverallProdQty : getCurrentProdDtl ? totalOrderQty : 0 ) ) { let count = parseInt(ItemQuantity) - parseInt( Object.keys(ReportholdData)?.length > 0 && totalOrderQty ? OverallProdQty : getCurrentProdDtl ? totalOrderQty : 0 ); return parseInt(count); } else { let count = 0; return count; } } }; const returnCountStock = ( ProdId, currentQty, orderDetails, InwardDtlId, onepcavailable ) => { if (onepcavailable === 'Y') { let SelectedProduct = ReorderProductData?.filter( (a) => a?.ProdId === ProdId && a?.InwardDtlId === InwardDtlId ); let totalSelectedProductQty = SelectedProduct?.reduce( (accumulator, card) => { return ( accumulator + parseInt( card?.StockAvailable === 'Y' ? card.SinglePc !== 'Y' ? card.OrderQty * card.NoOfPcs : card.OrderQty : 0 ) ); }, 0 ); let getCurrentProdDtl = orderDetails?.filter( (a) => a?.ProdId === ProdId && a?.InwardDtlId === InwardDtlId ); let totalOrderQty = getCurrentProdDtl?.reduce((accumulator, card) => { return ( accumulator + parseInt( card?.StockAvailable === 'Y' ? card.SinglePc !== 'Y' ? card.OrderQty * card.NoOfPcs : card.OrderQty : 0 ) ); }, 0); let OverallProdQty = totalOrderQty - totalSelectedProductQty; if ( parseInt(currentQty) > parseInt( Object.keys(ReportholdData)?.length > 0 && totalOrderQty ? OverallProdQty : getCurrentProdDtl ? totalOrderQty : 0 ) ) { let count = parseInt(currentQty) - parseInt( Object.keys(ReportholdData)?.length > 0 && totalOrderQty ? OverallProdQty : getCurrentProdDtl ? totalOrderQty : 0 ); return parseInt(count); } else { let count = 0; return count; } } else { let SelectedProduct = ReorderProductData?.filter( (a) => a?.ProdId === ProdId && a?.InwardDtlId === InwardDtlId ); let totalSelectedProductQty = SelectedProduct?.reduce( (accumulator, card) => { return ( accumulator + parseInt( card?.StockAvailable === 'Y' ? card.SinglePc !== 'Y' ? card.OrderQty : card.OverAllPcs % card.NoOfPcs >= card.OrderQty ? 0 : card.OrderQty % card.NoOfPcs === 0 ? Math.floor(card.OrderQty / card.NoOfPcs) : Math.floor(card.OrderQty / card.NoOfPcs) + 1 : 0 ) ); }, 0 ); let getCurrentProdDtl = orderDetails?.filter( (a) => a?.ProdId === ProdId && a?.InwardDtlId === InwardDtlId ); let totalOrderQty = getCurrentProdDtl?.reduce((accumulator, card) => { return ( accumulator + parseInt( card?.StockAvailable === 'Y' ? card.SinglePc !== 'Y' ? card.OrderQty : card.OverAllPcs % card.NoOfPcs >= card.OrderQty ? 0 : card.OrderQty % card.NoOfPcs === 0 ? Math.floor(card.OrderQty / card.NoOfPcs) : Math.floor(card.OrderQty / card.NoOfPcs) + 1 : 0 ) ); }, 0); let OverallProdQty = totalOrderQty - totalSelectedProductQty; if ( parseInt(currentQty) > parseInt( Object.keys(ReportholdData)?.length > 0 && totalOrderQty ? OverallProdQty : getCurrentProdDtl ? totalOrderQty : 0 ) ) { let count = parseInt(currentQty) - parseInt( Object.keys(ReportholdData)?.length > 0 && totalOrderQty ? OverallProdQty : getCurrentProdDtl ? totalOrderQty : 0 ); return parseInt(count); } else { let count = 0; return count; } } }; const returnVariantStock = ( ProdId, currentQty, orderDetails, ProdVariantName ) => { if (onePeiceFlow) { let SelectedProduct = ReorderProductData?.filter( (a) => a?.ProdId === ProdId && a?.ProdVariantName === ProdVariantName ); let totalSelectedProductQty = SelectedProduct?.reduce( (accumulator, card) => { return ( accumulator + parseInt( card?.StockAvailable === 'Y' ? card.SinglePc !== 'Y' ? card.OrderQty * card.NoOfPcs : card.OrderQty : 0 ) ); }, 0 ); let getCurrentProdDtl = orderDetails?.filter( (a) => a?.ProdId === ProdId && a?.ProdVariantName === ProdVariantName ); let totalOrderQty = getCurrentProdDtl?.reduce((accumulator, card) => { return ( accumulator + parseInt( card?.StockAvailable === 'Y' ? card.SinglePc !== 'Y' ? card.OrderQty * card.NoOfPcs : card.OrderQty : 0 ) ); }, 0); if ( parseInt(currentQty) > parseInt( Object.keys(ReportholdData)?.length > 0 && totalOrderQty ? totalOrderQty - totalSelectedProductQty : getCurrentProdDtl ? totalOrderQty : 0 ) ) { let count = parseInt(currentQty) - parseInt( Object.keys(ReportholdData)?.length > 0 && totalOrderQty ? totalOrderQty - totalSelectedProductQty : getCurrentProdDtl ? totalOrderQty : 0 ); return parseInt(count); } else { let count = 0; return count; } } else { let SelectedProduct = ReorderProductData?.filter( (a) => a?.ProdId === ProdId && a?.ProdVariantName === ProdVariantName ); let totalSelectedProductQty = SelectedProduct?.reduce( (accumulator, card) => { return ( accumulator + parseInt( card?.StockAvailable === 'Y' ? card.SinglePc !== 'Y' ? card.OrderQty : card.OverAllPcs % card.NoOfPcs >= card.OrderQty ? 0 : card.OrderQty % card.NoOfPcs === 0 ? Math.floor(card.OrderQty / card.NoOfPcs) : Math.floor(card.OrderQty / card.NoOfPcs) + 1 : 0 ) ); }, 0 ); let getCurrentProdDtl = orderDetails?.filter( (a) => a?.ProdId === ProdId && a?.ProdVariantName === ProdVariantName ); let totalOrderQty = getCurrentProdDtl?.reduce((accumulator, card) => { return ( accumulator + parseInt( card?.StockAvailable === 'Y' ? card.SinglePc !== 'Y' ? card.OrderQty : card.OverAllPcs % card.NoOfPcs >= card.OrderQty ? 0 : card.OrderQty % card.NoOfPcs === 0 ? Math.floor(card.OrderQty / card.NoOfPcs) : Math.floor(card.OrderQty / card.NoOfPcs) + 1 : 0 ) ); }, 0); if ( parseInt(currentQty) > parseInt( Object.keys(ReportholdData)?.length > 0 && totalOrderQty ? totalOrderQty - totalSelectedProductQty : getCurrentProdDtl ? totalOrderQty : 0 ) ) { let count = parseInt(currentQty) - parseInt( Object.keys(ReportholdData)?.length > 0 && totalOrderQty ? totalOrderQty - totalSelectedProductQty : getCurrentProdDtl ? totalOrderQty : 0 ); return parseInt(count); } else { let count = 0; return count; } } }; const StockDate = (date) => { let dateVal = moment(date, ['YYYY-MM-DDTHH:mm:ss']).format('DD-MM-YYYY'); return dateVal; }; const varientcolumns = [ { title: 'Variant Name', dataIndex: 'VarientName', key: 'VarientName', align: 'left', render: (_, record) => ( 0 || record.StockCount === 'Stock Not Maintained' ? { color: '#000', cursor: 'pointer' } : { color: '#f49898', cursor: 'not-allowed' } } > {record.VarientName} ), onCell: (record) => { return { onClick: () => { if ( record.StockCount > 0 || record.StockCount === 'Stock Not Maintained' ) { Stockfun(record); } }, }; }, }, { title: 'Stock Count', dataIndex: 'StockCount', key: 'StockCount', align: 'Right', render: (_, record, index) => ( 0 || record.StockCount === 'Stock Not Maintained' ? { color: '#000', cursor: 'pointer' } : { color: '#f49898', cursor: 'not-allowed' } } > {record.StockCount} ), onCell: (record) => { return { onClick: () => { if ( record.StockCount > 0 || record.StockCount === 'Stock Not Maintained' ) { Stockfun(record); } }, }; }, }, { title: 'Amount', dataIndex: 'Amount', key: 'Amount', align: 'right', render: (_, record, index) => ( 0 || record.StockCount === 'Stock Not Maintained' ? { color: '#000', cursor: 'pointer' } : { color: '#f49898', cursor: 'not-allowed' } } > {safeRound(record.Amount)} ), onCell: (record) => { return { onClick: () => { if ( record.StockCount > 0 || record.StockCount === 'Stock Not Maintained' ) { Stockfun(record); } }, }; }, }, ]; const stockcolumns = [ { title: 'Batch No', dataIndex: 'Batch No', key: 'Batch No', align: 'center', render: (text, record, index) => ( 0 ? { color: '#000', cursor: 'pointer' } : { color: '#f49898', cursor: 'not-allowed' } } > {record?.['Batch No']} ), onCell: (record) => { return { onClick: () => { if (record.StockCount > 0) { StockSelected(record); } }, }; }, }, { title: 'Stock Count', dataIndex: 'StockCount', key: 'StockCount', align: 'center', render: (_, record) => ( 0 ? { color: '#000', cursor: 'pointer' } : { color: '#f49898', cursor: 'not-allowed' } } > {record.StockCount} ), onCell: (record) => { return { onClick: () => { if (record.StockCount > 0) { StockSelected(record); } }, }; }, }, { title: 'Stock Date', dataIndex: 'Stock Date', key: 'Stock Date', align: 'center', render: (_, record) => ( 0 ? { color: '#000', cursor: 'pointer' } : { color: '#f49898', cursor: 'not-allowed' } } > {record?.['Stock Date']} ), onCell: (record) => { return { onClick: () => { if (record.StockCount > 0) { StockSelected(record); } }, }; }, }, { title: 'Exp Date', dataIndex: 'ExpDate', key: 'ExpDate', align: 'center', render: (_, record, index) => ( 0 ? { color: '#000', cursor: 'pointer' } : { color: '#f49898', cursor: 'not-allowed' } } > {record.ExpDate} ), onCell: (record) => { return { onClick: () => { if (record.StockCount > 0) { StockSelected(record); } }, }; }, }, { title: 'Price', dataIndex: 'Price', key: 'Price', align: 'center', render: (text) => {safeRound(text)}, onCell: (record) => { return { onClick: () => { if (record.StockCount > 0) { StockSelected(record); } }, }; }, }, ]; const qtydataSource = []; qtydata?.ProductDetail?.map((item, index) => { qtydataSource.push({ key: index, Quantity: item?.Size + ' ' + item?.UomName, Amount: item?.ProdVariantDetails?.[0]?.StockDetails?.[0]?.SellPrice, }); }); const varientdataSource = []; qtydata?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.map((item, index) => { varientdataSource.push({ key: index, VarientName: item?.ProdVariantName, Amount: onePeiceFlow ? item?.StockDetails?.[0]?.OnePcsPrice : item?.StockDetails?.[0]?.SellPrice, StockCount: qtydata?.ProductDetail?.[0]?.StockAvailable === 'Y' ? returnVariantStock( qtydata?.ProductDetail?.[QtyIndex]?.ProdId, item?.OverAllQty, CartOrderDetails, item?.ProdVariantName ) : 'Stock Not Maintained', }); }); const stockdataSource = []; qtydata?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[ VarientIndex ]?.StockDetails?.map((item, index) => { const expDate = new Date(item?.ExpDate); stockdataSource.push({ key: index, 'Batch No': item?.BatchRef, StockCount: onePeiceFlow ? returnCountStock( item?.ProdId, item?.BalanceQty, CartOrderDetails, item?.InwardDtlId ) * item?.NoOfPcs : returnCountStock( item?.ProdId, item?.BalanceQty, CartOrderDetails, item?.InwardDtlId ), 'Stock Date': StockDate(item?.InwardDate), Price: onePeiceFlow ? item?.OnePcsPrice : item?.SellPrice, ExpDate: expDate != 'Invalid Date' || null || undefined || '' ? StockDate(item?.ExpDate) : '-', }); }); const CloseModal = () => { setModelQty(false); setRepeatedModel(false); setProdexpir(false); setOnePeiceFlow(false); }; const CloseModal1 = () => { setModelstock(false); setRepeatedModel(false); setProdexpir(false); setOnePeiceFlow(false); }; const CloseVarientModal = () => { setModalVarient(false); setRepeatedModel(false); setProdexpir(false); setOnePeiceFlow(false); }; const Quantity = () => { setModelQty(true); }; const SingleQuantity = (item, onePcs) => { let count = item?.ProductDetail?.[0]?.ProdVariantDetails.length; if (count > 1) { setModalVarient(true); } else { setVarientIndex(0); SingleStockfun(item, onePcs); } }; const SingleStockfun = (item, onePcs) => { let count = item?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.length; if (StockPreferenceDetail?.SettingValue === 'Y') { if (count > 1) { setModelstock(true); } else { let Isincart = CartOrderDetails?.find( (cartItem) => cartItem?.ProdId === item?.ProductDetail?.[QtyIndex]?.ProdId && cartItem?.InwardDtlId === item?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[ VarientIndex ]?.StockDetails?.[0]?.InwardDtlId && cartItem?.OrderRate === item?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[ VarientIndex ]?.StockDetails?.[0]?.SellPrice && !cartItem?.SalesId ); if (onePcs) { let Isincartonepc = CartOrderDetails?.filter( (cartItem) => cartItem?.ProdId === item?.ProductDetail?.[QtyIndex]?.ProdId && cartItem?.InwardDtlId === item?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[ VarientIndex ]?.StockDetails?.[0]?.InwardDtlId && // (cartItem?.OrderRate === item?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex]?.StockDetails?.[0]?.SellPrice) !cartItem?.SalesId ); let totalOrderQty = Isincartonepc?.reduce((accumulator, card) => { return ( accumulator + parseInt( card?.StockAvailable === 'Y' ? card.SinglePc !== 'Y' ? card.OrderQty * card.NoOfPcs : card.OrderQty : 0 ) ); }, 0); if (Isincartonepc && Isincartonepc?.[0]?.StockAvailable === 'Y') { if (Isincartonepc?.[0]?.OverAllPcs > totalOrderQty) { dataTransfer(item, 0, 0, 0, onePcs); } else { dataTransfer(item, 0, 0, 1, onePcs); } } else { dataTransfer(item, 0, 0, 0, onePcs); } } else { if (Isincart && Isincart?.StockAvailable === 'Y') { if (Isincart?.BalanceQty > Isincart?.OrderQty) { dataTransfer(item, 0, 0, 0, onePcs); } else { dataTransfer(item, 0, 0, 1, onePcs); } } else { dataTransfer(item, 0, 0, 0, onePcs); } } } } else { let Isincart = CartOrderDetails?.find( (cartItem) => cartItem?.ProdId === item?.ProductDetail?.[QtyIndex]?.ProdId && cartItem?.InwardDtlId === item?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[0]?.InwardDtlId && cartItem?.OrderRate === item?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[0]?.SellPrice && !cartItem?.SalesId ); if (onePcs) { let Isincartonepc = CartOrderDetails?.filter( (cartItem) => cartItem?.ProdId === item?.ProductDetail?.[QtyIndex]?.ProdId && cartItem?.InwardDtlId === item?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[ VarientIndex ]?.StockDetails?.[0]?.InwardDtlId && // (cartItem?.OrderRate === item?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex]?.StockDetails?.[0]?.SellPrice) !cartItem?.SalesId ); let totalOrderQty = Isincartonepc?.reduce((accumulator, card) => { return ( accumulator + parseInt( card?.StockAvailable === 'Y' ? card.SinglePc !== 'Y' ? card.OrderQty * (card.NoOfPcs ? card.NoOfPcs : 1) : card.OrderQty : 0 ) ); }, 0); if (Isincartonepc && Isincartonepc?.[0]?.StockAvailable === 'Y') { if (Isincartonepc?.[0]?.OverAllPcs > totalOrderQty) { dataTransfer(item, 0, 0, 0, onePcs); } else { dataTransfer(item, 0, 0, 1, onePcs); } } else { dataTransfer(item, 0, 0, 0, onePcs); } } else { if (Isincart && Isincart?.StockAvailable === 'Y') { if (Isincart?.BalanceQty > Isincart?.OrderQty) { dataTransfer(item, 0, 0, 0, onePcs); } else { dataTransfer(item, 0, 0, 1, onePcs); } } else { dataTransfer(item, 0, 0, 0, onePcs); } } } }; const Stockfun = (index) => { setVarientIndex(index.key); const variantDetails = qtydata?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[index.key] || {}; const overallExpStatus = variantDetails.OverAllExpStatus; const count = variantDetails.StockDetails?.length || 0; if (StockPreferenceDetail?.SettingValue === 'Y') { if (count > 1) { if ( overallExpStatus === 'N' || (overallExpStatus === 'Y' && prodexpir) ) { setModalVarient(false); setModelstock(true); setVarItem(index.key); if (overallExpStatus === 'Y' && prodexpir) { setRepeatedModel(true); } } else if (overallExpStatus === 'Y' && ExpiredProduct) { setVarItem(index.key); openExpireModal({ title: 'Variant Expires', onOk: () => expVerFun(VarItem), onCancel: () => { setRepeatedModel(false); setProdexpir(false); }, }); } } else { if ( overallExpStatus === 'N' || (overallExpStatus === 'Y' && prodexpir) ) { let Isincart = CartOrderDetails?.find( (cartItem) => cartItem?.ProdId === qtydata?.ProductDetail?.[QtyIndex]?.ProdId && cartItem?.InwardDtlId === qtydata?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[ index.key ]?.StockDetails?.[0]?.InwardDtlId && cartItem?.OrderRate === qtydata?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[ index.key ]?.StockDetails?.[0]?.SellPrice && !cartItem?.SalesId ); if (onePeiceFlow) { let Isincartonepc = CartOrderDetails?.filter( (cartItem) => cartItem?.ProdId === qtydata?.ProductDetail?.[QtyIndex]?.ProdId && cartItem?.InwardDtlId === qtydata?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[ VarientIndex ]?.StockDetails?.[0]?.InwardDtlId && // (cartItem?.OrderRate === item?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex]?.StockDetails?.[0]?.SellPrice) !cartItem?.SalesId ); let totalOrderQty = Isincartonepc?.reduce((accumulator, card) => { return ( accumulator + parseInt( card?.StockAvailable === 'Y' ? card.SinglePc !== 'Y' ? card.OrderQty * (card.NoOfPcs ? card.NoOfPcs : 1) : card.OrderQty : 0 ) ); }, 0); if (Isincartonepc && Isincartonepc?.[0]?.StockAvailable === 'Y') { if (Isincartonepc?.[0]?.OverAllPcs > totalOrderQty) { dataTransfer(qtydata, QtyIndex, index.key, 0, onePeiceFlow); } else { dataTransfer(qtydata, QtyIndex, index.key, 1, onePeiceFlow); } } else { dataTransfer(qtydata, QtyIndex, index.key, 0, onePeiceFlow); } } else { if (Isincart && Isincart?.StockAvailable === 'Y') { if (Isincart?.BalanceQty > Isincart?.OrderQty) { dataTransfer(qtydata, QtyIndex, index.key, 0, onePeiceFlow); } else { dataTransfer(qtydata, QtyIndex, index.key, 1, onePeiceFlow); } } else { dataTransfer(qtydata, QtyIndex, index.key, 0, onePeiceFlow); } } setModelQty(false); setVarItem(index.key); if (overallExpStatus === 'Y' && prodexpir) { setProdexpir(false); setRepeatedModel(true); } } else if (overallExpStatus === 'Y') { setVarItem(index.key); if (!ExpiredProduct) { expVerFun(index.key); } else { openExpireModal({ title: 'Variant Expires', onOk: () => expVerFun(VarItem), onCancel: () => { setRepeatedModel(false); setProdexpir(false); }, }); } } } } else { let Isincart = CartOrderDetails?.find( (cartItem) => cartItem?.ProdId === qtydata?.ProductDetail?.[QtyIndex]?.ProdId && cartItem?.InwardDtlId === qtydata?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[index.key] ?.StockDetails?.[0]?.InwardDtlId && cartItem?.OrderRate === qtydata?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[index.key] ?.StockDetails?.[0]?.SellPrice && !cartItem?.SalesId ); if (onePeiceFlow) { let Isincartonepc = CartOrderDetails?.filter( (cartItem) => cartItem?.ProdId === qtydata?.ProductDetail?.[QtyIndex]?.ProdId && cartItem?.InwardDtlId === qtydata?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[ VarientIndex ]?.StockDetails?.[0]?.InwardDtlId && // (cartItem?.OrderRate === item?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex]?.StockDetails?.[0]?.SellPrice) !cartItem?.SalesId ); let totalOrderQty = Isincartonepc?.reduce((accumulator, card) => { return ( accumulator + parseInt( card?.StockAvailable === 'Y' ? card.SinglePc !== 'Y' ? card.OrderQty * (card.NoOfPcs ? card.NoOfPcs : 1) : card.OrderQty : 0 ) ); }, 0); if (Isincartonepc && Isincartonepc?.[0]?.StockAvailable === 'Y') { if (Isincartonepc?.[0]?.OverAllPcs > totalOrderQty) { dataTransfer(qtydata, QtyIndex, index.key, 0, onePeiceFlow); } else { dataTransfer(qtydata, QtyIndex, index.key, 1, onePeiceFlow); } } else { dataTransfer(qtydata, QtyIndex, index.key, 0, onePeiceFlow); } } else { if (Isincart && Isincart?.StockAvailable === 'Y') { if (Isincart?.BalanceQty > Isincart?.OrderQty) { dataTransfer(qtydata, QtyIndex, index.key, 0, onePeiceFlow); } else { dataTransfer(qtydata, QtyIndex, index.key, 1, onePeiceFlow); } } else { dataTransfer(qtydata, QtyIndex, index.key, 0, onePeiceFlow); } } setModelQty(false); } }; const VarientFun = (index) => { let selectedProIndex = qtydata?.ProductDetail?.findIndex( (item) => item?.ProdId === index?.ProdId && item?.Size === index?.Size && item?.UomName === index?.UomName && item?.Brand === index?.Brand ); setQtyIndex(selectedProIndex); let count = qtydata?.ProductDetail[selectedProIndex]?.ProdVariantDetails?.length; if (count > 1) { setModelQty(false); setModalVarient(true); } else { const item = { QtyIndex: selectedProIndex, VarientIndex: 0 }; singleVarient(item); setModelQty(false); } }; const singleVarient = (item) => { let count = qtydata?.ProductDetail?.[item?.QtyIndex]?.ProdVariantDetails?.[ item?.VarientIndex ]?.StockDetails?.length; if (StockPreferenceDetail?.SettingValue === 'Y') { if (count > 1) { setModalVarient(false); setModelstock(true); // setVarientIndex(index.key) } else { let Isincart = CartOrderDetails?.find( (cartItem) => cartItem?.ProdId === qtydata?.ProductDetail?.[item?.QtyIndex]?.ProdId && cartItem?.InwardDtlId === qtydata?.ProductDetail?.[item?.QtyIndex]?.ProdVariantDetails?.[ item?.VarientIndex ]?.StockDetails?.[0]?.InwardDtlId && cartItem?.OrderRate === qtydata?.ProductDetail?.[item?.QtyIndex]?.ProdVariantDetails?.[ item?.VarientIndex ]?.StockDetails?.[0]?.SellPrice && !cartItem?.SalesId ); if (onePeiceFlow) { let Isincartonepc = CartOrderDetails?.filter( (cartItem) => cartItem?.ProdId === qtydata?.ProductDetail?.[item?.QtyIndex]?.ProdId && cartItem?.InwardDtlId === qtydata?.ProductDetail?.[item?.QtyIndex]?.ProdVariantDetails?.[ item?.VarientIndexs ]?.StockDetails?.[0]?.InwardDtlId && // (cartItem?.OrderRate === item?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex]?.StockDetails?.[0]?.SellPrice) !cartItem?.SalesId ); let totalOrderQty = Isincartonepc?.reduce((accumulator, card) => { return ( accumulator + parseInt( card?.StockAvailable === 'Y' ? card.SinglePc !== 'Y' ? card.OrderQty * card.NoOfPcs : card.OrderQty : 0 ) ); }, 0); if (Isincartonepc && Isincartonepc?.[0]?.StockAvailable === 'Y') { if (Isincartonepc?.[0]?.OverAllPcs > totalOrderQty) { dataTransfer( qtydata, item?.QtyIndex, item?.VarientIndex, 0, onePeiceFlow ); } else { dataTransfer( qtydata, item?.QtyIndex, item?.VarientIndex, 1, onePeiceFlow ); } } else { dataTransfer( qtydata, item?.QtyIndex, item?.VarientIndex, 0, onePeiceFlow ); } } else { if (Isincart && Isincart?.StockAvailable === 'Y') { if (Isincart?.BalanceQty > Isincart?.OrderQty) { dataTransfer( qtydata, item?.QtyIndex, item?.VarientIndex, 0, onePeiceFlow ); } else { dataTransfer( qtydata, item?.QtyIndex, item?.VarientIndex, 1, onePeiceFlow ); } } else { dataTransfer( qtydata, item?.QtyIndex, item?.VarientIndex, 0, onePeiceFlow ); } } setModelQty(false); } } else { let Isincart = CartOrderDetails?.find( (cartItem) => cartItem?.ProdId === qtydata?.ProductDetail?.[item?.QtyIndex]?.ProdId && cartItem?.InwardDtlId === qtydata?.ProductDetail?.[item?.QtyIndex]?.ProdVariantDetails?.[ item?.VarientIndex ]?.StockDetails?.[0]?.InwardDtlId && cartItem?.OrderRate === qtydata?.ProductDetail?.[item?.QtyIndex]?.ProdVariantDetails?.[ item?.VarientIndex ]?.StockDetails?.[0]?.SellPrice && !cartItem?.SalesId ); if (onePeiceFlow) { let Isincartonepc = CartOrderDetails?.filter( (cartItem) => cartItem?.ProdId === qtydata?.ProductDetail?.[item?.QtyIndex]?.ProdId && cartItem?.InwardDtlId === qtydata?.ProductDetail?.[item?.QtyIndex]?.ProdVariantDetails?.[ item?.VarientIndex ]?.StockDetails?.[0]?.InwardDtlId && // (cartItem?.OrderRate === item?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex]?.StockDetails?.[0]?.SellPrice) !cartItem?.SalesId ); let totalOrderQty = Isincartonepc?.reduce((accumulator, card) => { return ( accumulator + parseInt( card?.StockAvailable === 'Y' ? card.SinglePc !== 'Y' ? card.OrderQty * card.NoOfPcs : card.OrderQty : 0 ) ); }, 0); if (Isincartonepc && Isincartonepc?.[0]?.StockAvailable === 'Y') { if (Isincartonepc?.[0]?.OverAllPcs > totalOrderQty) { dataTransfer( qtydata, item?.QtyIndex, item?.VarientIndex, 0, onePeiceFlow ); } else { dataTransfer( qtydata, item?.QtyIndex, item?.VarientIndex, 1, onePeiceFlow ); } } else { dataTransfer( qtydata, item?.QtyIndex, item?.VarientIndex, 0, onePeiceFlow ); } } else { if (Isincart && Isincart?.StockAvailable === 'Y') { if (Isincart?.BalanceQty > Isincart?.OrderQty) { dataTransfer( qtydata, item?.QtyIndex, item?.VarientIndex, 0, onePeiceFlow ); } else { dataTransfer( qtydata, item?.QtyIndex, item?.VarientIndex, 1, onePeiceFlow ); } } else { dataTransfer( qtydata, item?.QtyIndex, item?.VarientIndex, 0, onePeiceFlow ); } } setModelQty(false); } }; const StockSelected = (item) => { const stockDetails = qtydata?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[item.key] || {}; const overallExpStatus = stockDetails?.OverAllExpStatus; if (overallExpStatus === 'N' || overallExpStatus === 'Y') { const firstStockDetails = qtydata?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[0] ?.StockDetails?.[item.key] || {}; const firstOverallExpStatus = firstStockDetails.OverAllExpStatus; if ( overallExpStatus === 'N' || (firstOverallExpStatus === 'Y' && prodexpir) ) { dataTransfer(qtydata, QtyIndex, VarientIndex, item.key, onePeiceFlow); } else if (overallExpStatus === 'Y' && repeatedModel) { dataTransfer(qtydata, QtyIndex, VarientIndex, item.key, onePeiceFlow); } else { openExpireModal({ title: 'Stock Expires', onOk: () => expStockFun(StockItem), onCancel: () => { setRepeatedModel(false); setProdexpir(false); }, }); setStockItem(item.key); } } setProdexpir(false); closeExpireModal(); }; useEffect(() => { if (Object.keys(WSProductdata)?.length > 0) { AddOrderDetails(WSProductdata); } }, [WSProductdata]); const dataTransfer = (a, QtyIndex, VarientIndex, stockIndex, onePcs) => { const isKgsProduct = (a?.ProductDetail?.[QtyIndex]?.UomName?.toLowerCase() === 'kgs' || a?.ProductDetail?.[QtyIndex]?.UomName?.toLowerCase() === 'kg'?.toLowerCase()) && a?.ProductDetail?.[QtyIndex]?.Size === '1'; if ( WeightScalePort === true && isKgsProduct && WeightScaleWeight > 0.005 && WeightScaleWeight !== null ) { let TotalOrderRate = parseFloat( onePcs ? (a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.OnePcsPrice / 1000) * (parseFloat(WeightScaleWeight) * 1000) : a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.SellPrice / 1000 ) * (parseFloat(WeightScaleWeight) * 1000); let data = { Type: a?.Type, OverallQuantity: a?.OverAllQty, ActiveStatus: a?.ProductDetail?.[QtyIndex]?.ActiveStatus, AvailableFrom: a?.ProductDetail?.[QtyIndex]?.AvailableFrom, AvailableTo: a?.ProductDetail?.[QtyIndex]?.AvailableTo, Cess: a?.ProductDetail?.[QtyIndex]?.Cess, HSNCode: a?.ProductDetail?.[QtyIndex]?.HSNCode, BrandName: a?.ProductDetail?.[QtyIndex]?.BrandName, // 'ManufDate': a?.ProductDetail?.[QtyIndex]?.ManufDate, OpeningQty: a?.ProductDetail?.[QtyIndex]?.OpeningQty, PartNumber: a?.ProductDetail?.[QtyIndex]?.PartNumber, ProdId: a?.ProductDetail?.[QtyIndex]?.ProdId, ProdLogo: a?.ProductDetail?.[QtyIndex]?.ProdLogo, ProdName: a?.ProductDetail?.[QtyIndex]?.ProdName, QRCode: a?.ProductDetail?.[QtyIndex]?.QRCode, QtyBasedPrice: a?.ProductDetail?.[QtyIndex]?.QtyBasedPrice, Rack: a?.ProductDetail?.[QtyIndex]?.Rack, Size: parseFloat(WeightScaleWeight), StockAvailable: a?.ProductDetail?.[QtyIndex]?.StockAvailable, TokenAvailable: a?.ProductDetail?.[QtyIndex]?.TokenAvailable, TaxId: a?.ProductDetail?.[QtyIndex]?.TaxId, TaxPercentage: a?.ProductDetail?.[QtyIndex]?.TaxPercentage, TaxName: a?.ProductDetail?.[QtyIndex]?.TaxIdName, UniqueId: a?.ProductDetail?.[QtyIndex]?.UniqueId, UomName: onePcs ? 'PCS' : a?.ProductDetail?.[QtyIndex]?.UomName, SinglePc: onePcs ? 'Y' : 'N', NoOfPcs: a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.NoOfPcs, ProdVariantName: a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.ProdVariantName, BalanceQty: a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.BalanceQty, BatchRef: a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.BatchRef, InwardDate: a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.InwardDate, InwardDtlId: a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.InwardDtlId, ExpDate: a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.ExpDate, InwardId: a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.InwardId, MRP: onePcs ? a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.OnePcsPrice : a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.MRP, FullProductIdentifierDtls: a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.ProductIdentifierDtls, OrderRate: parseFloat(TotalOrderRate).toFixed(2), SellingPrice: parseFloat(TotalOrderRate).toFixed(2), SuppId: a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.SuppId, SuppName: a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.SuppName, OverAllPcs: a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.OverAllPcs, Offer: a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.OfferPrice, BookingTypeName: BookingType, CounterName: a?.CounterName, }; setModelQty(false); setModalVarient(false); setModelstock(false); setQtyIndex(0); setVarientIndex(0); setVarItem(0); (setItem(), setStockItem()); dispatch(changeSearchedData('')); AddOrderDetails(data); // dispatch(changeWeightScaleWeight(null)); closeExpireModal(); setProdexpir(false); setOnePeiceFlow(false); // } else { // setMessageType('error'); // setMessageData('Please Connect WeightScale'); // } // } else { // setMessageType('error'); // setMessageData('Please Select 1Kg Product'); // } } else { if ( (onePcs && a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.NoOfPcs > 0 && a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.OnePcsPrice > 0) || !onePcs || (a?.ProductDetail?.[QtyIndex]?.StockAvailable !== 'Y' && onePcs && a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.OnePcsPrice > 0) ) { let data = { Type: a?.Type, OverallQuantity: a?.OverAllQty, ActiveStatus: a?.ProductDetail?.[QtyIndex]?.ActiveStatus, AvailableFrom: a?.ProductDetail?.[QtyIndex]?.AvailableFrom, AvailableTo: a?.ProductDetail?.[QtyIndex]?.AvailableTo, Cess: a?.ProductDetail?.[QtyIndex]?.Cess, HSNCode: a?.ProductDetail?.[QtyIndex]?.HSNCode, BrandName: a?.ProductDetail?.[QtyIndex]?.BrandName, // 'ManufDate': a?.ProductDetail?.[QtyIndex]?.ManufDate, OpeningQty: a?.ProductDetail?.[QtyIndex]?.OpeningQty, PartNumber: a?.ProductDetail?.[QtyIndex]?.PartNumber, ProdId: a?.ProductDetail?.[QtyIndex]?.ProdId, ProdLogo: a?.ProductDetail?.[QtyIndex]?.ProdLogo, ProdName: a?.ProductDetail?.[QtyIndex]?.ProdName, QRCode: a?.ProductDetail?.[QtyIndex]?.QRCode, QtyBasedPrice: a?.ProductDetail?.[QtyIndex]?.QtyBasedPrice, Rack: a?.ProductDetail?.[QtyIndex]?.Rack, Size: onePcs ? '1' : a?.ProductDetail?.[QtyIndex]?.Size, StockAvailable: a?.ProductDetail?.[QtyIndex]?.StockAvailable, TokenAvailable: a?.ProductDetail?.[QtyIndex]?.TokenAvailable, TaxId: a?.ProductDetail?.[QtyIndex]?.TaxId, TaxPercentage: a?.ProductDetail?.[QtyIndex]?.TaxPercentage, TaxName: a?.ProductDetail?.[QtyIndex]?.TaxIdName, UniqueId: a?.ProductDetail?.[QtyIndex]?.UniqueId, UomName: a?.ProductDetail?.[QtyIndex]?.UomName, SinglePc: onePcs ? 'Y' : 'N', NoOfPcs: a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.NoOfPcs, ProdVariantName: a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.ProdVariantName, BalanceQty: a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.BalanceQty, BatchRef: a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.BatchRef, InwardDate: a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.InwardDate, InwardDtlId: a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.InwardDtlId, ExpDate: a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.ExpDate, InwardId: a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.InwardId, MRP: onePcs ? a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.OnePcsPrice : a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.MRP, OrderRate: onePcs ? a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.OnePcsPrice : a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.SellPrice, SellingPrice: onePcs ? a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.OnePcsPrice : a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.SellPrice, SuppId: a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.SuppId, OverAllPcs: a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.OverAllPcs, SuppName: a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.SuppName, Offer: a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.OfferPrice, FullProductIdentifierDtls: a?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[VarientIndex] ?.StockDetails?.[stockIndex]?.ProductIdentifierDtls, BookingTypeName: BookingType, CounterName: a?.CounterName, }; setModelQty(false); setModalVarient(false); setModelstock(false); setQtyIndex(0); setVarientIndex(0); setVarItem(0); (setItem(), setStockItem()); dispatch(changeSearchedData('')); AddOrderDetails(data); setOnePeiceFlow(false); } else { setMessageType('error'); setMessageData( 'Please add No.of pieces Inside the box in Product master' ); formRef.current.resetFields(['ItemName']); setSelectedProduct({}); setModelQty(false); setModalVarient(false); setModelstock(false); setQtyIndex(0); setVarientIndex(0); setVarItem(0); (setItem(), setStockItem()); dispatch(changeSearchedData('')); setOnePeiceFlow(false); } } }; const calculateOverAllQty = (item, filterItems) => { if (!item) return 0; const totalUsedQty = filterItems?.reduce((acc, card) => { if (card?.StockAvailable !== 'Y') return acc; const isSinglePcItem = item?.SinglePc === 'Y'; const isSinglePcCard = card?.SinglePc === 'Y'; let qty = 0; if (isSinglePcItem) { qty = isSinglePcCard ? card.OrderQty : card.OrderQty * card.NoOfPcs; } else { if (isSinglePcCard) { const remainder = card?.OverAllPcs % card?.NoOfPcs; qty = remainder >= card?.OrderQty ? 0 : Math.ceil(card?.OrderQty / card?.NoOfPcs); } else { qty = card.OrderQty; } } return acc + qty; }, 0) || 0; const availableQty = item?.SinglePc === 'Y' ? item?.OverAllPcs : item?.BalanceQty || 0; return (availableQty || 0) - totalUsedQty; }; const AddOrderDetails = async (item) => { if ((overAllLimitPreferenece || itemWiseLimitPreferenece) && maxQtyLimit) { if (overAllLimitPreferenece) { const calculatedOverAllQty = calculateOverAllQtyLimit(CartOrderDetails); if (calculatedOverAllQty + 1 > maxQtyLimit) { setMessageData(`Overall Quantity Limit Exceeds than ${maxQtyLimit}`); setMessageType('warning'); return; } } } if (preOrder) { await handlePreOrder(item); } else { await handleRegularOrder(item); } }; const handlePreOrder = async (item) => { let Response = await dispatch( getConfigType({ TypeName: 'Booking Type' }) ).unwrap(); let BookingTypeID; if (Response?.data?.statusCode == 1) { BookingTypeID = Response?.data?.data?.find( (item) => item?.ConfigName === 'Dine In' )?.ConfigId; } let Condition = GlobalPreOrderData?.some( (obj) => obj?.InwardDtlId === item?.InwardDtlId && obj?.SinglePc === item?.SinglePc ); if (PreOrderAdditem !== 'AddItems') { setMessageData('Have To choose Add Item Before select Any Item '); setMessageType('error'); return; } if (Condition) { setMessageData('Duplicate Data'); setMessageType('error'); return; } const calculateWithoutTaxRate = (qty, rate, taxPercentage) => { const totalAmount = qty * rate; const taxAmount = ( (totalAmount * taxPercentage) / (100 + taxPercentage) ).toFixed(2); const withoutTaxRate = (totalAmount - taxAmount).toFixed(2); return parseFloat(withoutTaxRate); }; const SelectedProduct = { ProdId: item?.ProdId, InwardDtlId: item?.InwardDtlId, ProdNameQty: item?.ProdName + ' ' + item?.Size + ' ' + item?.UomName, ProdName: item?.ProdName, Size: item?.Size, UomName: item?.UomName, OrderQty: 1, OrderRate: item?.OrderRate, TotalAmt: item?.OrderRate, Image: null, Description: null, Type: item?.Type, TaxAmt: 0, RefundQty: 0, TaxId: item?.TaxId, OrderStatus: 'O', OrderType: 'PRE', SinglePc: item?.SinglePc, BookingType: BookingTypeID, WithoutTaxRate: calculateWithoutTaxRate( 1, item?.OrderRate, item?.TaxPercentage ), StockAvailable: item?.StockAvailable, }; const Data = GlobalPreOrderData?.length > 0 ? [SelectedProduct, ...GlobalPreOrderData] : [SelectedProduct]; await dispatch(changepreOrderList(Data)); }; const handleRegularOrder = async (item) => { const isHoldOrder = OrderType === 'Hold'; const hasOffer = OfferCheckedInSetup && preferenceOffer; const isExistsInFreeProdList = hasOffer ? FreeProdList?.filter( (f) => f?.FreeProdId === item?.ProdId && f?.ProdVariantDetails?.some((variant) => variant?.StockDetails?.some( (stock) => stock?.FreeInwardDtlId === item?.InwardDtlId ) ) && f?.RemainingQty > 0 ) : []; const calculateTaxAmounts = (qty, rate, taxPercentage) => { const totalAmount = qty * rate; const taxAmount = ( (totalAmount * taxPercentage) / (100 + taxPercentage) ).toFixed(2); const withoutTaxRate = (totalAmount - taxAmount).toFixed(2); return { TotalAmt: totalAmount, TaxAmt: parseFloat(taxAmount), WithoutTaxRate: parseFloat(withoutTaxRate), }; }; // Helper function to create updated cart item const createUpdatedCartItem = (cartItem, newQty = null) => { const quantity = newQty || cartItem.OrderQty + 1; const taxAmounts = calculateTaxAmounts( quantity, cartItem.OrderRate, cartItem.TaxPercentage ); return { ...cartItem, OrderQty: quantity, ...taxAmounts, }; }; // Helper function to create new item for cart const createNewCartItem = (item, quantity = 1) => { const taxAmounts = calculateTaxAmounts( quantity, item.OrderRate, item.TaxPercentage ); return { ...item, localId: uuidv4(), OrderQty: quantity, ...taxAmounts, }; }; dispatch(changeHoldOrderDtl(false)); dispatch(changePreviousOrderLength(CartOrderDetails?.length)); const itemMatchCondition = (cartItem) => cartItem.ProdId === item.ProdId && cartItem.InwardDtlId === item.InwardDtlId && cartItem.OrderRate === item.OrderRate && cartItem.BookingTypeName === item.BookingTypeName && cartItem.ScaleType === item.ScaleType; // item.WeightscaleProd !== 'Y'; const isItemInCart = CartOrderDetails?.find( (cartItem) => itemMatchCondition(cartItem) && !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 isItemInCartfilter = CartOrderDetails?.filter( (cartItem) => cartItem?.ProdId === item?.ProdId && cartItem?.InwardDtlId === item?.InwardDtlId && cartItem?.OrderRate !== item?.OrderRate && !cartItem?.SalesId ); const isItemInCartHold = CartOrderDetails?.find( (cartItem) => itemMatchCondition(cartItem) && (cartItem?.OfferMode !== 'B' && cartItem?.OfferMode !== 'P' && cartItem?.OfferMode !== 'C' && cartItem?.OfferMode !== 'O' && cartItem?.OfferMode !== 'L' ? true : cartItem?.Offer === 0) ); // Filter cart items const otherOrderDataForNormal = CartOrderDetails?.filter( (cartItem) => !( itemMatchCondition(cartItem) && !cartItem.SalesId && ((cartItem?.OfferModeType && cartItem?.OfferMode === 'B' ? true : cartItem?.OfferMode !== 'B') && cartItem?.OfferMode !== 'P' && cartItem?.OfferMode !== 'L' && cartItem?.OfferMode !== 'C' && cartItem?.OfferMode !== 'O' ? true : cartItem?.Offer === 0) ) ); const otherOrderDataForNormalWithoutSalesId = CartOrderDetails?.filter( (cartItem) => !( itemMatchCondition(cartItem) && (cartItem?.OfferMode !== 'B' && cartItem?.OfferMode !== 'P' && cartItem?.OfferMode !== 'L' && cartItem?.OfferMode !== 'C' && cartItem?.OfferMode !== 'O' ? true : cartItem?.Offer === 0) ) ); try { // CASE 1: Item exists in cart, not Dine In, not Hold order if (isItemInCart && !isHoldOrder) { const itemInCart = CartOrderDetails?.find( (cartItem) => itemMatchCondition(cartItem) && !cartItem.SalesId ); let totalUsedQty = 0; const sameBookingTypeItems = CartOrderDetails?.filter( (cartItem) => itemMatchCondition(cartItem) && !cartItem.SalesId ); const differentBookingTypeItems = CartOrderDetails?.filter( (cartItem) => cartItem.ProdId === item.ProdId && cartItem.InwardDtlId === item.InwardDtlId && cartItem.OrderRate === item.OrderRate && cartItem.BookingTypeName !== item.BookingTypeName && cartItem.ScaleType === item.ScaleType && !cartItem.SalesId ); if (sameBookingTypeItems?.length > 0) { const stockAvailable = sameBookingTypeItems?.some( (item) => item?.StockAvailable === 'Y' ); if (stockAvailable) { totalUsedQty = sameBookingTypeItems?.reduce((acc, item) => { if (item?.StockAvailable === 'Y') { return acc + parseInt(item?.OrderQty); } return acc; }, 0); } } if (differentBookingTypeItems?.length > 0) { const stockAvailable = differentBookingTypeItems?.some( (item) => item?.StockAvailable === 'Y' ); if (stockAvailable) { totalUsedQty += differentBookingTypeItems?.reduce((acc, item) => { if (item?.StockAvailable === 'Y') { return acc + parseInt(item?.OrderQty); } return acc; }, 0); } } const overAllQty = calculateOverAllQty(itemInCart, isItemInCartfilter); if ( (overAllQty > totalUsedQty && isItemInCart?.StockAvailable === 'Y') || isItemInCart?.StockAvailable !== 'Y' ) { if ( isExistsInFreeProdList?.length > 0 && hasOffer && item?.SinglePc !== 'Y' ) { handleFreeProduct(item, isExistsInFreeProdList, addFirst); } else { const updatedCartItem = createUpdatedCartItem( isItemInCart, item?.OtherProduct === 'Others' || item?.ScaleType === 'weight' ? ( (item?.OrderQty || 0) + parseFloat(isItemInCart?.OrderQty) )?.toFixed(3) : null ); const updatedData = addFirst ? [updatedCartItem, ...otherOrderDataForNormal] : [...otherOrderDataForNormal, updatedCartItem]; if ( OverAllproductBasedOfferDatas?.ProdDtl?.length > 0 && hasOffer ) { handleFreeProductAvailable( updatedCartItem, updatedData, addFirst ); } else { dispatch(changeOrderCardDetails(updatedData)); } } } else { setMessageType('error'); setMessageData('Stock Not Available'); formRef.current.resetFields(['ItemName']); setSelectedProduct({}); } } // CASE 2: Item exists in cart (hold), is Hold order else if (isItemInCartHold && isHoldOrder) { const holddataproduct = ReorderProductData?.filter( (cartItem) => cartItem?.ProdId === item?.ProdId && cartItem?.InwardDtlId === item?.InwardDtlId ); let totalSelectedProductQty = holddataproduct?.reduce( (accumulator, card) => { return ( accumulator + parseInt( card?.StockAvailable === 'Y' ? item?.SinglePc === 'Y' ? card.SinglePc !== 'Y' ? card.OrderQty * card.NoOfPcs : card.OrderQty : card.SinglePc !== 'Y' ? card.OrderQty : card.OverAllPcs % card.NoOfPcs >= card.OrderQty ? 0 : card.OrderQty % card.NoOfPcs === 0 ? Math.floor(card.OrderQty / card.NoOfPcs) : Math.floor(card.OrderQty / card.NoOfPcs) + 1 : 0 ) ); }, 0 ); const itemInCartHold = CartOrderDetails?.find((cartItem) => itemMatchCondition(cartItem) ); const itemInCartHoldFilter = CartOrderDetails?.filter( (cartItem) => cartItem?.ProdId === item?.ProdId && cartItem?.InwardDtlId === item?.InwardDtlId && cartItem?.OrderRate !== item?.OrderRate ); const overAllQtyHold = calculateOverAllQty(itemInCartHold, itemInCartHoldFilter) + totalSelectedProductQty; let totalUsedQty = 0; const sameBookingTypeItems = CartOrderDetails?.filter((cartItem) => itemMatchCondition(cartItem) ); const differentBookingTypeItems = CartOrderDetails?.filter( (cartItem) => cartItem.ProdId === item.ProdId && cartItem.InwardDtlId === item.InwardDtlId && cartItem.OrderRate === item.OrderRate && cartItem.BookingTypeName !== item.BookingTypeName ); if (sameBookingTypeItems?.length > 0) { const stockAvailable = sameBookingTypeItems?.some( (item) => item?.StockAvailable === 'Y' ); if (stockAvailable) { totalUsedQty = sameBookingTypeItems?.reduce((acc, item) => { if (item?.StockAvailable === 'Y') { return acc + parseInt(item?.OrderQty); } return acc; }, 0); } } if (differentBookingTypeItems?.length > 0) { const stockAvailable = differentBookingTypeItems?.some( (item) => item?.StockAvailable === 'Y' ); if (stockAvailable) { totalUsedQty += differentBookingTypeItems?.reduce((acc, item) => { if (item?.StockAvailable === 'Y') { return acc + parseInt(item?.OrderQty); } return acc; }, 0); } } if (overAllQtyHold > totalUsedQty) { if ( isExistsInFreeProdList?.length > 0 && hasOffer && item?.SinglePc !== 'Y' ) { handleFreeProduct(item, isExistsInFreeProdList, addFirst); } else { const updatedCartItem = createUpdatedCartItem( isItemInCartHold, item?.OtherProduct === 'Others' || item?.ScaleType === 'weight' ? ( (item?.OrderQty || 0) + parseFloat(isItemInCartHold?.OrderQty) )?.toFixed(3) : null ); const updatedData = addFirst ? [updatedCartItem, ...otherOrderDataForNormalWithoutSalesId] : [...otherOrderDataForNormalWithoutSalesId, updatedCartItem]; if ( OverAllproductBasedOfferDatas?.ProdDtl?.length > 0 && hasOffer ) { handleFreeProductAvailable( updatedCartItem, updatedData, addFirst ); } else { dispatch(changeOrderCardDetails(updatedData)); } } } else { setMessageType('error'); setMessageData('Stock Not Available'); formRef.current.resetFields(['ItemName']); setSelectedProduct({}); } } // CASE 3: New item - not in cart else { if (item.OtherProduct === 'Others' || item.ScaleType == 'weight') { const newCartItem = createNewCartItem(item, item.OrderQty); const updatedData = addFirst ? [newCartItem, ...CartOrderDetails] : [...CartOrderDetails, newCartItem]; dispatch(changeOrderCardDetails(updatedData)); } else { if ( (item?.StockAvailable === 'Y' && calculateOverAllQty(item, isItemInCartfilter) > 0) || item?.StockAvailable === 'N' ) { if ( isExistsInFreeProdList?.length > 0 && hasOffer && item?.SinglePc !== 'Y' ) { handleFreeProduct(item, isExistsInFreeProdList, addFirst); } else { const newCartItem = createNewCartItem(item, 1); const updatedData = addFirst ? [newCartItem, ...CartOrderDetails] : [...CartOrderDetails, newCartItem]; if ( OverAllproductBasedOfferDatas?.ProdDtl?.length > 0 && hasOffer ) { handleFreeProductAvailable(newCartItem, updatedData, addFirst); } else { dispatch(changeOrderCardDetails(updatedData)); } } } else { setMessageType('error'); setMessageData('Stock Not Available'); formRef.current.resetFields(['ItemName']); setSelectedProduct({}); } } } } catch (error) { console.error('Error updating order details:', error); } finally { // Clean up dispatch calls dispatch(changeothersdata({})); dispatch(ChangeNewQrProduct({})); } }; const handleFreeProduct = (item, filteredFreeProdList, addFirst) => { if (!filteredFreeProdList?.length) return; const offerMode = filteredFreeProdList[0]?.OfferMode; // --- helper functions --- const calcTax = (qty, rate, taxPerc) => ((qty * rate * taxPerc) / 100).toFixed(2); const calcWithoutTax = (qty, rate, taxPerc) => qty * rate - ((qty * rate * taxPerc) / 100).toFixed(2); const updateFreeProductMeta = (base, qty, rate) => ({ ...base, FreeQty: qty, discount: qty * rate, RemainingQty: base.OverAllFreeQty - qty, ProdVariantDetails: base.ProdVariantDetails.map((variant) => ({ ...variant, StockDetails: variant.StockDetails.map((stock) => ({ ...stock, UsedFree: qty, RemainingFree: stock.RemainingFree - qty, })), })), }); const applyOffer = (offerList, updatedItem) => { if (offerMode === 'L') { const updated = loyaltyOfferApply( offerList, updatedItem, DineinId, TakAwayId ); dispatch(changeOfferAppliedProductsForLoyalty(updated)); dispatch(changeFreeProductForLoyalty(offerList[0])); } else if (offerMode === 'P' || offerMode === 'C' || offerMode === 'O') { const updated = buildOfferFromChangesForPromoCodes( PromoCodeOffersDatas?.[0], offerList, updatedItem, DineinId, TakAwayId ); dispatch(changeOfferAppliedProductsForLoyalty(updated)); dispatch(changeFreeProductForLoyalty(offerList[0])); } else { const updated = buildOfferFromChanges( OverAllproductBasedOfferDatas, offerList, updatedItem, DineinId, TakAwayId ); dispatch(ChangeOfferAppliedProducts(updated)); dispatch(ChangeFreeProductList(offerList[0])); } }; // --- main logic --- let UpdatedData = []; const existing = CartOrderDetails?.find( (c) => c.ProdId === item.ProdId && c.InwardDtlId === item.InwardDtlId && c.OrderRate === item.OrderRate && c.BookingTypeName === item.BookingTypeName && c.OfferMode === offerMode && c.Offer > 0 ); const existsInOther = CartOrderDetails?.find( (c) => c.ProdId === item.ProdId && c.InwardDtlId === item.InwardDtlId && c.OrderRate === item.OrderRate && c.BookingTypeName !== item.BookingTypeName && c.OfferMode === offerMode && c.Offer > 0 ); if (existing) { let newQty = existing.OrderQty + 1; const UpdatedCartItem = { ...existing, OrderQty: newQty, TotalAmt: existing.TotalAmt + existing.OrderRate, Offer: existing.Offer + existing.OrderRate, TaxAmt: calcTax(newQty, existing.OrderRate, existing.TaxPercentage), WithoutTaxRate: calcWithoutTax( newQty, existing.OrderRate, existing.TaxPercentage ), OfferMessage: [ { OfferId: filteredFreeProdList[0].OfferId, FreeQty: newQty, FreeProdId: filteredFreeProdList[0].FreeProdId, FreeProdName: filteredFreeProdList[0].FreeProdName, }, ], }; if (existsInOther) { newQty = newQty + existsInOther?.OrderQty; } const updatedOfferList = [ updateFreeProductMeta(filteredFreeProdList[0], newQty, item.OrderRate), ]; UpdatedData = CartOrderDetails.map((c) => c === existing ? UpdatedCartItem : c ); applyOffer(updatedOfferList, UpdatedCartItem); } else { let newQty = 1; const UpdatedCartItem = { ...item, localId: uuidv4(), OrderQty: newQty, TotalAmt: item.OrderRate, Offer: item.OrderRate, OfferType: offerMode, OfferMode: offerMode, TaxAmt: calcTax(1, item.OrderRate, item.TaxPercentage), WithoutTaxRate: calcWithoutTax(1, item.OrderRate, item.TaxPercentage), OfferMessage: [ { OfferId: filteredFreeProdList[0].OfferId, FreeQty: 1, FreeProdId: filteredFreeProdList[0].FreeProdId, FreeProdName: filteredFreeProdList[0].FreeProdName, }, ], }; if (existsInOther) { newQty = newQty + existsInOther?.OrderQty; } const updatedOfferList = [ updateFreeProductMeta(filteredFreeProdList[0], newQty, item.OrderRate), ]; UpdatedData = addFirst ? [UpdatedCartItem, ...CartOrderDetails] : [...CartOrderDetails, UpdatedCartItem]; applyOffer(updatedOfferList, UpdatedCartItem); } dispatch(changeOrderCardDetails(UpdatedData)); }; const handleFreeProductAvailable = async (item, cartData, addFirst) => { const offers = chooseOfferFun(item, cartData); if (!offers?.length) { const indexToCheck = addFirst ? 0 : cartData.length - 1; const productToCheck = cartData?.[addFirst ? 0 : cartData?.length - 1]; let updatedCartData = cartData; if (productToCheck?.OfferMode && productToCheck?.Offer > 0) { dispatch( RemoveOfferAppliedProduct({ ProdId: productToCheck?.ProdId, InwardDtlId: productToCheck?.InwardDtlId, OfferType: productToCheck?.OfferMode, }) ); updatedCartData = cartData.map((item, idx) => idx === indexToCheck ? { ...item, Offer: null, OfferMessage: undefined, OfferMode: undefined, OfferModeType: false, OfferType: undefined, OfferValue: null, } : item ); } const { updatedOrderCardDetails, updatedFreeProdList, updatedOfferAppliedProducts, hasChanges, } = processFreeProducts(updatedCartData, FreeProdList); if (hasChanges) { dispatch(changeOrderCardDetails(updatedOrderCardDetails)); dispatch(ChangeFreeProductList(updatedFreeProdList)); dispatch(ChangeOfferAppliedProducts(updatedOfferAppliedProducts)); } else { dispatch(changeOrderCardDetails(updatedOrderCardDetails)); } return; } let bestOffer = null; let OfferNeedToApply = true; let updatedFreeProductList = []; let sameProduct = false; for (const offer of offers) { if (offer.OfferMode === 'B') { const { OfferAmount, OfferMessage, OfferApply, updatedFreeProdList, ProductOfferType, } = applyBuyNGetFreeOffer(cartData, offer, item); offer.OfferAmount = OfferAmount; offer.OfferMessage = OfferMessage; OfferNeedToApply = OfferApply; updatedFreeProductList = updatedFreeProdList; sameProduct = ProductOfferType; } if (!bestOffer || offer.OfferAmount > bestOffer.OfferAmount) { bestOffer = offer; } } const UpdatedCartItemWithOffer = { ...item, Offer: sameProduct || bestOffer?.OfferMode === 'I' || bestOffer?.OfferMode === 'Q' ? bestOffer?.OfferAmount || item.Offer : item.Offer || bestOffer?.OfferAmount, OfferType: item?.OfferType || bestOffer?.OfferType, OfferMessage: item?.OfferMessage || bestOffer?.OfferMessage, OfferMode: item?.OfferMode || bestOffer?.OfferMode, OfferModeType: sameProduct, }; const shouldRemove = (c) => c.ProdId === item.ProdId && c.InwardDtlId === item.InwardDtlId && c.OrderRate === item.OrderRate && c.BookingTypeName === item.BookingTypeName && ((c?.OfferModeType && c?.OfferMode === 'B' ? true : c?.OfferMode !== 'B') && c?.OfferMode !== 'P' && c?.OfferMode !== 'C' && c?.OfferMode !== 'O' && c?.OfferMode !== 'L' ? true : c?.Offer === 0); const filteredCart = CartOrderDetails.filter((c) => !shouldRemove(c)); const UpdatedDataAfterOffer = addFirst ? [UpdatedCartItemWithOffer, ...filteredCart] : [...filteredCart, UpdatedCartItemWithOffer]; if (bestOffer && OfferNeedToApply) { dispatch(ChangeOfferAppliedProducts(bestOffer)); } const { updatedOrderCardDetails, updatedFreeProdList, updatedOfferAppliedProducts, hasChanges, } = processFreeProducts(UpdatedDataAfterOffer, updatedFreeProductList); // Update the states dispatch(changeOrderCardDetails(updatedOrderCardDetails)); if (hasChanges) { dispatch(ChangeFullFreeProductList(updatedFreeProdList)); dispatch(ChangeOfferAppliedProducts(updatedOfferAppliedProducts)); } else { dispatch(ChangeFullFreeProductList(updatedFreeProductList)); } }; function buildOfferFromChangesForPromoCodes( PromoCodeOffersDatas, ChangesHappenList, item, DineinId, TakAwayId ) { const results = []; ChangesHappenList.forEach((change) => { const offer = PromoCodeOffersDatas.ProdOfferDetails.find( (o) => o.OfferId === change.OfferId ); if (offer) { // 🛠️ Build normalized object const formatted = { OfferId: offer?.OfferId || '', OfferAmount: change?.discount || 0, OfferType: offer?.OfferType || '', // I / Q / B OfferCode: PromoCodeOffersDatas?.OfferCode, ActualOfferAmount: offer?.OfferAmt || 0, OfferValue: offer?.OfferAmt || 0, TableName: change?.TableName || '', TableUniqueName: change?.TableUniqueName || '', TableUniqueId: change?.TableUniqueId || '', // OfferType: offer?.ValueType || "", // F / P Detail: offer?.Detail || [], OfferCode: offer?.OfferCode || '', CustId: offer?.CustId || '', UsedCount: offer?.UsedCount || 0, AppliesTo: offer?.AppliesTo || '', BookingType: item?.BookingTypeName === 'Dine In' ? DineinId : TakAwayId, ActualFreeQty: change?.FreeQty, // ✅ Merge FreeProducts from offer + update with ChangesHappenList FreeProductsList: { FreeProdId: change?.FreeProdId, FreeQty: change?.FreeQty, FreeProdName: change?.FreeProdName, OfferId: offer?.OfferId, OverAllFreeQty: change?.OverAllFreeQty, ProdVariantDetails: change?.ProdVariantDetails?.map((e) => { return { FreeProdVariantName: e?.FreeProdVariantName, StockDetails: e?.StockDetails?.map((exp) => { return { ProdOfferId: exp?.ProdOfferId, FreeInwardDtlId: exp?.FreeInwardDtlId, ActiveStatus: exp?.ActiveStatus, }; }), }; }), }, // ✅ Always include product-level fields ProdId: '', SinglePc: '', StockAvailable: '', ProdVariantName: '', Type: '', InwardDtlId: '', ProdCat: '', HalfPrice: 'N', MinQty: 0, }; results.push(formatted); } }); return results; } function buildOfferFromChanges( OverAllproductBasedOfferDatas, ChangesHappenList, item, DineinId, TakeAwayId ) { const offersById = new Map( OverAllproductBasedOfferDatas.ProdDtl.map((o) => [o.OfferId, o]) ); return ChangesHappenList.flatMap((change) => { const offer = offersById.get(change.OfferId); if (!offer) return []; const getFreeProductsList = () => { const freeProducts = offer.FreeProducts || offer.FreeProductsList || []; const normalizedList = Array.isArray(freeProducts) ? freeProducts : [freeProducts]; return normalizedList.map((fp) => { if (!change?.ProdVariantDetails) { return { FreeProdId: fp?.FreeProdId || '', FreeQty: fp?.FreeQty || 0, FreeProdName: fp?.FreeProdName || '', ProdVariantDetails: fp?.ProdVariantDetails || [], }; } // Merge variant + stock details with change const updatedVariants = fp.ProdVariantDetails?.map((variant) => { const changedVariant = change.ProdVariantDetails.find( (v) => v.FreeProdVariantName === variant.ProdVariantName ); if (!changedVariant) return variant; const updatedStock = variant.StockDetails.map((stock) => { const changedStock = changedVariant.StockDetails.find( (s) => s.InwardDtlId === stock.InwardDtlId ); if (changedStock) { const { InwardDtlId, ...rest } = { ...stock, ...changedStock }; return { ...rest, FreeInwardDtlId: stock.InwardDtlId }; } const { InwardDtlId, ...rest } = stock; return { ...rest, FreeInwardDtlId: stock.InwardDtlId }; }); return { ...variant, StockDetails: updatedStock }; }); return { FreeProdId: fp?.FreeProdId || '', FreeQty: change?.FreeQty ?? (fp?.FreeQty || 0), FreeProdName: fp?.FreeProdName || '', ProdVariantDetails: updatedVariants || [], }; }); }; return { OfferId: offer.OfferId || '', OfferAmount: change?.discount || 0, OfferMode: offer.OfferType || '', // I / Q / B ActualOfferAmount: offer.OfferAmt || 0, OfferValue: offer.OfferAmt || 0, TableName: offer.TableName || '', TableUniqueName: offer.TableUniqueName || '', TableUniqueId: offer.TableUniqueId || '', ActualFreeQty: change?.FreeQty || 0, Detail: offer.Detail || [], OfferCode: offer.OfferCode || '', CustId: offer.CustId || '', UsedCount: offer.UsedCount || 0, AppliesTo: offer.AppliesTo || '', BookingType: item?.BookingTypeName === 'Dine In' ? DineinId : TakeAwayId, FreeProductsList: getFreeProductsList(), // Product-level fields ProdId: change?.ProdId || '', SinglePc: change?.SinglePc || '', StockAvailable: change?.StockAvailable || '', ProdVariantName: change?.ProdVariantName || '', Type: item?.Type || '', InwardDtlId: change?.InwardDtlId || '', ProdCat: change?.ProdCat || '', HalfPrice: offer.HalfPrice || 'N', MinQty: offer.MinQty || 0, }; }); } const loyaltyOfferApply = (ChangesHappenList, item, DineinId, TakAwayId) => { const result = []; const change = ChangesHappenList?.[0]; const formatted = { OfferId: change?.OfferId, OfferAmount: change?.discount || 0, OfferValue: change?.OfferAmt || 0, TableName: change?.TableName || '', TableUniqueName: change?.TableUniqueName || '', TableUniqueId: change?.TableUniqueId || '', ProdId: change?.ProdId || '', SinglePc: change?.SinglePc || '', StockAvailable: change?.StockAvailable || '', ProdVariantName: change?.ProdVariantName || '', ActualFreeQty: change?.FreeQty || 0, Type: '', BookingType: item?.BookingTypeName === 'Dine In' ? DineinId : TakAwayId, InwardDtlId: change?.InwardDtlId || '', OfferType: change?.OfferMode || '', Detail: [{}], ProdCat: change?.ProdCat || '', CustId: change?.CustId || '', UsedCount: change?.ProdVariantDetails?.reduce( (sum, variant) => sum + (variant?.StockDetails?.reduce( (variantSum, stock) => variantSum + (stock?.ProdLoyaltyPoint * stock?.UsedFree || 0), 0 ) || 0), 0 ) || 0, FreeProductsList: change, }; result?.push(formatted); return result; }; function chooseOfferFun(item, CartData) { return validateOffers( item, OverAllproductBasedOfferDatas, CartData, TakAwayId, DineinId ); } function changeFreeProductList(FreeProdList, newFreeProd) { if (!newFreeProd || !newFreeProd.ProdId || !newFreeProd.InwardDtlId) { return FreeProdList; // 🚫 Skip invalid payload } const index = FreeProdList.findIndex( (f) => f.ProdId === newFreeProd.ProdId && f.InwardDtlId === newFreeProd.InwardDtlId ); if (index !== -1) { let existing = JSON.parse(JSON.stringify(FreeProdList[index])); // deep clone if (newFreeProd.ProdVariantDetails) { newFreeProd.ProdVariantDetails.forEach((newVariant) => { const existingVariant = existing.ProdVariantDetails?.find( (v) => v.VariantName === newVariant.VariantName ); if (existingVariant) { newVariant.StockDetails.forEach((newStock) => { const existingStock = existingVariant.StockDetails?.find( (s) => s.InwardDtlId === newStock.InwardDtlId ); if (existingStock) { // ✅ Create a new object instead of mutating existingStock.EligibleFree = (existingStock.EligibleFree || 0) + (newStock.EligibleFree || 0); existingStock.UsedFree = (existingStock.UsedFree || 0) + (newStock.UsedFree || 0); existingStock.RemainingFree = (existingStock.RemainingFree || 0) + (newStock.RemainingFree || 0); } else { existingVariant.StockDetails = [ ...existingVariant.StockDetails, { ...newStock }, ]; } }); } else { if (!existing.ProdVariantDetails) existing.ProdVariantDetails = []; existing.ProdVariantDetails = [ ...existing.ProdVariantDetails, { ...newVariant }, ]; } }); } return FreeProdList.map((f, i) => i === index ? { ...existing, ...newFreeProd, ProdVariantDetails: existing.ProdVariantDetails, } : f ); } else { return [...FreeProdList, { ...newFreeProd }]; } } function applyBuyNGetFreeOffer(cartItem, offer, item) { const freeList = offer.FreeProductsList || []; let totalDiscount = 0; let offerMessage = ''; let OfferApply = true; let sameProductOffer = false; let updatedFreeProdList = [...FreeProdList]; freeList.forEach((freeProd) => { let data = updatedFreeProdList?.find( (e) => e.FreeProdId === freeProd.FreeProdId && e.InwardDtlId === item?.InwardDtlId ); // find matching item in cart const freeCartItem = cartItem.filter( (c) => c.ProdId === freeProd.FreeProdId && freeProd?.ProdVariantDetails?.some((pv) => pv?.StockDetails?.some((s) => s.InwardDtlId === c.InwardDtlId) ) ); // check if it's same product + inward const isSameProduct = offer.ProdId === freeProd.FreeProdId && freeProd?.ProdVariantDetails?.some((fpv) => fpv?.StockDetails?.some( (fs) => fs.InwardDtlId === freeCartItem?.[0]?.InwardDtlId ) ); if (!isSameProduct) { const buyQty = offer.BuyQty || 1; const getQty = freeProd.FreeQty || 0; // 🔥 Find how many buy-product are in cart const buyCartItem = cartItem.find((c) => c.ProdId === offer.ProdId); if (buyCartItem) { const eligibleCycles = Math.floor(buyCartItem.OrderQty / buyQty); const totalFreeEligible = eligibleCycles * getQty; if (totalFreeEligible > 0) { offerMessage = `Add ${totalFreeEligible} ${freeProd.FreeProdName} free`; } } } if (offer.HalfPrice === 'Y' && isSameProduct) { // 🔥 Half price for same product totalDiscount += freeCartItem?.reduce((acc, fc) => acc + (fc?.OrderQty || 0), 0) * freeCartItem?.[0]?.OrderRate * 0.5; sameProductOffer = true; } else if (isSameProduct) { // 🔥 Buy N Get M (same product) const buyQty = offer.BuyQty || 1; const getQty = freeProd.FreeQty || 0; const cycleSize = buyQty + getQty; const fullCycles = Math.floor( freeCartItem?.reduce((acc, fc) => acc + (fc?.OrderQty || 0), 0) / cycleSize ); const totalFreeQty = fullCycles * getQty; totalDiscount += totalFreeQty * freeCartItem?.[0].OrderRate; sameProductOffer = true; // offerMessage = `${freeProd.FreeProdName} -> ${Math.ceil(totalFreeQty / 2)} qty Free Eligible`; } else { // 🔥 Different product free const buyQty = offer.BuyQty || 1; const getQty = freeProd.FreeQty; // find buy product qty in cart const buyCartItem = cartItem.filter( (c) => c?.ProdId === offer?.ProdId && (offer?.InwardDtlId ? c?.InwardDtlId === offer?.InwardDtlId : true) ); const buyOrderQty = buyCartItem?.reduce( (acc, fc) => acc + (fc?.OrderQty || 0), 0 ); // ✅ total eligible free qty (cycles of Buy X Get Y) const eligibleCycles = Math.floor(buyOrderQty / buyQty); const totalFreeQty = eligibleCycles * getQty; totalDiscount += 0; // 🟢 Offer message handling if (buyOrderQty === 0) { offerMessage = `No free eligible right now`; } else if (buyOrderQty % buyQty !== 0) { const remainingToNext = buyQty - (buyOrderQty % buyQty); offerMessage = `Buy ${remainingToNext} more ${offer.ProdName} to get ${getQty} ${freeProd.FreeProdName} free`; } else if (totalFreeQty > 0) { offerMessage = `${freeProd.FreeProdName} -> ${totalFreeQty} qty Free Eligible`; } else { offerMessage = `No free eligible right now`; } const usedFree = data?.FreeQty || 0; const remainingFree = Math.max(totalFreeQty - usedFree, 0); const FreeProdList = { OfferId: offer.OfferId, ProdId: item?.ProdId, ProdVariantName: item?.ProdVariantName, StockAvailable: item?.StockAvailable, OfferMode: offer.OfferMode, TableName: offer.TableName, TableUniqueName: offer.TableUniqueName, InwardDtlId: item?.InwardDtlId || null, FreeProdId: freeProd.FreeProdId, FreeProdName: freeProd.FreeProdName, ProdCat: item?.ProdCat, SinglePc: item?.SinglePc, BatchRef: item?.BatchRef, OverAllFreeQty: totalFreeQty, FreeQty: usedFree, RemainingQty: remainingFree, ProdVariantDetails: freeProd.ProdVariantDetails.map((variant) => ({ FreeProdVariantName: variant.ProdVariantName, StockDetails: variant.StockDetails.map((stock) => { // 🔎 inward-based usage const matchedCartItem = cartItem.find( (c) => c.ProdId === freeProd.FreeProdId && c.InwardDtlId === stock.InwardDtlId ); const usedFreeForStock = matchedCartItem?.OrderQty || 0; const remainingFreeForStock = Math.max( totalFreeQty - usedFreeForStock, 0 ); return { FreeInwardDtlId: stock.InwardDtlId, ProdOfferId: stock.ProdOfferId, ActiveStatus: stock.ActiveStatus, EligibleFree: totalFreeQty, UsedFree: usedFreeForStock, RemainingFree: remainingFreeForStock, }; }), })), }; updatedFreeProdList = changeFreeProductList( updatedFreeProdList, FreeProdList ); OfferApply = false; } }); return { OfferAmount: totalDiscount, OfferMessage: offerMessage, OfferApply: OfferApply, updatedFreeProdList: updatedFreeProdList, ProductOfferType: sameProductOffer ? true : false, }; } const processFreeProducts = (updatedData, freeProdList) => { if (!freeProdList || freeProdList.length === 0) { return { updatedOrderCardDetails: updatedData, updatedFreeProdList: freeProdList, updatedOfferAppliedProducts: [], hasChanges: false, }; } let updatedOrderCardDetails = []; let updatedFreeProdList = [...freeProdList]; // Create a copy to avoid mutations let updatedOfferAppliedProducts = []; // Track offer applied products let hasChanges = false; updatedData?.forEach((item) => { // STEP 1: Check if item is already a free product (with offer applied) const foundInFreeProdList = freeProdList?.filter( (prod) => prod?.OfferId === item?.OfferMessage?.[0]?.OfferId && prod?.FreeProdId === item?.ProdId && prod?.OfferMode === item?.OfferMode && prod?.ProdVariantDetails?.some((variant) => variant?.StockDetails?.some( (stock) => stock?.FreeInwardDtlId === item?.InwardDtlId ) ) ); // STEP 2: Check if item is a paid product that can be converted to free const availableFreeProduct = updatedFreeProdList?.find( (prod) => prod?.FreeProdId === item?.ProdId && prod?.RemainingQty > 0 && prod?.ProdVariantDetails?.some((variant) => variant?.StockDetails?.some( (stock) => stock?.FreeInwardDtlId === item?.InwardDtlId ) ) && item?.SinglePc !== 'Y' ); const isPaidProductThatCanBeFree = availableFreeProduct && (!item.OfferMode || item.OfferMode?.trim() === '') && (item.Offer === 0 || !item.Offer); // STEP 3: Handle paid product conversion to free if (isPaidProductThatCanBeFree) { hasChanges = true; // Mark that changes occurred const maxFreeQty = Math.min( item.OrderQty, availableFreeProduct.RemainingQty ); const remainingPaidQty = Math.max( item.OrderQty - availableFreeProduct.RemainingQty, 0 ); // Create free item if (maxFreeQty > 0) { const freeItem = { ...item, OrderQty: maxFreeQty, TotalAmt: maxFreeQty * item.OrderRate, Offer: maxFreeQty * item.OrderRate, // Full discount OfferType: availableFreeProduct.OfferMode, OfferMode: availableFreeProduct.OfferMode, TaxAmt: ( (maxFreeQty * item.OrderRate * item.TaxPercentage) / 100 ).toFixed(2), WithoutTaxRate: ( maxFreeQty * item.OrderRate - (maxFreeQty * item.OrderRate * item.TaxPercentage) / 100 ).toFixed(2), OfferMessage: [ { OfferId: availableFreeProduct.OfferId, FreeQty: maxFreeQty, FreeProdId: availableFreeProduct.FreeProdId, FreeProdName: availableFreeProduct.FreeProdName, }, ], }; // Check if free version already exists in updatedOrderCardDetails const existingFreeIndex = updatedOrderCardDetails.findIndex( (od) => od.ProdId === freeItem.ProdId && od.InwardDtlId === freeItem.InwardDtlId && od.OrderRate === freeItem.OrderRate && od.BookingTypeName === freeItem.BookingTypeName && od.OfferMode === freeItem.OfferMode && od.Offer > 0 && od.MRP === freeItem.MRP ); if (existingFreeIndex !== -1) { // Merge with existing free item const existing = updatedOrderCardDetails[existingFreeIndex]; updatedOrderCardDetails[existingFreeIndex] = { ...existing, OrderQty: existing.OrderQty + freeItem.OrderQty, TotalAmt: existing.TotalAmt + freeItem.TotalAmt, Offer: existing.Offer + freeItem.Offer, WithoutTaxRate: ( parseFloat(existing.WithoutTaxRate) + parseFloat(freeItem.WithoutTaxRate) ).toFixed(2), TaxAmt: ( parseFloat(existing.TaxAmt) + parseFloat(freeItem.TaxAmt) ).toFixed(2), }; } else { freeItem.localId = uuidv4(); updatedOrderCardDetails.push(freeItem); } // Update the free product list (create new object to avoid mutation) const freeProductIndex = updatedFreeProdList.findIndex( (f) => f.OfferId === availableFreeProduct.OfferId && f.FreeProdId === availableFreeProduct.FreeProdId ); if (freeProductIndex !== -1) { updatedFreeProdList[freeProductIndex] = { ...updatedFreeProdList[freeProductIndex], FreeQty: (updatedFreeProdList[freeProductIndex].FreeQty || 0) + maxFreeQty, RemainingQty: updatedFreeProdList[freeProductIndex].RemainingQty - maxFreeQty, ProdVariantDetails: updatedFreeProdList[ freeProductIndex ].ProdVariantDetails.map((variant) => ({ ...variant, StockDetails: variant.StockDetails.map((stock) => { if (stock.FreeInwardDtlId === item.InwardDtlId) { return { ...stock, UsedFree: (stock.UsedFree || 0) + maxFreeQty, RemainingFree: Math.max( (stock.RemainingFree || 0) - maxFreeQty, 0 ), }; } return stock; }), })), discount: (updatedFreeProdList[freeProductIndex].discount || 0) + maxFreeQty * item.OrderRate, }; } const filteredOfferAppliedProduct = offerAppliedProducts?.find( (op) => op.OfferId === availableFreeProduct.OfferId && op.ProdId === availableFreeProduct.ProdId && op.InwardDtlId === availableFreeProduct.InwardDtlId && op.OfferMode === availableFreeProduct.OfferMode ); // Create offer applied product entry const offerAppliedProduct = { OfferId: availableFreeProduct.OfferId, ProdId: availableFreeProduct.ProdId, InwardDtlId: availableFreeProduct.InwardDtlId, OfferAmount: (filteredOfferAppliedProduct?.OfferAmount || 0) + maxFreeQty * item.OrderRate, // Total discount amount OfferMode: availableFreeProduct.OfferMode, OfferType: availableFreeProduct.OfferType, TableName: availableFreeProduct.TableName, TableUniqueName: availableFreeProduct.TableUniqueName, ActualOfferAmount: (filteredOfferAppliedProduct?.OfferAmount || 0) + maxFreeQty * item.OrderRate, OfferValue: (filteredOfferAppliedProduct?.OfferValue || 0) + maxFreeQty * item.OrderRate, ActualFreeQty: (filteredOfferAppliedProduct?.ActualFreeQty || 0) + maxFreeQty, AppliesTo: item.ProdId, BookingType: item.BookingType || (item.BookingTypeName === 'Dine In' ? DineinId : TakAwayId), FreeProductsList: [ { FreeProdId: availableFreeProduct.FreeProdId, FreeQty: (filteredOfferAppliedProduct?.FreeProductsList?.[0] ?.FreeQty || 0) + maxFreeQty, FreeProdName: availableFreeProduct.FreeProdName, ProdVariantDetails: availableFreeProduct.ProdVariantDetails || [], }, ], // Product-level fields SinglePc: item.SinglePc, StockAvailable: item.StockAvailable, ProdVariantName: item.ProdVariantName, Type: item.Type, ProdCat: item.ProdCat, HalfPrice: availableFreeProduct.HalfPrice, MinQty: availableFreeProduct.MinQty, }; updatedOfferAppliedProducts.push(offerAppliedProduct); } // Create paid item for remaining quantity if (remainingPaidQty > 0) { const paidItem = { ...item, OrderQty: remainingPaidQty, TotalAmt: remainingPaidQty * item.OrderRate, TaxAmt: ( (remainingPaidQty * item.OrderRate * item.TaxPercentage) / 100 ).toFixed(2), WithoutTaxRate: ( remainingPaidQty * item.OrderRate - (remainingPaidQty * item.OrderRate * item.TaxPercentage) / 100 ).toFixed(2), Offer: 0, OfferType: '', OfferMessage: [], OfferMode: '', }; // Remove offer-related properties delete paidItem.OfferType; delete paidItem.OfferMessage; delete paidItem.OfferMode; // Check if paid version already exists const existingPaidIndex = updatedOrderCardDetails.findIndex( (od) => od.ProdId === paidItem.ProdId && od.InwardDtlId === paidItem.InwardDtlId && od.OrderRate === paidItem.OrderRate && !od.SalesId && (od.Offer === 0 || !od.Offer) && od.MRP === paidItem.MRP ); if (existingPaidIndex !== -1) { // Merge with existing paid item const existing = updatedOrderCardDetails[existingPaidIndex]; updatedOrderCardDetails[existingPaidIndex] = { ...existing, OrderQty: existing.OrderQty + paidItem.OrderQty, TotalAmt: existing.TotalAmt + paidItem.TotalAmt, WithoutTaxRate: ( parseFloat(existing.WithoutTaxRate) + parseFloat(paidItem.WithoutTaxRate) ).toFixed(2), TaxAmt: ( parseFloat(existing.TaxAmt) + parseFloat(paidItem.TaxAmt) ).toFixed(2), }; } else { paidItem.localId = uuidv4(); updatedOrderCardDetails.push(paidItem); } } return; // Skip the rest of processing for this item } // STEP 4: Handle existing free products (original logic) if (foundInFreeProdList?.length > 0) { const freeProduct = foundInFreeProdList[0]; if (freeProduct?.RemainingQty !== 0) { // If there are remaining free quantities, push the original item const isAlreadyExists = updatedOrderCardDetails.findIndex( (od) => od.ProdId === item.ProdId && od.InwardDtlId === item.InwardDtlId && od.OrderRate === item.OrderRate && od.BookingTypeName === item.BookingTypeName && !od.SalesId && od.OfferMode === item.OfferMode && od.Offer > 0 && od.MRP === item.MRP ); if (isAlreadyExists !== -1) { updatedOrderCardDetails[isAlreadyExists] = { ...updatedOrderCardDetails[isAlreadyExists], OrderQty: updatedOrderCardDetails[isAlreadyExists].OrderQty + item.OrderQty, TotalAmt: updatedOrderCardDetails[isAlreadyExists].TotalAmt + item.TotalAmt, WithoutTaxRate: updatedOrderCardDetails[isAlreadyExists].WithoutTaxRate + item.WithoutTaxRate, Offer: updatedOrderCardDetails[isAlreadyExists].Offer + item.Offer, OfferMessage: updatedOrderCardDetails[isAlreadyExists]?.OfferMessage?.[0] ?.FreeQty > item?.OfferMessage?.[0]?.FreeQty ? updatedOrderCardDetails[isAlreadyExists]?.OfferMessage : item?.OfferMessage, }; } else { updatedOrderCardDetails.push(item); } } else if ( freeProduct?.RemainingQty === 0 && item?.OrderQty > freeProduct?.FreeQty ) { // Split the item into free and paid portions const freeQty = freeProduct.FreeQty; const paidQty = item.OrderQty - freeProduct.FreeQty; // Create free item (with original offer details) const freeItem = { ...item, OrderQty: freeQty, WithoutTaxRate: freeQty * item.OrderRate, TotalAmt: freeQty * item.OrderRate, Offer: freeQty * item.OrderRate, }; // Create paid item (without offer details) const paidItem = { ...item, OrderQty: paidQty, TotalAmt: paidQty * (item.SellingPrice || item.OrderRate), WithoutTaxRate: paidQty * item.OrderRate, Offer: 0, OfferType: '', OfferMessage: [], OfferMode: '', }; delete paidItem.OfferType; delete paidItem.OfferMessage; delete paidItem.OfferMode; updatedOrderCardDetails.push(freeItem); const isAlreadyExists = updatedOrderCardDetails.findIndex( (od) => od.ProdId === paidItem.ProdId && od.InwardDtlId === paidItem.InwardDtlId && od.OrderRate === paidItem.OrderRate && !od.SalesId && (od.Offer === 0 || !od.Offer) ); if (isAlreadyExists !== -1) { const existingItem = updatedOrderCardDetails[isAlreadyExists]; updatedOrderCardDetails[isAlreadyExists] = { ...existingItem, OrderQty: existingItem.OrderQty + paidItem.OrderQty, TotalAmt: existingItem.TotalAmt + paidItem.TotalAmt, WithoutTaxRate: existingItem.WithoutTaxRate + paidItem.WithoutTaxRate, }; } else { paidItem.localId = uuidv4(); updatedOrderCardDetails.push(paidItem); } } else { updatedOrderCardDetails.push(item); } } else { // STEP 5: No matching free product found, push original item updatedOrderCardDetails.push(item); } }); return { updatedOrderCardDetails, updatedFreeProdList, updatedOfferAppliedProducts, hasChanges, }; }; const onComplete = useCallback(() => { setMessageData(null); setMessageType(null); }, []); const handleQuickCancel = async () => { setQuickAdd(false); dispatch(changeSearchedData([])); formRef.current.resetFields(['ItemName']); }; const expFun = (item) => { setProdexpir(true); setQtydata(item); let count = item?.ProductDetail?.length; if (count > 1) { Quantity(); } else { SingleQuantity(item, onePeiceFlow); } closeExpireModal(); }; const expVerFun = (item) => { let count = qtydata?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[item] ?.StockDetails?.length; if (count > 1) { setRepeatedModel(true); setModalVarient(false); setModelstock(true); } else { setRepeatedModel(true); dataTransfer(qtydata, QtyIndex, item, 0, onePeiceFlow); setModelQty(false); } closeExpireModal(); }; const expStockFun = (item) => { dataTransfer(qtydata, QtyIndex, VarientIndex, item, onePeiceFlow); closeExpireModal(); }; let brandMapping = {}; // Group product details by Brand ID qtydata?.ProductDetail?.forEach((item) => { const brandId = item?.BrandName; if (!brandMapping[brandId]) { brandMapping[brandId] = []; } brandMapping[brandId].push(item); }); const BrandCheckresult = qtydata?.ProductDetail?.every((product) => { return product.BrandName === null || product.BrandName === undefined; }); const getMaxBrandWidth = () => { let maxBrandDataLength = 0; // Iterate through each brand and find the maximum length of the specified key Object.values(brandMapping).forEach((brand) => { const keyDataLength = brand.length; if (keyDataLength > maxBrandDataLength) { maxBrandDataLength = keyDataLength; } }); // Set your width logic here based on the maxBrandDataLength const maxWidth = maxBrandDataLength >= 5 ? 750 : 'max-content'; return maxWidth; }; // Example usage for checking the length of 'ProdVariantDetails' const widthBasedOnProdVariantDetails = getMaxBrandWidth(); return ( <>
OnfocusTrue()} >
({ value: option.ProdName, label: (
{ setOnePeiceFlow(false); }} > {option.ProdName}
{option.ProductDetail?.filter( (item) => item.OnePcsAvailable == 'Y' ).length !== 0 && ( { setOnePeiceFlow(true); }} /> )}
), })) } className="Search-auto-field" ref={inputRef} onChange={ProductNameOnChange} onSelect={ProductOnSelect} placeholder="Product Name (SHIFT + S)" allowClear={{ clearIcon: , }} autoFocus={autoCompleteVisible} onFocus={handleFocus} />
{isMobile && screenWidth <= 768 && ( // handleQrcode()} // // onClick={() => OnfocusTrue()} // /> { ProductNameOnChange(value, true); }} /> )} OnfocusTrue()} />
{ProductSearch?.length > 5 && QuickAdd && GetmultipleSearchDatas.some((e) => e.toLowerCase() === 'qrcode') && (
)} {BSComboData == 'Combo1' && FeatureAddonData?.FeatureDtls?.find( (item) => item?.FeatureAddonName?.toLowerCase() === 'weight scale' ) && }
{expireModal?.open && ( { expireModal.onOk?.(); closeExpireModal(); }} onCancel={() => { expireModal.onCancel?.(); closeExpireModal(); }} /> )} } open={modelQty} width={widthBasedOnProdVariantDetails} footer={null} handleCancel={CloseModal} >

Item Name:

{qtydata?.ProdName}

{Object.keys(brandMapping)?.map((brandId) => (

{' '} {brandId !== 'null' && brandId !== 'undefined' ? brandId : ''}

{brandMapping[brandId]?.map((item, index) => (
0 || item?.StockAvailable !== 'Y' ? 'ItemQtyCard' : 'ItemQtyCard-disabled' } onClick={() => VarientFun(item)} >
{`Product

{item?.Size + ' ' + item?.UomName}

{returnQtyCount( item?.ProdId, item, CartOrderDetails ) > 0 || item?.StockAvailable !== 'Y' ? (

  { item?.ProdVariantDetails?.[0]?.StockDetails?.[0] ?.SellPrice }

) : ( '' )}
))}
{brandId !== 'null' && brandId !== 'undefined' ?
: ''}
))} {Object.keys(brandMapping).length === 0 && (

No product details available

)}
} open={modelstock} // width={500} footer={null} handleCancel={CloseModal1} >

Item Name:

{qtydata?.ProdName}

Item Quantity:

{qtydata?.ProductDetail?.[QtyIndex]?.Size}{' '} {onePeiceFlow ? 'PCS' : qtydata?.ProductDetail?.[QtyIndex]?.UomName}

} open={ModalVarient} width={500} footer={null} handleCancel={CloseVarientModal} >

Item Name:

{qtydata?.ProdName}

Item Quantity:

{qtydata?.ProductDetail?.[QtyIndex]?.Size}{' '} {onePeiceFlow ? 'PCS' : qtydata?.ProductDetail?.[QtyIndex]?.UomName}

); }