import React, { useCallback, useEffect, useRef, useState } from 'react'; import { shallowEqual, useDispatch, useSelector } from 'react-redux'; import moment from 'moment'; import { Badge, Tooltip } from 'antd'; import defaultimage from '../../../../Images/defaultItemImg.png'; import FormHeader from '../../../PageComponents/FormHeader'; import { SelectedGlobalCardColorDetail, SelectedGlobalCardFont, StoredSessionData, getTemplateData, } from '../../../../Features/ThemeChange/ThemeChange'; import { Tables } from '../../../../Components/Tables/Table'; import { GlobalProductSubCategorie, GlobalItemCard, getLayoutproductCard, GlobalOrderCardDetails, changeOrderCardDetails, changeSearchedData, ChangeAllItemData, GlobalAllItemData, GlobalCardAccess, getSelectedFavItems, GlobalSelectedDatas, GlobalEditfavItems, getEditFavItems, GlobalAccessForOthers, GlobalAlldat, Globalothersdata, GlobalProductCategorie, getCardDataWithoutSub, changeothersdata, ChangeNewQrProduct, GlobalWSProduct, GlobalNewQrProduct, GlobalBookingType, GlobalSearchData, getCardDataWithoutSubmodule, changePreviousOrderLength, changeHoldOrderDtl, GlobalReorderHoldDetails, GlobalWeightScalePort, GlobalWeightScaleWeight, GlobalExpDateforHeight, GlobalOrderType, GlobalReorderProductDetails, getConfigType, GlobalPayementloader, GlobalPaymentTransactionNumber, PreferenceData, changeCardData, GlobaldraggingComponent, GlobalisAlphabeticFormat, GlobalBtoBQuickProductTransfer, changeBtoBQuickProductTransfer, GlobalRetailWSSalesType, GlobalisFavClicked, GlobalCategorieData, GlobalSubcategorieData, GlobalProductCardTrigger, GlobalGetmultipleSearchDatas, getmultipleSearch, } from '../../../../Features/BookingScreen/BookingData/BookingData'; import { GlobalPreOrderAdditem, GlobalPreOrderList, GlobalpreOrderOpen, changepreOrderList, } from '../../../../Features/BookingScreen/PreOrder/PreOrder'; import { DefaultModal } from '../../../../Components/Modal/DefaultModal'; import { Messages } from '../../../../Components/Notifications/Messages'; import '../../../../Styles/BookingScreen/Components/BSItemCards/BSItemCard.scss'; import WebFont from 'webfontloader'; import FeaturesFunctionalities from '../BookingFunctionality/FeaturesFunctionalities'; import { isMobile } from 'react-device-detect'; import { Global_OrderOfferDetail, Global_PromoCodeOffers, } from '../../../../Features/Offer/Offer'; import { DndContext, useSensor, useSensors, PointerSensor, TouchSensor, closestCenter, } from '@dnd-kit/core'; import { SortableContext, arrayMove, rectSortingStrategy, } from '@dnd-kit/sortable'; import { v4 as uuidv4 } from 'uuid'; // import './styles.css'; // Your styles if any // Dummy SortableCard component import { useSortable } from '@dnd-kit/sortable'; import { CSS } from '@dnd-kit/utilities'; // import HuggingFaceVoiceForm from '../../../VoiceToText/VoiceToText.jsx'; import VoiceToTextItemCard from '../../../VoiceToText/VoiceToTextItemCard.jsx'; import { ExtractDateFormate } from '../../../../Services/Others.js'; import { changeFreeProductForLoyalty, ChangeFreeProductList, ChangeFullFreeProductList, changeFullOfferAppliedProducts, ChangeOfferAppliedProducts, changeOfferAppliedProductsForLoyalty, changeTriggerOfferFree, getOfferinBooking, GlobalFreeProdList, GlobalOfferAppliedProducts, GlobalTriggerOfferFree, RemoveOfferAppliedProduct, } from '../../../../Features/Offer/Offernew/BookingOffernew.js'; import { validateOffers } from './ValidateOffer.jsx'; import { useSaleswiseOfferWatcher } from './SalesWiseOffer.jsx'; import { ApplicationPreferences } from '../../../../Features/BrachLogin/BranchLogin.js'; import { useDateStore } from '../../../../Features/BookingScreen/BookingData/DateStore.js'; import AddProduct from '../../../../Components/AddProduct/AddProduct.jsx'; import { MdOutlineAddShoppingCart } from 'react-icons/md'; import { bulkpostdata } from '../../../../Features/ProductPage/ProductPage.js'; import ProductPriceChange from '../UtillComponents/ProductPriceChange.jsx'; import ExpireConfirmModal from '../BookingFunctionality/ExpireConfirmModal.jsx'; import { calculateOverAllQtyLimit } from '../../../../utils/calculations.js'; export function SortableCard({ id, children, item }) { const { attributes, listeners, setNodeRef, transform, transition, isDragging, } = useSortable({ id }); const style = { transform: CSS.Transform.toString(transform), transition, opacity: isDragging ? 0.5 : 1, // Add mobile-specific styling for better touch interaction // touchAction: 'none', // Prevents default touch behaviors userSelect: 'none', // Prevents text selection during drag // Add mobile-specific cursor and visual feedback cursor: isMobile ? 'grab' : 'default', // Add a subtle shadow for mobile to indicate draggability boxShadow: isMobile && !isDragging ? '0 2px 4px rgba(0,0,0,0.1)' : 'none', }; const draggingComponent = useSelector(GlobaldraggingComponent); const allowDrag = draggingComponent === 'card'; return (
{children}
); } const BSItemCard = (props) => { const cardFunction = props?.cardFunctionality; // const applyOffer = useApplyOfferto_CardDetail(); const preferenceDatas = useSelector(PreferenceData, shallowEqual); const { selectedDate } = useDateStore(); 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 preferenceSingleSales = preferenceDatas?.[0]?.['SettingDtlDetails']?.find( (item) => item.SettingIdName === 'Single Booking Only' )?.SettingValue === 'Y'; const AddProductCard = preferenceDatas?.[0]?.['SettingDtlDetails']?.find( (item) => item.SettingIdName === 'AddProductCard' )?.SettingValue === 'N'; // const AddCustomerDetails = useSelector( // GlobalAddCustomerDetails, // shallowEqual // ); const offerAppliedProducts = useSelector( GlobalOfferAppliedProducts, shallowEqual ); // const SelectedCust = useSelector(GlobalSelOption, shallowEqual); const AllCategoryDatas = useSelector(GlobalCategorieData, shallowEqual); const AllsubcatgoryDatas = useSelector(GlobalSubcategorieData, shallowEqual); const RetailWSSalesType = useSelector(GlobalRetailWSSalesType, shallowEqual); const GPreOrderList = useSelector(GlobalPreOrderList, shallowEqual); const [modelQty, setModelQty] = useState(false); const [modelstock, setModelstock] = useState(false); const [ModalVarient, setModalVarient] = useState(false); const [QtyIndex, setQtyIndex] = useState(0); const [VarientIndex, setVarientIndex] = useState(0); const [prodexpir, setProdexpir] = useState(false); const [initialRun, setInitialRun] = useState(false); const [Item, setItem] = useState(); const [VarItem, setVarItem] = useState(0); const [StockItem, setStockItem] = useState(); const [noSubcatCardData, setNoSubcatCardData] = useState(); const [qtydata, setQtydata] = useState(); const [products, setProducts] = useState([ { id: 1, name: '', price: '', code: '', size: '1', category: '' }, ]); const PreOrderAdditem = useSelector(GlobalPreOrderAdditem, shallowEqual); const OrderType = useSelector(GlobalOrderType, shallowEqual); const ProdSubCat = useSelector(GlobalProductSubCategorie); const ItemCard = useSelector(GlobalItemCard, shallowEqual); const globaldata = useSelector(GlobalAlldat, shallowEqual); const { action: quickBranchtoBranchTransfer, selectedProducts } = useSelector( GlobalBtoBQuickProductTransfer ); const preOrder = useSelector(GlobalpreOrderOpen, shallowEqual); const templateData = useSelector(getTemplateData, shallowEqual); const temp5 = templateData?.BookingLayout?.[0] === 'Layout5'; const OfferCheckedInSetup = templateData?.BookingNavbar?.[1].some( (item) => item?.OptionName == 'Offer' ); const globalAllItemdata = useSelector(GlobalAllItemData); const EditfavItems = useSelector(GlobalEditfavItems); const BookingType = useSelector(GlobalBookingType); const ProductSearch = useSelector(GlobalSearchData); const [SelectedProdNames, setSelectedProdNames] = useState(EditfavItems); const [PreOrderSelectedProdNames, setPreOrderSelectedProdNames] = useState( [] ); const [newMoreProductModel, setNewMoreProductModel] = useState(false); const CardAccess = useSelector(GlobalCardAccess, shallowEqual); const globalAccessForOthers = useSelector( GlobalAccessForOthers, shallowEqual ); const SelectedCardColor = useSelector( SelectedGlobalCardColorDetail, shallowEqual ); const GetmultipleSearchDatas = useSelector( GlobalGetmultipleSearchDatas, shallowEqual ); const SelectedCardFont = useSelector(SelectedGlobalCardFont, shallowEqual); const CartOrderDetails = useSelector(GlobalOrderCardDetails, shallowEqual); const SelectedDatas = useSelector(GlobalSelectedDatas, shallowEqual); const otherscarddata = useSelector(Globalothersdata, shallowEqual); const WSProductdata = useSelector(GlobalWSProduct, shallowEqual); const NewQrProductData = useSelector(GlobalNewQrProduct, shallowEqual); const ReportholdData = useSelector(GlobalReorderHoldDetails, shallowEqual); console.log(GetmultipleSearchDatas, 'GetmultipleSearchDatas'); const ReorderProductData = useSelector( GlobalReorderProductDetails, shallowEqual ); const WeightScalePort = useSelector(GlobalWeightScalePort, shallowEqual); const WeightScaleWeight = useSelector(GlobalWeightScaleWeight, shallowEqual); const PaymentTransactionNumber = useSelector( GlobalPaymentTransactionNumber, shallowEqual ); const OverAllproductBasedOfferDatas = useSelector( (state) => state?.BookingOFferNew?.OverAllProductBasedProducts, shallowEqual ); const PromoCodeOffersDatas = useSelector( Global_PromoCodeOffers, shallowEqual ); const allowDecimal = preferenceDatas?.[0]?.SettingDtlDetails?.find( (setting) => setting?.SettingIdName?.toLowerCase() === 'decimal' && setting?.SettingValue === 'Y' ); const [messageType, setMessageType] = useState(null); const [messageData, setMessageData] = useState(null); const [repeatedModel, setRepeatedModel] = useState(false); const [StockPreferenceDetail, setStockPreferenceDetail] = useState(); const [QuickAdd, setQuickAdd] = useState(true); const [onePeiceFlow, setOnePeiceFlow] = useState(false); const [BillOrderPre, setBillOrderPre] = useState(); const [qtyExpData, setQtyExpData] = useState(); const OrderOfferDetail = useSelector(Global_OrderOfferDetail); // const [freeProductsOffers, setfreeProductsOffers] = useState([]); const [screenWidth, setScreenWidth] = useState(window.innerWidth); // const [screenHeight, setScreenHeight] = useState(window.innerHeight); const ProdCat = useSelector(GlobalProductCategorie, shallowEqual); const paymentloader = useSelector(GlobalPayementloader, shallowEqual); const SessionData = useSelector(StoredSessionData, shallowEqual); const AppId = SessionData?.AppId; const CompId = SessionData?.CompId; const BranchId = SessionData?.BranchId; const UserId = SessionData?.UserId; const dispatch = useDispatch(); const voiceTriggerRef = useRef(null); const scrollContainerRef = useRef(null); const isDragging = useRef(false); const startX = useRef(0); const scrollLeft = useRef(0); const itemListScrollRef = useRef(null); const [selectedBrand, setSelectedBrand] = useState('Others'); const [showLeftButton, setShowLeftButton] = useState(false); const [showRightButton, setShowRightButton] = useState(false); const [ExpiredProduct, setExpiredProduct] = useState(); const [ConfigDataList, setConfigDataList] = useState([]); const alphabeticFormat = useSelector(GlobalisAlphabeticFormat); // const PricingAppPricingName = useSelector(GlobalPricingAppPricingName); const favouriteCat = useSelector(GlobalisFavClicked, shallowEqual); const FreeProdList = useSelector(GlobalFreeProdList); const triggerOfferFree = useSelector(GlobalTriggerOfferFree); const productCardTrigger = useSelector(GlobalProductCardTrigger); const appPreferences = useSelector(ApplicationPreferences); const [expireModal, setExpireModal] = useState({ open: false, title: '', onOk: null, onCancel: null, }); const salespagefields = appPreferences?.find( (pref) => pref?.PreferredCatName === 'Sales Page Fields' )?.PreferenceCatDetails; const AvailableDate = salespagefields?.find( (type) => type?.PreferredSubCatName?.toLowerCase() === 'available date' && type?.PreferredStatus === 'Y' ); const SingleMember = salespagefields?.find( (type) => type?.PreferredSubCatName?.toLowerCase() === 'single member' && type?.PreferredStatus === 'Y' ); useSaleswiseOfferWatcher(); const TakAwayId = ConfigDataList?.find( (a) => a?.ConfigName === 'TakeAway' )?.ConfigId; const DineinId = ConfigDataList?.find( (a) => a?.ConfigName === 'Dine In' )?.ConfigId; useEffect(() => { itemListScrollRef.current?.scrollTo(0, 0); }, [ProdCat, ProdSubCat, favouriteCat]); useEffect(() => { if (ConfigDataList?.length === 0) { getBookingTypeId(); } }, []); useEffect(() => { if ( triggerOfferFree && CartOrderDetails?.length > 0 && FreeProdList?.length > 0 ) { console.log('Before call'); let { ModifiedData, UpdatedFreeProdList, AppliedOffers } = handleLoyaltyFreeProducts(CartOrderDetails, FreeProdList); console.log( 'After call', ModifiedData, UpdatedFreeProdList, AppliedOffers ); console.log(AppliedOffers, 'AppliedOffers'); dispatch(changeOrderCardDetails(ModifiedData)); dispatch(ChangeFullFreeProductList(UpdatedFreeProdList)); dispatch(changeFullOfferAppliedProducts(AppliedOffers)); dispatch(changeTriggerOfferFree(false)); } }, [triggerOfferFree]); 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, }; } const openExpireModal = ({ title, onOk, onCancel }) => { setExpireModal({ open: true, title, onOk, onCancel, }); }; const closeExpireModal = () => { setExpireModal((prev) => ({ ...prev, open: false })); }; // Usage example: // const result = handleLoyaltyFreeProducts(orderCardDtls, freeProdDtls); // console.log(result.ModifiedData); // console.log(result.UpdatedFreeProdList); // console.log(result.AppliedOffers); async function getOffers() { await dispatch( getOfferinBooking({ AppId: AppId, CompId: CompId, BranchId: BranchId }) ).unwrap(); } useEffect(() => { const filteredOffers = OrderOfferDetail?.filter( ({ TableName, TableUniqueName, OfferCode, Type, FreeProductsList }) => { if ( (TableName === 'LoyaltyPoints' && TableUniqueName === 'UniqueId' && Type === 'A') || ((TableName === 'CustomerPromo' || TableName === 'CustomerCoupon' || TableName === 'OfferCode') && OfferCode != null && TableUniqueName === 'UniqueId') ) { return FreeProductsList?.ExistingList?.length > 0; } if (TableName === 'BuyXGetXOffers') return true; } ); // setfreeProductsOffers(filteredOffers); getOffers(); }, [OrderOfferDetail]); useEffect(() => { if (SelectedCardFont) { WebFont.load({ google: { families: [SelectedCardFont], // Load the selected font }, }); } }, [SelectedCardFont]); const cardData = !globalAccessForOthers ? CardAccess ? SelectedDatas?.length > 1 ? SelectedDatas : SelectedDatas?.[0]?.AppId === 0 && SelectedDatas?.[0]?.CompId === 0 ? [] : SelectedDatas : ItemCard?.length == 0 || (ItemCard?.[0]?.AppId === 0 && ItemCard?.[0]?.CompId === 0) ? noSubcatCardData : ItemCard : ''; const cardDataForNewPrd = !globalAccessForOthers ? CardAccess ? SelectedDatas : ItemCard?.length == 0 ? noSubcatCardData : ItemCard : ''; // function safeRound(amountStr) { if (amountStr == null) return allowDecimal ? '0.00' : '0'; const cleaned = String(amountStr).replace(/[^0-9.-]+/g, ''); const num = Number(cleaned); if (isNaN(num)) return allowDecimal ? '0.00' : '0'; return allowDecimal ? num.toFixed(2) : Math.round(num).toString(); } useEffect(() => { // fetchedit(); getPreferenceStock(); // dispatch(changepreOrder(false)); Commented to Add Normal Produts After Adding the Combo Pack !!!!!! Dont Touch Without Shifayath Permission }, [preferenceDatas]); useEffect(() => { if (AppId && CompId && BranchId) { fetchedit(); GetmultipleSearchData(); } // dispatch(changepreOrder(false)); Commented to Add Normal Produts After Adding the Combo Pack !!!!!! Dont Touch Without Shifayath Permission }, [AppId, CompId, BranchId]); const GetmultipleSearchData = async () => { const data = { AppId, CompId, BranchId, }; try { const response = await dispatch(getmultipleSearch(data)); } catch (error) { console.error('Get Search Terms Error:', error); } }; useEffect(() => { setPreOrderSelectedProdNames([]); // dispatch(changePreOrderAdditem(null)); }, [preOrder]); useEffect(() => { if (ProdCat && ProdSubCat !== NaN) { // if (ProdCat && !isNaN(ProdSubCat)) { productCardList(); } }, [ProdSubCat, productCardTrigger]); useEffect(() => { if (noSubcatCardData) { setNoSubcatCardData(); } if ( ProductSearch?.length > 5 && GetmultipleSearchDatas.some((e) => e.toLowerCase() === 'qrcode') ) { setQuickAdd(true); } }, [ProductSearch, GetmultipleSearchDatas]); useEffect(() => { if ( !initialRun && (!ProdSubCat || ProdSubCat != NaN || ProdSubCat === 'NaN') && ProdCat ) { // if (!initialRun && (!ProdSubCat || !isNaN(ProdSubCat)) && ProdCat) { setInitialRun(true); productCardList(); } }, [ProdCat, initialRun]); const productCardList = async () => { //condition if ( (templateData?.BookingLayout?.[1]?.some( (item) => item?.OptionName === 'SubCategory' ) || templateData?.BookingCategory?.[0] == 'Category5') && ProdSubCat && ProdCat ) { let data = { CompId: CompId, BranchId: BranchId, AppId: AppId, ProdSubCat: ProdSubCat, ...(AvailableDate && selectedDate ? { date: Array.isArray(selectedDate) ? selectedDate .map((d) => (d?.format ? d.format('YYYY-MM-DD') : d)) .join(',') : selectedDate?.format ? selectedDate.format('YYYY-MM-DD') : selectedDate, } : {}), }; //mohan let response = await dispatch(getLayoutproductCard(data)).unwrap(); if (response?.data?.statusCode == 1) { setNoSubcatCardData(response?.data?.data); } } else if ( !templateData?.BookingLayout?.[1]?.some( (item) => item?.OptionName === 'SubCategory' ) && templateData?.BookingCategory?.[0] != 'Category5' && ProdCat ) { let data = { compId: CompId, branchId: BranchId, appId: AppId, prodCat: ProdCat, }; // 👇 only add date if AvailableDate is true if (AvailableDate && selectedDate) { data.date = selectedDate; } let response = await dispatch(getCardDataWithoutSubmodule(data)).unwrap(); if (response?.data?.statusCode == 1) { setNoSubcatCardData(response?.data?.data); } } else if ( (templateData?.BookingLayout?.[1]?.some( (item) => item?.OptionName === 'SubCategory' ) || templateData?.BookingCategory?.[0] == 'Category5') && !ProdSubCat && ProdCat && ProdSubCat != 'NaN' ) { let data = { compId: CompId, branchId: BranchId, appId: AppId, prodCat: ProdCat, ...(AvailableDate && selectedDate ? { date: Array.isArray(selectedDate) ? selectedDate .map((d) => (d?.format ? d.format('YYYY-MM-DD') : d)) .join(',') : selectedDate?.format ? selectedDate.format('YYYY-MM-DD') : selectedDate, } : {}), }; let response = await dispatch(getCardDataWithoutSub(data)).unwrap(); if (response?.data?.statusCode == 1) { setNoSubcatCardData(response?.data?.data); } } }; const getBookingTypeId = async () => { let tempconfigdata = await dispatch( getConfigType({ TypeName: 'Booking Type' }) ).unwrap(); if (tempconfigdata?.data?.statusCode == 1) { setConfigDataList(tempconfigdata?.data?.data); } }; const fetchedit = async () => { let data = { CompId: CompId, BranchId: BranchId, AppId: AppId, }; let res = await dispatch(getEditFavItems(data)).unwrap(); if (res?.data?.statusCode == 1) { setSelectedProdNames(res?.data?.data); } else { setSelectedProdNames([]); } }; useEffect(() => { DispatchData(); }, [SelectedProdNames]); const DispatchData = async () => { await dispatch(ChangeAllItemData(SelectedProdNames)); }; useEffect(() => { if (Object.keys(WSProductdata)?.length > 0) { AddOrderDetails(WSProductdata); } }, [WSProductdata]); useEffect(() => { if (ItemCard?.[0]?.QrBasedSearch === 'Y') { if (ItemCard?.[0]?.OverAllExpStatus == 'Y' && ExpiredProduct) { openExpireModal({ title: 'Product Expires', onOk: () => expFun(Item), }); setItem(ItemCard?.[0]); } else { setQtydata(ItemCard?.[0]); SingleQuantity(ItemCard?.[0], false); } } else if (ItemCard?.[0]?.OnePcQRBased === 'Y') { if (ItemCard?.[0]?.OverAllExpStatus == 'Y' && ExpiredProduct) { openExpireModal({ title: 'Product Expires', onOk: () => expFun(Item), }); setItem(ItemCard?.[0]); setOnePeiceFlow(true); } else { setQtydata(ItemCard?.[0]); SingleQuantity(ItemCard?.[0], true); } } }, [ItemCard]); useEffect(() => { // let data = otherscarddata if (Object.keys(otherscarddata)?.length > 0) { let data = { Type: otherscarddata?.Type ? otherscarddata?.Type : 'P', OverallQuantity: otherscarddata?.OverAllQty, ActiveStatus: otherscarddata?.ActiveStatus, AvailableFrom: otherscarddata?.AvailableFrom, AvailableTo: otherscarddata?.AvailableTo, Cess: otherscarddata?.Cess, ExpDate: otherscarddata?.ExpDate, HSNCode: otherscarddata?.HSNCode, ManufDate: otherscarddata?.ManufDate, OpeningQty: otherscarddata?.OpeningQty, ProdType: otherscarddata?.ProdType, PartNumber: otherscarddata?.PartNumber, ProdId: otherscarddata?.ProdId, ProdLogo: otherscarddata?.ProdLogo, ProdName: otherscarddata?.ProdName, QRCode: otherscarddata?.QRCode, QtyBasedPrice: otherscarddata?.QtyBasedPrice, Rack: otherscarddata?.Rack, Size: otherscarddata?.Size, StockAvailable: otherscarddata?.StockAvailable, TaxId: otherscarddata?.TaxId, TaxPercentage: otherscarddata?.TaxPercentage, TaxName: otherscarddata?.TaxIdName, UniqueId: otherscarddata?.UniqueId, UomName: otherscarddata?.UomName, ProdVariantName: otherscarddata?.ProdVariantName, //sri BalanceQty: otherscarddata?.BalanceQty, BatchRef: otherscarddata?.BatchRef, ModelNumber: otherscarddata?.ModelNumber, //sri FullProductIdentifierDtls: otherscarddata?.FullProductIdentifierDtls, //sri InwardDate: otherscarddata?.InwardDate, InwardDtlId: otherscarddata?.InwardDtlId, InwardId: otherscarddata?.InwardId, MRP: otherscarddata?.MRP, Offer: otherscarddata?.OfferPrice, OrderRate: otherscarddata?.SellPrice, SellingPrice: otherscarddata?.SellPrice, // edit srii SuppId: otherscarddata?.SuppId, SuppName: otherscarddata?.SuppName, OrderQty: otherscarddata?.Quantity, OtherProduct: otherscarddata?.OtherProduct, // 'ProdVariantName': otherscarddata?.ProdVariantName, BookingTypeName: BookingType, SinglePc: otherscarddata?.SinglePc, CounterName: '', //sri }; AddOrderDetails(data, otherscarddata?.Quantity); } // data["OrderRate"] = otherscarddata?.SellPrice }, [otherscarddata]); useEffect(() => { if (Object.keys(NewQrProductData)?.length > 0) { let addQrProductData = { ...NewQrProductData }; addQrProductData['OrderRate'] = addQrProductData['SellPrice']; addQrProductData['OrderQty'] = addQrProductData['Quantity']; addQrProductData['SellingPrice'] = addQrProductData['SellPrice']; addQrProductData['BookingTypeName'] = BookingType; AddOrderDetails(addQrProductData); } }, [NewQrProductData]); const getPreferenceStock = async () => { const PreferenceStckDtl = preferenceDatas?.[0]?.SettingDtlDetails; const StockPreference = PreferenceStckDtl?.find( (item) => item.SettingIdName === 'StockSelection' ); setStockPreferenceDetail(StockPreference); const BillOrder = PreferenceStckDtl?.find( (item) => item.SettingIdName === 'BillItemsOrder' ); setBillOrderPre(BillOrder?.SettingValue); const expiredDate = PreferenceStckDtl?.find( (item) => item.SettingIdName === 'ExpiredSelection' )?.SettingValue === 'Y'; setExpiredProduct(expiredDate); }; const CloseModal = () => { setModelQty(false); setRepeatedModel(false); setProdexpir(false); setOnePeiceFlow(false); setSelectedBrand('Others'); }; 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' && item?.ProductDetail?.[QtyIndex]?.StockAvailable == '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' && qtydata?.ProductDetail?.[QtyIndex]?.StockAvailable == '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?.[ index.key ]?.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); setSelectedBrand('Others'); setVarItem(index.key); if (overallExpStatus === 'Y' && prodexpir) { setProdexpir(false); setRepeatedModel(true); return; } } else if (overallExpStatus === 'Y' && ExpiredProduct) { setVarItem(index.key); openExpireModal({ title: 'Variant Expires', onOk: () => expVerFun(VarItem), onCancel: () => { setRepeatedModel(false); setProdexpir(false); }, }); return; } } } else { if (overallExpStatus === 'N' || (overallExpStatus === 'Y' && prodexpir)) { const stockDetails = qtydata?.ProductDetail?.[QtyIndex]?.ProdVariantDetails?.[index.key] ?.StockDetails; console.log(stockDetails, CartOrderDetails, 'currIndex'); 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?.[ index.key ]?.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 { const findNextAvailableStockIndex = ( stockDetails, CartOrderDetails, prodId ) => { if (!stockDetails || stockDetails.length === 0) return 0; for (let i = 0; i < stockDetails.length; i++) { const stock = stockDetails[i]; // Find if this specific stock is already in cart const cartItem = CartOrderDetails?.find( (item) => item?.ProdId === prodId && item?.InwardDtlId === stock?.InwardDtlId && item?.OrderRate === stock?.SellPrice && !item?.SalesId ); // If not in cart, this stock has full balance available - use this if (!cartItem) { return i; } // If in cart and NOT fully utilized, continue using this stock if (cartItem && cartItem?.OrderQty < cartItem?.BalanceQty) { return i; } // If OrderQty === BalanceQty (fully utilized), move to next stock // Continue the loop... } // If all stocks are exhausted, return the last index return stockDetails.length - 1; }; const currentProdId = qtydata?.ProductDetail?.[QtyIndex]?.ProdId; // Find the next available stock index dynamically const nextAvailableIndex = findNextAvailableStockIndex( stockDetails, CartOrderDetails, currentProdId ); dataTransfer( qtydata, QtyIndex, index.key, nextAvailableIndex, onePeiceFlow ); } setModelQty(false); setSelectedBrand('Others'); setVarItem(index.key); if (overallExpStatus === 'Y' && prodexpir) { setProdexpir(false); setRepeatedModel(true); return; } } else if (overallExpStatus === 'Y' && ExpiredProduct) { setVarItem(index.key); openExpireModal({ title: 'Variant Expires', onOk: () => expVerFun(VarItem), onCancel: () => { setRepeatedModel(false); setProdexpir(false); }, }); return; } setModelQty(false); setSelectedBrand('Others'); } }; const VarientFun = (index) => { const QtyExpire = index?.ProdVariantDetails.every( (item) => item.OverAllExpStatus === 'Y' ); if (QtyExpire && ExpiredProduct) { openExpireModal({ title: 'Quantity Expires', onOk: () => expQtyFun(qtyExpData), onCancel: () => { setRepeatedModel(false); (setProdexpir(false), closeExpireModal()); }, }); setQtyExpData(index); } else { const selectedProIndex = qtydata?.ProductDetail?.findIndex( (item) => item?.ProdId === index?.ProdId && item?.Size === index?.Size && item?.UomName === index?.UomName && item?.Brand === index?.Brand ); if (selectedProIndex !== -1) { const count = qtydata?.ProductDetail[selectedProIndex]?.ProdVariantDetails ?.length || 0; if (count > 1) { setModelQty(false); setSelectedBrand('Others'); setModalVarient(true); } else { const item = { QtyIndex: selectedProIndex, VarientIndex: 0 }; singleVarient(item); setModelQty(false); setSelectedBrand('Others'); } } setQtyIndex(selectedProIndex); setVarientIndex(0); setRepeatedModel(false); } }; const singleVarient = (item) => { let count = qtydata?.ProductDetail?.[item?.QtyIndex]?.ProdVariantDetails?.[ item?.VarientIndex ]?.StockDetails?.length; if ( StockPreferenceDetail?.SettingValue === 'Y' && qtydata?.ProductDetail?.[item?.QtyIndex]?.StockAvailable == '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?.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); setSelectedBrand('Others'); } } 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); setSelectedBrand('Others'); } }; 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); setRepeatedModel(false); }; const [priceChangeProduct, setPriceChangeProduct] = useState([]); const [productPriceChange, setProductPriceChange] = useState(false); const CardOnclick = async (item, Parameter) => { setOnePeiceFlow(Parameter === 'OnePeiceProduct'); const transformedItem = { ...item, ProductDetail: item.ProductDetail // .filter((detail) => detail.OnePcsAvailable === "Y") .map(({ ProdId, ProdName, ProdVariantDetails, ...rest }) => ({ ProdId, ProdName, ProdVariantDetails, ...rest, })), }; const modiffiedData = Parameter === 'OnePeiceProduct' ? transformedItem : item; setQtydata(modiffiedData); if (modiffiedData.OverAllExpStatus === 'Y' && ExpiredProduct) { openExpireModal({ title: 'Product Expires', onOk: () => expFun(modiffiedData), }); setItem(modiffiedData); } else if (modiffiedData) { setQtydata(modiffiedData); let count = modiffiedData?.ProductDetail?.length; if (count > 1) { Quantity(modiffiedData); } else { setQtyIndex(0); SingleQuantity(modiffiedData, Parameter === 'OnePeiceProduct'); } } }; const StockDate = (date) => { let dateVal = moment(date, ['YYYY-MM-DDTHH:mm:ss']).format('DD-MM-YYYY'); return dateVal; }; const AddOrderDetails = async (item, Qty = 1) => { if ((overAllLimitPreferenece || itemWiseLimitPreferenece) && maxQtyLimit) { if (overAllLimitPreferenece) { const calculatedOverAllQty = calculateOverAllQtyLimit(CartOrderDetails); if (calculatedOverAllQty + Qty > maxQtyLimit) { setMessageData(`Overall Quantity Limit Exceeds than ${maxQtyLimit}`); setMessageType('warning'); return; } } else if (itemWiseLimitPreferenece) { const inwardQtyMap = CartOrderDetails.reduce((acc, curr) => { const inwardId = curr?.InwardDtlId; const qty = Number(curr?.OrderQty) || 0; if (acc[inwardId]) { acc[inwardId] += qty; } else { acc[inwardId] = qty; } return acc; }, {}); const currentInwardId = item?.InwardDtlId; const addQty = Qty || 1; if (inwardQtyMap[currentInwardId]) { inwardQtyMap[currentInwardId] += addQty; } else { inwardQtyMap[currentInwardId] = addQty; } console.log('Final InwardDtlId Qty Map:', inwardQtyMap); const isExceeded = Object.values(inwardQtyMap).some( (qty) => qty > maxQtyLimit ); if (isExceeded) { setMessageData(`Item 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 = PreOrderSelectedProdNames?.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 = PreOrderSelectedProdNames?.length > 0 ? [SelectedProduct, ...PreOrderSelectedProdNames] : [SelectedProduct]; await setPreOrderSelectedProdNames(Data); await dispatch(changepreOrderList(Data)); }; const handleRegularOrder = async (item) => { const isHoldOrder = OrderType === 'Hold'; const addFirst = BillOrderPre === 'Y'; 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 isItemInCartHold = CartOrderDetails?.find( (cartItem) => itemMatchCondition(cartItem) && ((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) ); // 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 !== 'C' && cartItem?.OfferMode !== 'O' && cartItem?.OfferMode !== 'L' ? true : cartItem?.Offer === 0) ) ); const otherOrderDataForNormalWithoutSalesId = CartOrderDetails?.filter( (cartItem) => !( itemMatchCondition(cartItem) && ((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) ) ); try { // CASE 1: Item exists in cart, not Dine In, not Hold order if (isItemInCart && !isHoldOrder) { 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)); } } } // CASE 2: Item exists in cart (hold), is Hold order else if (isItemInCartHold && isHoldOrder) { 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)); } } } // 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 ( 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)); } } } } } 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 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 || PromoCodeOffersDatas?.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 ); } const handleBulkUpload = async () => { console.log( AllCategoryDatas, AllsubcatgoryDatas, 'AllsubcatgoryDatas', ProdSubCat ); let ProdcatName = AllCategoryDatas?.find((cat) => cat?.ProdCat == ProdCat)?.ProdCatName || 'General'; let ProdsubcatName = AllsubcatgoryDatas?.find((subcat) => subcat?.ProdSubCat == ProdSubCat) ?.ProdSubCatName || 'General'; const Postdata = products?.map((e, index) => { if (e?.name == null || e?.name === '') { setMessageData(`Product Name is missing at Row ${index + 1} `); setMessageType('error'); throw new Error(`Product Name is missing at Row ${index + 1} `); } if (e?.price == null || e?.price === '') { setMessageData( `Price is missing for product at Row ${index + 1} (${e?.name || 'Unknown'})` ); setMessageType('error'); throw new Error( `Price is missing for product at index ${index} (${e?.name || 'Unknown'})` ); } return { AppId, CompId, BranchId, CreatedBy: UserId, ProdName: e?.name, ProdVariantName: '', ProdCat: ProdcatName, ProdSubCat: ProdsubcatName, Brand: '', PartNumber: '', HSNCode: '', ProdNameCode: e?.code, UOM: e?.UOMName, Size: e?.size || 1, MRP: e.price, SellPrice: e.price, WhSalePrice: '', TaxId: 'NIL - 0%', StockAvailable: 'No', OnePcsAvailable: 'No', TokenAvailable: 'No', AutoGenerateQr: 'No', AutoGenerateSingleQr: 'No', OnePcQR: '', QRCode: '', Rack: '', AvailableFrom: null, AvailableTo: null, ManufDate: null, ExpDate: null, }; }); const response = await dispatch( bulkpostdata({ ProdDetails: Postdata }) ).unwrap(); if (response?.data?.statusCode === 1) { productCardList(); setMessageData(response?.data?.message); setMessageType('success'); setNewMoreProductModel(false); setProducts([ { id: 1, name: '', price: '', code: '', size: '1', category: '' }, ]); } else { setMessageData(response?.data?.message); setMessageType('error'); } }; 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, // still overall, can later split if needed 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, }; } // Filter only free products with remaining quantity const availableFreeProdList = freeProdList?.filter( (prod) => prod?.RemainingQty > 0 ); 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 returnCount = (ProdName, currentQty, orderDetails, overallpcs) => { let SelectedProduct = ReorderProductData?.filter( (a) => a?.ProdName === ProdName ); 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 ); // Include combo consumption from ReorderProductData (SetCount == 0) try { const reorderComboLines = (ReorderProductData || []).filter( (a) => a?.Type === 'C' ); if (reorderComboLines?.length > 0) { const reorderComboConsumed = reorderComboLines.reduce( (sum, comboLine) => { const setZero = comboLine?.SetCount === 0 || comboLine?.SetCount === '0'; if (!setZero) return sum; const details = Array.isArray(comboLine?.ProdDetail) ? comboLine?.ProdDetail : []; const orderQty = parseInt(comboLine?.OrderQty || 1); const consumed = details.reduce((inner, d) => { const nameMatches = d?.ProdName === ProdName || d?.ProductName === ProdName; if (nameMatches && d?.StockAvailable === 'Y') { const compQty = parseInt(d?.ProductQty ?? 1); return inner + orderQty * (isNaN(compQty) ? 1 : compQty); } return inner; }, 0); return sum + consumed; }, 0 ); totalSelectedProductQty = parseInt(totalSelectedProductQty || 0) + parseInt(reorderComboConsumed || 0); } } catch (_) {} let getCurrentProdDtl = orderDetails?.filter( (a) => a?.ProdName === ProdName ); let ComboProdDtl = orderDetails?.filter((a) => a?.Type === 'C'); if (overallpcs === 'Y' && ComboProdDtl?.length > 0) { getCurrentProdDtl = getCurrentProdDtl?.filter((a) => a?.Type !== 'C'); } 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); // Combo adjustment: // If combos (Type === 'C') include this product and that component has SetCount == 0 // and StockAvailable === 'Y', treat each occurrence as consuming one unit. if (Array.isArray(ComboProdDtl) && ComboProdDtl.length > 0) { try { const comboExtraQty = ComboProdDtl.reduce((sum, comboLine) => { // Use combo-level SetCount when detail-level SetCount is absent const comboSetCountZero = comboLine?.SetCount === 0 || comboLine?.SetCount === '0'; if (!comboSetCountZero) return sum; const details = comboLine?.ProdDetail; if (!Array.isArray(details)) return sum; const orderQty = parseInt(comboLine?.OrderQty || 1); const consumed = details.reduce((innerSum, d) => { const nameMatches = d?.ProdName === ProdName || d?.ProductName === ProdName; const stockYes = d?.StockAvailable === 'Y'; if (nameMatches && stockYes) { const compQty = parseInt(d?.ProductQty ?? 1); return innerSum + orderQty * (isNaN(compQty) ? 1 : compQty); } return innerSum; }, 0); return sum + consumed; }, 0); totalOrderQty = parseInt(totalOrderQty || 0) + parseInt(comboExtraQty || 0); } catch (e) { // ignore structure mismatches } } 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 returnOnepcCount = (ProdName, currentQty, orderDetails, overallpcs) => { let SelectedProduct = ReorderProductData?.filter( (a) => a?.ProdName === ProdName ); 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?.ProdName === ProdName ); 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; } }; 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 ); // Include combo consumption from ReorderProductData (pieces flow) try { const reorderComboLines = (ReorderProductData || []).filter( (a) => a?.Type === 'C' ); if (reorderComboLines?.length > 0) { const reorderComboConsumed = reorderComboLines.reduce( (sum, comboLine) => { const setZero = comboLine?.SetCount === 0 || comboLine?.SetCount === '0'; if (!setZero) return sum; const details = Array.isArray(comboLine?.ProdDetail) ? comboLine?.ProdDetail : []; const orderQty = parseInt(comboLine?.OrderQty || 1); const consumed = details.reduce((inner, d) => { if (d?.ProdId === ProdId && d?.StockAvailable === 'Y') { const compQty = parseInt(d?.ProductQty ?? 1); return inner + orderQty * (isNaN(compQty) ? 1 : compQty); } return inner; }, 0); return sum + consumed; }, 0 ); totalSelectedProductQty = parseInt(totalSelectedProductQty || 0) + parseInt(reorderComboConsumed || 0); } } catch (_) {} 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); // Include combo consumption for pieces flow try { const comboLines = orderDetails?.filter((a) => a?.Type === 'C') || []; const comboConsumed = comboLines.reduce((sum, comboLine) => { const comboSetZero = comboLine?.SetCount === 0 || comboLine?.SetCount === '0'; if (!comboSetZero) return sum; const details = Array.isArray(comboLine?.ProdDetail) ? comboLine?.ProdDetail : []; const orderQty = parseInt(comboLine?.OrderQty || 1); const consumedForThisCombo = details.reduce((inner, d) => { if (d?.ProdId === ProdId && d?.StockAvailable === 'Y') { const compQty = parseInt(d?.ProductQty ?? 1); return inner + orderQty * (isNaN(compQty) ? 1 : compQty); } return inner; }, 0); return sum + consumedForThisCombo; }, 0); totalOrderQty = parseInt(totalOrderQty || 0) + parseInt(comboConsumed || 0); } catch (_) {} 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 ); // Include combo consumption from ReorderProductData (quantity flow) try { const reorderComboLines = (ReorderProductData || []).filter( (a) => a?.Type === 'C' ); if (reorderComboLines?.length > 0) { const reorderComboConsumed = reorderComboLines.reduce( (sum, comboLine) => { const setZero = comboLine?.SetCount === 0 || comboLine?.SetCount === '0'; if (!setZero) return sum; const details = Array.isArray(comboLine?.ProdDetail) ? comboLine?.ProdDetail : []; const orderQty = parseInt(comboLine?.OrderQty || 1); const consumed = details.reduce((inner, d) => { if (d?.ProdId === ProdId && d?.StockAvailable === 'Y') { return inner + orderQty; } return inner; }, 0); return sum + consumed; }, 0 ); totalSelectedProductQty = parseInt(totalSelectedProductQty || 0) + parseInt(reorderComboConsumed || 0); } } catch (_) {} 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); // Include combo consumption for quantity flow try { const comboLines = orderDetails?.filter((a) => a?.Type === 'C') || []; const comboConsumed = comboLines.reduce((sum, comboLine) => { const comboSetZero = comboLine?.SetCount === 0 || comboLine?.SetCount === '0'; if (!comboSetZero) return sum; const details = Array.isArray(comboLine?.ProdDetail) ? comboLine?.ProdDetail : []; const orderQty = parseInt(comboLine?.OrderQty || 1); const consumedForThisCombo = details.reduce((inner, d) => { if (d?.ProdId === ProdId && d?.StockAvailable === 'Y') { return inner + orderQty; } return inner; }, 0); return sum + consumedForThisCombo; }, 0); totalOrderQty = parseInt(totalOrderQty || 0) + parseInt(comboConsumed || 0); } catch (_) {} 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, overallpcs ) => { 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 ); // Include combo consumption from ReorderProductData (pieces + batch) try { const reorderComboLines = (ReorderProductData || []).filter( (a) => a?.Type === 'C' ); if (reorderComboLines?.length > 0) { const reorderComboConsumed = reorderComboLines.reduce( (sum, comboLine) => { const setZero = comboLine?.SetCount === 0 || comboLine?.SetCount === '0'; if (!setZero) return sum; const details = Array.isArray(comboLine?.ProdDetail) ? comboLine?.ProdDetail : []; const orderQty = parseInt(comboLine?.OrderQty || 1); const consumed = details.reduce((inner, d) => { if ( d?.ProdId === ProdId && d?.InwardDtlId === InwardDtlId && d?.StockAvailable === 'Y' ) { const compQty = parseInt(d?.ProductQty ?? 1); return inner + orderQty * (isNaN(compQty) ? 1 : compQty); } return inner; }, 0); return sum + consumed; }, 0 ); totalSelectedProductQty = parseInt(totalSelectedProductQty || 0) + parseInt(reorderComboConsumed || 0); } } catch (_) {} 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); // Include combo consumption (no one-piece logic for combos) try { const comboLines = orderDetails?.filter((a) => a?.Type === 'C') || []; const comboConsumed = comboLines.reduce((sum, comboLine) => { const comboSetZero = comboLine?.SetCount === 0 || comboLine?.SetCount === '0'; if (!comboSetZero) return sum; const details = Array.isArray(comboLine?.ProdDetail) ? comboLine?.ProdDetail : []; const orderQty = parseInt(comboLine?.OrderQty || 1); const consumedForThisCombo = details.reduce((inner, d) => { if ( d?.ProdId === ProdId && d?.InwardDtlId === InwardDtlId && d?.StockAvailable === 'Y' ) { const compQty = parseInt(d?.ProductQty ?? 1); return inner + orderQty * (isNaN(compQty) ? 1 : compQty); } return inner; }, 0); return sum + consumedForThisCombo; }, 0); totalOrderQty = parseInt(totalOrderQty || 0) + parseInt(comboConsumed || 0); } catch (_) {} 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 ); // Include combo consumption from ReorderProductData (quantity + batch) try { const reorderComboLines = (ReorderProductData || []).filter( (a) => a?.Type === 'C' ); if (reorderComboLines?.length > 0) { const reorderComboConsumed = reorderComboLines.reduce( (sum, comboLine) => { const setZero = comboLine?.SetCount === 0 || comboLine?.SetCount === '0'; if (!setZero) return sum; const details = Array.isArray(comboLine?.ProdDetail) ? comboLine?.ProdDetail : []; const orderQty = parseInt(comboLine?.OrderQty || 1); const consumed = details.reduce((inner, d) => { if ( d?.ProdId === ProdId && d?.InwardDtlId === InwardDtlId && d?.StockAvailable === 'Y' ) { return inner + orderQty; } return inner; }, 0); return sum + consumed; }, 0 ); totalSelectedProductQty = parseInt(totalSelectedProductQty || 0) + parseInt(reorderComboConsumed || 0); } } catch (_) {} 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); // Include combo consumption for quantity flow try { const comboLines = orderDetails?.filter((a) => a?.Type === 'C') || []; const comboConsumed = comboLines.reduce((sum, comboLine) => { const comboSetZero = comboLine?.SetCount === 0 || comboLine?.SetCount === '0'; if (!comboSetZero) return sum; const details = Array.isArray(comboLine?.ProdDetail) ? comboLine?.ProdDetail : []; const orderQty = parseInt(comboLine?.OrderQty || 1); const consumedForThisCombo = details.reduce((inner, d) => { if ( d?.ProdId === ProdId && d?.InwardDtlId === InwardDtlId && d?.StockAvailable === 'Y' ) { return inner + orderQty; } return inner; }, 0); return sum + consumedForThisCombo; }, 0); totalOrderQty = parseInt(totalOrderQty || 0) + parseInt(comboConsumed || 0); } catch (_) {} 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 ) => { // let ReorderProdetails = BookingType === "Dine In" && !UnpaidData ? ReportholdData?.OrderDtlDetails // : BookingType === "Dine In" && UnpaidData ? ReportholdData?.productDetails // : ReportholdData?.productDetails 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 varientcolumns = [ { title: 'Variant Name', dataIndex: 'VarientName', key: 'VarientName', align: 'left', render: (_, record, index) => ( 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' } } > {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, index) => ( 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, index) => ( 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: (_, record, index) => ( 0 ? { color: '#000', cursor: 'pointer' } : { color: '#f49898', cursor: 'not-allowed' } } > {safeRound(record.Price)} ), 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?.[QtyIndex]?.StockAvailable === 'Y' ? onePeiceFlow ? returnVariantStock( qtydata?.ProductDetail?.[QtyIndex]?.ProdId, item?.OverAllPcs, CartOrderDetails, item?.ProdVariantName ) : returnVariantStock( qtydata?.ProductDetail?.[QtyIndex]?.ProdId, item?.OverAllQty, CartOrderDetails, item?.ProdVariantName ) : 'Stock Not Maintained', VariantAvailableFrom: item?.AvailableFrom, VariantAvailableTo: item?.AvailableTo, SlotStatus: item?.StockDetails?.[0]?.SlotStatus, InwardDtlId: item?.StockDetails?.[0]?.InwardDtlId, BookedDate: selectedDate, BookedQty: item?.StockDetails?.[0]?.BookedQty, TotalSlotQty: item?.StockDetails?.[0]?.TotalSlotQty, }); }); 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?.OverAllPcs, CartOrderDetails, item?.InwardDtlId, 'Y' ) : returnCountStock( item?.ProdId, item?.BalanceQty, CartOrderDetails, item?.InwardDtlId, 'N', item?.OverAllPcs ), 'Stock Date': ExtractDateFormate(item?.InwardDate), Price: onePeiceFlow ? item?.OnePcsPrice : item?.SellPrice, ExpDate: expDate != 'Invalid Date' || null || undefined || '' ? ExtractDateFormate(item?.ExpDate) : '-', }); }); const extractProductDetails = (a, QtyIndex, VarientIndex, stockIndex) => { const detail = a?.ProductDetail?.[QtyIndex]; const variant = detail?.ProdVariantDetails?.[VarientIndex]; const stock = variant?.StockDetails?.[stockIndex]; return { detail, variant, stock }; }; const buildOrderData = ( a, detail, variant, stock, size, orderRate, onePcs, weightscale ) => { const { ProdCat, Type, OverAllQty: OverallQuantity, CounterName } = a || {}; const { ActiveStatus, AvailableFrom, AvailableTo, Cess, HSNCode, BrandName, OpeningQty, PartNumber, ProdId, ProdLogo, ProdName, QRCode, QtyBasedPrice, Rack, StockAvailable, TokenAvailable, TaxId, TaxPercentage, TaxIdName: TaxName, UniqueId, UomName, DiscountLimitType, DiscountLimit, } = detail || {}; const { NoOfPcs, BalanceQty, BatchRef, ModelNumber, ProductIdentifierDtls: FullProductIdentifierDtls, InwardDate, InwardDtlId, ExpDate, InwardId, MRP, OnePcsPrice, SellPrice, SuppId, SuppName, OverAllPcs, OfferPrice: Offer, TotalSlotQty, BookedQty, } = stock || {}; const BalanceBookedQty = TotalSlotQty || 0 - BookedQty || 0; const { ProdVariantName, AvailableFrom: VariantAvailableFrom, AvailableTo: VariantAvailableTo, } = variant || {}; return { ProdCat, Type, OverallQuantity, ActiveStatus, AvailableFrom, AvailableTo, Cess, HSNCode, BrandName, OpeningQty, PartNumber, ProdId, ProdLogo, ProdName, QRCode, QtyBasedPrice, Rack, Size: size, StockAvailable, TokenAvailable, TaxId, TaxPercentage, TaxName, UniqueId, UomName: onePcs ? 'PCS' : UomName, SinglePc: onePcs ? 'Y' : 'N', NoOfPcs, ProdVariantName, VariantAvailableFrom, VariantAvailableTo, BalanceQty, BatchRef, ModelNumber, FullProductIdentifierDtls, InwardDate, InwardDtlId, ExpDate, InwardId, MRP: onePcs ? OnePcsPrice : MRP, OrderRate: orderRate, SellingPrice: orderRate, SuppId, SuppName, OverAllPcs, Offer, BookingTypeName: BookingType, CounterName, DiscountLimitType, DiscountLimit, BookedDate: selectedDate, BalanceBookedQty, ScaleType: weightscale ? weightscale : '', }; }; const resetProductModal = () => { setModelQty(false); setSelectedBrand('Others'); setModalVarient(false); setModelstock(false); setQtyIndex(0); setVarientIndex(0); setVarItem(0); setItem(); setStockItem(); dispatch(changeSearchedData('')); setOnePeiceFlow(false); }; const dataTransfer = async ( a, QtyIndex, VarientIndex, stockIndex, onePcs ) => { const { detail, variant, stock } = extractProductDetails( a, QtyIndex, VarientIndex, stockIndex ); console.log(stock, 'stock in dataTransfer'); // mohan 05-08-2025 const price = onePcs ? stock?.OnePcsPrice : RetailWSSalesType === 'W' ? stock?.WhSalePrice || stock?.SellPrice : stock?.SellPrice; const size = onePcs ? '1' : detail?.Size; if (quickBranchtoBranchTransfer) { const data = buildOrderData( a, detail, variant, stock, size, price, onePcs ); if (!selectedProducts?.some((s) => s.ProdId === detail?.ProdId)) { dispatch( changeBtoBQuickProductTransfer({ action: quickBranchtoBranchTransfer, selectedProducts: [ ...selectedProducts, { ...data, OrderQty: 1, TotalAmt: parseFloat(detail?.OrderRate).toFixed(2), }, ], }) ); } else { setMessageType('error'); setMessageData('Product already added'); } } else { const isKgsProduct = (detail?.UomName?.toLowerCase() === 'kgs' || detail?.UomName?.toLowerCase() === 'kg') && detail?.Size === '1'; console.log( isKgsProduct, WeightScalePort, WeightScaleWeight, 'isKgsProduct' ); if ( WeightScalePort === true && isKgsProduct && WeightScaleWeight > 0.005 && WeightScaleWeight !== null ) { let weightscale = 'weight'; // if (isKgsProduct) { // if (WeightScaleWeight > 0 && WeightScaleWeight !== null) { const basePrice = onePcs ? stock?.OnePcsPrice : stock?.SellPrice; const totalRate = ( (basePrice / 1000) * (parseFloat(WeightScaleWeight) * 1000) ).toFixed(2); let orderqty = parseFloat(WeightScaleWeight); const data = buildOrderData( a, detail, variant, stock, detail?.Size, basePrice, onePcs, weightscale ); let fulldata = { ...data, OrderQty: orderqty, }; await AddOrderDetails(fulldata); // dispatch(changeWeightScaleWeight(null)); setRepeatedModel(false); setProdexpir(false); resetProductModal(); // } else { // setMessageType('error'); // setMessageData('Please Connect WeightScale'); // } // } else { // setMessageType('error'); // setMessageData('Please Select 1Kg Product'); // } } else { const isValidPcs = onePcs && stock?.NoOfPcs > 0 && stock?.OnePcsPrice > 0; const allowNonPcs = !onePcs || (detail?.StockAvailable !== 'Y' && onePcs && stock?.OnePcsPrice > 0); if (isValidPcs || allowNonPcs) { const data = buildOrderData( a, detail, variant, stock, size, price, onePcs ); resetProductModal(); AddOrderDetails(data); } else { setMessageType('error'); setMessageData( 'Please add No.of pieces Inside the box in Product master' ); resetProductModal(); } } } }; useEffect(() => { setPreOrderSelectedProdNames(GPreOrderList); }, [GPreOrderList]); const pickData = (e, item) => { if (e.target.checked === true) { setSelectedProdNames([ ...globalAllItemdata, { ProdName: item.ProdName, ProdId: item.ProductDetail?.[0]?.ProdId, ProdCat: item.ProdCat, ProdCatName: item.ProdCatName, }, ]); } else { console.log('SelectedProdNames', SelectedProdNames); setSelectedProdNames( SelectedProdNames?.filter( (data) => !(data?.ProdName == item.ProdName && data?.ProdCat == item.ProdCat) ) ); } }; const handleQuickCancel = async () => { setQuickAdd(false); dispatch(changeSearchedData('')); // Base data for all calls let baseData = { CompId, BranchId, AppId, }; // 👇 Only add date if AvailableDate and selectedDate exist if (AvailableDate && selectedDate) { baseData.Date = selectedDate; } // 1️⃣ Favourite items await dispatch(getSelectedFavItems(baseData)).unwrap(); // 2️⃣ For layout with SubCategory let data1 = { ...baseData, ProdSubCat, }; // 3️⃣ For layout without SubCategory let data2 = { compId: CompId, branchId: BranchId, appId: AppId, prodCat: ProdCat, ...(AvailableDate && selectedDate ? { date: selectedDate } : {}), // conditionally add }; if ( templateData?.BookingLayout?.[1]?.some( (item) => item?.OptionName === 'SubCategory' ) && ProdSubCat ) { await dispatch(getLayoutproductCard(data1)).unwrap(); } else if ( !templateData?.BookingLayout?.[1]?.some( (item) => item?.OptionName === 'SubCategory' ) ) { await dispatch(getCardDataWithoutSubmodule(data2)).unwrap(); } else { await dispatch(getCardDataWithoutSub(data2)).unwrap(); } }; const onComplete = useCallback(() => { setMessageData(null); setMessageType(null); }, []); const expFun = (item) => { console.log(item, 'itemitemitemitemitemitemitemitem'); let count = item?.ProductDetail?.length; if (count > 1) { Quantity(); } else { setVarItem(0); SingleQuantity(item, onePeiceFlow); } closeExpireModal(); setProdexpir(true); setQtydata(item); }; 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 ItemSellingPrice = (item) => { // const variantWithDetails = item?.ProductDetail?.find((variant) => variant?.ProdVariantDetails?.length > 0); if (preferenceSingleSales && item.OnePcsAvailable === 'Y') { return ( item?.ProductDetail?.[0]?.ProdVariantDetails?.[0]?.StockDetails?.[0] ?.OnePcsPrice || 0 ); // OnePcsPrice } const variantWithDetails = item?.ProductDetail?.find( (variant) => variant?.ProdVariantDetails?.length > 0 && variant?.ProdVariantDetails?.[0]?.StockDetails?.[0]?.SellPrice ); if (variantWithDetails) { // Access the details of the first variant with ProdVariantDetails const firstVariantDetails = variantWithDetails?.ProdVariantDetails?.[0]?.StockDetails?.[0] ?.SellPrice; return firstVariantDetails; } else { // Handle the case where no variant satisfies the condition return 0; // or any other value you want to return } }; const ItemMRP = (item) => { // const variantWithDetails = item?.ProductDetail?.find((variant) => variant?.ProdVariantDetails?.length > 0); if (preferenceSingleSales && item.OnePcsAvailable === 'Y') { return ( item?.ProductDetail?.[0]?.ProdVariantDetails?.[0]?.StockDetails?.[0] ?.OnePcsPrice || 0 ); // OnePcsPrice } const variantWithDetails = item?.ProductDetail?.find( (variant) => variant?.ProdVariantDetails?.length > 0 && variant?.ProdVariantDetails?.[0]?.StockDetails?.[0]?.MRP ); if (variantWithDetails) { // Access the details of the first variant with ProdVariantDetails const firstVariantDetails = variantWithDetails?.ProdVariantDetails?.[0]?.StockDetails?.[0]?.MRP; return firstVariantDetails; } else { // Handle the case where no variant satisfies the condition return 0; // or any other value you want to return } }; const ItemSize = (item) => { if (preferenceSingleSales && item?.OnePcsAvailable === 'Y') { return 1; } const variantWithDetails = item?.ProductDetail?.find( (variant) => variant?.ProdVariantDetails?.length > 0 ); if (variantWithDetails) { // Access the details of the first variant with ProdVariantDetails const firstVariantDetails = variantWithDetails?.Size; return firstVariantDetails; } else { // Handle the case where no variant satisfies the condition return null; // or any other value you want to return } }; const ItemUomName = (item) => { if (preferenceSingleSales && item?.OnePcsAvailable === 'Y') { return 'PCS'; } const variantWithDetails = item?.ProductDetail?.find( (variant) => variant?.ProdVariantDetails?.length > 0 ); if (variantWithDetails) { // Access the details of the first variant with ProdVariantDetails const firstVariantDetails = variantWithDetails?.UomName; return firstVariantDetails; } else { // Handle the case where no variant satisfies the condition return null; // or any other value you want to return } }; const expQtyFun = (index) => { const selectedProIndex = qtydata?.ProductDetail?.findIndex( (item) => item?.ProdId === index?.ProdId && item?.Size === index?.Size && item?.UomName === index?.UomName && item?.Brand === index?.Brand ); if (selectedProIndex !== -1) { const count = qtydata?.ProductDetail[selectedProIndex]?.ProdVariantDetails?.length || 0; if (count > 1) { setModelQty(false); setSelectedBrand('Others'); setModalVarient(true); } else { const item = { QtyIndex: selectedProIndex, VarientIndex: 0 }; singleVarient(item); setModelQty(false); setSelectedBrand('Others'); } } setQtyIndex(selectedProIndex); setRepeatedModel(true); 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); setSelectedBrand('Others'); } closeExpireModal(); }; const expStockFun = (item) => { dataTransfer(qtydata, QtyIndex, VarientIndex, item, onePeiceFlow); closeExpireModal(); }; 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; }; useEffect(() => { function handleResize() { setScreenWidth(window.innerWidth); } window.addEventListener('resize', handleResize); return () => { window.removeEventListener('resize', handleResize); }; }, []); // Example usage for checking the length of 'ProdVariantDetails' const widthBasedOnProdVariantDetails = getMaxBrandWidth(); const ExpDate = useSelector(GlobalExpDateforHeight); let containerHeight = ''; if (templateData?.BookingLayout?.[0] === 'Layout1') { if (templateData?.BookingBilling?.[0] == 'Billing1') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 310}px` : '61vh' : screenWidth < 600 ? `${props?.screenHeight - 320}px` : '60vh' : '76vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing2') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 300}px` : '61vh' : screenWidth < 600 ? `${props?.screenHeight - 310}px` : '60vh' : '76vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing3') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 340}px` : '63vh' : screenWidth < 600 ? `${props?.screenHeight - 350}px` : '62vh' : '76vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing4') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 300}px` : '63vh' : screenWidth < 600 ? `${props?.screenHeight - 310}px` : '62vh' : '76vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing5') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 300}px` : '60vh' : screenWidth < 600 ? `${props?.screenHeight - 310}px` : '59vh' : '76vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing6') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 300}px` : '60vh' : screenWidth < 600 ? `${props?.screenHeight - 310}px` : '59vh' : '76vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing7') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 300}px` : '60vh' : screenWidth < 600 ? `${props?.screenHeight - 310}px` : '59vh' : '76vh'; } } else if (templateData?.BookingLayout?.[0] === 'Layout2') { if (templateData?.BookingBilling?.[0] == 'Billing1') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 310}px` : '61vh' : screenWidth < 600 ? `${props?.screenHeight - 320}px` : '60vh' : '74vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing2') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 320}px` : '61vh' : screenWidth < 600 ? `${props?.screenHeight - 330}px` : '60vh' : '74vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing3') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 320}px` : '63vh' : screenWidth < 600 ? `${props?.screenHeight - 330}px` : '62vh' : '74vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing4') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 320}px` : '63vh' : screenWidth < 600 ? `${props?.screenHeight - 330}px` : '62vh' : '74vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing5') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 320}px` : '60vh' : screenWidth < 600 ? `${props?.screenHeight - 330}px` : '61vh' : '74vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing6') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 320}px` : '60vh' : screenWidth < 600 ? `${props?.screenHeight - 330}px` : '59vh' : '74vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing7') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 310}px` : '61vh' : screenWidth < 600 ? `${props?.screenHeight - 320}px` : '60vh' : '75vh'; } } else if (templateData?.BookingLayout?.[0] === 'Layout3') { if (templateData?.BookingBilling?.[0] == 'Billing1') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 390}px` : '58vh' : screenWidth < 600 ? `${props?.screenHeight - 400}px` : '57vh' : '73vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing2') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 390}px` : '57vh' : screenWidth < 600 ? `${props?.screenHeight - 400}px` : '56vh' : '73vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing3') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 395}px` : '57vh' : screenWidth < 600 ? `${props?.screenHeight - 400}px` : '56vh' : '73vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing4') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 390}px` : '57vh' : screenWidth < 600 ? `${props?.screenHeight - 400}px` : '56vh' : '75vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing5') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 385}px` : '57vh' : screenWidth < 600 ? `${props?.screenHeight - 395}px` : '56vh' : '72vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing6') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 385}px` : '57vh' : screenWidth < 600 ? `${props?.screenHeight - 395}px` : '56vh' : '72vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing7') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 390}px` : '57vh' : screenWidth < 600 ? `${props?.screenHeight - 400}px` : '56vh' : '72vh'; } } else if (templateData?.BookingLayout?.[0] === 'Layout4') { if (templateData?.BookingBilling?.[0] == 'Billing1') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 260}px` : '73vh' : screenWidth < 600 ? `${props?.screenHeight - 270}px` : '72vh' : '88vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing2') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 220}px` : '73vh' : screenWidth < 600 ? `${props?.screenHeight - 230}px` : '72vh' : '88vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing3') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 260}px` : '73vh' : screenWidth < 600 ? `${props?.screenHeight - 270}px` : '72vh' : '88vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing4') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 230}px` : '73vh' : screenWidth < 600 ? `${props?.screenHeight - 240}px` : '72vh' : '88vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing5') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 230}px` : '73vh' : screenWidth < 600 ? `${props?.screenHeight - 240}px` : '72vh' : '88vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing6') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 260}px` : '73vh' : screenWidth < 600 ? `${props?.screenHeight - 270}px` : '72vh' : '88vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing7') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 260}px` : '73vh' : screenWidth < 600 ? `${props?.screenHeight - 270}px` : '72vh' : '88vh'; } } else if (templateData?.BookingLayout?.[0] === 'Layout5') { if (templateData?.BookingBilling?.[0] == 'Billing1') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 280}px` : '72vh' : screenWidth < 600 ? `${props?.screenHeight - 290}px` : '70vh' : '88vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing2') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 260}px` : '72vh' : screenWidth < 600 ? `${props?.screenHeight - 270}px` : '70vh' : '88vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing3') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 270}px` : '72vh' : screenWidth < 600 ? `${props?.screenHeight - 280}px` : '70vh' : '88vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing4') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 270}px` : '72vh' : screenWidth < 600 ? `${props?.screenHeight - 280}px` : '70vh' : '88vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing5') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 260}px` : '72vh' : screenWidth < 600 ? `${props?.screenHeight - 270}px` : '70vh' : '88vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing6') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 260}px` : '72vh' : screenWidth < 600 ? `${props?.screenHeight - 270}px` : '70vh' : '88vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing7') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 270}px` : '72vh' : screenWidth < 600 ? `${props?.screenHeight - 280}px` : '70vh' : '88vh'; } } else if (templateData?.BookingLayout?.[0] === 'Layout6') { if (templateData?.BookingBilling?.[0] == 'Billing1') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 330}px` : '61vh' : screenWidth < 600 ? `${props?.screenHeight - 340}px` : '60vh' : '76vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing2') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 260}px` : '61vh' : screenWidth < 600 ? `${props?.screenHeight - 370}px` : '60vh' : '76vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing3') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 320}px` : '61vh' : screenWidth < 600 ? `${props?.screenHeight - 330}px` : '60vh' : '76vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing4') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 320}px` : '61vh' : screenWidth < 600 ? `${props?.screenHeight - 320}px` : '60vh' : '76vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing5') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 290}px` : '61vh' : screenWidth < 600 ? `${props?.screenHeight - 300}px` : '60vh' : '76vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing6') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 320}px` : '61vh' : screenWidth < 600 ? `${props?.screenHeight - 330}px` : '60vh' : '76vh'; } else if (templateData?.BookingBilling?.[0] == 'Billing7') { containerHeight = isMobile ? ExpDate >= 7 ? screenWidth < 600 ? `${props?.screenHeight - 280}px` : '61vh' : screenWidth < 600 ? `${props?.screenHeight - 290}px` : '60vh' : '76vh'; } } //new const [draggableCardData, setDraggableCardData] = useState([]); useEffect(() => { if (Array.isArray(cardData)) { const withIds = cardData.map((item, idx) => ({ ...item, id: item?.ProductDetail?.[0]?.ProdName + '-' + idx, })); // const newData = alphabeticFormat // ? [...withIds].sort((a, b) => { // const nameA = a?.ProductDetail?.[0]?.ProdName || ""; // const nameB = b?.ProductDetail?.[0]?.ProdName || ""; // return nameA.localeCompare(nameB); // }) // : [...withIds].sort((a, b) => { // const nameA = a?.ProductDetail?.[0]?.ProdName || ""; // const nameB = b?.ProductDetail?.[0]?.ProdName || ""; // return nameB.localeCompare(nameA); // }); setDraggableCardData(withIds); } }, [cardData, alphabeticFormat]); const sensors = useSensors( useSensor(PointerSensor, { activationConstraint: { distance: isMobile ? 5 : 8, // <- reduced distance for mobile }, }), useSensor(TouchSensor, { activationConstraint: { delay: isMobile ? 50 : 100, // <- even faster response for mobile tolerance: isMobile ? 10 : 8, // <- more tolerance for mobile touch }, }) ); const handleDragEnd = (event) => { const { active, over } = event; // Ensure `over` is not null if (!over) return; if (active.id !== over.id) { const oldIndex = draggableCardData.findIndex((i) => i.id === active.id); const newIndex = draggableCardData.findIndex((i) => i.id === over.id); const updatedData = arrayMove(draggableCardData, oldIndex, newIndex); // const newData = alphabeticFormat // ? [...updatedData].sort((a, b) => { // const nameA = a?.ProductDetail?.[0]?.ProdName || ""; // const nameB = b?.ProductDetail?.[0]?.ProdName || ""; // return nameA.localeCompare(nameB); // }) // : [...updatedData].sort((a, b) => { // const nameA = a?.ProductDetail?.[0]?.ProdName || ""; // const nameB = b?.ProductDetail?.[0]?.ProdName || ""; // return nameB.localeCompare(nameA); // }); setDraggableCardData(updatedData); dispatch(changeCardData(updatedData)); } }; const updateScrollButtons = () => { const container = scrollContainerRef.current; if (!container) return; const { scrollLeft, scrollWidth, clientWidth } = container; console.log( container, 'sl:', scrollLeft, 'w:', scrollWidth, 'cw:', clientWidth ); setShowLeftButton(scrollLeft > 5); setShowRightButton(scrollLeft + clientWidth < scrollWidth - 5); }; useEffect(() => { const container = scrollContainerRef.current; if (!container) return; // ✅ Call once after layout requestAnimationFrame(() => { updateScrollButtons(); }); container.addEventListener('scroll', updateScrollButtons); window.addEventListener('resize', updateScrollButtons); const resizeObserver = new ResizeObserver(updateScrollButtons); resizeObserver.observe(container); return () => { container.removeEventListener('scroll', updateScrollButtons); window.removeEventListener('resize', updateScrollButtons); resizeObserver.disconnect(); }; }, [modelstock, ModalVarient, modelQty]); const handleScrollClickLeft = (scrollOffset) => { scrollContainerRef.current.scrollBy({ left: -scrollOffset, behavior: 'smooth', }); }; const handleScrollClickRight = (scrollOffset) => { scrollContainerRef.current.scrollBy({ left: scrollOffset, behavior: 'smooth', }); }; // const isDragging = useRef(false); // MOUSE EVENTS const handleMouseDown = (e) => { isDragging.current = true; startX.current = e.pageX - scrollContainerRef.current.offsetLeft; scrollLeft.current = scrollContainerRef.current.scrollLeft; scrollContainerRef.current.style.cursor = 'grabbing'; }; const handleMouseMove = (e) => { if (!isDragging.current) return; e.preventDefault(); // Important: prevents text selection and smooth scroll interference const x = e.pageX - scrollContainerRef.current.offsetLeft; const walk = (x - startX.current) * 0.8; // Adjust multiplier for speed scrollContainerRef.current.scrollLeft = scrollLeft.current - walk; }; const handleMouseUp = () => { isDragging.current = false; scrollContainerRef.current.style.cursor = 'grab'; }; // TOUCH EVENTS const handleTouchStart = (e) => { isDragging.current = true; startX.current = e.touches[0].pageX - scrollContainerRef.current.offsetLeft; scrollLeft.current = scrollContainerRef.current.scrollLeft; }; const handleTouchMove = (e) => { if (!isDragging.current) return; e.preventDefault(); // Prevents native scrolling const x = e.touches[0].pageX - scrollContainerRef.current.offsetLeft; const walk = (x - startX.current) * 0.8; // Adjust multiplier as needed scrollContainerRef.current.scrollLeft = scrollLeft.current - walk; }; const handleTouchEnd = () => { isDragging.current = false; }; const allProducts = Object.values(brandMapping).flat(); const brandGroups = {}; allProducts.forEach((product) => { const brandName = product.BrandName && product.BrandName !== 'null' && product.BrandName !== 'undefined' && product.BrandName.trim() !== '' ? product.BrandName : 'Others'; if (!brandGroups[brandName]) { brandGroups[brandName] = []; } brandGroups[brandName].push(product); }); useEffect(() => { const brandKeys = Object.keys(brandGroups || {}); if (brandKeys.length === 0) return; // Only set if selectedBrand is not present in the new brandGroups if (!brandKeys.includes(selectedBrand)) { if (brandKeys.includes('Others')) { setSelectedBrand('Others'); } else { setSelectedBrand(brandKeys[0]); } } }, [brandGroups]); const sortedBrandNames = Object.keys(brandGroups).sort((a, b) => a === 'Others' ? -1 : b === 'Others' ? 1 : 0 ); const [prodname, setprodname] = useState(''); const [prodQty, setprodQty] = useState(0); const normalize = (str) => str?.toLowerCase()?.replace(/\s+/g, ' ')?.trim(); const result = prodname ? (cardData || [])?.filter( (item) => normalize(item.ProdName).includes(normalize(prodname)) || normalize(item.ProdCatName).includes(normalize(prodname)) || item.ProductDetail?.some((detail) => normalize(detail.ProdName).includes(normalize(prodname)) ) ) : cardData; console.log(prodQty, 'cardDatacardData', result, prodname); const AddnewProduct = () => { setNewMoreProductModel(true); }; useEffect(() => { const item = result?.[0]; const detail = item?.ProductDetail?.[0]; const isInStock = detail?.StockAvailable === 'Y' && item?.OverAllQty > prodQty; const isStockNotTracked = detail?.StockAvailable === 'N'; if (result?.length > 0 && prodname && (isInStock || isStockNotTracked)) { // CardOnclick(item,(item?.OnePcsAvailable && preferenceSingleSales) && 'OnePeiceProduct' ); CardOnclick( result?.[0], result?.[0]?.OnePcsAvailable === 'Y' && preferenceSingleSales && 'OnePeiceProduct' ); // AddOrderDetails2(result?.[0]) } else if (item?.OverAllQty < prodQty) { setMessageType('error'); setMessageData('NoStack'); } }, [prodname]); function getClassNameBasedOnCard(type) { switch (type) { case 'Card1': return 'AddNewProductSalesBTNCard1'; case 'Card2': return 'AddNewProductSalesBTNCard2'; case 'Card3': return 'AddNewProductSalesBTNCard3'; case 'Card4': return 'AddNewProductSalesBTNCard4'; default: return 'AddNewProductSalesBTNCard1'; } } function encrypt(code, key) { // Implement encryption logic using a secure algorithm // For demonstration purposes, this is a simple XOR encryption let encrypted = ( <>
{messageType && messageData && ( )}
{ // trigger child function voiceTriggerRef?.current?.listening(); }} style={{ position: 'absolute', zIndex: '12', top: templateData?.BookingNavbar?.[0] === 'Navbar3' && templateData?.BookingLayout?.[0] === 'Layout3' ? '1rem' : templateData?.BookingNavbar?.[0] === 'Navbar3' && ['Layout1', 'Layout2'].includes( templateData?.BookingLayout?.[0] ) ? '13px' : templateData?.BookingNavbar?.[0] === 'Navbar3' && ['Layout4', 'Layout5', 'Layout6'].includes( templateData?.BookingLayout?.[0] ) ? '4.4rem' : ['Layout4', 'Layout5', 'Layout6'].includes( templateData?.BookingLayout?.[0] ) ? '2.8rem' : templateData?.BookingNavbar?.[0] === 'Navbar3' ? '3rem' : '', }} > { setprodname(data.product); setprodQty(data.qty); }} />
{/*

{prodname}

*/}
{/*
*/} {cardData?.length > 0 ? ( <> item.id)} strategy={rectSortingStrategy} >
{AddProductCard && !favouriteCat && ProdCat && (
Add Product
)} {draggableCardData.map((item) => ( {templateData?.BookingCard?.[0] != 'Card4' ? (
0) || item?.ProductDetail?.some( (item) => item?.StockAvailable !== 'Y' ) ? 'BkPrdCardActive' : 'BkPrdCardDeActive' } > {!isMobile ? ( {globaldata && ( pickData(e, item)} style={{ position: 'absolute', zIndex: 1, transform: 'scale(1.5)', cursor: 'pointer', }} checked={( globalAllItemdata || EditfavItems )?.some( // (a) => a?.ProdName === item?.ProdName (a) => a?.ProdName === item?.ProdName && a?.ProdCat === item?.ProdCat )} /> )}
// handleMouseDownItemCard(e, item) // } // onMouseUp={(e) => // handleMouseUpItemCard(e, item) // } // onMouseLeave={handleMouseLeave} // onTouchStart={(e) => // handleTouchStartItemCard(e, item) // } // onTouchEnd={(e) => // handleTouchEndItemCard(e, item) // } // onTouchCancel={handleTouchCancelItemCard} // onContextMenu={(e) => e.preventDefault()} onClick={(e) => { if ( !( (item?.OverAllQty !== undefined && !preferenceSingleSales ? returnCount( item?.ProductDetail?.[0] ?.ProdName, item?.OverAllQty, CartOrderDetails ) : returnOnepcCount( item?.ProductDetail?.[0] ?.ProdName, item?.OverAllPcs, CartOrderDetails ) > 0) || item?.ProductDetail?.some( (item) => item?.StockAvailable !== 'Y' ) ) ) { e.stopPropagation(); } else { CardOnclick( item, item?.OnePcsAvailable === 'Y' && preferenceSingleSales && 'OnePeiceProduct' ); } }} data-aos="zoom-in" data-aos-duration="600" > {(cardFunction?.BigImage || cardFunction?.SmallImage) && ( )}

{item?.ProdName}{' '} {(item?.OverAllQty !== undefined && !preferenceSingleSales ? returnCount( item?.ProductDetail?.[0] ?.ProdName, item?.OverAllQty, CartOrderDetails, item ) : returnOnepcCount( item?.ProductDetail?.[0] ?.ProdName, item?.OverAllPcs, CartOrderDetails ) > 0) || item?.ProductDetail?.some( (item) => item?.StockAvailable !== 'Y' ) ? ( '' ) : (

No Stock

)}

{cardFunction?.MRP && ((item?.OverAllQty !== undefined && (!preferenceSingleSales ? item?.OverAllQty !== 0 : item?.OverAllPcs !== 0) && item?.OverAllQty !== null) || item?.ProductDetail?.some( (item) => item?.StockAvailable !== 'Y' )) && (

{ItemMRP(item) > 0 ? `MRP: ₹ ${ItemMRP(item)}` : ''}

)} {cardFunction?.Price && ((item?.OverAllQty !== undefined && (!preferenceSingleSales ? item?.OverAllQty !== 0 : item?.OverAllPcs !== 0) && item?.OverAllQty !== null) || item?.ProductDetail?.some( (item) => item?.StockAvailable !== 'Y' )) && (

₹ {ItemSellingPrice(item)}  <> ({ItemSize(item)}{' '} {ItemUomName(item)})

)}
{cardFunction?.StockCount && item?.OverAllQty !== undefined && (!preferenceSingleSales ? item?.OverAllQty !== 0 : item?.OverAllPcs !== 0) && (
{item?.ProductDetail?.some( (item) => item?.StockAvailable === 'Y' ) && item?.OverAllQty !== null && ( )}
)}
{item?.ProductDetail?.filter( (item) => item.OnePcsAvailable == 'Y' ).length !== 0 && !preferenceSingleSales && (
{ if ( !( (item?.OverAllQty !== undefined && returnOnepcCount( item?.ProductDetail?.[0] ?.ProdName, item?.OverAllPcs, CartOrderDetails ) > 0) || item?.ProductDetail?.some( (item) => item?.StockAvailable !== 'Y' ) ) ) { e.stopPropagation(); } else { CardOnclick( item, 'OnePeiceProduct' ); } }} style={{ fontFamily: SelectedCardFont || '', backgroundColor: SelectedCardColor?.FontColor || '#ffffff', color: returnOnepcCount( item?.ProductDetail?.[0] ?.ProdName, item?.OverAllPcs, CartOrderDetails ) > 0 || item?.ProductDetail?.some( (product) => product?.StockAvailable !== 'Y' ) ? cardFunction?.Background ? SelectedCardColor?.BackgroundColor || '#000000' : '#fff' : '#ff4d4f', }} > {SingleMember ? 'Single' : '1 PCS'}
)}
) : ( <> {globaldata && ( pickData(e, item)} style={{ position: 'absolute', zIndex: 1, transform: 'scale(1.5)', cursor: 'pointer', }} checked={( globalAllItemdata || EditfavItems )?.some( // (a) => a?.ProdName === item?.ProdName (a) => a?.ProdName === item?.ProdName && a?.ProdCat === item?.ProdCat )} /> )}
{ if ( !( (item?.OverAllQty !== undefined && !preferenceSingleSales ? returnCount( item?.ProductDetail?.[0] ?.ProdName, item?.OverAllQty, CartOrderDetails ) : returnOnepcCount( item?.ProductDetail?.[0] ?.ProdName, item?.OverAllPcs, CartOrderDetails ) > 0) || item?.ProductDetail?.some( (item) => item?.StockAvailable !== 'Y' ) ) ) { e.stopPropagation(); } else { CardOnclick( item, item?.OnePcsAvailable === 'Y' && preferenceSingleSales && 'OnePeiceProduct' ); } }} // data-aos="zoom-in" data-aos-duration="600" > {(cardFunction?.BigImage || cardFunction?.SmallImage) && ( )}

{item?.ProdName}{' '} {(item?.OverAllQty !== undefined && !preferenceSingleSales ? returnCount( item?.ProductDetail?.[0] ?.ProdName, item?.OverAllQty, CartOrderDetails, item ) : returnOnepcCount( item?.ProductDetail?.[0] ?.ProdName, item?.OverAllPcs, CartOrderDetails ) > 0) || item?.ProductDetail?.some( (item) => item?.StockAvailable !== 'Y' ) ? ( '' ) : (

No Stock

)}

{cardFunction?.MRP && ((item?.OverAllQty !== undefined && (!preferenceSingleSales ? item?.OverAllQty !== 0 : item?.OverAllPcs !== 0) && item?.OverAllQty !== null) || item?.ProductDetail?.some( (item) => item?.StockAvailable !== 'Y' )) && (

{ItemMRP(item) > 0 ? `MRP: ₹ ${ItemMRP(item)}` : ''}

)} {cardFunction?.Price && ((item?.OverAllQty !== undefined && (!preferenceSingleSales ? item?.OverAllQty !== 0 : item?.OverAllPcs !== 0) && item?.OverAllQty !== null) || item?.ProductDetail?.some( (item) => item?.StockAvailable !== 'Y' )) && (

₹ {ItemSellingPrice(item)}  {/* {item?.ProductDetail?.[0]?.ProdVariantDetails?.[0]?.StockDetails?.[0]?.SellPrice}  */} {/* {ItemSellingPrice(item)} */} ({ItemSize(item)}{' '} {ItemUomName(item)})

)}
{cardFunction?.StockCount && item?.OverAllQty !== undefined && (!preferenceSingleSales ? item?.OverAllQty !== 0 : item?.OverAllPcs !== 0) && (
{item?.ProductDetail?.some( (item) => item?.StockAvailable === 'Y' ) && item?.OverAllQty !== null && ( )}
)}
{item?.ProductDetail?.filter( (item) => item.OnePcsAvailable == 'Y' ).length !== 0 && !preferenceSingleSales && (
{ if ( !( (item?.OverAllQty !== undefined && returnOnepcCount( item?.ProductDetail?.[0] ?.ProdName, item?.OverAllPcs, CartOrderDetails ) > 0) || item?.ProductDetail?.some( (item) => item?.StockAvailable !== 'Y' ) ) ) { e.stopPropagation(); } else { CardOnclick( item, 'OnePeiceProduct' ); } }} style={{ fontFamily: SelectedCardFont || '', backgroundColor: SelectedCardColor?.FontColor || '#ffffff', color: returnOnepcCount( item?.ProductDetail?.[0] ?.ProdName, item?.OverAllPcs, CartOrderDetails ) > 0 || item?.ProductDetail?.some( (product) => product?.StockAvailable !== 'Y' ) ? cardFunction?.Background ? SelectedCardColor?.BackgroundColor || '#000000' : '#fff' : '#ff4d4f', }} > {SingleMember ? 'Single' : '1 PCS'}
)} )}
) : (
0) || item?.ProductDetail?.some( (item) => item?.StockAvailable !== 'Y' ) ? 'card4Main card4Main-active' : 'card4Main card4Main-deactive' } // onMouseDown={(e) => // handleMouseDownItemCard(e, item) // } // onMouseUp={(e) => // handleMouseUpItemCard(e, item, true) // } // onMouseLeave={handleMouseLeave} // onTouchStart={(e) => // handleTouchStartItemCard(e, item) // } // onTouchEnd={(e) => // handleTouchEndItemCard(e, item, true) // } // onTouchCancel={handleTouchCancelItemCard} // onContextMenu={(e) => e.preventDefault()} onClick={(e) => { if ( !( (item?.OverAllQty !== undefined && !preferenceSingleSales ? returnCount( item?.ProductDetail?.[0]?.ProdName, item?.OverAllQty, CartOrderDetails ) : returnOnepcCount( item?.ProductDetail?.[0]?.ProdName, item?.OverAllPcs, CartOrderDetails ) > 0) || item?.ProductDetail?.some( (item) => item?.StockAvailable !== 'Y' ) ) ) { e.stopPropagation(); // Prevent event bubbling if no stock or condition isn't met } else { // Ensure this only runs if the "One Piece" condition isn't triggered if ( !e.target.closest('.card4Main-onepiece') ) { CardOnclick( item, item?.OnePcsAvailable === 'Y' && preferenceSingleSales && 'OnePeiceProduct' ); // This will trigger if you're clicking outside the "One Piece" button } } }} > {/* Global Data Checkbox */} {globaldata && ( e.stopPropagation()} onChange={(e) => { e.stopPropagation(); pickData(e, item); }} style={{ position: 'absolute', zIndex: 1, transform: 'scale(1.5)', cursor: 'pointer', }} checked={( globalAllItemdata || EditfavItems )?.some( (a) => a?.ProdName === item?.ProdName && a?.ProdCat === item?.ProdCat )} /> )} {/* Tooltip for Product Name */}
{item?.ProdName} {(item?.OverAllQty !== undefined && !preferenceSingleSales ? returnCount( item?.ProductDetail?.[0]?.ProdName, item?.OverAllQty, CartOrderDetails, item ) : returnOnepcCount( item?.ProductDetail?.[0]?.ProdName, item?.OverAllPcs, CartOrderDetails ) > 0) || item?.ProductDetail?.some( (item) => item?.StockAvailable !== 'Y' ) ? ( '' ) : (

No Stock

)}
{cardFunction?.MRP && ((item?.OverAllQty !== undefined && !preferenceSingleSales ? returnCount( item?.ProductDetail?.[0]?.ProdName, item?.OverAllQty, CartOrderDetails, item ) : returnOnepcCount( item?.ProductDetail?.[0]?.ProdName, item?.OverAllPcs, CartOrderDetails ) > 0) || item?.ProductDetail?.some( (item) => item?.StockAvailable !== 'Y' )) && (
{ItemMRP(item) > 0 ? `MRP: ₹ ${ItemMRP(item)}` : ''}
)} {((item?.OverAllQty !== undefined && !preferenceSingleSales ? returnCount( item?.ProductDetail?.[0]?.ProdName, item?.OverAllQty, CartOrderDetails, item ) : returnOnepcCount( item?.ProductDetail?.[0]?.ProdName, item?.OverAllPcs, CartOrderDetails ) > 0) || item?.ProductDetail?.some( (item) => item?.StockAvailable !== 'Y' )) && (
₹ {ItemSellingPrice(item)}
<> ({ItemSize(item)} {ItemUomName(item)})
)}
{/* Stock Count Badge */} {cardFunction?.StockCount && item?.OverAllQty !== undefined && (!preferenceSingleSales ? item?.OverAllQty !== 0 : item?.OverAllPcs !== 0) && (
{item?.ProductDetail?.some( (item) => item?.StockAvailable === 'Y' ) && item?.OverAllQty !== null && ( )}
)} {/* One Piece Button */} {item?.ProductDetail?.filter( (item) => item.OnePcsAvailable == 'Y' ).length !== 0 && !preferenceSingleSales && (
{ e.stopPropagation(); // Stop event propagation to the parent div if ( !( (item?.OverAllQty !== undefined && returnOnepcCount( item?.ProductDetail?.[0] ?.ProdName, item?.OverAllPcs, CartOrderDetails ) > 0) || item?.ProductDetail?.some( (item) => item?.StockAvailable !== 'Y' ) ) ) { return; // Don't proceed if the condition isn't met } else { CardOnclick(item, 'OnePeiceProduct'); // This only runs when you click the "One Piece" button } }} style={{ fontFamily: SelectedCardFont || '', backgroundColor: SelectedCardColor?.FontColor || '#ffffff', color: returnOnepcCount( item?.ProductDetail?.[0]?.ProdName, item?.OverAllPcs, CartOrderDetails ) > 0 || item?.ProductDetail?.some( (product) => product?.StockAvailable !== 'Y' ) ? cardFunction?.Background ? SelectedCardColor?.BackgroundColor || '#000000' : '#fff' : '#ff4d4f', }} > {SingleMember ? 'Single' : '1 PCS'}
)}
)}
))}
) : ProductSearch?.length > 5 && GetmultipleSearchDatas.some( (e) => e.toLowerCase() === 'qrcode' ) && (cardData?.length == 0 || cardData == undefined) ? (
{/* cardData mohan 18-04-2025 */}
) : ( <>
 
 
 
 
)} {paymentloader === true && (
 
 
 
 

{' '} Please wait while we process your payment

{PaymentTransactionNumber != null && (

Transaction Number : {PaymentTransactionNumber}

)}
)}
{expireModal?.open && ( { expireModal.onOk?.(); closeExpireModal(); }} onCancel={() => { expireModal.onCancel?.(); closeExpireModal(); }} /> )} {modelQty && (
} open={modelQty} width={800} handleCancel={CloseModal} footer={null} maskTransitionName="" transitionName="" children={

Item Name:

{qtydata?.ProdName}

{/* Horizontal scroll container */}
{/* Left Scroll Button */} {showLeftButton && (
handleScrollClickLeft(200)} style={{ position: 'absolute', left: 0, top: '35%', transform: 'translateY(-50%)', zIndex: 10, background: '#fff', padding: '0.5rem', cursor: 'pointer', boxShadow: '0 0 5px rgba(0,0,0,0.2)', }} > ◄
)} {/* Scroll Container */}
{Object.keys(brandGroups) .sort((a, b) => a === 'Others' ? -1 : b === 'Others' ? 1 : 0 ) .map((brand) => (
setSelectedBrand(brand)} style={{ minWidth: '150px', background: selectedBrand === brand ? '#cce5ff' : '#f4f4f4', borderRadius: '8px', padding: '0.8rem', flexShrink: 0, cursor: 'pointer', userSelect: 'none', textAlign: 'center', fontWeight: selectedBrand === brand ? '600' : 'normal', fontFamily: 'Poppins', }} > {brand === 'Others' ? 'Others' : brand}
))}
{/* Right Scroll Button */} {showRightButton && (
handleScrollClickRight(200)} style={{ position: 'absolute', right: 0, top: '35%', transform: 'translateY(-50%)', zIndex: 10, background: '#fff', padding: '0.5rem', cursor: 'pointer', boxShadow: '0 0 5px rgba(0,0,0,0.2)', }} > ►
)}
{/* Selected brand products */}

