From 25ee1333592edf40577febf2211f9ea03acff0dd Mon Sep 17 00:00:00 2001 From: Tamilselvan Date: Fri, 6 Feb 2026 12:56:38 +0530 Subject: [PATCH] chnaged --- src/Pages/StockMaster/StockList.jsx | 552 +++++++++++++++++++++++++--- src/Services/utils.js | 61 ++- 2 files changed, 557 insertions(+), 56 deletions(-) diff --git a/src/Pages/StockMaster/StockList.jsx b/src/Pages/StockMaster/StockList.jsx index e32cc5e..ad84da5 100644 --- a/src/Pages/StockMaster/StockList.jsx +++ b/src/Pages/StockMaster/StockList.jsx @@ -1,22 +1,27 @@ -import { useState, useEffect, useCallback } from 'react'; +import { useState, useEffect, useRef, useCallback } from 'react'; import { useNavigate, useLocation } from 'react-router-dom'; import { useDispatch, useSelector } from 'react-redux'; -import { PlusOutlined, EyeOutlined } from '@ant-design/icons'; -import { Image, Table } from 'antd'; +import { PlusOutlined, EyeOutlined, PrinterFilled } from '@ant-design/icons'; +import { Image, Pagination, Space, Table } from 'antd'; import { changeBreadCrumb, getEmpAccess, } from '../../Features/AppPage/CenterPage.js'; +import QRCode from 'qrcode'; import { Tables } from '../../Components/Tables/Table'; import FormHeader from '../PageComponents/FormHeader.jsx'; import Search from '../../Components/Forms/Search.jsx'; +import { style, getPageStyle } from '../Product/Printstyles.js'; import Buttons from '../../Components/Forms/Buttons'; import { getSession, dateFormatChange, ExtractDateFormate, + printDiv, } from '../../Services/Others'; import { Messages } from '../../Components/Notifications/Messages'; +import { useQuery, useQueryClient } from '@tanstack/react-query'; +import dayjs from 'dayjs'; import { getStockData, getProductData, @@ -45,8 +50,27 @@ import '../../Styles/Employee/EmpMaster.scss'; import { IoEye } from 'react-icons/io5'; import { useAuth } from '../../AuthContext.jsx'; import { getPreferenceData } from '../../Features/BookingScreen/BookingData/BookingData.js'; +import { + getBarcodeSessionsIDs, + getBarcodeTemplate, +} from '../../Features/Barcode/Barcode.js'; +import StickerPrintModel from '../Product/StickerPrintModal.jsx'; +import StickerPrintTemplates from '../Product/StickerTemplates.jsx'; +import QRCodeCopiesModal from '../Product/QRCodeCopiesModal.jsx'; +import { DatePicker } from 'antd'; +import { + generateBarcode, + generateCodeImage, + generateQRCode, + generateQRCodeCopy, +} from '../../Services/utils.js'; +const { RangePicker } = DatePicker; +const barCodeImage = + 'https://cdn.pixabay.com/photo/2014/04/02/16/19/barcode-306926_1280.png'; +const qrCodeImage = + 'https://cdn.pixabay.com/photo/2015/03/21/09/34/qr-683354_640.png'; const subDirectory = import.meta.env.BASE_URL; - +const previewText = 'Barcode Preview'; const items = [ { name: 'Home', @@ -59,6 +83,7 @@ const items = [ ]; const StockList = () => { + const formRef = useRef(); const { SadminuserAccess } = useAuth(); let SAAccessCommonMaster = SadminuserAccess?.find( (e) => e?.MenuName === 'Product Receipt' @@ -71,15 +96,15 @@ const StockList = () => { const AppId = getSession('AppId'); const UserId = getSession('UserId'); const UserType = getSession('UserType'); - + const [printReady, setPrintReady] = useState(false); const StockData = useSelector(purchaseDataSelector); + console.log(StockData, 'StockData'); const SupplierData = useSelector(supplierSelector); const excelDataValues = useSelector(excelDataSelector); const TaxData = useSelector(taxSelector); const [filteredInfo, setFilteredInfo] = useState({}); const [sortedInfo, setSortedInfo] = useState({}); - const [searchedText, setSearchedText] = useState(''); const [messageType, setMessageType] = useState(null); const [messageData, setMessageData] = useState(null); @@ -103,19 +128,58 @@ const StockList = () => { const [imageModal, setImageModal] = useState(false); const [currentImageIndex, setCurrentImageIndex] = useState(0); const [IMEISeriandata, setIMEISeriandata] = useState([]); + + const [base64Image, setBase64Image] = useState(null); + const [barcodeBase64Image, setBarcodeBase64Image] = useState(null); + const [dropdownValue, setDropdownValue] = useState(); + const [QrandbarcodeDatas, setQrandbarcodeDatas] = useState([]); + const [printProductName, setPrintProductName] = useState(false); + const [copies, setCopies] = useState(); + const [coresdata, setCoresdata] = useState([]); + const [barcodeTemplateDetails, setBarcodeTemplateDetails] = useState([]); + const [stockWiseQrcode, setstockWiseQrcode] = useState(false); + const [productWiseQrcode, setProductWiseQrcode] = useState(false); + const [selectedRecords, setSelectedRecords] = useState([]); + const [activeTab, setActiveTab] = useState('stock'); + const [MultiCode, setMultiCode] = useState(true); + const [TotalCount, setTotalCount] = useState(null); + const [dateStrings, setDateStrings] = useState([ + dayjs().format('YYYY-MM-DD'), + dayjs().format('YYYY-MM-DD'), + ]); + const [SearchText, setSearchText] = useState(null); + const [debouncedSearchText, setDebouncedSearchText] = useState(null); + + useEffect(() => { + const timer = setTimeout(() => { + setDebouncedSearchText(SearchText); + }, 500); + + return () => clearTimeout(timer); + }, [SearchText]); + console.log(QrandbarcodeDatas, 'QrandbarcodeDatas'); + const [templateOptions, setTemplateOptions] = useState({ + mrp: false, + barcode: false, + color: false, + eDate: false, + mDate: false, + sellingPrice: false, + productName: false, + value: '', + secondValue: '', + qrcode: false, + codeType: '', + }); + useEffect(() => { try { fetchData(); - // dispatch( - // getStockData({ CompId: CompId, BranchId: BranchId, AppId: AppId }) - // ).unwrap(); } catch (err) { console.log(err, 'err'); } getPreference(); - // if (UserType === "Employee") { - // fetchApi() - // } + getBarcodeSessionData(); }, []); useEffect(() => { @@ -154,6 +218,7 @@ const StockList = () => { useEffect(() => { dispatch(changeBreadCrumb({ items: items })); + barcodeApiData(); }, []); async function fetchData() { if (location?.state?.Notiffy) { @@ -161,7 +226,81 @@ const StockList = () => { setMessageData(location?.state?.Notiffy.messageData); } } + const fetchDataget = async ({ queryKey }) => { + const [_, dates, page] = queryKey; + const Response = await dispatch( + getPurchaseData({ + AppId: AppId, + BranchId: BranchId, + CompId: CompId, + OrderFromDate: dates?.[0] ?? '', + OrderToDate: dates?.[1] ?? '', + PageNumber: page, + }) + ).unwrap(); + if (Response?.data?.statusCode === 1) { + setTotalCount(Response?.data?.TotalCount); + return Response?.data?.data; + } else { + setTotalCount(0); + return []; + } + }; + const handleDateChange = (dates, dateStrings) => { + // setDateRange(dateStrings); + if (dateStrings[0] && dateStrings[1]) { + setDateStrings(dateStrings); + setpage(1); + } + }; + const { data, isLoading, error } = useQuery({ + queryKey: ['purchaseEntry', dateStrings, page], + queryFn: fetchDataget, + enabled: true, + staleTime: 1000 * 60 * 5, + cacheTime: 1000 * 60 * 30, + keepPreviousData: true, + refetchOnMount: 'always', + refetchOnWindowFocus: true, + refetchOnReconnect: true, + }); + const { data: countData } = useQuery({ + queryKey: ['searchPurchaseEntry', debouncedSearchText], + queryFn: searchData, + enabled: !!debouncedSearchText, + staleTime: 1000 * 60 * 5, + cacheTime: 1000 * 60 * 30, + keepPreviousData: true, + refetchOnMount: 'always', + refetchOnWindowFocus: true, + refetchOnReconnect: true, + }); + + const filteredData = debouncedSearchText ? countData || [] : data || []; + console.log(data, countData, '1111111111111111', filteredData); + async function searchData({ queryKey }) { + const [_, SearchText] = queryKey; + + const Response = await dispatch( + getPurchaseData({ + AppId: AppId, + BranchId: BranchId, + CompId: CompId, + OrderFromDate: dateStrings?.[0] ?? '', + OrderToDate: dateStrings?.[1] ?? '', + search: SearchText, + }) + ).unwrap(); + if (Response?.data?.statusCode === 1) { + setTotalCount(Response?.data?.TotalCount); + setpage(1); + return Response?.data?.data; + } else { + setTotalCount(0); + return []; + } + } const handleChange = (pagination, filters, sorter) => { setFilteredInfo(filters); setSortedInfo(sorter); @@ -172,10 +311,10 @@ const StockList = () => { }; const onSearch = (value) => { - setSearchedText(value); + setSearchText(e?.target?.value); }; const onSearchChange = (e) => { - setSearchedText(e?.target?.value); + setSearchText(e?.target?.value); }; const getPreference = async () => { const data = { AppId: AppId, CompId: CompId, BranchId: BranchId }; @@ -243,6 +382,40 @@ const StockList = () => { return allowDecimal ? num.toFixed(2) : Math.round(num).toString(); } + const QrandBarcodeDats = async (ProdDetails) => { + const result = await Promise.all( + ProdDetails.map(async (item) => { + const data = await QRCode.toDataURL(item.QRCode); + + return { + key: item.QRCode, + url: data, + productName: item.ProdName, + copiesCount: item.AcceptedQty, + StockAvailable: item.StockAvailable, + }; + }) + ); + + setQrandbarcodeDatas((prev) => [...prev, ...result]); + }; + + const Qrcode = (record) => { + setSelectedRecords(record?.ProdDetails); + QrandBarcodeDats(record?.ProdDetails); + setOpen(true); + }; + const barcodeApiData = async () => { + const getResponse = await dispatch( + getBarcodeTemplate({ compId: CompId, appId: AppId, branchId: BranchId }) + ).unwrap(); + if (getResponse?.data?.statusCode === 1) { + if (getResponse?.data?.data?.length > 0) { + const { TemplateDetails } = getResponse?.data?.data?.[0]; + setBarcodeTemplateDetails(TemplateDetails); + } + } + }; const columns = [ { title: 'Sl.No', @@ -264,13 +437,6 @@ const StockList = () => { {extractLastNumberOrderId(text, row?.FYStatus)} ), - filteredValue: [searchedText], - onFilter: (value, record) => { - return extractLastNumberOrderId(record.InvoiceNo, record?.FYStatus) - ?.toString() - .toLowerCase() - .includes(value.toLowerCase()); - }, }, { title: 'Invoice Amount', @@ -341,6 +507,29 @@ const StockList = () => { } }, }, + { + title: 'Print', + key: 'Print', + dataIndex: 'Print', + width: '100px', + align: 'center', + render: (_, record) => ( + // productData.length >= 1 ? ( + + {record?.ProdDetails?.some((item) => item?.QRCode != null) ? ( + + Qrcode(record)} + /> + + ) : ( + '-' + )} + + ), + // ) : null, + }, ]; const Proddetailcolumns = [ { @@ -475,11 +664,41 @@ const StockList = () => { navigate(`${subDirectory}setting/purchase-entry/new`); }; //------------------------------------------------------------------------------------------------------------------------------ - + const getBarcodeSessionData = async () => { + try { + let resp = await dispatch(getBarcodeSessionsIDs()).unwrap(); + if (resp?.data?.statusCode === 1) { + setCoresdata( + resp?.data?.data?.filter( + (item) => !item.ConfigName?.includes('100X13 (55MM Printable Gold)') + ) || [] + ); + } else { + setCoresdata([]); + } + } catch (error) { + console.error('Error fetching barcode session data:', error); + } + }; useEffect(() => { Bulkuploadsubdata(); }, []); + const imageUrlToBase64 = async (url) => { + try { + const response = await fetch(url); + const blob = await response.blob(); + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onloadend = () => resolve(reader.result); + reader.onerror = reject; + reader.readAsDataURL(blob); + }); + } catch (error) { + console.error('Error fetching or converting image:', error); + throw error; + } + }; const Bulkuploadsubdata = async () => { dispatch( getSupplierData({ AppId: AppId, BranchId: BranchId, CompId: CompId }) @@ -675,25 +894,25 @@ const StockList = () => { PaymentAmount: PaymentAmount.toFixed(2), InvoiceDate: groupInfo.InwardDate ? moment(groupInfo.InwardDate, 'YYYY-MM-DD').format( - 'YYYY-MM-DDTHH:mm:ss' - ) + 'YYYY-MM-DDTHH:mm:ss' + ) : null, SuppInvoiceNo: groupInfo.SupplierInvoiceNumber, SuppInvoiceDate: groupInfo.SupplierInvoiceDate ? moment(groupInfo.SupplierInvoiceDate, 'YYYY-MM-DD').format( - 'YYYY-MM-DDTHH:mm:ss' - ) + 'YYYY-MM-DDTHH:mm:ss' + ) : null, DeliveryChallanNo: groupInfo.DeliveryChallanNo, DeliveryInvoiceDate: groupInfo.DeliveryInvoiceDate ? moment(groupInfo.DeliveryInvoiceDate, 'YYYY-MM-DD').format( - 'YYYY-MM-DDTHH:mm:ss' - ) + 'YYYY-MM-DDTHH:mm:ss' + ) : null, DueDate: groupInfo.DueDate ? moment(groupInfo.DueDate, 'YYYY-MM-DD').format( - 'YYYY-MM-DDTHH:mm:ss' - ) + 'YYYY-MM-DDTHH:mm:ss' + ) : null, InvoiceAmount: Totalamount.toFixed(2), TaxAmount: Totaltax.toFixed(2), @@ -711,13 +930,13 @@ const StockList = () => { FreeQty: item.FreeQty, ManufDate: item.ManufactureDate ? moment(item.ManufactureDate, 'YYYY-MM-DD').format( - 'YYYY-MM-DDTHH:mm:ss' - ) + 'YYYY-MM-DDTHH:mm:ss' + ) : null, ExpDate: item.ExpireDate ? moment(item.ExpireDate, 'YYYY-MM-DD').format( - 'YYYY-MM-DDTHH:mm:ss' - ) + 'YYYY-MM-DDTHH:mm:ss' + ) : null, BatchNo: item.BatchNo, ModelNo: item.ModelNo, @@ -727,7 +946,7 @@ const StockList = () => { SellPrice: item.SalesPrice, OnePcsPrice: item.AmountPerPiece, NoOfPcs: item.NumberofPieceInside, - WhSalePrice: item.WholesalePrice + WhSalePrice: item.WholesalePrice, })), }; }); @@ -759,7 +978,17 @@ const StockList = () => { setMessageData('No data to submit. Please upload an Excel file.'); } }; - + const CoresOnChange = (params) => { + setDropdownValue(params); + formRef.current?.setFieldsValue({ Cross: params }); + const template = barcodeTemplateDetails?.find( + (find) => find.SessionName === params + ); + const checkComponent = (name) => + template?.OptionDetails?.some((some) => some.OptionName === name); + const productName = checkComponent('Product Name'); + setPrintProductName(productName); + }; // const ProductName = Productdata ?.map((e)=>e.ProdName+' '(+e.Size+' '+e.UomName)) const ProductName = Productdata?.map( (e) => `${e.ProdName} (${e.Size} ${e.UomName})` @@ -810,6 +1039,162 @@ const StockList = () => { // return allowDecimal ? num.toFixed(2) : Math.round(num).toString(); // } + + const onFinish = async () => { + const template = barcodeTemplateDetails?.find( + (find) => find.SessionName === dropdownValue + ); + const templateAvailable = template === undefined ? false : true; + + if (templateAvailable) { + const checkComponent = (name) => + template?.OptionDetails?.some((some) => some.OptionName === name); + const mrp = checkComponent('MRP'); + const barcode = checkComponent('Barcode'); + const color = checkComponent('Color'); + const eDate = checkComponent('E Date'); + const mDate = checkComponent('M Date'); + const sellingPrice = checkComponent('Selling Price'); + const productName = checkComponent('Product Name'); + const qrcode = checkComponent('Qrcode'); + const position = template.Position !== '' ? template.Position : ''; + const positionString = + template.PositionString !== '' ? template.PositionString : ''; + + setTemplateOptions({ + mrp: mrp, + barcode: barcode, + color: color, + eDate: eDate, + mDate: mDate, + sellingPrice: sellingPrice, + productName: productName, + value: position, + secondValue: positionString, + qrcode: qrcode, + codeType: template?.CodeType, + }); + } + + setPrintReady(true); + setTimeout(async () => { + switch (dropdownValue) { + case '15X15 6cross': + await printDiv( + templateAvailable ? 'label-15X156cross' : 'StickerPrints0', + style + getPageStyle(92) + ); + break; + case '22X35 3cross': + await printDiv( + templateAvailable ? '22X353cross' : 'StickerPrints1', + style + getPageStyle(105) + ); + break; + case '25X25 4cross': + await printDiv( + templateAvailable ? '25X254cross' : 'StickerPrints2', + style + getPageStyle(100) + ); + break; + case '25X50 2cross': + await printDiv( + templateAvailable ? '25X502cross' : 'StickerPrints3', + style + getPageStyle(100) + ); + break; + case '50X30 Single': + await printDiv( + templateAvailable ? '50X30Single' : 'StickerPrints4', + style + ); + break; + case '50X25 Single': + await printDiv( + templateAvailable ? '50X25Single' : 'StickerPrints5', + style + ); + break; + case '100X13 (55MM Printable)': + await printDiv( + templateAvailable ? '100X13(55MMPrintable)' : 'StickerPrints6', + style + ); + break; + case '100X15 (70MM Printable)': + await printDiv( + templateAvailable ? '100X15(70MMPrintable)' : 'StickerPrints7', + style + ); + break; + case '100X150': + await printDiv( + templateAvailable ? '100X150' : 'StickerPrints8', + style + ); + break; + default: + alert('! Select correct cross '); + } + handleQRStickerPrinterModelCancel(); + setPrintReady(false); + }, 100); + }; + const handleQRStickerPrinterModelCancel = () => { + setDropdownValue(); + setCopies(); + setOpen(false); + formRef?.current?.resetFields(); + setSelectedRecords([]); + setQrandbarcodeDatas([]); + // setMultiCode(false); + }; + const totalCopies = QrandbarcodeDatas?.reduce( + (sum, item) => sum + Number(item?.copiesCount || 0), + 0 + ); + + const CopiesOnChange = (params) => { + setCopies(params); + formRef.current?.setFieldsValue({ Copies: params }); + }; + + const imageTagBarcodeAndQR = useCallback( + (w = 'auto', fs = '6px', codeData = null) => { + const currentCode = codeData; + return ( + (templateOptions.barcode || templateOptions.qrcode) && ( + <> + Barcode + {templateOptions.codeType !== 'B' && ( +

+ {currentCode} +

+ )} + + ) + ); + }, + [templateOptions, MultiCode, barcodeBase64Image, base64Image] + ); + + const countOfProduct = debouncedSearchText + ? countData?.length + ? countData?.length + : 0 + : TotalCount; return (
@@ -822,14 +1207,28 @@ const StockList = () => {
-
-
+
+
+
+ + current && current > dayjs().startOf('day') + } + /> +
{
{' '} + {countOfProduct > 10 && ( + + `Total ${countOfProduct ? countOfProduct : 0} items` + } + /> + )}{' '}
{
} /> + + + {printReady && ( + + generateQRCodeCopy(QrandbarcodeDatas, code) + } + generateCodeImage={generateCodeImage} + imageTagBarcodeAndQR={imageTagBarcodeAndQR} + dropdownValue={dropdownValue} + barcodeTemplateDetails={barcodeTemplateDetails} + /> + )} + setstockWiseQrcode(false)} + type="stock" + onFinish={onFinish} + QrandbarcodeDatas={QrandbarcodeDatas} + setQrandbarcodeDatas={setQrandbarcodeDatas} + /> + + setProductWiseQrcode(false)} + type="product" + onFinish={onFinish} + QrandbarcodeDatas={QrandbarcodeDatas} + setQrandbarcodeDatas={setQrandbarcodeDatas} + />
); }; diff --git a/src/Services/utils.js b/src/Services/utils.js index 4b89d29..8228675 100644 --- a/src/Services/utils.js +++ b/src/Services/utils.js @@ -1,21 +1,52 @@ -import { useSelector, useDispatch } from "react-redux"; +import { useSelector, useDispatch } from 'react-redux'; import { - ChangeTotalAmount, - globalExtraTotalAmount, -} from "../Features/ExteraCharges/ExtraCharges"; + ChangeTotalAmount, + globalExtraTotalAmount, +} from '../Features/ExteraCharges/ExtraCharges'; export const useUtilsComponent = () => { - const dispatch = useDispatch(); - const extraCharges = useSelector(globalExtraTotalAmount); + const dispatch = useDispatch(); + const extraCharges = useSelector(globalExtraTotalAmount); - const removeExtraCharge = (item) => { - const filtered = extraCharges?.filter( - (e) => e?.localId !== item?.localId - ); - dispatch(ChangeTotalAmount(filtered)); - }; + const removeExtraCharge = (item) => { + const filtered = extraCharges?.filter((e) => e?.localId !== item?.localId); + dispatch(ChangeTotalAmount(filtered)); + }; - return { - removeExtraCharge, - }; + return { + removeExtraCharge, + }; +}; +export const generateBarcode = (code) => { + try { + const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); + JsBarcode(svg, code, { + format: 'CODE128', + displayValue: false, + lineColor: '#030303', + width: 2, + height: 40, + }); + const svgData = new XMLSerializer().serializeToString(svg); + return `data:image/svg+xml;base64,${btoa(svgData)}`; + } catch (error) { + return null; + } +}; +export const generateQRCode = (QrandbarcodeDatas, code) => { + let Data = QrandbarcodeDatas?.find((e) => e?.key === code)?.url; + return Data; +}; +export const generateQRCodeCopy = (QrandbarcodeDatas, code) => { + const found = QrandbarcodeDatas?.find((e) => e?.key === code); + + const count = Number(found?.copiesCount); + return Number.isFinite(count) && count > 0 ? count : 0; +}; +export const generateCodeImage = (code, codeType = 'Q') => { + if (codeType === 'B') { + return generateBarcode(code); + } else { + return generateQRCode(QrandbarcodeDatas, code); + } };