6611 lines
248 KiB
JavaScript
6611 lines
248 KiB
JavaScript
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||
import { shallowEqual, useDispatch, useSelector } from 'react-redux';
|
||
import { Badge, DatePicker, Modal, Tooltip, message } from 'antd';
|
||
import { ExclamationCircleOutlined, PlusOutlined } from '@ant-design/icons';
|
||
import defaultimage from '../../../../Images/defaultItemImg.png';
|
||
import FormHeader from '../../../PageComponents/FormHeader';
|
||
import {
|
||
SelectedGlobalCardColorDetail,
|
||
SelectedGlobalCardFont,
|
||
StoredSessionData,
|
||
getTemplateData,
|
||
} from '../../../../Features/ThemeChange/ThemeChange';
|
||
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,
|
||
GlobalUnpaidData,
|
||
GlobalWeightScalePort,
|
||
GlobalWeightScaleWeight,
|
||
changeWeightScaleWeight,
|
||
GlobalExpDateforHeight,
|
||
GlobalBookingTypeBoth,
|
||
GlobalOrderType,
|
||
GlobalReorderProductDetails,
|
||
getConfigType,
|
||
GlobalPayementloader,
|
||
GlobalPaymentTransactionNumber,
|
||
GlobalSelOption,
|
||
PreferenceData,
|
||
changeCardData,
|
||
GlobaldraggingComponent,
|
||
GlobalisAlphabeticFormat,
|
||
GlobalBtoBQuickProductTransfer,
|
||
changeBtoBQuickProductTransfer,
|
||
GlobalRetailWSSalesType,
|
||
GlobalisFavClicked,
|
||
PostBlockSlots,
|
||
GlobalPreviousOrderLength,
|
||
GlobalSummeryTotalAmount,
|
||
slotTimeStatus,
|
||
changeAddBookingDetailsTrigger,
|
||
GlobalAddBookingDetailsTrigger,
|
||
GlobalGetmultipleSearchDatas,
|
||
getmultipleSearch,
|
||
GlobalAllBookingType,
|
||
} 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 VoiceToTextItemCard from '../../../VoiceToText/VoiceToTextItemCard.jsx';
|
||
import { ExtractDateFormate } from '../../../../Services/Others.js';
|
||
import {
|
||
changeFullOfferAppliedProducts,
|
||
changeOfferAppliedProductsForMembership,
|
||
GlobalOfferAppliedProducts,
|
||
} from '../../../../Features/Offer/Offernew/BookingOffernew.js';
|
||
import { useSaleswiseOfferWatcher } from './SalesWiseOffer.jsx';
|
||
import { ApplicationPreferences } from '../../../../Features/BrachLogin/BranchLogin.js';
|
||
import { useDateStore } from '../../../../Features/BookingScreen/BookingData/DateStore.js';
|
||
import { onReceiveNotification } from '../../../../Features/SignalR/signalRClient.js';
|
||
import { IoClose } from 'react-icons/io5';
|
||
import { MdBlock } from 'react-icons/md';
|
||
import dayjs from 'dayjs';
|
||
import BSCustomerSelect from '../UtillComponents/BSSelectCustomer.jsx';
|
||
import BSNavBarAddUser from '../UtillComponents/BSNavBarAddUser.jsx';
|
||
import { FaAngleLeft, FaAngleRight } from 'react-icons/fa';
|
||
import useRemoveFromCart from './RemoveFromCartFunction.jsx';
|
||
import { LuMinus } from 'react-icons/lu';
|
||
import BranchName from '../../Template/BranchName.jsx';
|
||
import { FiPlus } from 'react-icons/fi';
|
||
|
||
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 (
|
||
<div
|
||
ref={setNodeRef}
|
||
style={style}
|
||
{...(allowDrag ? attributes : {})}
|
||
{...(allowDrag ? listeners : {})}
|
||
>
|
||
{children}
|
||
</div>
|
||
);
|
||
}
|
||
|
||
const BsBookingitemCard = (props) => {
|
||
const voiceTriggerRef = useRef(null);
|
||
const unsubscribeRef = useRef(null);
|
||
|
||
const AllBookingType = useSelector(GlobalAllBookingType);
|
||
|
||
const { removeFromCart, clearAllItems, decline } = useRemoveFromCart();
|
||
const handleRemoveFromCart = async (item) => {
|
||
await removeFromCart(item, setPreviousdataLength);
|
||
};
|
||
const handleDecline = async (item) => {
|
||
await decline(item, setPreviousdataLength);
|
||
};
|
||
|
||
const cardFunction = props?.cardFunctionality;
|
||
// const applyOffer = useApplyOfferto_CardDetail();
|
||
const preferenceDatas = useSelector(PreferenceData, shallowEqual);
|
||
const { selectedDate, setSelectedDate, isBulk } = useDateStore();
|
||
|
||
const preferenceOffer =
|
||
preferenceDatas?.[0]?.['SettingDtlDetails']?.find(
|
||
(item) => item.SettingIdName === 'Offer'
|
||
)?.SettingValue === 'Y';
|
||
// const AddCustomerDetails = useSelector(
|
||
// GlobalAddCustomerDetails,
|
||
// shallowEqual
|
||
// );
|
||
|
||
const offerAppliedProducts = useSelector(
|
||
GlobalOfferAppliedProducts,
|
||
shallowEqual
|
||
);
|
||
// const SelectedCust = useSelector(GlobalSelOption, shallowEqual);
|
||
const GetmultipleSearchDatas = useSelector(
|
||
GlobalGetmultipleSearchDatas,
|
||
shallowEqual
|
||
);
|
||
const RetailWSSalesType = useSelector(GlobalRetailWSSalesType, shallowEqual);
|
||
// const CustDetails = SelectedCust ? SelectedCust : AddCustomerDetails?.[0];
|
||
const BookingTypeBoth = useSelector(GlobalBookingTypeBoth);
|
||
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 [expModel, setexpModel] = useState(false);
|
||
const [prodexpir, setProdexpir] = useState(false);
|
||
const [expVarModel, setexpVarModel] = useState(false);
|
||
const [expStockModel, setexpStockModel] = 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 PreOrderAdditem = useSelector(GlobalPreOrderAdditem, shallowEqual);
|
||
const OrderType = useSelector(GlobalOrderType, shallowEqual);
|
||
const ProdSubCat = useSelector(GlobalProductSubCategorie);
|
||
const ItemCard = useSelector(GlobalItemCard, shallowEqual);
|
||
const selOption = useSelector(GlobalSelOption);
|
||
const globaldata = useSelector(GlobalAlldat, shallowEqual);
|
||
const TotalAmount = useSelector(GlobalSummeryTotalAmount, 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 Discount = useSelector(GlobalOverAllOfferAmt);
|
||
const [SelectedProdNames, setSelectedProdNames] = useState(EditfavItems);
|
||
const [PreOrderSelectedProdNames, setPreOrderSelectedProdNames] = useState(
|
||
[]
|
||
);
|
||
const PreviousOrderLength = useSelector(GlobalPreviousOrderLength);
|
||
const [PreviousdataLength, setPreviousdataLength] =
|
||
useState(PreviousOrderLength);
|
||
const CardAccess = useSelector(GlobalCardAccess, shallowEqual);
|
||
const globalAccessForOthers = useSelector(
|
||
GlobalAccessForOthers,
|
||
shallowEqual
|
||
);
|
||
const SelectedCardColor = useSelector(
|
||
SelectedGlobalCardColorDetail,
|
||
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);
|
||
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 [expQtyModel, setExpQtyModel] = useState(false);
|
||
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 AddBookingDetailsTrigger = useSelector(GlobalAddBookingDetailsTrigger);
|
||
|
||
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 [TempCartData, setTempCartData] = useState(CartOrderDetails || []);
|
||
const dispatch = useDispatch();
|
||
|
||
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 appPreferences = useSelector(ApplicationPreferences);
|
||
const [draggableCardData, setDraggableCardData] = useState([]);
|
||
const [refreshKey, setRefreshKey] = useState(0);
|
||
|
||
const [dateRange, setDateRange] = useState([]);
|
||
const [activeMode, setActiveMode] = useState('slot');
|
||
const [currentSlotIndex, setCurrentSlotIndex] = useState(0);
|
||
const slotItems = [
|
||
'Slot 1',
|
||
'Slot 2',
|
||
'Slot 3',
|
||
'Slot 4',
|
||
'Slot 5',
|
||
'Slot 6',
|
||
];
|
||
const visibleSlots = 2;
|
||
const maxIndex = Math.max(0, draggableCardData.length - visibleSlots);
|
||
const currentActiveOffer = getCurrentMembership(selOption?.MembershipDetail);
|
||
|
||
const handleSlotPrev = () => {
|
||
setCurrentSlotIndex((prev) => Math.max(0, prev - 2));
|
||
};
|
||
|
||
const handleSlotNext = () => {
|
||
setCurrentSlotIndex((prev) => Math.min(maxIndex, prev + 2));
|
||
};
|
||
|
||
// Add these states to your component
|
||
const [selectionMode, setSelectionMode] = useState(false);
|
||
const [selectedSlots, setSelectedSlots] = useState([]);
|
||
const [bookedDetails, setBookedDetails] = useState(false);
|
||
const [selectedSlotDetails, setSelectedSlotDetails] = useState(null);
|
||
const [showAllBookingsModal, setShowAllBookingsModal] = useState(false);
|
||
const [selectedCustomerBookings, setSelectedCustomerBookings] =
|
||
useState(null);
|
||
const [loadingSlotAction, setLoadingSlotAction] = useState({});
|
||
|
||
useEffect(() => {
|
||
if (activeMode == 'individual') {
|
||
setOnePeiceFlow(true);
|
||
} else {
|
||
setOnePeiceFlow(false);
|
||
}
|
||
}, [activeMode]);
|
||
|
||
// Handler for checkbox selection
|
||
const handleSlotSelection = (e, data) => {
|
||
if (e.target.checked) {
|
||
setSelectedSlots((prev) => [...prev, data]);
|
||
} else {
|
||
setSelectedSlots((prev) =>
|
||
prev.filter(
|
||
(slot) =>
|
||
!(
|
||
slot.ProdId === data.ProdId &&
|
||
slot.InwardDtlId === data.InwardDtlId &&
|
||
slot.VariantAvailableFrom === data.VariantAvailableFrom &&
|
||
slot.VariantAvailableTo === data.VariantAvailableTo &&
|
||
slot.BookedDate === data.BookedDate
|
||
)
|
||
)
|
||
);
|
||
}
|
||
};
|
||
const handleBookedDetails = (slot) => {
|
||
setSelectedSlotDetails(slot);
|
||
setBookedDetails(true);
|
||
};
|
||
|
||
const handleSlotTimeUpdate = async (slot, bookingDate, type) => {
|
||
const key = `${slot?.SalesId}-${type}`;
|
||
if (loadingSlotAction[key]) return;
|
||
|
||
let data = {
|
||
SalesId: [slot?.SalesId],
|
||
BookingDate: bookingDate,
|
||
UpdatedBy: UserId,
|
||
};
|
||
if (type === 'start') {
|
||
if (slot?.StartTime) {
|
||
message?.error('Play already started for this slot');
|
||
return;
|
||
}
|
||
data.Type = 'S';
|
||
} else if (type === 'end') {
|
||
if (slot?.EndTime) {
|
||
message?.error('Play already ended for this slot');
|
||
return;
|
||
}
|
||
data.Type = 'E';
|
||
}
|
||
setLoadingSlotAction((prev) => ({ ...prev, [key]: true }));
|
||
try {
|
||
const res = await dispatch(slotTimeStatus(data))?.unwrap();
|
||
if (res?.data?.statusCode === 1) {
|
||
message?.success(
|
||
`Play ${type === 'start' ? 'started' : 'ended'} successfully`
|
||
);
|
||
// dispatch(triggerSlotTime());
|
||
if (favouriteCat) {
|
||
let data = {
|
||
CompId: CompId,
|
||
BranchId: BranchId,
|
||
AppId: AppId,
|
||
...(AvailableDate && selectedDate
|
||
? {
|
||
fromDate: selectedDate?.[0],
|
||
toDate: selectedDate?.[1],
|
||
}
|
||
: {}),
|
||
};
|
||
await dispatch(getSelectedFavItems(data)).unwrap();
|
||
} else {
|
||
await productCardList();
|
||
}
|
||
} else {
|
||
message?.error(res?.data?.response);
|
||
}
|
||
} finally {
|
||
setLoadingSlotAction((prev) => ({ ...prev, [key]: false }));
|
||
}
|
||
};
|
||
|
||
const handleShowAllBookings = (customer) => {
|
||
setSelectedCustomerBookings(customer);
|
||
setShowAllBookingsModal(true);
|
||
};
|
||
// Handler for button click in selection mode
|
||
const handleSlotButtonClick = async (
|
||
newdata,
|
||
product,
|
||
onePeiceFlow,
|
||
ispast
|
||
) => {
|
||
if (!ispast) {
|
||
return;
|
||
}
|
||
const [productIndex, detailIndex, variantIndex] = newdata?.key?.split('-');
|
||
// await dataTransfer(product, detailIndex, variantIndex,0,onePeiceFlow);
|
||
let data = {
|
||
...newdata,
|
||
SinglePc: onePeiceFlow ? 'Y' : 'N',
|
||
Product: product,
|
||
BookingTypeName: 'TakeAway',
|
||
};
|
||
const isSelected = CartOrderDetails?.some(
|
||
(selected) =>
|
||
selected.ProdId === data.ProdId &&
|
||
selected.InwardDtlId === data.InwardDtlId &&
|
||
selected.VariantAvailableFrom === data.VariantAvailableFrom &&
|
||
selected.VariantAvailableTo === data.VariantAvailableTo &&
|
||
selected.BookedDate === data.BookedDate
|
||
);
|
||
if (isSelected) {
|
||
// let data = await dataTransfer(product, detailIndex, variantIndex, 0, onePeiceFlow);
|
||
const { detail, variant, stock } = extractProductDetails(
|
||
product,
|
||
detailIndex,
|
||
variantIndex,
|
||
0
|
||
);
|
||
const price = onePeiceFlow
|
||
? stock?.OnePcsPrice
|
||
: RetailWSSalesType === 'W'
|
||
? stock?.WhSalePrice || stock?.SellPrice
|
||
: stock?.SellPrice;
|
||
const size = onePeiceFlow ? '1' : detail?.Size;
|
||
const removedata = buildOrderData(
|
||
product,
|
||
detail,
|
||
variant,
|
||
stock,
|
||
size,
|
||
price,
|
||
onePeiceFlow
|
||
);
|
||
handleRemoveFromCart(removedata);
|
||
} else {
|
||
// setSelectedSlots((prev) => [...prev, data]);
|
||
await dataTransfer(product, detailIndex, variantIndex, 0, onePeiceFlow);
|
||
}
|
||
};
|
||
const handleSingleSlotIncrease = async (newdata, product, onePeiceFlow) => {
|
||
const [productIndex, detailIndex, variantIndex] = newdata?.key?.split('-');
|
||
// await dataTransfer(product, detailIndex, variantIndex,0,onePeiceFlow);
|
||
let data = {
|
||
...newdata,
|
||
SinglePc: onePeiceFlow ? 'Y' : 'N',
|
||
Product: product,
|
||
BookingTypeName: 'TakeAway',
|
||
};
|
||
const isSelected = CartOrderDetails?.some(
|
||
(selected) =>
|
||
selected.ProdId === data.ProdId &&
|
||
selected.InwardDtlId === data.InwardDtlId &&
|
||
selected.VariantAvailableFrom === data.VariantAvailableFrom &&
|
||
selected.VariantAvailableTo === data.VariantAvailableTo &&
|
||
selected.BookedDate === data.BookedDate
|
||
);
|
||
if (isSelected) {
|
||
await dataTransfer(product, detailIndex, variantIndex, 0, onePeiceFlow);
|
||
} else {
|
||
// setSelectedSlots((prev) => [...prev, data]);
|
||
await dataTransfer(product, detailIndex, variantIndex, 0, onePeiceFlow);
|
||
}
|
||
};
|
||
const handleRemoveSingle = async (newdata, product, onePeiceFlow) => {
|
||
const [productIndex, detailIndex, variantIndex] = newdata?.key?.split('-');
|
||
// await dataTransfer(product, detailIndex, variantIndex,0,onePeiceFlow);
|
||
let data = {
|
||
...newdata,
|
||
SinglePc: onePeiceFlow ? 'Y' : 'N',
|
||
Product: product,
|
||
BookingTypeName: 'TakeAway',
|
||
};
|
||
const isSelected = CartOrderDetails?.some(
|
||
(selected) =>
|
||
selected.ProdId === data.ProdId &&
|
||
selected.InwardDtlId === data.InwardDtlId &&
|
||
selected.VariantAvailableFrom === data.VariantAvailableFrom &&
|
||
selected.VariantAvailableTo === data.VariantAvailableTo &&
|
||
selected.BookedDate === data.BookedDate
|
||
);
|
||
if (isSelected) {
|
||
const { detail, variant, stock } = extractProductDetails(
|
||
product,
|
||
detailIndex,
|
||
variantIndex,
|
||
0
|
||
);
|
||
const price = onePeiceFlow
|
||
? stock?.OnePcsPrice
|
||
: RetailWSSalesType === 'W'
|
||
? stock?.WhSalePrice || stock?.SellPrice
|
||
: stock?.SellPrice;
|
||
const size = onePeiceFlow ? '1' : detail?.Size;
|
||
const removedata = buildOrderData(
|
||
product,
|
||
detail,
|
||
variant,
|
||
stock,
|
||
size,
|
||
price,
|
||
onePeiceFlow
|
||
);
|
||
const removetemdata = { ...removedata, OrderQty: 1 };
|
||
handleDecline(removetemdata);
|
||
} else {
|
||
// setSelectedSlots((prev) => [...prev, data]);
|
||
await dataTransfer(product, detailIndex, variantIndex, 0, onePeiceFlow);
|
||
}
|
||
};
|
||
|
||
// Handler for submitting selected slots with PostBlockSlots
|
||
const handleSubmitSelectedSlots = async () => {
|
||
if (TotalAmount > 0) {
|
||
setModalVarient(false);
|
||
// alert('Total Amount greater than 0, proceed to payment');
|
||
// const AddBooking = new CustomEvent('MembershipZeroPayment');
|
||
// window.dispatchEvent(AddBooking);
|
||
} else {
|
||
dispatch(changeAddBookingDetailsTrigger(true));
|
||
// triggerBooking({ value: 'TakeAway', pay: true });
|
||
// const AddBooking = new CustomEvent('MembershipZeroPayment');
|
||
// window.dispatchEvent(AddBooking);
|
||
}
|
||
};
|
||
|
||
const handleSubmitBlockSlots = async () => {
|
||
try {
|
||
// Validate inputs
|
||
if (!selectedSlots?.length) {
|
||
setMessageType('error');
|
||
setMessageData('No slots selected');
|
||
return;
|
||
}
|
||
|
||
if (!CompId || !BranchId || !AppId || !UserId) {
|
||
setMessageType('error');
|
||
setMessageData('Missing session data');
|
||
return;
|
||
}
|
||
|
||
const selectedCount = selectedSlots.length; // Store count before reset
|
||
let prodList = [];
|
||
|
||
for (const slot of selectedSlots) {
|
||
let slotStatus = slot?.SlotStatus?.toLowerCase();
|
||
let isBooked = slotStatus === 'booked';
|
||
const isPartiallyBooked =
|
||
slotStatus === 'partially booked' ||
|
||
CartOrderDetails?.some(
|
||
(item) =>
|
||
item?.SinglePc === 'Y' &&
|
||
item?.VariantAvailableFrom === slot?.VariantAvailableFrom &&
|
||
item?.VariantAvailableTo === slot?.VariantAvailableTo
|
||
);
|
||
const qty =
|
||
Number(slot?.TotalSlotQty || 0) - Number(slot?.BookedQty || 0);
|
||
|
||
if (!isBooked) {
|
||
prodList.push({
|
||
ProdId: slot?.ProdId || qtydata?.ProductDetail?.[QtyIndex]?.ProdId,
|
||
InwardDtlId: slot?.InwardDtlId,
|
||
SinglePc:
|
||
onePeiceFlow || (isPartiallyBooked && !onePeiceFlow) ? 'Y' : 'N',
|
||
Qty: isPartiallyBooked && !onePeiceFlow ? qty : 1,
|
||
Date: slot?.BookedDate,
|
||
});
|
||
}
|
||
}
|
||
|
||
if (!prodList.length) {
|
||
setMessageType('error');
|
||
setMessageData('No valid slots to book');
|
||
return;
|
||
}
|
||
|
||
const BlockPostdata = {
|
||
CompId: CompId,
|
||
BranchId: BranchId,
|
||
AppId: AppId,
|
||
Status: 'Block',
|
||
CreatedBy: UserId,
|
||
ProductList: prodList,
|
||
};
|
||
|
||
const res = await dispatch(PostBlockSlots(BlockPostdata)).unwrap();
|
||
|
||
if (res?.data?.statusCode === 1) {
|
||
setSelectedSlots([]);
|
||
setSelectionMode(false);
|
||
setMessageType('success');
|
||
setMessageData(`${selectedCount} slots booked successfully`);
|
||
if (favouriteCat) {
|
||
let data = {
|
||
CompId: CompId,
|
||
BranchId: BranchId,
|
||
AppId: AppId,
|
||
...(AvailableDate && selectedDate
|
||
? {
|
||
fromDate: selectedDate?.[0],
|
||
toDate: selectedDate?.[1],
|
||
}
|
||
: {}),
|
||
};
|
||
await dispatch(getSelectedFavItems(data)).unwrap();
|
||
} else {
|
||
await productCardList();
|
||
}
|
||
} else {
|
||
throw new Error('Failed to book slots');
|
||
}
|
||
} catch (error) {
|
||
console.error('Error submitting slots:', error);
|
||
setMessageType('error');
|
||
setMessageData('Error booking slots');
|
||
}
|
||
};
|
||
|
||
// Reset selection when modal closes
|
||
useEffect(() => {
|
||
if (!ModalVarient) {
|
||
setSelectionMode(false);
|
||
setSelectedSlots([]);
|
||
}
|
||
}, [ModalVarient]);
|
||
useEffect(() => {
|
||
if (!AddBookingDetailsTrigger) {
|
||
ModalVarient && setModalVarient(false);
|
||
}
|
||
}, [AddBookingDetailsTrigger]);
|
||
|
||
useEffect(() => {
|
||
if (!ItemCard?.length || !qtydata?.ProdId) return;
|
||
|
||
const sourceArray = favouriteCat ? SelectedDatas : ItemCard;
|
||
const filteredItem = sourceArray?.find(
|
||
(item) => item.ProdId === qtydata?.ProdId
|
||
);
|
||
|
||
if (filteredItem) {
|
||
setQtydata(filteredItem);
|
||
}
|
||
}, [ItemCard, SelectedDatas, qtydata?.ProdId, favouriteCat]);
|
||
|
||
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();
|
||
|
||
useEffect(() => {
|
||
itemListScrollRef.current?.scrollTo(0, 0);
|
||
}, [ProdCat, ProdSubCat, favouriteCat]);
|
||
useEffect(() => {
|
||
if (ConfigDataList?.length === 0) {
|
||
getBookingTypeId();
|
||
}
|
||
}, []);
|
||
const prodCatRef = useRef(ProdCat);
|
||
const prodSubCatRef = useRef(ProdSubCat);
|
||
const selectedDateRef = useRef(selectedDate);
|
||
|
||
useEffect(() => {
|
||
selectedDateRef.current = selectedDate;
|
||
}, [selectedDate]);
|
||
|
||
useEffect(() => {
|
||
prodCatRef.current = ProdCat;
|
||
prodSubCatRef.current = ProdSubCat;
|
||
}, [ProdCat, ProdSubCat]);
|
||
useEffect(() => {
|
||
const subscribeToNotification = async () => {
|
||
const unsubscribeFn = await onReceiveNotification(async (title, msg) => {
|
||
console.log('📢 Notification:', title, msg);
|
||
const currentProdCat = prodCatRef.current;
|
||
const currentProdSubCat = prodSubCatRef.current;
|
||
if (favouriteCat) {
|
||
let data = {
|
||
CompId: CompId,
|
||
BranchId: BranchId,
|
||
AppId: AppId,
|
||
...(AvailableDate && selectedDate
|
||
? {
|
||
fromDate: selectedDate?.[0],
|
||
toDate: selectedDate?.[1],
|
||
}
|
||
: {}),
|
||
};
|
||
await dispatch(getSelectedFavItems(data)).unwrap();
|
||
} else if (currentProdCat && !isNaN(currentProdSubCat)) {
|
||
console.log(
|
||
currentProdCat,
|
||
currentProdSubCat,
|
||
'ProdSubCatProdSubCatProdSubCatProdSubCatProdSubCat'
|
||
);
|
||
productCardList();
|
||
} else {
|
||
console.log(
|
||
currentProdCat,
|
||
currentProdSubCat,
|
||
'ProdSubCatProdSubCatProdSubCatProdSubCatProdSubCat'
|
||
);
|
||
}
|
||
});
|
||
|
||
unsubscribeRef.current = unsubscribeFn;
|
||
};
|
||
|
||
subscribeToNotification();
|
||
return () => {
|
||
if (unsubscribeRef.current) {
|
||
unsubscribeRef.current();
|
||
console.log('🔌 Unsubscribed from notifications');
|
||
}
|
||
};
|
||
}, []);
|
||
|
||
useEffect(() => {
|
||
if (CartOrderDetails?.length > 0 && selOption) {
|
||
if (selOption?.MembershipDetail?.length == 0) {
|
||
dispatch(changeFullOfferAppliedProducts([]));
|
||
return;
|
||
}
|
||
const currentActiveOffer = getCurrentMembership(
|
||
selOption?.MembershipDetail
|
||
);
|
||
const calculateTotalHours = (cartData) => {
|
||
let totalHours = 0;
|
||
let totalAmt = 0;
|
||
const itemsWithHours = []; // Track individual items with their hours and amounts
|
||
|
||
cartData.forEach((item, index) => {
|
||
const timeFrom = item?.VariantAvailableFrom;
|
||
const timeTo = item?.VariantAvailableTo;
|
||
if (timeFrom && timeTo) {
|
||
const [hoursFrom, minutesFrom] = timeFrom.split(':').map(Number);
|
||
const [hoursTo, minutesTo] = timeTo.split(':').map(Number);
|
||
|
||
const totalMinutesFrom = hoursFrom * 60 + minutesFrom;
|
||
const totalMinutesTo = hoursTo * 60 + minutesTo;
|
||
|
||
const hrs = (totalMinutesTo - totalMinutesFrom) / 60;
|
||
const itemHours = hrs * item?.Size * item?.OrderQty;
|
||
|
||
totalHours += itemHours;
|
||
|
||
// Store item details for prioritization
|
||
itemsWithHours.push({
|
||
index: index, // Track original index
|
||
hours: itemHours,
|
||
amount: item?.TotalAmt,
|
||
amountPerHour: item?.TotalAmt / itemHours,
|
||
item: item,
|
||
});
|
||
}
|
||
totalAmt += item?.TotalAmt;
|
||
});
|
||
|
||
return { totalHours, totalAmt, itemsWithHours };
|
||
};
|
||
|
||
const { totalHours, totalAmt, itemsWithHours } =
|
||
calculateTotalHours(CartOrderDetails);
|
||
const needsUpdate = (newOffers) => {
|
||
return CartOrderDetails.some((item, index) => {
|
||
const newOffer = newOffers[index] || 0;
|
||
const currentOffer = item?.Offer || 0;
|
||
return Math.abs(newOffer - currentOffer) > 0.01; // Use small threshold for floating point comparison
|
||
});
|
||
};
|
||
if (currentActiveOffer) {
|
||
if (currentActiveOffer?.RemainingSessionHrs > 0) {
|
||
if (totalHours <= currentActiveOffer?.RemainingSessionHrs) {
|
||
// All hours can be covered
|
||
const offer = [
|
||
{
|
||
OfferId: currentActiveOffer?.MembershipId,
|
||
OfferAmount: totalAmt,
|
||
OfferValue: totalAmt,
|
||
TableName: 'MemberShip',
|
||
TableUniqueName: 'MemberShip',
|
||
OfferType: 'M',
|
||
OfferMode: 'M',
|
||
Detail: [{ MembershipName: currentActiveOffer?.MemberName }],
|
||
CustId: selOption?.CustId,
|
||
Usedhours: totalHours,
|
||
PlanId: currentActiveOffer?.PlanId,
|
||
},
|
||
];
|
||
dispatch(changeOfferAppliedProductsForMembership(offer));
|
||
} else if (totalHours > currentActiveOffer?.RemainingSessionHrs) {
|
||
// Prioritize items with higher amount per hour
|
||
const sortedItems = [...itemsWithHours].sort(
|
||
(a, b) => b.amountPerHour - a.amountPerHour
|
||
);
|
||
|
||
let remainingHours = currentActiveOffer?.RemainingSessionHrs;
|
||
let offerAmount = 0;
|
||
const offerByIndex = {};
|
||
|
||
for (const item of sortedItems) {
|
||
if (remainingHours <= 0) break;
|
||
|
||
if (item.hours <= remainingHours) {
|
||
offerByIndex[item.index] = item.amount;
|
||
offerAmount += item.amount;
|
||
remainingHours -= item.hours;
|
||
} else {
|
||
const partialOffer =
|
||
(remainingHours / item.hours) * item.amount;
|
||
offerByIndex[item.index] = partialOffer;
|
||
offerAmount += partialOffer;
|
||
remainingHours = 0;
|
||
}
|
||
}
|
||
|
||
const newOffers = CartOrderDetails.map(
|
||
(item, index) => offerByIndex[index] || 0
|
||
);
|
||
|
||
if (needsUpdate(newOffers)) {
|
||
const updatedCartDetails = CartOrderDetails.map(
|
||
(item, index) => ({
|
||
...item,
|
||
Offer: newOffers[index],
|
||
})
|
||
);
|
||
dispatch(changeOrderCardDetails(updatedCartDetails));
|
||
}
|
||
|
||
const offer = [
|
||
{
|
||
OfferId: currentActiveOffer?.MembershipId,
|
||
OfferAmount: offerAmount,
|
||
OfferValue: offerAmount,
|
||
TableName: 'MemberShip',
|
||
TableUniqueName: 'MemberShip',
|
||
OfferType: 'M',
|
||
OfferMode: 'M',
|
||
Detail: [{ MembershipName: currentActiveOffer?.MemberName }],
|
||
CustId: selOption?.CustId,
|
||
Usedhours: currentActiveOffer?.RemainingSessionHrs,
|
||
PlanId: currentActiveOffer?.PlanId,
|
||
},
|
||
];
|
||
dispatch(changeOfferAppliedProductsForMembership(offer));
|
||
}
|
||
} else if (currentActiveOffer?.RemainingDays > 0) {
|
||
const offerValue =
|
||
currentActiveOffer?.DiscountType === 'F'
|
||
? currentActiveOffer?.Discount || 0
|
||
: totalAmt * ((currentActiveOffer?.Discount || 0) / 100);
|
||
const offer = [
|
||
{
|
||
OfferId: currentActiveOffer?.MembershipId,
|
||
OfferAmount: offerValue,
|
||
OfferValue: offerValue,
|
||
TableName: 'MemberShip',
|
||
TableUniqueName: 'MemberShip',
|
||
OfferType: 'M',
|
||
OfferMode: 'M',
|
||
Detail: [{ MembershipName: currentActiveOffer?.MemberName }],
|
||
CustId: selOption?.CustId,
|
||
Usedhours: 0,
|
||
PlanId: currentActiveOffer?.PlanId,
|
||
},
|
||
];
|
||
dispatch(changeOfferAppliedProductsForMembership(offer));
|
||
} else {
|
||
dispatch(
|
||
changeFullOfferAppliedProducts(
|
||
offerAppliedProducts?.filter((off) => off?.OfferMode !== 'M')
|
||
)
|
||
);
|
||
}
|
||
}
|
||
}
|
||
if (CartOrderDetails?.length == 0) {
|
||
dispatch(changeFullOfferAppliedProducts([]));
|
||
}
|
||
console.log('Membership Offer Applied', selOption);
|
||
if (!selOption) {
|
||
dispatch(changeFullOfferAppliedProducts([]));
|
||
}
|
||
}, [CartOrderDetails, selOption]);
|
||
|
||
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);
|
||
}, [OrderOfferDetail]);
|
||
|
||
useEffect(() => {
|
||
if (SelectedCardFont) {
|
||
WebFont.load({
|
||
google: {
|
||
families: [SelectedCardFont], // Load the selected font
|
||
},
|
||
});
|
||
}
|
||
}, [SelectedCardFont]);
|
||
// const cardData = !globalAccessForOthers
|
||
// ? CardAccess
|
||
// ? SelectedDatas
|
||
// : ItemCard?.length == 0 ? noSubcatCardData : ItemCard
|
||
// : "";
|
||
//mohan 18-04-2025
|
||
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(() => {
|
||
if (bookedDetails) {
|
||
const itemCardData = ItemCard?.find((item) =>
|
||
item?.ProductDetail?.[0]?.ProdVariantDetails?.some((variant) =>
|
||
variant?.StockDetails?.some(
|
||
(stock) => stock?.InwardDtlId === selectedSlotDetails?.InwardDtlId
|
||
)
|
||
)
|
||
);
|
||
const filteredVariant =
|
||
itemCardData?.ProductDetail?.[0]?.ProdVariantDetails?.find((variant) =>
|
||
variant?.StockDetails?.some(
|
||
(stock) => stock?.InwardDtlId === selectedSlotDetails?.InwardDtlId
|
||
)
|
||
);
|
||
const filteredStock = filteredVariant?.StockDetails?.find(
|
||
(stock) => stock?.InwardDtlId === selectedSlotDetails?.InwardDtlId
|
||
);
|
||
const updatedSelectedSlotDetails = {
|
||
...filteredStock,
|
||
ProdName: itemCardData?.ProductDetail?.[0]?.ProdName,
|
||
ProdSubCatName: itemCardData?.ProdSubCatName,
|
||
BookedDate: filteredVariant?.TempDate,
|
||
AvailableFrom: filteredVariant?.AvailableFrom,
|
||
AvailableTo: filteredVariant?.AvailableTo,
|
||
};
|
||
setSelectedSlotDetails(updatedSelectedSlotDetails);
|
||
if (showAllBookingsModal) {
|
||
const selectedCustomer = filteredStock?.CustomerDetails?.find(
|
||
(cust) => cust?.CustId === selectedCustomerBookings?.CustId
|
||
);
|
||
setSelectedCustomerBookings(selectedCustomer);
|
||
}
|
||
}
|
||
}, [ItemCard]);
|
||
|
||
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 && ProdSubCat !== 'NaN' && ProdSubCat) {
|
||
// if (ProdCat && !isNaN(ProdSubCat)) {
|
||
productCardList();
|
||
}
|
||
}, [ProdSubCat]);
|
||
useEffect(() => {
|
||
if (favouriteCat) {
|
||
let data = {
|
||
CompId: CompId,
|
||
BranchId: BranchId,
|
||
AppId: AppId,
|
||
...(AvailableDate && selectedDate
|
||
? {
|
||
fromDate: selectedDate?.[0],
|
||
toDate: selectedDate?.[1],
|
||
}
|
||
: {}),
|
||
};
|
||
dispatch(getSelectedFavItems(data)).unwrap();
|
||
} else {
|
||
productCardList();
|
||
}
|
||
}, [selectedDate]);
|
||
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 &&
|
||
templateData?.BookingCategory?.[0] != 'Category5'
|
||
) {
|
||
// if (!initialRun && (!ProdSubCat || !isNaN(ProdSubCat)) && ProdCat) {
|
||
setInitialRun(true);
|
||
productCardList();
|
||
}
|
||
}, [ProdCat, initialRun]);
|
||
// const formatDateFromRange = (date) => {
|
||
// if (!date) return null;
|
||
// if (date?.format) {
|
||
// return date.format('YYYY-MM-DD');
|
||
// }
|
||
// if (dayjs(date).isValid()) {
|
||
// return dayjs(date).format('YYYY-MM-DD');
|
||
// }
|
||
// return date;
|
||
// };
|
||
|
||
const productCardList = async () => {
|
||
//condition
|
||
const currentProdCat = prodCatRef.current;
|
||
const currentProdSubCat = prodSubCatRef.current;
|
||
const currentDateRef = selectedDateRef.current;
|
||
if (
|
||
(templateData?.BookingLayout?.[1]?.some(
|
||
(item) => item?.OptionName === 'SubCategory'
|
||
) ||
|
||
templateData?.BookingCategory?.[0] == 'Category5') &&
|
||
currentProdSubCat &&
|
||
currentProdCat
|
||
) {
|
||
let data = {
|
||
CompId: CompId,
|
||
BranchId: BranchId,
|
||
AppId: AppId,
|
||
ProdSubCat: currentProdSubCat,
|
||
...(AvailableDate && currentDateRef
|
||
? {
|
||
fromDate: currentDateRef?.[0],
|
||
toDate: currentDateRef?.[1],
|
||
}
|
||
: {}),
|
||
};
|
||
//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'
|
||
) &&
|
||
currentProdCat
|
||
) {
|
||
let data = {
|
||
compId: CompId,
|
||
branchId: BranchId,
|
||
appId: AppId,
|
||
prodCat: currentProdCat,
|
||
...(AvailableDate && currentDateRef
|
||
? {
|
||
fromDate: currentDateRef?.[0],
|
||
toDate: currentDateRef?.[1],
|
||
}
|
||
: {}),
|
||
};
|
||
|
||
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'
|
||
) &&
|
||
!currentProdSubCat &&
|
||
currentProdCat &&
|
||
currentProdSubCat != 'NaN'
|
||
) {
|
||
let data = {
|
||
compId: CompId,
|
||
branchId: BranchId,
|
||
appId: AppId,
|
||
prodCat: currentProdCat,
|
||
...(AvailableDate && currentDateRef
|
||
? {
|
||
fromDate: currentDateRef?.[0],
|
||
toDate: currentDateRef?.[1],
|
||
}
|
||
: {}),
|
||
};
|
||
|
||
let response = await dispatch(getCardDataWithoutSub(data)).unwrap();
|
||
|
||
if (response?.data?.statusCode == 1) {
|
||
setNoSubcatCardData(response?.data?.data);
|
||
}
|
||
}
|
||
};
|
||
|
||
const getBookingTypeId = async () => {
|
||
setConfigDataList(AllBookingType);
|
||
let configdata = AllBookingType;
|
||
let checkName = BookingTypeBoth ? 'DineIn,TakeAway' : BookingType;
|
||
|
||
let filterconfigdata = configdata?.find((a) => a?.ConfigName === checkName);
|
||
// setSelectedBookingType(filterconfigdata?.ConfigId);
|
||
};
|
||
|
||
function getCurrentMembership(memberships) {
|
||
if (!memberships?.length) return null;
|
||
|
||
// ✅ Clone the array to avoid mutating read-only data
|
||
const sorted = [...memberships].sort(
|
||
(a, b) => new Date(a.CreatedDate) - new Date(b.CreatedDate)
|
||
);
|
||
|
||
// Step 1: find active plan
|
||
const active = sorted.find(
|
||
(m) => m.RemainingDays > 0 || m.RemainingSessionHrs > 0
|
||
);
|
||
if (active) return active;
|
||
|
||
// Step 2: if no active plan, find the next upcoming (based on CreatedDate)
|
||
const now = new Date();
|
||
const next = sorted.find((m) => new Date(m.CreatedDate) > now);
|
||
return next || null;
|
||
}
|
||
|
||
const fetchedit = async () => {
|
||
let data = {
|
||
CompId: CompId,
|
||
BranchId: BranchId,
|
||
AppId: AppId,
|
||
...(AvailableDate && selectedDate
|
||
? {
|
||
fromDate: selectedDate?.[0],
|
||
toDate: selectedDate?.[1],
|
||
}
|
||
: {}),
|
||
};
|
||
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) {
|
||
setexpModel(true);
|
||
setItem(ItemCard?.[0]);
|
||
} else {
|
||
setQtydata(ItemCard?.[0]);
|
||
SingleQuantity(ItemCard?.[0], false);
|
||
}
|
||
} else if (ItemCard?.[0]?.OnePcQRBased === 'Y') {
|
||
if (ItemCard?.[0]?.OverAllExpStatus == 'Y' && ExpiredProduct) {
|
||
setexpModel(true);
|
||
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,
|
||
CounterName: '', //sri
|
||
};
|
||
AddOrderDetails(data);
|
||
}
|
||
// 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 to12Hour = (timeStr) => {
|
||
if (!timeStr) return '';
|
||
let [h, m] = timeStr.split(':');
|
||
h = parseInt(h, 10);
|
||
const suffix = h >= 12 ? 'PM' : 'AM';
|
||
h = h % 12 || 12;
|
||
return `${h}:${m}${suffix}`;
|
||
};
|
||
|
||
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) => {
|
||
// if (count > 1) {
|
||
setModalVarient(true);
|
||
setActiveMode('slot');
|
||
// } else {
|
||
// setVarientIndex(0);
|
||
// SingleStockfun(item, onePcs);
|
||
// }
|
||
};
|
||
|
||
const Stockfun = async (index, onePeiceFlow) => {
|
||
let CartUpdateData = [];
|
||
|
||
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);
|
||
setexpVarModel(true);
|
||
}
|
||
} 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) {
|
||
CartUpdateData = await dataTransfer(
|
||
qtydata,
|
||
QtyIndex,
|
||
index.key,
|
||
0,
|
||
onePeiceFlow
|
||
);
|
||
} else {
|
||
CartUpdateData = await dataTransfer(
|
||
qtydata,
|
||
QtyIndex,
|
||
index.key,
|
||
1,
|
||
onePeiceFlow
|
||
);
|
||
}
|
||
} else {
|
||
CartUpdateData = await dataTransfer(
|
||
qtydata,
|
||
QtyIndex,
|
||
index.key,
|
||
0,
|
||
onePeiceFlow
|
||
);
|
||
}
|
||
} else {
|
||
if (Isincart && Isincart?.StockAvailable === 'Y') {
|
||
if (Isincart?.BalanceQty > Isincart?.OrderQty) {
|
||
CartUpdateData = await dataTransfer(
|
||
qtydata,
|
||
QtyIndex,
|
||
index.key,
|
||
0,
|
||
onePeiceFlow
|
||
);
|
||
} else {
|
||
CartUpdateData = await dataTransfer(
|
||
qtydata,
|
||
QtyIndex,
|
||
index.key,
|
||
1,
|
||
onePeiceFlow
|
||
);
|
||
}
|
||
} else {
|
||
CartUpdateData = await 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);
|
||
setexpVarModel(true);
|
||
return;
|
||
}
|
||
}
|
||
} 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) {
|
||
CartUpdateData = await dataTransfer(
|
||
qtydata,
|
||
QtyIndex,
|
||
index.key,
|
||
0,
|
||
onePeiceFlow
|
||
);
|
||
} else {
|
||
CartUpdateData = await dataTransfer(
|
||
qtydata,
|
||
QtyIndex,
|
||
index.key,
|
||
1,
|
||
onePeiceFlow
|
||
);
|
||
}
|
||
} else {
|
||
CartUpdateData = await dataTransfer(
|
||
qtydata,
|
||
QtyIndex,
|
||
index.key,
|
||
0,
|
||
onePeiceFlow
|
||
);
|
||
}
|
||
} else {
|
||
if (Isincart && Isincart?.StockAvailable === 'Y') {
|
||
if (Isincart?.BalanceQty > Isincart?.OrderQty) {
|
||
CartUpdateData = await dataTransfer(
|
||
qtydata,
|
||
QtyIndex,
|
||
index.key,
|
||
0,
|
||
onePeiceFlow
|
||
);
|
||
} else {
|
||
CartUpdateData = await dataTransfer(
|
||
qtydata,
|
||
QtyIndex,
|
||
index.key,
|
||
1,
|
||
onePeiceFlow
|
||
);
|
||
}
|
||
} else {
|
||
CartUpdateData = await 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);
|
||
setexpVarModel(true);
|
||
return;
|
||
}
|
||
setModelQty(false);
|
||
setSelectedBrand('Others');
|
||
}
|
||
|
||
return CartUpdateData;
|
||
};
|
||
const VarientFun = (index) => {
|
||
const QtyExpire = index?.ProdVariantDetails.every(
|
||
(item) => item.OverAllExpStatus === 'Y'
|
||
);
|
||
if (QtyExpire && ExpiredProduct) {
|
||
setExpQtyModel(true);
|
||
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 {
|
||
setexpStockModel(true);
|
||
setStockItem(item.key);
|
||
}
|
||
}
|
||
|
||
setProdexpir(false);
|
||
setRepeatedModel(false);
|
||
};
|
||
|
||
const CardOnclick = async (item, index, Parameter) => {
|
||
console.log(item, index, 'setCurrentSlotIndex');
|
||
setCurrentSlotIndex(index);
|
||
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) {
|
||
setexpModel(true);
|
||
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 AddOrderDetails = async (item) => {
|
||
if (preOrder) {
|
||
await handlePreOrder(item);
|
||
} else {
|
||
let data = await handleRegularOrder(item);
|
||
return data;
|
||
}
|
||
};
|
||
|
||
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 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 &&
|
||
// console.log(new Date(cartItem.BookedDate).toDateString() , item,"mohandate")
|
||
// if both sides have date info, check match too
|
||
|
||
cartItem.BookedDate &&
|
||
item.BookedDate &&
|
||
cartItem.BookedDate === item.BookedDate;
|
||
const isItemInCart = CartOrderDetails?.find(
|
||
(cartItem) => itemMatchCondition(cartItem) && !cartItem.SalesId
|
||
);
|
||
|
||
const isItemInCartHold = CartOrderDetails?.find((cartItem) =>
|
||
itemMatchCondition(cartItem)
|
||
);
|
||
|
||
// Filter cart items
|
||
const otherOrderDataForNormal = CartOrderDetails?.filter(
|
||
(cartItem) => !(itemMatchCondition(cartItem) && !cartItem.SalesId)
|
||
);
|
||
|
||
const otherOrderDataForNormalWithoutSalesId = CartOrderDetails?.filter(
|
||
(cartItem) => !itemMatchCondition(cartItem)
|
||
);
|
||
|
||
try {
|
||
// CASE 1: Item exists in cart, not Dine In, not Hold order
|
||
|
||
if (isItemInCart && !isHoldOrder) {
|
||
const updatedCartItem = createUpdatedCartItem(isItemInCart);
|
||
const updatedData = addFirst
|
||
? [updatedCartItem, ...otherOrderDataForNormal]
|
||
: [...otherOrderDataForNormal, updatedCartItem];
|
||
|
||
dispatch(changeOrderCardDetails(updatedData));
|
||
UpdateBlockSlot(updatedCartItem);
|
||
}
|
||
// CASE 2: Item exists in cart (hold), is Hold order
|
||
else if (isItemInCartHold && isHoldOrder) {
|
||
const updatedCartItem = createUpdatedCartItem(isItemInCartHold);
|
||
const updatedData = addFirst
|
||
? [updatedCartItem, ...otherOrderDataForNormalWithoutSalesId]
|
||
: [...otherOrderDataForNormalWithoutSalesId, updatedCartItem];
|
||
|
||
dispatch(changeOrderCardDetails(updatedData));
|
||
UpdateBlockSlot(updatedCartItem);
|
||
}
|
||
// CASE 3: New item - not in cart
|
||
else {
|
||
if (item.OtherProduct === 'Others') {
|
||
const newCartItem = createNewCartItem(item, item.OrderQty);
|
||
const updatedData = addFirst
|
||
? [newCartItem, ...CartOrderDetails]
|
||
: [...CartOrderDetails, newCartItem];
|
||
|
||
dispatch(changeOrderCardDetails(updatedData));
|
||
UpdateBlockSlot(newCartItem);
|
||
} else {
|
||
const newCartItem = createNewCartItem(item, 1);
|
||
const updatedData = addFirst
|
||
? [newCartItem, ...CartOrderDetails]
|
||
: [...CartOrderDetails, newCartItem];
|
||
dispatch(changeOrderCardDetails(updatedData));
|
||
UpdateBlockSlot(newCartItem);
|
||
return newCartItem;
|
||
}
|
||
}
|
||
} catch (error) {
|
||
console.error('Error updating order details:', error);
|
||
} finally {
|
||
// Clean up dispatch calls
|
||
dispatch(changeothersdata({}));
|
||
dispatch(ChangeNewQrProduct({}));
|
||
}
|
||
};
|
||
const UpdateBlockSlot = async (newCartItem) => {
|
||
let BlockPostdata = {
|
||
CompId: CompId,
|
||
BranchId: BranchId,
|
||
AppId: AppId,
|
||
|
||
Status: 'Block',
|
||
CreatedBy: UserId,
|
||
ProductList: [
|
||
{
|
||
ProdId: newCartItem?.ProdId,
|
||
InwardDtlId: newCartItem?.InwardDtlId,
|
||
SinglePc: newCartItem?.SinglePc,
|
||
Qty: 1,
|
||
Date: newCartItem?.BookedDate,
|
||
},
|
||
],
|
||
};
|
||
await dispatch(PostBlockSlots(BlockPostdata)).unwrap();
|
||
};
|
||
|
||
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 = (data, CartOrderDetails) => {
|
||
const baseAvailable =
|
||
parseInt(data?.TotalSlotQty || 0) - parseInt(data?.BookedQty || 0);
|
||
|
||
// Calculate total single piece order qty from cart
|
||
const inCartQty = CartOrderDetails?.reduce((acc, item) => {
|
||
const same =
|
||
item?.InwardDtlId === data?.InwardDtlId &&
|
||
item?.ProdVariantName?.toLowerCase() ===
|
||
data?.VarientName?.toLowerCase() &&
|
||
item?.VariantAvailableFrom === data?.VariantAvailableFrom &&
|
||
item?.VariantAvailableTo === data?.VariantAvailableTo &&
|
||
item?.BookedDate &&
|
||
data?.BookedDate &&
|
||
item?.BookedDate?.split('T')[0] === data?.BookedDate?.split('T')[0];
|
||
|
||
if (same && item?.SinglePc === 'Y') {
|
||
return acc + (parseInt(item?.OrderQty) || 0);
|
||
}
|
||
return acc;
|
||
}, 0);
|
||
|
||
return Math.max(baseAvailable, 0);
|
||
};
|
||
const varientcolumns = [
|
||
{
|
||
title: 'Variant Name',
|
||
dataIndex: 'VarientName',
|
||
key: 'VarientName',
|
||
align: 'left',
|
||
render: (_, record, index) => (
|
||
<span
|
||
style={
|
||
record.StockCount > 0 ||
|
||
record.StockCount === 'Stock Not Maintained'
|
||
? { color: '#000', cursor: 'pointer' }
|
||
: { color: '#f49898', cursor: 'not-allowed' }
|
||
}
|
||
>
|
||
{record.VarientName}
|
||
</span>
|
||
),
|
||
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) => (
|
||
<span
|
||
style={
|
||
record.StockCount > 0 ||
|
||
record.StockCount === 'Stock Not Maintained'
|
||
? { color: '#000', cursor: 'pointer' }
|
||
: { color: '#f49898', cursor: 'not-allowed' }
|
||
}
|
||
>
|
||
{record.StockCount}
|
||
</span>
|
||
),
|
||
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) => (
|
||
<span
|
||
style={
|
||
record.StockCount > 0 ||
|
||
record.StockCount === 'Stock Not Maintained'
|
||
? { color: '#000', cursor: 'pointer' }
|
||
: { color: '#f49898', cursor: 'not-allowed' }
|
||
}
|
||
>
|
||
{record.Amount}
|
||
</span>
|
||
),
|
||
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) => (
|
||
<span
|
||
style={
|
||
record.StockCount > 0
|
||
? { color: '#000', cursor: 'pointer' }
|
||
: { color: '#f49898', cursor: 'not-allowed' }
|
||
}
|
||
>
|
||
{record?.['Batch No']}
|
||
</span>
|
||
),
|
||
onCell: (record) => {
|
||
return {
|
||
onClick: () => {
|
||
if (record.StockCount > 0) {
|
||
StockSelected(record);
|
||
}
|
||
},
|
||
};
|
||
},
|
||
},
|
||
{
|
||
title: 'Stock Count',
|
||
dataIndex: 'StockCount',
|
||
key: 'StockCount',
|
||
align: 'center',
|
||
render: (_, record, index) => (
|
||
<span
|
||
style={
|
||
record.StockCount > 0
|
||
? { color: '#000', cursor: 'pointer' }
|
||
: { color: '#f49898', cursor: 'not-allowed' }
|
||
}
|
||
>
|
||
{record.StockCount}
|
||
</span>
|
||
),
|
||
onCell: (record) => {
|
||
return {
|
||
onClick: () => {
|
||
if (record.StockCount > 0) {
|
||
StockSelected(record);
|
||
}
|
||
},
|
||
};
|
||
},
|
||
},
|
||
{
|
||
title: 'Stock Date',
|
||
dataIndex: 'Stock Date',
|
||
key: 'Stock Date',
|
||
align: 'center',
|
||
render: (_, record, index) => (
|
||
<span
|
||
style={
|
||
record.StockCount > 0
|
||
? { color: '#000', cursor: 'pointer' }
|
||
: { color: '#f49898', cursor: 'not-allowed' }
|
||
}
|
||
>
|
||
{record?.['Stock Date']}
|
||
</span>
|
||
),
|
||
onCell: (record) => {
|
||
return {
|
||
onClick: () => {
|
||
if (record.StockCount > 0) {
|
||
StockSelected(record);
|
||
}
|
||
},
|
||
};
|
||
},
|
||
},
|
||
{
|
||
title: 'Exp Date',
|
||
dataIndex: 'ExpDate',
|
||
key: 'ExpDate',
|
||
align: 'center',
|
||
render: (_, record, index) => (
|
||
<span
|
||
style={
|
||
record.StockCount > 0
|
||
? { color: '#000', cursor: 'pointer' }
|
||
: { color: '#f49898', cursor: 'not-allowed' }
|
||
}
|
||
>
|
||
{record.ExpDate}
|
||
</span>
|
||
),
|
||
onCell: (record) => {
|
||
return {
|
||
onClick: () => {
|
||
if (record.StockCount > 0) {
|
||
StockSelected(record);
|
||
}
|
||
},
|
||
};
|
||
},
|
||
},
|
||
{
|
||
title: 'Price',
|
||
dataIndex: 'Price',
|
||
key: 'Price',
|
||
align: 'center',
|
||
render: (_, record, index) => (
|
||
<span
|
||
style={
|
||
record.StockCount > 0
|
||
? { color: '#000', cursor: 'pointer' }
|
||
: { color: '#f49898', cursor: 'not-allowed' }
|
||
}
|
||
>
|
||
{safeRound(record.Price)}
|
||
</span>
|
||
),
|
||
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,
|
||
// VariantAvailableFrom: item?.AvailableFrom,
|
||
// VariantAvailableTo: item?.AvailableTo,
|
||
// SlotStatus: item?.StockDetails?.[0]?.SlotStatus,
|
||
// InwardDtlId: item?.StockDetails?.[0]?.InwardDtlId,
|
||
// BookedDate: selectedDate?.format('YYYY-MM-DD'),
|
||
// BookedQty: item?.StockDetails?.[0]?.BookedQty,
|
||
// TotalSlotQty: item?.StockDetails?.[0]?.TotalSlotQty,
|
||
|
||
// });
|
||
// });
|
||
const [dates, setDates] = useState([]);
|
||
const [slots, setSlots] = useState([]);
|
||
const [isAllSelected, setIsAllSelected] = useState(false);
|
||
const formatDate = (dateStr) => {
|
||
if (!dateStr) return '';
|
||
const date = new Date(dateStr);
|
||
const day = String(date.getDate()).padStart(2, '0');
|
||
const month = date.toLocaleString('en-US', { month: 'short' });
|
||
const year = date.getFullYear();
|
||
return `${day} ${month} ${year}`;
|
||
};
|
||
|
||
// useEffect(() => {
|
||
// // Process multiple products from draggableCardData for date-based time slots
|
||
// if (draggableCardData && draggableCardData.length > 0) {
|
||
// const allVariantDetails = [];
|
||
// draggableCardData?.forEach((product, productIndex) => {
|
||
// // Iterate through all ProductDetail entries for each product
|
||
// product?.ProductDetail?.forEach((productDetail, detailIndex) => {
|
||
// // Iterate through all ProdVariantDetails for each ProductDetail
|
||
// productDetail?.ProdVariantDetails?.forEach((variant, variantIndex) => {
|
||
// // Only process variants that have time slots (AvailableFrom and AvailableTo)
|
||
|
||
// // Get stock details (first stock detail if available)
|
||
// const stockDetail = variant?.StockDetails?.[0] || {};
|
||
|
||
// // Create slot data object
|
||
// const slotData = {
|
||
// key: `${productIndex}-${detailIndex}-${variantIndex}`,
|
||
// ProdId: product?.ProdId,
|
||
// ProdName: product?.ProdName,
|
||
// VarientName: variant?.ProdVariantName,
|
||
// TempDate: variant?.tempDate ,
|
||
// BookedDate: variant?.tempDate,
|
||
// Amount: onePeiceFlow
|
||
// ? stockDetail?.OnePcsPrice || 0
|
||
// : stockDetail?.SellPrice || 0,
|
||
// VariantAvailableFrom: variant?.AvailableFrom,
|
||
// VariantAvailableTo: variant?.AvailableTo,
|
||
// SlotStatus: stockDetail?.SlotStatus || null,
|
||
// InwardDtlId: stockDetail?.InwardDtlId || null,
|
||
// BookedQty: stockDetail?.BookedQty || 0,
|
||
// TotalSlotQty: stockDetail?.TotalSlotQty || 0,
|
||
// isBooked: stockDetail?.SlotStatus?.toLowerCase() === 'booked',
|
||
// isBlocked: stockDetail?.SlotStatus?.toLowerCase() === 'blocked',
|
||
// // Additional product info for reference
|
||
// ProductIndex: productIndex,
|
||
// ProductDetailIndex: detailIndex,
|
||
// VariantIndex: variantIndex,
|
||
// };
|
||
// console.log(slotData, 'slotDataslotData');
|
||
// // Add to flat array
|
||
// setModalVarientData(slotData)
|
||
// // Organize by date and time slot
|
||
// }
|
||
// );
|
||
// });
|
||
// });
|
||
|
||
// console.log(allVariantDetails, 'allVariantDetailsallVariantDetails');
|
||
// }
|
||
// }, [draggableCardData, qtydata, QtyIndex, onePeiceFlow, selectedDate, isBulk]);
|
||
|
||
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
|
||
) => {
|
||
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,
|
||
TempDate,
|
||
} = 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: TempDate,
|
||
BalanceBookedQty,
|
||
};
|
||
};
|
||
|
||
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
|
||
);
|
||
|
||
// 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 {
|
||
if (WeightScalePort === true) {
|
||
const isKgsProduct =
|
||
(detail?.UomName?.toLowerCase() === 'kgs' ||
|
||
detail?.UomName?.toLowerCase() === 'kg') &&
|
||
detail?.Size === '1';
|
||
if (isKgsProduct) {
|
||
if (WeightScaleWeight > 0 && WeightScaleWeight !== null) {
|
||
const basePrice = onePcs ? stock?.OnePcsPrice : stock?.SellPrice;
|
||
const totalRate = (
|
||
(basePrice / 1000) *
|
||
(parseFloat(WeightScaleWeight) * 1000)
|
||
).toFixed(2);
|
||
const data = buildOrderData(
|
||
a,
|
||
detail,
|
||
variant,
|
||
stock,
|
||
parseFloat(WeightScaleWeight),
|
||
totalRate,
|
||
onePcs
|
||
);
|
||
|
||
resetProductModal();
|
||
await AddOrderDetails(data);
|
||
dispatch(changeWeightScaleWeight(null));
|
||
setRepeatedModel(false);
|
||
setProdexpir(false);
|
||
} 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();
|
||
let dataReturn = await AddOrderDetails(data);
|
||
return dataReturn;
|
||
} 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 {
|
||
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,
|
||
...(AvailableDate && selectedDate
|
||
? {
|
||
fromDate: selectedDate?.[0],
|
||
toDate: selectedDate?.[1],
|
||
}
|
||
: {}),
|
||
};
|
||
|
||
// 👇 Only add date if AvailableDate and selectedDate exist
|
||
// if (AvailableDate && selectedDate) {
|
||
// baseData.date = Array.isArray(selectedDate)
|
||
// ? selectedDate
|
||
// .map((d) => (d?.format ? d.format('YYYY-MM-DD') : d))
|
||
// .join(',')
|
||
// : selectedDate?.format
|
||
// ? selectedDate.format('YYYY-MM-DD')
|
||
// : 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
|
||
? {
|
||
fromDate: selectedDate?.[0],
|
||
toDate: selectedDate?.[1],
|
||
}
|
||
: {}),
|
||
};
|
||
|
||
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) => {
|
||
let count = item?.ProductDetail?.length;
|
||
if (count > 1) {
|
||
Quantity();
|
||
} else {
|
||
setVarItem(0);
|
||
SingleQuantity(item, onePeiceFlow);
|
||
}
|
||
setexpModel(false);
|
||
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);
|
||
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 null; // or any other value you want to return
|
||
}
|
||
};
|
||
|
||
const ItemSize = (item) => {
|
||
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) => {
|
||
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);
|
||
setExpQtyModel(false);
|
||
};
|
||
|
||
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');
|
||
}
|
||
setexpVarModel(false);
|
||
};
|
||
|
||
const expStockFun = (item) => {
|
||
dataTransfer(qtydata, QtyIndex, VarientIndex, item, onePeiceFlow);
|
||
setexpStockModel(false);
|
||
};
|
||
|
||
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);
|
||
};
|
||
}, []);
|
||
|
||
useEffect(() => {
|
||
function handleResize() {
|
||
setScreenHeight(window.innerHeight);
|
||
}
|
||
|
||
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
|
||
|
||
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);
|
||
// }
|
||
if (Array.isArray(cardData)) {
|
||
const withIds = cardData.map((product, productIndex) => {
|
||
const updatedProductDetail = (product?.ProductDetail || []).map(
|
||
(detail, detailIndex) => {
|
||
const updatedVariants = (detail?.ProdVariantDetails || []).map(
|
||
(variant, variantIndex) => {
|
||
const stock = variant?.StockDetails?.[0] || {}; // take the first stock detail
|
||
|
||
// Merge stock details directly into variant
|
||
return {
|
||
key: `${productIndex}-${detailIndex}-${variantIndex}`,
|
||
...variant,
|
||
VariantAvailableFrom: variant?.AvailableFrom,
|
||
VariantAvailableTo: variant?.AvailableTo,
|
||
BookedDate: variant?.TempDate,
|
||
...stock, // flattening stock fields
|
||
};
|
||
}
|
||
);
|
||
|
||
return {
|
||
...detail,
|
||
ProdVariantDetails: updatedVariants, // replaced with flattened variants
|
||
};
|
||
}
|
||
);
|
||
|
||
return {
|
||
...product,
|
||
id: product?.ProductDetail?.[0]?.ProdName + '-' + productIndex,
|
||
ProductDetail: updatedProductDetail,
|
||
};
|
||
});
|
||
|
||
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;
|
||
|
||
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;
|
||
|
||
const getDatePickerValue = (selectedDate) => {
|
||
if (Array.isArray(selectedDate) && selectedDate.length === 2) {
|
||
// Convert both dates in array to dayjs objects
|
||
return [dayjs(selectedDate[0]), dayjs(selectedDate[1])];
|
||
}
|
||
};
|
||
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(result?.[0]);
|
||
// AddOrderDetails2(result?.[0])
|
||
} else if (item?.OverAllQty < prodQty) {
|
||
setMessageType('error');
|
||
setMessageData('NoStack');
|
||
}
|
||
}, [prodname]);
|
||
|
||
function encrypt(code, key) {
|
||
// Implement encryption logic using a secure algorithm
|
||
// For demonstration purposes, this is a simple XOR encryption
|
||
let encrypted = (
|
||
<>
|
||
<div
|
||
className="bs-item-card-masterdiv"
|
||
style={{
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
overflowY: 'scroll',
|
||
height: '80vh',
|
||
paddingBottom: '6rem',
|
||
}}
|
||
ref={itemListScrollRef}
|
||
>
|
||
{messageType && messageData && (
|
||
<Messages
|
||
messageType={messageType}
|
||
messageData={messageData}
|
||
onComplete={onComplete}
|
||
/>
|
||
)}
|
||
|
||
<div
|
||
className="voiceToTextIcon"
|
||
style={{
|
||
position: 'absolute',
|
||
zIndex: '12',
|
||
top:
|
||
templateData?.BookingLayout?.[0] === 'Layout5' ||
|
||
templateData?.BookingLayout?.[0] === 'Layout4' ||
|
||
templateData?.BookingLayout?.[0] === 'Layout6'
|
||
? '2.5rem'
|
||
: '',
|
||
}}
|
||
onClick={() => {
|
||
// trigger child function
|
||
voiceTriggerRef?.current?.listening();
|
||
}}
|
||
>
|
||
<VoiceToTextItemCard
|
||
ref={voiceTriggerRef}
|
||
setVoiceData={(data) => {
|
||
setprodname(data.product);
|
||
setprodQty(data.qty);
|
||
}}
|
||
/>
|
||
</div>
|
||
{/* <p>{prodname}</p> */}
|
||
<div style={{ display: 'flex', justifyContent: 'flex-start' }}>
|
||
<div
|
||
className="BSItemCard-master-container"
|
||
style={{
|
||
rowGap: cardFunction?.BigImage ? '15px' : '15px',
|
||
pointerEvents: OrderType === 'Failed' ? 'none' : 'auto',
|
||
overflow: 'auto',
|
||
}}
|
||
>
|
||
{/* <div className="BSItemCard-master-container" > */}
|
||
{cardData?.length > 0 ? (
|
||
<>
|
||
<DndContext
|
||
sensors={sensors}
|
||
collisionDetection={closestCenter}
|
||
onDragEnd={handleDragEnd}
|
||
>
|
||
<SortableContext
|
||
items={draggableCardData?.map((item) => item?.id)}
|
||
strategy={rectSortingStrategy}
|
||
>
|
||
<div
|
||
style={{
|
||
display: 'flex',
|
||
flexWrap: 'wrap',
|
||
gap: '8px',
|
||
}}
|
||
className={
|
||
templateData?.BookingCard?.[0] != 'Card4'
|
||
? ''
|
||
: 'CategoryHorizontalNewcontainer'
|
||
}
|
||
>
|
||
{draggableCardData.map((item, index) => (
|
||
<SortableCard
|
||
key={item.id || index}
|
||
id={item.id || index}
|
||
item={item}
|
||
>
|
||
{templateData?.BookingCard?.[0] != 'Card4' ? (
|
||
<div
|
||
style={{
|
||
position: 'relative',
|
||
overflow: 'auto',
|
||
}}
|
||
className={
|
||
// (item?.OverAllQty !== undefined &&
|
||
// returnCount(
|
||
// item?.ProductDetail?.[0]?.ProdVariantDetails?.length > 0,
|
||
// item?.OverAllQty,
|
||
// CartOrderDetails,
|
||
// item?.OverAllPcs
|
||
// ) > 0) ||
|
||
// item?.ProductDetail?.some(
|
||
// (item) => item?.StockAvailable !== 'Y'
|
||
// )
|
||
item?.ProductDetail?.[0]?.ProdVariantDetails
|
||
?.length > 0
|
||
? 'BkPrdCardActive'
|
||
: 'BkPrdCardDeActive'
|
||
}
|
||
>
|
||
{!isMobile ? (
|
||
<Tooltip title={item.ProdName}>
|
||
{globaldata && (
|
||
<input
|
||
type="checkbox"
|
||
value={item.ProductDetail?.[0]?.ProdId}
|
||
name={item.ProdName}
|
||
onChange={(e) => 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
|
||
)}
|
||
/>
|
||
)}
|
||
<div
|
||
style={{
|
||
alignItems: 'center',
|
||
backgroundColor:
|
||
cardFunction?.SmallImage &&
|
||
cardFunction?.Background &&
|
||
(SelectedCardColor
|
||
? SelectedCardColor?.[
|
||
'BackgroundColor'
|
||
]
|
||
: ''),
|
||
padding:
|
||
!cardFunction?.ImageUp &&
|
||
!cardFunction?.ImageDown
|
||
? cardFunction?.SmallImage &&
|
||
'5px 9px'
|
||
: '8px 2px',
|
||
flexDirection:
|
||
cardFunction?.ImageRight &&
|
||
'row-reverse'
|
||
? cardFunction?.ImageRight &&
|
||
'row-reverse'
|
||
: cardFunction?.ImageUp && 'column'
|
||
? cardFunction?.ImageUp &&
|
||
'column'
|
||
: cardFunction?.ImageDown &&
|
||
'column-reverse'
|
||
? cardFunction?.ImageDown &&
|
||
'column-reverse'
|
||
: cardFunction?.ImageLeft &&
|
||
'row',
|
||
borderRadius:
|
||
cardFunction?.EdgeCurve && '6px',
|
||
width:
|
||
!cardFunction?.ImageUp &&
|
||
!cardFunction?.ImageDown &&
|
||
!cardFunction?.BigImage &&
|
||
!cardFunction?.ImageRight &&
|
||
cardFunction?.SmallImage &&
|
||
(cardFunction?.ImageUp ||
|
||
cardFunction?.ImageDown)
|
||
? '6rem'
|
||
: cardFunction?.BigImage && '9rem',
|
||
height:
|
||
!cardFunction?.ImageUp &&
|
||
!cardFunction?.BigImage &&
|
||
'',
|
||
pointerEvents: globaldata && 'none',
|
||
}}
|
||
className={
|
||
cardFunction?.SmallImage
|
||
? 'BSItemCard-container-smallimage'
|
||
: 'BSItemCard-container'
|
||
}
|
||
onClick={(e) => {
|
||
CardOnclick(item, index);
|
||
}}
|
||
data-aos="zoom-in"
|
||
data-aos-duration="600"
|
||
>
|
||
{(cardFunction?.BigImage ||
|
||
cardFunction?.SmallImage) && (
|
||
<img
|
||
style={{
|
||
objectFit:
|
||
cardFunction?.BigImage && '',
|
||
height: !cardFunction?.BigImage
|
||
? (!cardFunction?.BigImage &&
|
||
cardFunction?.SmallImage) ||
|
||
cardFunction?.ImageLeft ||
|
||
cardFunction?.ImageUp ||
|
||
cardFunction?.ImageDown
|
||
? '3rem'
|
||
: cardFunction?.BigImage &&
|
||
'7rem'
|
||
: '5rem',
|
||
}}
|
||
className={
|
||
cardFunction?.SmallImage
|
||
? 'BSItemCard-image-smallimage'
|
||
: 'BSItemCard-image'
|
||
}
|
||
src={
|
||
item?.ProductDetail?.[0]
|
||
?.ProdLogo === ''
|
||
? defaultimage
|
||
: item?.ProductDetail?.[0]
|
||
?.ProdLogo
|
||
? item?.ProductDetail?.[0]
|
||
?.ProdLogo
|
||
: defaultimage
|
||
}
|
||
alt=""
|
||
/>
|
||
)}
|
||
<div
|
||
className={
|
||
cardFunction?.SmallImage
|
||
? 'BSItemCard-content-smallimage'
|
||
: 'BSItemCard-content'
|
||
}
|
||
style={{
|
||
backgroundColor:
|
||
cardFunction?.Background &&
|
||
(SelectedCardColor
|
||
? SelectedCardColor?.[
|
||
'BackgroundColor'
|
||
]
|
||
: ''),
|
||
|
||
position: !cardFunction?.BigImage
|
||
? 'relative'
|
||
: 'absolute',
|
||
flexDirection:
|
||
!cardFunction?.BigImage && 'column',
|
||
borderRadius:
|
||
!cardFunction?.BigImage &&
|
||
cardFunction?.EdgeCurve &&
|
||
'6px',
|
||
bottom: cardFunction?.BigImage && '',
|
||
cardFunction,
|
||
width:
|
||
!cardFunction?.BigImage &&
|
||
!cardFunction?.SmallImage &&
|
||
'',
|
||
height: cardFunction?.SmallImage
|
||
? '5.5rem'
|
||
: !cardFunction?.BigImage &&
|
||
'5.5rem',
|
||
alignItems:
|
||
!cardFunction?.BigImage &&
|
||
!cardFunction?.SmallImage &&
|
||
'center',
|
||
textAlign:
|
||
!cardFunction?.BigImage &&
|
||
!cardFunction?.SmallImage &&
|
||
'center',
|
||
flexWrap:
|
||
cardFunction?.BigImage && 'wrap',
|
||
// flexDirection:
|
||
// cardFunction?.SmallImage ||
|
||
// (cardFunction?.BigImage && "column"),
|
||
}}
|
||
>
|
||
<p
|
||
style={{
|
||
textTransform:
|
||
cardFunction?.TextCapitalize &&
|
||
'uppercase',
|
||
width: !cardFunction?.SmallImage
|
||
? cardFunction?.BigImage &&
|
||
'120px'
|
||
: cardFunction?.SmallImage &&
|
||
!cardFunction?.ImageUp &&
|
||
!cardFunction?.ImageDown &&
|
||
'85px',
|
||
// Width: cardFunction?.BigImage && "70px",
|
||
fontSize:
|
||
!cardFunction?.BigImage &&
|
||
!cardFunction?.SmallImage &&
|
||
'12px', //naresh27
|
||
whiteSpace:
|
||
!cardFunction?.BigImage &&
|
||
'pre-wrap',
|
||
margin: 'auto',
|
||
fontFamily: SelectedCardFont
|
||
? SelectedCardFont
|
||
: '',
|
||
color: SelectedCardColor
|
||
? SelectedCardColor?.['FontColor']
|
||
: '',
|
||
textOverflow: 'ellipsis',
|
||
}}
|
||
className="BSItemCard-itemName"
|
||
>
|
||
{item?.ProdName}
|
||
{}
|
||
</p>
|
||
{cardFunction?.Price && (
|
||
<p
|
||
className="BSItemCard-itemPrice"
|
||
style={{
|
||
fontSize:
|
||
!cardFunction?.SmallImage
|
||
? cardFunction?.BigImage &&
|
||
'12px'
|
||
: '12px',
|
||
textAlign: 'center',
|
||
lineHeight: '2',
|
||
fontFamily: SelectedCardFont
|
||
? SelectedCardFont
|
||
: '',
|
||
color: SelectedCardColor
|
||
? SelectedCardColor?.[
|
||
'FontColor'
|
||
]
|
||
: '',
|
||
}}
|
||
>
|
||
₹ {ItemSellingPrice(item)}
|
||
{/* {item?.ProductDetail?.[0]?.ProdVariantDetails?.[0]?.StockDetails?.[0]?.SellPrice} */}
|
||
{/* {ItemSellingPrice(item)} */}
|
||
<span className="BSItemCard-itemCount">
|
||
({ItemSize(item)}
|
||
{ItemUomName(item)})
|
||
</span>
|
||
</p>
|
||
)}
|
||
</div>
|
||
|
||
{cardFunction?.StockCount &&
|
||
item?.OverAllQty !== undefined &&
|
||
item?.OverAllQty !== 0 && (
|
||
<div
|
||
style={{
|
||
top:
|
||
!cardFunction?.BigImage && '0',
|
||
right:
|
||
!cardFunction?.BigImage &&
|
||
!cardFunction?.SmallImage &&
|
||
'0px',
|
||
position: 'absolute',
|
||
}}
|
||
className={
|
||
cardFunction?.BigImage
|
||
? 'BSItemCard-badge'
|
||
: 'BSItemCard-badge-withoutimage'
|
||
}
|
||
>
|
||
{item?.ProductDetail?.some(
|
||
(item) =>
|
||
item?.StockAvailable === 'Y'
|
||
) &&
|
||
item?.OverAllQty !== null && (
|
||
<Badge
|
||
count={returnCount(
|
||
item?.ProductDetail?.[0]
|
||
?.ProdName,
|
||
item?.OverAllQty,
|
||
CartOrderDetails
|
||
)}
|
||
overflowCount={10000}
|
||
></Badge>
|
||
)}
|
||
</div>
|
||
)}
|
||
</div>
|
||
</Tooltip>
|
||
) : (
|
||
<>
|
||
{globaldata && (
|
||
<input
|
||
type="checkbox"
|
||
value={item.ProductDetail?.[0]?.ProdId}
|
||
name={item.ProdName}
|
||
onChange={(e) => 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
|
||
)}
|
||
/>
|
||
)}
|
||
|
||
<div
|
||
style={{
|
||
alignItems: 'center',
|
||
backgroundColor:
|
||
cardFunction?.SmallImage &&
|
||
cardFunction?.Background &&
|
||
(SelectedCardColor
|
||
? SelectedCardColor?.[
|
||
'BackgroundColor'
|
||
]
|
||
: ''),
|
||
padding:
|
||
!cardFunction?.ImageUp &&
|
||
!cardFunction?.ImageDown
|
||
? cardFunction?.SmallImage &&
|
||
'5px 9px'
|
||
: '8px 2px',
|
||
flexDirection:
|
||
cardFunction?.ImageRight &&
|
||
'row-reverse'
|
||
? cardFunction?.ImageRight &&
|
||
'row-reverse'
|
||
: cardFunction?.ImageUp && 'column'
|
||
? cardFunction?.ImageUp &&
|
||
'column'
|
||
: cardFunction?.ImageDown &&
|
||
'column-reverse'
|
||
? cardFunction?.ImageDown &&
|
||
'column-reverse'
|
||
: cardFunction?.ImageLeft &&
|
||
'row',
|
||
borderRadius:
|
||
cardFunction?.EdgeCurve && '6px',
|
||
width:
|
||
!cardFunction?.ImageUp &&
|
||
!cardFunction?.ImageDown &&
|
||
!cardFunction?.BigImage &&
|
||
!cardFunction?.ImageRight &&
|
||
cardFunction?.SmallImage &&
|
||
(cardFunction?.ImageUp ||
|
||
cardFunction?.ImageDown)
|
||
? '6rem'
|
||
: cardFunction?.BigImage && '9rem',
|
||
height:
|
||
!cardFunction?.ImageUp &&
|
||
!cardFunction?.BigImage &&
|
||
'',
|
||
pointerEvents: globaldata && 'none',
|
||
}}
|
||
className={
|
||
cardFunction?.SmallImage
|
||
? 'BSItemCard-containers-smallimage-mobile'
|
||
: 'BSItemCard-containers-mobile'
|
||
}
|
||
onClick={(e) => {
|
||
CardOnclick(item, index);
|
||
}}
|
||
// data-aos="zoom-in" data-aos-duration="600"
|
||
>
|
||
{(cardFunction?.BigImage ||
|
||
cardFunction?.SmallImage) && (
|
||
<img
|
||
style={{
|
||
objectFit:
|
||
cardFunction?.BigImage && '',
|
||
height: !cardFunction?.BigImage
|
||
? (!cardFunction?.BigImage &&
|
||
cardFunction?.SmallImage) ||
|
||
cardFunction?.ImageLeft ||
|
||
cardFunction?.ImageUp ||
|
||
cardFunction?.ImageDown
|
||
? '3rem'
|
||
: cardFunction?.BigImage &&
|
||
'7rem'
|
||
: '4rem',
|
||
}}
|
||
className={
|
||
cardFunction?.SmallImage
|
||
? 'BSItemCard-image-smallimage'
|
||
: 'BSItemCard-image'
|
||
}
|
||
src={
|
||
item?.ProductDetail?.[0]
|
||
?.ProdLogo === ''
|
||
? defaultimage
|
||
: item?.ProductDetail?.[0]
|
||
?.ProdLogo
|
||
? item?.ProductDetail?.[0]
|
||
?.ProdLogo
|
||
: defaultimage
|
||
}
|
||
alt=""
|
||
/>
|
||
)}
|
||
<div
|
||
className={
|
||
cardFunction?.SmallImage
|
||
? 'BSItemCard-content-smallimage'
|
||
: 'BSItemCard-content'
|
||
}
|
||
style={{
|
||
backgroundColor:
|
||
cardFunction?.Background &&
|
||
(SelectedCardColor
|
||
? SelectedCardColor?.[
|
||
'BackgroundColor'
|
||
]
|
||
: ''),
|
||
|
||
position: !cardFunction?.BigImage
|
||
? 'relative'
|
||
: 'absolute',
|
||
flexDirection:
|
||
!cardFunction?.BigImage && 'column',
|
||
borderRadius:
|
||
!cardFunction?.BigImage &&
|
||
cardFunction?.EdgeCurve &&
|
||
'6px',
|
||
bottom: cardFunction?.BigImage && '',
|
||
cardFunction,
|
||
width:
|
||
!cardFunction?.BigImage &&
|
||
!cardFunction?.SmallImage &&
|
||
'',
|
||
height: cardFunction?.SmallImage
|
||
? '5.5rem'
|
||
: !cardFunction?.BigImage &&
|
||
'4.5rem',
|
||
alignItems:
|
||
!cardFunction?.BigImage &&
|
||
!cardFunction?.SmallImage &&
|
||
'center',
|
||
textAlign:
|
||
!cardFunction?.BigImage &&
|
||
!cardFunction?.SmallImage &&
|
||
'center',
|
||
flexWrap:
|
||
cardFunction?.BigImage && 'wrap',
|
||
}}
|
||
>
|
||
<p
|
||
style={{
|
||
textTransform:
|
||
cardFunction?.TextCapitalize &&
|
||
'uppercase',
|
||
width: !cardFunction?.SmallImage
|
||
? cardFunction?.BigImage &&
|
||
'120px'
|
||
: cardFunction?.SmallImage &&
|
||
!cardFunction?.ImageUp &&
|
||
!cardFunction?.ImageDown &&
|
||
'85px',
|
||
// Width: cardFunction?.BigImage && "70px",
|
||
fontSize:
|
||
!cardFunction?.BigImage &&
|
||
!cardFunction?.SmallImage &&
|
||
'12px', //naresh27
|
||
whiteSpace:
|
||
!cardFunction?.BigImage &&
|
||
'pre-wrap',
|
||
margin: 'auto',
|
||
fontFamily: SelectedCardFont
|
||
? SelectedCardFont
|
||
: '',
|
||
color: SelectedCardColor
|
||
? SelectedCardColor?.['FontColor']
|
||
: '',
|
||
textOverflow: 'ellipsis',
|
||
}}
|
||
className="BSItemCard-itemName"
|
||
>
|
||
{item?.ProdName}{' '}
|
||
</p>
|
||
{cardFunction?.Price &&
|
||
((item?.OverAllQty !== undefined &&
|
||
item?.OverAllQty !== 0 &&
|
||
item?.OverAllQty !== null) ||
|
||
item?.ProductDetail?.some(
|
||
(item) =>
|
||
item?.StockAvailable !== 'Y'
|
||
)) && (
|
||
<p
|
||
className="BSItemCard-itemPrice"
|
||
style={{
|
||
fontSize:
|
||
!cardFunction?.SmallImage
|
||
? cardFunction?.BigImage &&
|
||
'12px'
|
||
: '12px',
|
||
textAlign: 'center',
|
||
lineHeight: '2',
|
||
fontFamily: SelectedCardFont
|
||
? SelectedCardFont
|
||
: '',
|
||
color: SelectedCardColor
|
||
? SelectedCardColor?.[
|
||
'FontColor'
|
||
]
|
||
: '',
|
||
}}
|
||
>
|
||
₹ {ItemSellingPrice(item)}
|
||
{/* {item?.ProductDetail?.[0]?.ProdVariantDetails?.[0]?.StockDetails?.[0]?.SellPrice} */}
|
||
{/* {ItemSellingPrice(item)} */}
|
||
<span className="BSItemCard-itemCount">
|
||
({ItemSize(item)}
|
||
{ItemUomName(item)})
|
||
</span>
|
||
</p>
|
||
)}
|
||
</div>
|
||
|
||
{cardFunction?.StockCount &&
|
||
item?.OverAllQty !== undefined &&
|
||
item?.OverAllQty !== 0 && (
|
||
<div
|
||
style={{
|
||
top:
|
||
!cardFunction?.BigImage && '0',
|
||
right:
|
||
!cardFunction?.BigImage &&
|
||
!cardFunction?.SmallImage &&
|
||
'0px',
|
||
position: 'absolute',
|
||
}}
|
||
className={
|
||
cardFunction?.BigImage
|
||
? 'BSItemCard-badge'
|
||
: 'BSItemCard-badge-withoutimage'
|
||
}
|
||
>
|
||
{item?.ProductDetail?.some(
|
||
(item) =>
|
||
item?.StockAvailable === 'Y'
|
||
) &&
|
||
item?.OverAllQty !== null && (
|
||
<Badge
|
||
count={returnCount(
|
||
item?.ProductDetail?.[0]
|
||
?.ProdName,
|
||
item?.OverAllQty,
|
||
CartOrderDetails
|
||
)}
|
||
overflowCount={10000}
|
||
></Badge>
|
||
)}
|
||
</div>
|
||
)}
|
||
</div>
|
||
</>
|
||
)}
|
||
</div>
|
||
) : (
|
||
<div
|
||
className={
|
||
item?.ProductDetail?.[0]?.ProdVariantDetails
|
||
?.length > 0
|
||
? 'card4Main card4Main-active'
|
||
: 'card4Main card4Main-deactive'
|
||
}
|
||
onClick={(e) => {
|
||
CardOnclick(item, index); // This will trigger if you're clicking outside the "One Piece" button
|
||
}}
|
||
>
|
||
{/* Global Data Checkbox */}
|
||
{globaldata && (
|
||
<input
|
||
type="checkbox"
|
||
value={item.ProductDetail?.[0]?.ProdId}
|
||
name={item.ProdName}
|
||
onClick={(e) => e.stopPropagation()}
|
||
onChange={(e) => 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 */}
|
||
<Tooltip title={item.ProdName}>
|
||
<div className="card4Img">
|
||
<img
|
||
width={50}
|
||
height={60}
|
||
src={
|
||
item?.ProductDetail?.[0]?.ProdLogo ===
|
||
''
|
||
? defaultimage
|
||
: item?.ProductDetail?.[0]?.ProdLogo
|
||
? item?.ProductDetail?.[0]?.ProdLogo
|
||
: defaultimage
|
||
}
|
||
alt=""
|
||
/>
|
||
</div>
|
||
</Tooltip>
|
||
|
||
<div className="Card4datas">
|
||
<div className="card4ProductName">
|
||
{item?.ProdName}
|
||
</div>
|
||
{item?.ProductDetail?.[0]?.ProdVariantDetails
|
||
?.length > 0 && (
|
||
<div className="card4PriceUom">
|
||
<div className="card4Price">
|
||
₹ {ItemSellingPrice(item)}
|
||
</div>
|
||
<div className="card4Uom">
|
||
{ItemSize(item)} {ItemUomName(item)}
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
{/* Stock Count Badge */}
|
||
{cardFunction?.StockCount &&
|
||
item?.OverAllQty !== undefined &&
|
||
item?.OverAllQty !== 0 && (
|
||
<div
|
||
style={{
|
||
top: '0',
|
||
right: '0px',
|
||
position: 'absolute',
|
||
}}
|
||
className="card4Main-badge"
|
||
>
|
||
{item?.ProductDetail?.some(
|
||
(item) => item?.StockAvailable === 'Y'
|
||
) &&
|
||
item?.OverAllQty !== null && (
|
||
<Badge
|
||
count={returnCount(
|
||
item?.ProductDetail?.[0]
|
||
?.ProdName,
|
||
item?.OverAllQty,
|
||
CartOrderDetails
|
||
)}
|
||
overflowCount={10000}
|
||
></Badge>
|
||
)}
|
||
</div>
|
||
)}
|
||
</div>
|
||
)}
|
||
</SortableCard>
|
||
))}
|
||
</div>
|
||
</SortableContext>
|
||
</DndContext>
|
||
</>
|
||
) : ProductSearch?.length > 5 &&
|
||
GetmultipleSearchDatas.some(
|
||
(e) => e.toLowerCase() === 'qrcode'
|
||
) &&
|
||
(cardData?.length == 0 || cardData == undefined) ? (
|
||
<div>
|
||
{/* cardData mohan 18-04-2025 */}
|
||
<FeaturesFunctionalities
|
||
handleQuickAddCancel={handleQuickCancel}
|
||
QuickAdd={QuickAdd}
|
||
ProductSearch={true}
|
||
ProductSearchType={'I'}
|
||
cardData={cardDataForNewPrd}
|
||
/>
|
||
</div>
|
||
) : (
|
||
<>
|
||
<div
|
||
className={!temp5 ? 'NodataFound' : 'NodataFound5'}
|
||
style={{
|
||
display: globalAccessForOthers && 'none',
|
||
}}
|
||
>
|
||
Name
|
||
<div align="Namecenter" className="fond">
|
||
<div className="Namecontener_general">
|
||
<div className="Namecontener_mixte">
|
||
<div className="ballcolor ball_1"> </div>
|
||
</div>
|
||
Name
|
||
<div className="Namecontener_mixte">
|
||
<div className="ballcolor ball_2"> </div>
|
||
</div>
|
||
Name
|
||
<div className="Namecontener_mixte">
|
||
<div className="ballcolor ball_3"> </div>
|
||
</div>
|
||
Name
|
||
<div className="Namecontener_mixte">
|
||
<div className="ballcolor ball_4"> </div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</>
|
||
)}
|
||
{paymentloadNameer === true && (
|
||
<div className="NamePayment-loader1">
|
||
<div className="NamePayment-loader">
|
||
<div className="Namecontener_mixte">
|
||
<div className="ballcolor ball_1"> </div>
|
||
</div>
|
||
Name
|
||
<div className="Namecontener_mixte">
|
||
<div className="ballcolor ball_2"> </div>
|
||
</div>
|
||
Name
|
||
<div className="Namecontener_mixte">
|
||
<div className="ballcolor ball_3"> </div>
|
||
</div>
|
||
Name
|
||
<div className="Namecontener_mixte">
|
||
<div className="ballcolor ball_4"> </div>
|
||
</div>
|
||
<p style={{ marginTop: '2rem' }}>
|
||
{' '}
|
||
Please wait while we process your payment
|
||
</p>
|
||
{PaymentTransactionNumber != null && (
|
||
<p style={{ fontSize: '16px', fontWeight: '600' }}>
|
||
Transaction Number : {PaymentTransactionNumber}
|
||
</p>
|
||
)}
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{expModel && (
|
||
<Modal
|
||
title={
|
||
<div
|
||
style={{ display: 'flex', gap: '1rem', flexDirection: 'row' }}
|
||
>
|
||
<div>
|
||
<ExclamationCircleOutlined
|
||
style={{ color: 'rgb(231 176 12)', fontSize: '30px' }}
|
||
/>
|
||
</div>
|
||
<div>
|
||
<h4>Product Expires</h4>
|
||
</div>
|
||
</div>
|
||
}
|
||
open={expModel}
|
||
onOk={() => expFun(Item)}
|
||
onCancel={() => setexpModel(false)}
|
||
okText="Submit"
|
||
cancelText="Don't Submit"
|
||
maskTransitionName="" // Remove animation for the mask
|
||
transitionName=""
|
||
></Modal>
|
||
)}
|
||
|
||
{expQtyModel && (
|
||
<Modal
|
||
title={
|
||
<div
|
||
style={{ display: 'flex', gap: '1rem', flexDirection: 'row' }}
|
||
>
|
||
<ExclamationCircleOutlined
|
||
style={{ color: 'rgb(231 176 12)', fontSize: '30px' }}
|
||
/>
|
||
<h3>Quantity Expires</h3>
|
||
</div>
|
||
}
|
||
open={expQtyModel}
|
||
onOk={() => expQtyFun(qtyExpData)}
|
||
onCancel={() => {
|
||
(setRepeatedModel(false),
|
||
setProdexpir(false),
|
||
setExpQtyModel(false));
|
||
}}
|
||
okText="Submit"
|
||
cancelText="Don't Submit"
|
||
maskTransitionName=""
|
||
transitionName=""
|
||
></Modal>
|
||
)}
|
||
|
||
{expVarModel && (
|
||
<Modal
|
||
title={
|
||
<div
|
||
style={{ display: 'flex', gap: '1rem', flexDirection: 'row' }}
|
||
>
|
||
<ExclamationCircleOutlined
|
||
style={{ color: 'rgb(231 176 12)', fontSize: '30px' }}
|
||
/>
|
||
<h3>Variant Expires</h3>
|
||
</div>
|
||
}
|
||
open={expVarModel}
|
||
onOk={() => expVerFun(VarItem)}
|
||
onCancel={() => {
|
||
(setexpVarModel(false),
|
||
setRepeatedModel(false),
|
||
setProdexpir(false));
|
||
}}
|
||
okText="Submit"
|
||
cancelText="Don't Submit"
|
||
maskTransitionName=""
|
||
transitionName=""
|
||
></Modal>
|
||
)}
|
||
{expStockModel && (
|
||
<Modal
|
||
title={
|
||
<div
|
||
style={{ display: 'flex', gap: '1rem', flexDirection: 'row' }}
|
||
>
|
||
<ExclamationCircleOutlined
|
||
style={{ color: 'rgb(231 176 12)', fontSize: '30px' }}
|
||
/>
|
||
<h3>Stock Expires</h3>
|
||
</div>
|
||
}
|
||
open={expStockModel}
|
||
onOk={() => expStockFun(StockItem)}
|
||
onCancel={() => {
|
||
(setexpStockModel(false),
|
||
setRepeatedModel(false),
|
||
setProdexpir(false));
|
||
}}
|
||
okText="Submit"
|
||
cancelText="Don't Submit"
|
||
maskTransitionName=""
|
||
transitionName=""
|
||
></Modal>
|
||
)}
|
||
|
||
{modelQty && (
|
||
<DefaultModal
|
||
title={
|
||
<div className="EditQuantity-title">
|
||
<FormHeader title={'SubItem'} />
|
||
</div>
|
||
}
|
||
open={modelQty}
|
||
width={800}
|
||
handleCancel={CloseModal}
|
||
footer={null}
|
||
maskTransitionName=""
|
||
transitionName=""
|
||
children={
|
||
<div>
|
||
<div className="EditQuantity-heading">
|
||
<div className="EditQuantity-headingname">
|
||
<p className="EditQuantity-itemname">Item Name:</p>
|
||
</div>
|
||
<div
|
||
className="EditQuantity-headingproductname"
|
||
style={{ marginLeft: '1rem' }}
|
||
>
|
||
<p className="EditQuantity-productname">
|
||
{qtydata?.ProdName}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div
|
||
style={{ height: 'auto' }}
|
||
className={
|
||
BrandCheckresult
|
||
? 'Card-modal-table'
|
||
: 'Brand-Card-modal-table'
|
||
}
|
||
>
|
||
{/* Horizontal scroll container */}
|
||
|
||
<div
|
||
style={{
|
||
position: 'relative',
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
}}
|
||
>
|
||
{/* Left Scroll Button */}
|
||
{showLeftButton && (
|
||
<div
|
||
className="CategoryHorizontal-icon"
|
||
onClick={() => 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)',
|
||
}}
|
||
>
|
||
◄
|
||
</div>
|
||
)}
|
||
|
||
{/* Scroll Container */}
|
||
<div
|
||
id="mainDiv"
|
||
className="CategoryHorizontal-scroll-container"
|
||
ref={scrollContainerRef}
|
||
onMouseDown={handleMouseDown}
|
||
onMouseMove={handleMouseMove}
|
||
onMouseUp={handleMouseUp}
|
||
onMouseLeave={handleMouseUp}
|
||
onTouchStart={handleTouchStart}
|
||
onTouchMove={handleTouchMove}
|
||
onTouchEnd={handleTouchEnd}
|
||
style={{
|
||
cursor: 'grab',
|
||
overflowX: 'auto',
|
||
display: 'flex',
|
||
gap: '1rem',
|
||
}}
|
||
>
|
||
{Object.keys(brandGroups)
|
||
.sort((a, b) =>
|
||
a === 'Others' ? -1 : b === 'Others' ? 1 : 0
|
||
)
|
||
.map((brand) => (
|
||
<div
|
||
key={brand}
|
||
onClick={() => 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 ? 'bold' : 'normal',
|
||
}}
|
||
>
|
||
{brand === 'Others' ? 'Others' : brand}
|
||
</div>
|
||
))}
|
||
</div>
|
||
|
||
{/* Right Scroll Button */}
|
||
{showRightButton && (
|
||
<div
|
||
className="CategoryHorizontal-icon"
|
||
onClick={() => 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)',
|
||
}}
|
||
>
|
||
►
|
||
</div>
|
||
)}
|
||
</div>
|
||
{/* Selected brand products */}
|
||
<div style={{ marginTop: '1rem', overflow: 'auto' }}>
|
||
<h3 style={{ margin: '0 0 20px 0' }}>
|
||
{selectedBrand === 'Others' ? 'Others' : selectedBrand}{' '}
|
||
Products
|
||
</h3>
|
||
<ul
|
||
className="webkit-ul"
|
||
style={{
|
||
listStyle: 'none',
|
||
padding: 0,
|
||
display: 'flex',
|
||
flexWrap: 'wrap',
|
||
gap: '1rem',
|
||
}}
|
||
>
|
||
{(brandGroups[selectedBrand] || []).map(
|
||
(product, index) => {
|
||
const qtyCount = returnQtyCount(
|
||
product?.ProdId,
|
||
product,
|
||
CartOrderDetails
|
||
);
|
||
const isAvailable = product?.StockAvailable !== 'Y';
|
||
const isDisabled = qtyCount > 0 || isAvailable;
|
||
|
||
return (
|
||
<div key={`${product?.brandId}-${index}`}>
|
||
<div
|
||
style={{ position: 'relative' }}
|
||
className={
|
||
isDisabled
|
||
? 'ItemQtyCard'
|
||
: 'ItemQtyCard-disabled'
|
||
}
|
||
onClick={() => VarientFun(product)}
|
||
>
|
||
<div className="ItemQtyImgCard">
|
||
<img
|
||
src={product?.ProdLogo || defaultimage}
|
||
width={'80px'}
|
||
height={'70px'}
|
||
alt={`Product ${index}`}
|
||
/>
|
||
</div>
|
||
<div
|
||
className={
|
||
cardFunction?.BigImage
|
||
? 'BSItemCard-badge'
|
||
: 'BSItemCard-badge-withoutimage'
|
||
}
|
||
>
|
||
<Badge
|
||
count={qtyCount}
|
||
overflowCount={10000}
|
||
></Badge>
|
||
</div>
|
||
|
||
<div className="qtyDetail">
|
||
<p className="qtyUomName-itemCard">
|
||
{product?.Size + ' ' + product?.UomName}
|
||
</p>
|
||
{!isDisabled && (
|
||
<p
|
||
style={{
|
||
color: 'red',
|
||
fontSize: '12',
|
||
textAlign: 'center',
|
||
fontWeight: '600',
|
||
}}
|
||
>
|
||
No Stock
|
||
</p>
|
||
)}
|
||
{isDisabled && (
|
||
<p className="qtyprice">
|
||
<sup style={{ fontFamily: 'Gilroy' }}>
|
||
₹
|
||
</sup>
|
||
|
||
{safeRound(
|
||
product?.ProdVariantDetails?.[0]
|
||
?.StockDetails?.[0]?.SellPrice
|
||
)}
|
||
</p>
|
||
)}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
)}
|
||
</ul>
|
||
</div>
|
||
|
||
{Object.keys(brandMapping).length === 0 && (
|
||
<p>No product details available</p>
|
||
)}
|
||
</div>
|
||
</div>
|
||
}
|
||
/>
|
||
)}
|
||
{/* {modelstock && (
|
||
<DefaultModal
|
||
title={
|
||
<div className="EditQuantity-title">
|
||
<FormHeader title={'Item Stock'} />
|
||
</div>
|
||
}
|
||
open={modelstock}
|
||
// width={500}
|
||
footer={null}
|
||
top={0}
|
||
handleCancel={CloseModal1}
|
||
maskTransitionName=""
|
||
transitionName=""
|
||
children={
|
||
<div>
|
||
<div
|
||
className="EditQuantity-heading"
|
||
style={{
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
marginBottom: '3rem',
|
||
alignItems: 'start',
|
||
}}
|
||
>
|
||
<div style={{ display: 'flex' }}>
|
||
<div className="EditQuantity-headingname">
|
||
<p className="EditQuantity-itemname">Item Name:</p>
|
||
</div>
|
||
<div
|
||
className="EditQuantity-headingproductname"
|
||
style={{ marginLeft: '1rem' }}
|
||
>
|
||
<p className="EditQuantity-productname">
|
||
{qtydata?.ProdName}{' '}
|
||
{!qtydata?.ProductDetail?.[
|
||
QtyIndex
|
||
]?.ProdVariantDetails?.[
|
||
VarientIndex
|
||
]?.ProdVariantName?.toLowerCase()?.includes('variant')
|
||
&& (
|
||
<span>
|
||
(
|
||
{
|
||
qtydata?.ProductDetail?.[QtyIndex]
|
||
?.ProdVariantDetails?.[VarientIndex]
|
||
?.ProdVariantName
|
||
}
|
||
){' '}
|
||
</span>
|
||
)}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div style={{ display: 'flex' }}>
|
||
<div className="EditQuantity-headingname">
|
||
<p className="EditQuantity-itemname">Item Unit:</p>
|
||
</div>
|
||
<div
|
||
className="EditQuantity-headingproductname"
|
||
style={{ marginLeft: '1rem' }}
|
||
>
|
||
<p className="EditQuantity-productname">
|
||
{qtydata?.ProductDetail?.[QtyIndex]?.Size}{' '}
|
||
{onePeiceFlow
|
||
? 'PCS'
|
||
: qtydata?.ProductDetail?.[QtyIndex]?.UomName}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div className="Re-Print-table">
|
||
<Tables columns={stockcolumns} data={stockdataSource} />
|
||
</div>
|
||
</div>
|
||
}
|
||
/>
|
||
)} */}
|
||
{ModalVarient && (
|
||
<DefaultModal
|
||
// title={
|
||
// <div className="EditQuantity-title">
|
||
// <FormHeader title={AvailableDate ? "Slots" : 'Item Variant'} />
|
||
// </div>
|
||
// }
|
||
width={'97vw'}
|
||
open={ModalVarient}
|
||
key={refreshKey}
|
||
// width={"90vw"}
|
||
className={'bookingModalBulk'}
|
||
top={0}
|
||
footer={null}
|
||
handleCancel={CloseVarientModal}
|
||
maskTransitionName=""
|
||
transitionName=""
|
||
children={
|
||
// isBulk ? (
|
||
<>
|
||
<div className="bulk-slot-table">
|
||
{/* Slot header */}
|
||
<div className="SportsSlotHeader">
|
||
<div className="SportsSlotHeader1">
|
||
<BranchName IconStatus={true} />
|
||
</div>
|
||
<div className="SportsSlotHeader2">
|
||
{currentActiveOffer && (
|
||
<div className="membershipSummaryOneLine">
|
||
{currentActiveOffer?.MemberName || '-'} |
|
||
{formatDate(currentActiveOffer?.PlanStartDate)} -{' '}
|
||
{formatDate(currentActiveOffer?.PlanEndDate)} | Hrs:{' '}
|
||
{currentActiveOffer?.RemainingSessionHrs || 0} | Off:{' '}
|
||
{currentActiveOffer?.Discount
|
||
? `${currentActiveOffer.Discount}${currentActiveOffer.DiscountType === 'P' ? '%' : ''}`
|
||
: '0%'}
|
||
</div>
|
||
)}{' '}
|
||
{/* <MembershipCard MembershipDetail={selOption?.MembershipDetail} selectedCustomer={selOption} showCard={selOption?.MembershipDetail?.length>0} /> */}
|
||
<BSCustomerSelect TopName={'navbar-top'} />
|
||
<BSNavBarAddUser />
|
||
</div>
|
||
</div>
|
||
{/* datepicker for slot */}
|
||
<div className="sportsubHeader">
|
||
<div className="sports-slot-toggle">
|
||
<button
|
||
className={`sports-toggle-btn ${activeMode === 'slot' ? 'active' : ''}`}
|
||
onClick={() => {
|
||
setActiveMode('slot');
|
||
}}
|
||
>
|
||
Slot
|
||
</button>
|
||
<button
|
||
className={`sports-toggle-btn ${activeMode === 'individual' ? 'active' : ''}`}
|
||
onClick={() => {
|
||
setActiveMode('individual');
|
||
}}
|
||
>
|
||
Individual
|
||
</button>
|
||
</div>
|
||
<DatePicker.RangePicker
|
||
format="DD/MMM/YYYY"
|
||
value={getDatePickerValue(selectedDate)}
|
||
disabledDate={(current) =>
|
||
current && current < dayjs().startOf('day')
|
||
}
|
||
onChange={(dates) => {
|
||
if (!dates) {
|
||
// User hit clear, so set today's date range
|
||
const today = dayjs();
|
||
setSelectedDate([today, today]); // or today → tomorrow, if you prefer
|
||
return;
|
||
}
|
||
setSelectedDate(dates);
|
||
}}
|
||
/>
|
||
<button
|
||
className={`corner-selection-btn ${selectionMode ? 'active' : ''}`}
|
||
onClick={() => setSelectionMode(!selectionMode)}
|
||
>
|
||
{selectionMode ? (
|
||
<>
|
||
Close
|
||
<IoClose size={20} />
|
||
</>
|
||
) : (
|
||
<>
|
||
Block
|
||
<MdBlock size={20} />
|
||
</>
|
||
)}
|
||
</button>
|
||
</div>
|
||
{/* Slot Split Section */}
|
||
<div className="slotSectionMain">
|
||
<div
|
||
className={`SlotSlideBTN ${currentSlotIndex === 0 ? 'disabled' : ''}`}
|
||
onClick={handleSlotPrev}
|
||
>
|
||
<FaAngleLeft />
|
||
</div>
|
||
<div className="SlideSlotMain">
|
||
{draggableCardData
|
||
?.slice(
|
||
currentSlotIndex,
|
||
currentSlotIndex + visibleSlots
|
||
)
|
||
.map((product, productIndex) => {
|
||
// Get all variants for this specific product from modalVarientData
|
||
const noIndividualSlots =
|
||
product?.ProductDetail?.[0]?.ProdVariantDetails?.every(
|
||
(variant) => variant?.OnePcsPrice === 0
|
||
);
|
||
return (
|
||
<div
|
||
key={
|
||
product?.id || currentSlotIndex + productIndex
|
||
}
|
||
className={`slotproductName ${activeMode === 'individual' && noIndividualSlots ? 'hide' : ''}`}
|
||
>
|
||
{/* <p className="slotGroundName">
|
||
{product?.ProdName}
|
||
</p> */}
|
||
<div
|
||
key={currentSlotIndex + productIndex}
|
||
className="bookingSportSlot"
|
||
>
|
||
<p className="slotGroundName">
|
||
{' '}
|
||
{product?.ProdName}
|
||
</p>
|
||
<div className="slotTimingSelectMain">
|
||
{product?.ProductDetail?.[0]
|
||
?.ProdVariantDetails?.length > 0 ? (
|
||
Object?.entries(
|
||
product?.ProductDetail?.[0]?.ProdVariantDetails?.reduce(
|
||
(acc, timeSlot) => {
|
||
// Extract date (for example, from AvailableFrom or TempDate)
|
||
const dateKey = dayjs(
|
||
timeSlot?.TempDate
|
||
)?.format('YYYY-MM-DD');
|
||
|
||
if (!acc[dateKey]) acc[dateKey] = [];
|
||
acc[dateKey].push(timeSlot);
|
||
return acc;
|
||
},
|
||
{}
|
||
) || {}
|
||
)?.map(([date, slots]) => (
|
||
<div
|
||
key={date}
|
||
className="date-slot-group"
|
||
>
|
||
{/* Common date header */}
|
||
<div className="slot-date-header">
|
||
{dayjs(date).format('DD MMM YYYY')}
|
||
</div>
|
||
|
||
<div className="slotTimingSelectMain">
|
||
{slots.map((timeSlot, idx) => {
|
||
const isBooked =
|
||
timeSlot?.SlotStatus?.toLowerCase() ==
|
||
'booked' || false;
|
||
const isBlocked =
|
||
timeSlot?.SlotStatus?.toLowerCase() ==
|
||
'blocked' || false;
|
||
const isPartiallyBooked =
|
||
timeSlot?.SlotStatus?.toLowerCase() ===
|
||
'partially booked' || false;
|
||
const isPartiallyBlocked =
|
||
timeSlot?.SlotStatus?.toLowerCase() ===
|
||
'partially blocked' || false;
|
||
|
||
const isSelected =
|
||
CartOrderDetails?.some(
|
||
(selected) =>
|
||
selected.ProdId ===
|
||
timeSlot?.ProdId &&
|
||
selected.InwardDtlId ===
|
||
timeSlot?.InwardDtlId &&
|
||
selected.VariantAvailableFrom ===
|
||
timeSlot?.VariantAvailableFrom &&
|
||
selected.VariantAvailableTo ===
|
||
timeSlot?.VariantAvailableTo &&
|
||
selected.BookedDate ===
|
||
timeSlot?.BookedDate
|
||
);
|
||
|
||
const isAlreadyAdded =
|
||
CartOrderDetails?.some((item) => {
|
||
const itemDate =
|
||
item?.BookedDate
|
||
? new Date(
|
||
item?.BookedDate
|
||
).toLocaleDateString()
|
||
: null;
|
||
|
||
return (
|
||
item?.InwardDtlId ===
|
||
timeSlot?.InwardDtlId &&
|
||
item?.VariantAvailableFrom ===
|
||
timeSlot?.VariantAvailableFrom &&
|
||
item?.VariantAvailableTo ===
|
||
timeSlot?.VariantAvailableTo &&
|
||
item?.ProdVariantName?.toLowerCase() ===
|
||
timeSlot?.VarientName?.toLowerCase() &&
|
||
itemDate === dataDate &&
|
||
(item?.SinglePc === 'Y'
|
||
? returnVariantStock(
|
||
data,
|
||
CartOrderDetails
|
||
) === 0
|
||
: true)
|
||
);
|
||
});
|
||
const slotDateTime = new Date(
|
||
`${timeSlot?.BookedDate?.split('T')[0]}T${timeSlot?.AvailableFrom}`
|
||
);
|
||
const now = new Date();
|
||
const isPast = slotDateTime >= now;
|
||
const BlockSelectedSlots =
|
||
selectedSlots?.some(
|
||
(selected) =>
|
||
selected.InwardDtlId ===
|
||
timeSlot?.InwardDtlId &&
|
||
selected.VariantAvailableFrom ===
|
||
timeSlot?.VariantAvailableFrom &&
|
||
selected.VariantAvailableTo ===
|
||
timeSlot?.VariantAvailableTo &&
|
||
selected.TempDate ===
|
||
timeSlot?.BookedDate
|
||
);
|
||
const isDisabled =
|
||
isBooked ||
|
||
(isBlocked && !isSelected);
|
||
const slotEnded =
|
||
new Date(
|
||
`${timeSlot?.BookedDate?.split('T')[0]}T${timeSlot?.AvailableTo}`
|
||
) <= new Date();
|
||
|
||
return (
|
||
<div
|
||
key={idx}
|
||
className={`slotTimingSelect ${
|
||
isBooked
|
||
? 'booked'
|
||
: isAlreadyAdded
|
||
? 'incart'
|
||
: isPartiallyBooked
|
||
? 'partial'
|
||
: isBlocked &
|
||
!isSelected ||
|
||
slotEnded
|
||
? 'blocked'
|
||
: isBlocked ||
|
||
isSelected ||
|
||
isPartiallyBlocked ||
|
||
isSelected
|
||
? 'selected'
|
||
: BlockSelectedSlots
|
||
? 'blocked'
|
||
: 'available'
|
||
} ${timeSlot?.OnePcsPrice <= 0 && activeMode === 'individual' ? 'hide' : ''}`}
|
||
// ${isSelected ? 'selected' : ''}
|
||
disabled={isDisabled}
|
||
onClick={(e) => {
|
||
if (
|
||
!isBooked &&
|
||
!isDisabled &&
|
||
!onePeiceFlow
|
||
) {
|
||
!(
|
||
onePeiceFlow ||
|
||
isPartiallyBooked ||
|
||
isPartiallyBlocked
|
||
) &&
|
||
!selectionMode &&
|
||
handleSlotButtonClick(
|
||
timeSlot,
|
||
product,
|
||
onePeiceFlow ||
|
||
isPartiallyBooked,
|
||
!slotEnded
|
||
);
|
||
}
|
||
}}
|
||
>
|
||
<div className="slot-header">
|
||
{to12Hour(
|
||
timeSlot?.AvailableFrom
|
||
)}{' '}
|
||
-{' '}
|
||
{to12Hour(
|
||
timeSlot?.AvailableTo
|
||
)}
|
||
</div>
|
||
<div className="slot-price">
|
||
₹
|
||
{onePeiceFlow ||
|
||
isPartiallyBooked
|
||
? timeSlot?.OnePcsPrice
|
||
: timeSlot?.SellPrice || 0}
|
||
</div>
|
||
<div className="slotBTNquantity">
|
||
{(onePeiceFlow ||
|
||
isPartiallyBooked ||
|
||
isPartiallyBlocked) &&
|
||
!isBooked &&
|
||
!isBlocked &&
|
||
!slotEnded && (
|
||
<>
|
||
<button
|
||
className="slotBTNquantity-decrease"
|
||
onClick={(e) => {
|
||
handleRemoveSingle(
|
||
timeSlot,
|
||
product,
|
||
true
|
||
);
|
||
}}
|
||
// disabled={returnVariantStock(timeSlot, CartOrderDetails) === (parseInt(timeSlot?.TotalSlotQty) - timeSlot?.BookedQty)}
|
||
disabled={
|
||
!CartOrderDetails?.some(
|
||
(selected) =>
|
||
selected.ProdId ===
|
||
timeSlot.ProdId &&
|
||
selected.InwardDtlId ===
|
||
timeSlot.InwardDtlId &&
|
||
selected.VariantAvailableFrom ===
|
||
timeSlot.VariantAvailableFrom &&
|
||
selected.VariantAvailableTo ===
|
||
timeSlot.VariantAvailableTo &&
|
||
selected.BookedDate ===
|
||
timeSlot.BookedDate
|
||
)
|
||
}
|
||
icon={
|
||
<PlusOutlined />
|
||
}
|
||
>
|
||
{' '}
|
||
<LuMinus />{' '}
|
||
</button>
|
||
{returnVariantStock(
|
||
timeSlot,
|
||
CartOrderDetails
|
||
)}
|
||
Avl
|
||
<button
|
||
className="slotBTNquantity-increase"
|
||
onClick={() => {
|
||
handleSingleSlotIncrease(
|
||
timeSlot,
|
||
product,
|
||
true
|
||
);
|
||
}}
|
||
icon={
|
||
<PlusOutlined />
|
||
}
|
||
disabled={
|
||
returnVariantStock(
|
||
timeSlot,
|
||
CartOrderDetails
|
||
) <= 0
|
||
}
|
||
>
|
||
{' '}
|
||
<FiPlus
|
||
size={17}
|
||
/>{' '}
|
||
</button>
|
||
</>
|
||
)}
|
||
</div>
|
||
{selectionMode &&
|
||
!isBlocked &&
|
||
!isBooked &&
|
||
!slotEnded && (
|
||
<input
|
||
type="checkbox"
|
||
checked={
|
||
BlockSelectedSlots ||
|
||
false
|
||
}
|
||
onChange={(e) =>
|
||
handleSlotSelection(
|
||
e,
|
||
timeSlot
|
||
)
|
||
}
|
||
/>
|
||
)}
|
||
|
||
{(timeSlot?.SlotStatus ===
|
||
'Partially Booked' ||
|
||
timeSlot?.SlotStatus ===
|
||
'Booked') && (
|
||
<div
|
||
onClick={(e) => {
|
||
e.stopPropagation();
|
||
handleBookedDetails({
|
||
...timeSlot,
|
||
ProdName:
|
||
product
|
||
?.ProductDetail?.[0]
|
||
?.ProdName,
|
||
ProdSubCatName:
|
||
product?.ProdSubCatName,
|
||
});
|
||
}}
|
||
>
|
||
<span className="slot-booked">
|
||
{timeSlot?.SlotStatus}
|
||
</span>
|
||
</div>
|
||
)}
|
||
</div>
|
||
);
|
||
})}
|
||
</div>
|
||
</div>
|
||
))
|
||
) : (
|
||
<div
|
||
style={{
|
||
color: 'red',
|
||
textAlign: 'center',
|
||
marginTop: '10px',
|
||
fontWeight: 600,
|
||
}}
|
||
>
|
||
No Slots Available
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
})}
|
||
</div>
|
||
<div
|
||
className={`SlotSlideBTN ${currentSlotIndex >= maxIndex ? 'disabled' : ''}`}
|
||
onClick={handleSlotNext}
|
||
>
|
||
<FaAngleRight />
|
||
</div>
|
||
</div>
|
||
|
||
{/* Select All and Submit buttons for bulk mode */}
|
||
<div className="bulk-actions">
|
||
<div className="bulk-submit-btn">
|
||
{selectionMode && selectedSlots?.length > 0 && (
|
||
<div className="selection-submit-container">
|
||
<button
|
||
className="selection-submit-btn"
|
||
onClick={handleSubmitBlockSlots}
|
||
>
|
||
<span className="submit-count">
|
||
{selectedSlots.length}
|
||
</span>
|
||
Submit Selected
|
||
</button>
|
||
</div>
|
||
)}
|
||
|
||
{CartOrderDetails.length > 0 && !selectionMode && (
|
||
<button onClick={handleSubmitSelectedSlots}>
|
||
Add {CartOrderDetails.length} Selected Slots to Cart
|
||
</button>
|
||
)}
|
||
</div>
|
||
</div>
|
||
|
||
{/* Status Legend */}
|
||
<div className="Slot-status">
|
||
<div className="Slot-status-div">
|
||
<span className="available"> </span> Available
|
||
</div>
|
||
<div className="Slot-status-div">
|
||
<span className="booked"> </span> Booked
|
||
</div>
|
||
<div className="Slot-status-div">
|
||
<span className="IsinCart"> </span> Blocked
|
||
</div>
|
||
<div className="Slot-status-div">
|
||
<span className="Single"> </span> Partial Available
|
||
</div>
|
||
<div className="Slot-status-div">
|
||
<span className="selected-indicator"> </span> Selected
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<DefaultModal
|
||
width={700}
|
||
open={bookedDetails}
|
||
className={'booked-slot-details-modal'}
|
||
footer={null}
|
||
handleCancel={() => {
|
||
setSelectedSlotDetails(null);
|
||
setBookedDetails(false);
|
||
}}
|
||
children={
|
||
<>
|
||
<div className="booked-details-container">
|
||
<h3 className="booked-details-title">
|
||
Booking Details
|
||
</h3>
|
||
<div className="booked-slot-info">
|
||
<div className="info-row">
|
||
<span className="info-label">Slot:</span>
|
||
<span className="info-value">
|
||
{`${selectedSlotDetails?.ProdSubCatName ? selectedSlotDetails?.ProdSubCatName + ' - ' : ''}` +
|
||
'(' +
|
||
selectedSlotDetails?.ProdName +
|
||
')'}
|
||
</span>
|
||
</div>
|
||
<div className="info-row">
|
||
<span className="info-label">Time:</span>
|
||
<span className="info-value">
|
||
{to12Hour(selectedSlotDetails?.AvailableFrom)} -{' '}
|
||
{to12Hour(selectedSlotDetails?.AvailableTo)}
|
||
</span>
|
||
</div>
|
||
<div className="info-row">
|
||
<span className="info-label">Date:</span>
|
||
<span className="info-value">
|
||
{dayjs(selectedSlotDetails?.BookedDate)?.format(
|
||
'DD MMM YYYY'
|
||
)}
|
||
</span>
|
||
</div>
|
||
<div className="info-row">
|
||
<span className="info-label">Total Slots:</span>
|
||
<span className="info-value">
|
||
{selectedSlotDetails?.TotalSlotQty}
|
||
</span>
|
||
</div>
|
||
<div className="info-row">
|
||
<span className="info-label">Booked:</span>
|
||
<span className="info-value">
|
||
{selectedSlotDetails?.BookedQty}
|
||
</span>
|
||
</div>
|
||
<div className="info-row">
|
||
<span className="info-label">Status:</span>
|
||
<span className="info-value status-badge">
|
||
{selectedSlotDetails?.SlotStatus}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
<h4 className="customer-details-title">
|
||
Customer Details
|
||
</h4>
|
||
<div className="customer-table-wrapper">
|
||
<table className="customer-details-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Customer Name</th>
|
||
<th>Mobile</th>
|
||
<th>Actions</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{selectedSlotDetails?.CustomerDetails?.map(
|
||
(customer, index) => {
|
||
const slotDateTime = new Date(
|
||
`${selectedSlotDetails?.BookedDate.split('T')[0]}T${selectedSlotDetails?.AvailableFrom}`
|
||
);
|
||
const slotDateTimeTo = new Date(
|
||
`${selectedSlotDetails?.BookedDate.split('T')[0]}T${selectedSlotDetails?.AvailableTo}`
|
||
);
|
||
const now = new Date();
|
||
const isPast = slotDateTime >= now;
|
||
const isFuture = slotDateTimeTo <= now;
|
||
|
||
return (
|
||
<tr key={index}>
|
||
<td>{customer.CustName || 'N/A'}</td>
|
||
<td>{customer.CustMobile || 'N/A'}</td>
|
||
<td className="action-buttons">
|
||
{customer?.CustBookDetails?.length >
|
||
1 ? (
|
||
<button
|
||
className="show-all-btn"
|
||
onClick={() =>
|
||
handleShowAllBookings(customer)
|
||
}
|
||
>
|
||
Show All (
|
||
{customer.CustBookDetails.length})
|
||
</button>
|
||
) : customer?.CustBookDetails
|
||
?.length === 1 ? (
|
||
<>
|
||
<button
|
||
className="start-btn"
|
||
disabled={
|
||
customer.CustBookDetails[0]
|
||
.StartTime || isPast
|
||
}
|
||
onClick={() =>
|
||
handleSlotTimeUpdate(
|
||
customer.CustBookDetails[0],
|
||
customer?.BookingDate,
|
||
'start'
|
||
)
|
||
}
|
||
>
|
||
Start
|
||
</button>
|
||
<button
|
||
className="end-btn"
|
||
disabled={
|
||
!customer.CustBookDetails[0]
|
||
.StartTime ||
|
||
customer.CustBookDetails[0]
|
||
.EndTime ||
|
||
isPast
|
||
}
|
||
onClick={() =>
|
||
handleSlotTimeUpdate(
|
||
customer.CustBookDetails[0],
|
||
customer?.BookingDate,
|
||
'end'
|
||
)
|
||
}
|
||
>
|
||
End
|
||
</button>
|
||
</>
|
||
) : (
|
||
<span>No Bookings</span>
|
||
)}
|
||
</td>
|
||
</tr>
|
||
);
|
||
}
|
||
)}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
<DefaultModal
|
||
width={800}
|
||
open={showAllBookingsModal}
|
||
className={'all-bookings-modal'}
|
||
footer={null}
|
||
handleCancel={() => {
|
||
setShowAllBookingsModal(false);
|
||
setSelectedCustomerBookings(null);
|
||
}}
|
||
children={
|
||
<div className="all-bookings-container">
|
||
<h3 className="all-bookings-title">
|
||
{selectedCustomerBookings?.CustName ||
|
||
selectedCustomerBookings?.CustMobile}
|
||
's Bookings
|
||
</h3>
|
||
{selectedCustomerBookings?.CustMobile && (
|
||
<p className="customer-mobile">
|
||
Mobile: {selectedCustomerBookings?.CustMobile}
|
||
</p>
|
||
)}
|
||
<div className="bookings-table-wrapper">
|
||
<table className="bookings-details-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Booked By</th>
|
||
<th>Booked Date</th>
|
||
<th>Start Time</th>
|
||
<th>End Time</th>
|
||
<th>Actions</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{selectedCustomerBookings?.CustBookDetails?.map(
|
||
(booking, index) => (
|
||
<tr key={index}>
|
||
<td>{booking.BookedBy || 'N/A'}</td>
|
||
<td>
|
||
{booking.CreatedDate
|
||
? dayjs(booking.CreatedDate).format(
|
||
'DD MMM YYYY hh:mm A'
|
||
)
|
||
: 'N/A'}
|
||
</td>
|
||
<td>
|
||
{booking.StartTime
|
||
? dayjs(booking.StartTime).format(
|
||
'hh:mm A'
|
||
)
|
||
: '-'}
|
||
</td>
|
||
<td>
|
||
{booking.EndTime
|
||
? dayjs(booking.EndTime).format(
|
||
'hh:mm A'
|
||
)
|
||
: '-'}
|
||
</td>
|
||
<td className="action-buttons">
|
||
<button
|
||
className="start-btn"
|
||
disabled={booking.StartTime}
|
||
onClick={() =>
|
||
handleSlotTimeUpdate(
|
||
booking,
|
||
selectedCustomerBookings?.BookingDate,
|
||
'start'
|
||
)
|
||
}
|
||
>
|
||
Start
|
||
</button>
|
||
<button
|
||
className="end-btn"
|
||
disabled={
|
||
!booking.StartTime ||
|
||
booking.EndTime
|
||
}
|
||
onClick={() =>
|
||
handleSlotTimeUpdate(
|
||
booking,
|
||
selectedCustomerBookings?.BookingDate,
|
||
'end'
|
||
)
|
||
}
|
||
>
|
||
End
|
||
</button>
|
||
</td>
|
||
</tr>
|
||
)
|
||
)}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
}
|
||
/>
|
||
</>
|
||
}
|
||
/>
|
||
</>
|
||
}
|
||
/>
|
||
)}
|
||
</>
|
||
);
|
||
|
||
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(BsBookingitemCard);
|