{selectedBrand === 'Others' ? 'Others' : selectedBrand}{' '} Products

    {(brandGroups[selectedBrand] || []).map( (product, index) => { const qtyCount = returnQtyCount( product?.ProdId, product, CartOrderDetails ); const isAvailable = product?.StockAvailable !== 'Y'; const isDisabled = qtyCount > 0 || isAvailable; return (
    VarientFun(product)} >
    {`Product

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

    {!isDisabled && (

    No Stock

    )} {isDisabled && (

      {safeRound( product?.ProdVariantDetails?.[0] ?.StockDetails?.[0]?.SellPrice )}

    )}
    ); } )}
{Object.keys(brandMapping).length === 0 && (

No product details available

)}
} /> )} {modelstock && ( } open={modelstock} // width={500} footer={null} top={0} handleCancel={CloseModal1} maskTransitionName="" transitionName="" children={

Item Name:

{qtydata?.ProdName}{' '} {!qtydata?.ProductDetail?.[ QtyIndex ]?.ProdVariantDetails?.[ VarientIndex ]?.ProdVariantName?.toLowerCase()?.includes( 'variant' ) && ( ( { qtydata?.ProductDetail?.[QtyIndex] ?.ProdVariantDetails?.[VarientIndex] ?.ProdVariantName } ){' '} )}

Item Unit:

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

} /> )} {ModalVarient && ( } open={ModalVarient} width={500} top={0} footer={null} handleCancel={CloseVarientModal} maskTransitionName="" transitionName="" children={

Item Name:

{qtydata?.ProdName}

Item Unit:

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

} /> )} {productPriceChange && priceChangeProduct?.length > 0 && ( )} {newMoreProductModel && ( setNewMoreProductModel(false)} children={ <> } /> )} ); for (let i = 0; i < code?.length; i++) { encrypted += String.fromCharCode( code.charCodeAt(i) ^ key.charCodeAt(i % key.length) ); } return encrypted; } function decrypt(encrypted, key) { // Implement decryption logic let decrypted = encrypt(); for (let i = 0; i < encrypted?.length; i++) { decrypted += String.fromCharCode( encrypted.charCodeAt(i) ^ key.charCodeAt(i % key.length) ); } return decrypted; } const encryptedCode = encrypt(); // Encrypted React component code const decryptionKey = decrypt(); // Decryption key (keep it secure) const decryptedCode = decrypt(encryptedCode, decryptionKey); return <>{encrypt()}; }; export default React.memo(BSItemCard);