import { useCallback, useEffect, useRef, useState } from 'react'; import { useDispatch } from 'react-redux'; import dayjs from 'dayjs'; import { Form, DatePicker } from 'antd'; import { DropDowns } from '../../Components/Forms/DropDown'; import { Messages } from '../../Components/Notifications/Messages'; import FormHeader from '../PageComponents/FormHeader'; import { InputField } from '../../Components/Forms/InputField'; import { BiSearchAlt } from "react-icons/bi"; import { getRescheduleSlot, getSlotReschedule } from '../../Features/BookingScreen/BookingData/BookingData'; import { getSession } from '../../Services/Others'; import { postRescheduleSlot } from '../../Features/CancelReschedule/CancelApplicableProd'; import "../../Styles/CancelReschedule/BookingRechedule.scss" import { DatePicProd } from "../../Components/Forms/DatePickerProduct"; import { useNavigate } from "react-router-dom"; import { FaEye } from "react-icons/fa"; import Buttons from "../../Components/Forms/Buttons"; import { ArrowRightOutlined } from '@ant-design/icons'; import { changeBreadCrumb } from '../../Features/AppPage/CenterPage'; const SEARCH_OPTIONS = [ { label: 'Bill No', value: 'Bill No' }, { label: 'Date', value: 'Date' }, ]; const subDirectory = import.meta.env.ENV_BASE_URL; const breadcrumbItems = [ { name: "Home", link: `${subDirectory}app-page/home` }, { name: "Booking Reschedule", link: `${subDirectory}setting/booking-reschedule` }, { name: "List", link: `${subDirectory}setting/booking-reschedule/list` }, ]; const BookingReScedule = () => { const formRef = useRef(); const navigateTo = useNavigate(); const CompId = getSession('CompId'); const BranchId = getSession('BranchId'); const AppId = getSession('AppId'); const UserId = getSession('UserId'); const UserType = getSession('UserType'); const dispatch = useDispatch(); const [searchType, setSearchType] = useState('Bill No'); const [form, setForm] = useState({ BillNo: '', Date: '' }); const [messages, setMessage] = useState({ type: null, data: null }); const [billData, setBillData] = useState([]); const [selectedRowKey, setSelectedRowKey] = useState(null); const [productSlots, setProductSlots] = useState({}); const [selectedSlots, setSelectedSlots] = useState({}); const [dateSelections, setDateSelections] = useState({}); const handelNavigateToList = () => { navigateTo(`${subDirectory}setting/booking-reschedule/list`); }; useEffect(() => { dispatch(changeBreadCrumb({ items: breadcrumbItems })); }, []); const handleBillSelect = (orderId) => { setSelectedRowKey(orderId); setSelectedSlots({}); setDateSelections({}); setProductSlots({}); }; const handleSlotChange = (InwardDtlId, slot) => { if (slot.status === "booked" || slot.status === "blocked") return; setSelectedSlots(prev => ({ ...prev, customerSloteDtl: billData?.[0]?.productDetails?.[0], [InwardDtlId]: { SlotFrom: slot.from, SlotTo: slot.to, Rate: slot.amount, slotId: slot.id, SalesQty: slot.SalesQty, InwardDtlId: slot.InwardDtlId } })); }; const handleDateChange = async (item, date) => { const { ProdId, InwardDtlId, Type, Rate, TotalAmt, TaxAmt, SinglePc } = item; try { if (date) { const formattedDate = date.format('YYYY-MM-DD'); const Payload = { AppId, BranchId, CompId, prodId: ProdId, date: formattedDate }; const res = await dispatch(getSlotReschedule(Payload)).unwrap(); if (!res?.data?.data?.[0]?.ProductDetail) { throw new Error('No slot data available'); } const productDetails = res.data.data[0].ProductDetail; const variants = productDetails[0]?.ProdVariantDetails || []; const formattedSlots = variants.map((v, index) => { const stock = v.StockDetails?.[0] || {}; const available = Number(stock.TotalSlotQty || 0) - Number(stock.BookedQty || 0); let status = "available"; if (stock.SlotStatus === "Blocked") status = "blocked"; else if (available <= 0) status = "booked"; else if (available < Number(stock.TotalSlotQty)) status = "partial"; const amount = v.SinglePc === "Y" ? stock.OnePcsPrice || 0 : stock.SellPrice || 0; const slotInwardDtlId = stock?.InwardDtlId; return { id: index, name: v.ProdVariantName, InwardDtlId: slotInwardDtlId, from: v.AvailableFrom, to: v.AvailableTo, SalesQty: stock.SalesQty, amount, available, status, productSlotDetails: item }; }); // Store slots specific to this product setProductSlots(prev => ({ ...prev, [InwardDtlId]: formattedSlots })); // Store date selection for this product setDateSelections(prev => ({ ...prev, [InwardDtlId]: { ProdId, InwardDtlId, Type, Rate, TotalAmt, TaxAmt, SinglePc: SinglePc, RescheduleDate: formattedDate, } })); } else { // Remove date selection and slots for this product setDateSelections(prev => { const updated = { ...prev }; delete updated[InwardDtlId]; return updated; }); setSelectedSlots(prev => { const updated = { ...prev }; delete updated[InwardDtlId]; return updated; }); setProductSlots(prev => { const updated = { ...prev }; delete updated[InwardDtlId]; return updated; }); } } catch (error) { setMessage({ type: 'error', data: error?.message || 'An error occurred while fetching slot data' }); } }; const formatTime = (timeStr) => { if (!timeStr) return ""; const [hour, minute] = timeStr.split(":").map(Number); const period = hour >= 12 ? "PM" : "AM"; const formattedHour = hour % 12 || 12; return `${formattedHour}:${String(minute).padStart(2, '0')} ${period}`; }; const handleSearchTypeChange = (value) => { setSearchType(value); setForm({ BillNo: '', Date: '' }); setBillData([]); setSelectedRowKey(null); }; const handleInputChange = (name, value) => { setForm((prev) => ({ ...prev, [name]: value })); }; const handleSubmit = async () => { const formValues = formRef.current?.getFieldsValue(); const { BillNo, Date } = formValues; let date = null; if (Date !== undefined && Date) { date = Date.format('YYYY-MM-DD'); } const data = { segmentValue: searchType, date, AppId, CompId, BranchId, OrderId: searchType === 'Bill No' ? `O${AppId}-${CompId}-${BranchId}-${UserId}-${BillNo}` : undefined, }; try { const res = await dispatch(getRescheduleSlot(data)).unwrap(); if (res?.data?.statusCode === 1) { setBillData(res?.data?.data); if (res?.data?.data?.length === 1) { handleBillSelect(res?.data?.data?.[0]?.OrderId); } else { setSelectedRowKey(null); } } else { setBillData([]); setSelectedRowKey(null); setMessage({ type: 'error', data: res?.data?.response }); } } catch (error) { setBillData([]); setMessage({ type: 'error', data: error?.message || 'An error occurred while fetching data' }); } }; const onComplete = useCallback(() => { setMessage({ type: null, data: null }); }, []); const onFinishPost = async () => { const selectedDateKeys = Object.keys(dateSelections); if (!selectedDateKeys.length) { setMessage({ type: "error", data: "Please select a date for at least one item" }); return; } // Check if all selected dates have slots selected const hasUnselectedSlots = selectedDateKeys.some(key => !selectedSlots[key]); if (hasUnselectedSlots) { setMessage({ type: "error", data: "Please select time slots for all selected dates" }); return; } try { const orderData = billData.find(bill => bill.OrderId === selectedRowKey); const SalesId = orderData?.productDetails?.[0]?.SalesId; const PaymentStatus = orderData?.PaymentStatus; const salesQty = orderData?.productDetails?.[0]?.SalesQty; // Build payload only for products that have both date AND slot selected const RescheduleSlotsDtl = selectedDateKeys.map(key => { const dateInfo = dateSelections[key]; const slotInfo = selectedSlots[key]; return { ProdId: dateInfo.ProdId, InwardDtlId: slotInfo.InwardDtlId, Type: dateInfo.Type, Qty: salesQty, Rate: dateInfo.Rate, TotalAmt: dateInfo.TotalAmt, TaxAmt: dateInfo.TaxAmt, SinglePc: dateInfo.SinglePc, RescheduleDate: dateInfo.RescheduleDate, SlotFrom: slotInfo.SlotFrom, SlotTo: slotInfo.SlotTo }; }); const originalPayment = orderData?.OrderPaymentDtls?.[0] || {}; const Amount = RescheduleSlotsDtl.reduce((acc, item) => acc + (item.TotalAmt || 0), 0); const payload = { AppId, CompId, BranchId, OrderId: selectedRowKey, SalesId, RescheduleSlotsDtl, OrderPaymentDtl: [ { PaymentType: originalPayment.PaymentType, Amount, PaymentStatus, PaymentOptionType: originalPayment.PaymentOptionType } ], CreatedBy: UserId }; console.log('Payload being sent:', payload); const res = await dispatch(postRescheduleSlot(payload)).unwrap(); if (res?.data?.statusCode === 1) { setMessage({ type: "success", data: res?.data?.response || "Rescheduled successfully" }); setSelectedRowKey(null); formRef.current?.resetFields(); setDateSelections({}); setSelectedSlots({}); setBillData([]); setProductSlots({}); setSearchType("Bill No"); } else { setMessage({ type: "error", data: res?.data?.response || "Failed to reschedule" }); } } catch (error) { setMessage({ type: "error", data: error?.message || "An error occurred" }); } }; const getLabel = (value) => { const option = SEARCH_OPTIONS.find(opt => opt.value === value); return option ? option.label : ''; }; const handleSearch = () => { formRef.current?.submit(); }; const selectedProducts = billData ?.find(({ OrderId }) => OrderId === selectedRowKey) ?.productDetails || []; const hasDateSelections = Object.keys(dateSelections).length > 0; return (
Select your Bill:
Select Date to Reschedule
| Select Date | Facility | Name | Current Slot | Current Booking Slot | Current Date | Slot Qty | Rate |
|---|---|---|---|---|---|---|---|
|
|
{item.ProdCatName} | {item.ProdSubCatName} {item.ProdName} | {item.ProdVariantName} | {formatTime(item.AvailableFrom)} {formatTime(item.AvailableTo)} | {dayjs(item.BookingDate).format('DD/MM/YYYY')} | {item.SalesQty} | ₹{item.Rate} |
{dayjs(dateSelections[InwardDtlId].RescheduleDate).format('DD MMM YYYY')}
No slots available for this date
)}