diff --git a/retail updated jan 27.zip b/retail updated jan 27.zip deleted file mode 100644 index c983482..0000000 Binary files a/retail updated jan 27.zip and /dev/null differ diff --git a/src/Pages/Product/Printstyles.js b/src/Pages/Product/Printstyles.js index 056e69c..1ebcbd6 100644 --- a/src/Pages/Product/Printstyles.js +++ b/src/Pages/Product/Printstyles.js @@ -297,7 +297,7 @@ height: 149mm; padding: 4px 4px; border-radius: 6px; } -.Qrcodeimage, +// .Qrcodeimage, // .Barcodeimage { // display: flex; // gap: 6px; @@ -341,61 +341,13 @@ height: 149mm; // width: 100%; // justify-content: space-evenly; // } -#25X502cross{ - margin: 0 !important; - padding: 0 !important; - width: 101.6mm; -} - .Cross25X50container{ - display: grid; - grid-template-columns: repeat(2, 50mm); - column-gap: 0.5mm; - width: 101.6mm; - } -#15X156cross{ - margin: 0 !important; - padding: 0 !important; -} + + + #StickerPrints0{ width: 90mm; } - -.labelGrid15 { - width: 92mm; -} - -@media print { - body { - margin: 0 !important; - padding: 0 !important; - } -} - -.label15 { - width: 15mm; - height: 15mm; - display: flex; - align-items: center; - justify-content: center; - box-sizing: border-box; -} - -.BarQrprint2details { - display: flex; - flex-direction: column; - align-items: center; - gap: 1mm; - font-size: 6px; - font-weight: 600; - text-align: center; - padding : 3px; - .productNameBQ, -.MRPBQ { - line-height: 1; -} -} - .Sticker1 { width: 35mm; height: 22mm; @@ -432,14 +384,6 @@ height: 149mm; // 25x25 4 Cross Dummy -.text-ellipsis { - width: 90%; - white-space: nowrap; - overflow: hidden; - text-align: center; - text-overflow: ellipsis; -} - @media print { body { margin: 0 !important; @@ -579,6 +523,7 @@ height: 149mm; height: auto; object-fit: contain; } + .product-id2 { margin: 0; padding: 0; @@ -657,6 +602,205 @@ height: 149mm; } +// 22x35 3cross Dummy +#StickerPrints1 { + width: 105mm; + margin: 0; + padding: 0; +} + +.label-wrapper-22x35 { + width: 35mm; + height: 22mm; + + box-sizing: border-box; + padding: 1mm; + + display: flex; + align-items: center; + justify-content: center; + gap : 0; + background: #fff; +} + +.label-wrapper-22x35 p { + margin: 0; + padding: 0; + font-size: 10px; + font-weight: 600; + line-height: 1.1; +} + +.label-wrapper-22x35 p:last-child { + margin-top: 2px; + font-size: 8px; + font-weight: 600; +} + +.label-wrapper-22x35 img { + width: 14mm; + height: 14mm; + object-fit: contain; +} + +// 25x50 2 Cross + +#25X502cross { + margin: 0 !important; + padding: 0 !important; + width: 100mm; +} + +.grid25x50_2cross { + display: grid; + grid-template-columns: repeat(2, 50mm); + width: 100mm; + column-gap: 0; + padding: 0; +} + +.label25x50-wrapper { + width: 50mm; + height: 25mm; + + box-sizing: border-box; + padding: 1.5mm; + + display: flex; + align-items: center; + justify-content: center; + + background: #fff; +} + +.label25x50-name { + font-size: 10px; + line-height: 1; + white-space: nowrap; + font-weight: 600; +} + +.label25x50-mrp { + font-size: 9px; + line-height: 1; + white-space: nowrap; + font-weight: 600; +} + +.label25x50-container { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; +} + +.label25x50-container img { + width: 16mm; + height: 16mm; + object-fit: contain; +} + +// 25x50 2 Cross Dummy + +#StickerPrints3 { + width: 100mm; + margin: 0; + padding: 0; +} + +.label-25x50-content { + width: 50mm; + height: 25mm; + + box-sizing: border-box; + padding: 1.5mm; + + display: flex; + align-items: center; + justify-content: space-between; + + background: #fff; +} + +.label-25x50-content > div { + width: 60%; + display: flex; + flex-direction: column; + justify-content: center; + gap: 1mm; + font-weight: 600; +} + +.label-25x50-content p { + margin: 0; + padding: 0; + font-size: 10px; + line-height: 1; +} + +.label-25x50-content p:last-child { + font-size: 9px; + white-space: nowrap; +} + +.label-25x50-content img { + width: 20mm; /* QR SAFE SIZE */ + height: 20mm; + object-fit: contain; +} + +// 15x15 6 Cross + +#label-15X156cross { + width: 92mm; + margin: 0 !important; + padding: 0 !important; +} + +.label-15x15-container { + display: grid; + grid-template-columns: repeat(6, 15mm); + width: 100%; + column-gap: 0.5mm; + row-gap: 0; + align-items: flex-start; +} + +.label-15x15-wrapper { + width: 15mm; + height: 15mm; + box-sizing: border-box; + display: flex; + align-items: center; + justify-content: center; + + background: #fff; +} + +.label-15x15-content { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: flex-start; + + text-align: center; +} + +.label-15x15-name, +.label-15x15-mrp { + font-size: 6px; + white-space: nowrap; +} + +.label-15x15-wrapper img { + width: 7.5mm; + height: 7.5mm; + object-fit: contain; +} + + .text-ellipsis { width: 90%; white-space: nowrap; @@ -664,6 +808,15 @@ height: 149mm; text-align: center; text-overflow: ellipsis; } + +.text-clamp-2 { + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; + line-height: 1.1; + max-height: 2.8em; +} `; export const getPageStyle = (width) => ` diff --git a/src/Pages/Product/ProductList.jsx b/src/Pages/Product/ProductList.jsx index 2370773..cced5d0 100644 --- a/src/Pages/Product/ProductList.jsx +++ b/src/Pages/Product/ProductList.jsx @@ -1951,8 +1951,8 @@ const ProductList = () => { switch (dropdownValue) { case '15X15 6cross': // COMPLETE await printDiv( - templateAvailable ? '15X156cross' : 'StickerPrints0', - style + getPageStyle(92) + templateAvailable ? 'label-15X156cross' : 'StickerPrints0', + (style + getPageStyle(92)) ); handleQRStickerPrinterModelCancel(); break; @@ -1973,7 +1973,7 @@ const ProductList = () => { case '25X50 2cross': //Need to check await printDiv( templateAvailable ? '25X502cross' : 'StickerPrints3', - style + style + getPageStyle(100) ); handleQRStickerPrinterModelCancel(); break; @@ -4036,12 +4036,12 @@ const ProductList = () => { const copyCount = generateQRCodeCopy(record?.QRCode); return Array?.from({ length: copyCount })?.map((_, copyIndex) => (

8 ? 'text-ellipsis' : ''}`} + className={`${nickName ? '' : (proName + ' (' + size + ')')?.length > 8 ? 'text-clamp-2' : ''}`} > {record.ProdName} ({record.Size} {record.UomName}) @@ -4055,15 +4055,14 @@ const ProductList = () => { templateOptions?.codeType ) || base64Image } - style={{ width: '52px', height: '52px' }} />

)) } ) : Array?.from({ length: copies })?.map((_, index) => ( -
-
+
+

8 ? 'text-ellipsis' : ''}`} > @@ -4073,7 +4072,6 @@ const ProductList = () => {

))} @@ -4191,19 +4189,19 @@ const ProductList = () => {
-
+
{selectedRecords?.length > 0 ? selectedRecords?.map((record, recordIndex) => { const copyCount = generateQRCodeCopy(record?.QRCode); console.log(copyCount, 'copyCount3') return Array.from({ length: copyCount })?.map((_, copyIndex) => (

12 ? 'text-ellipsis' : ''}`} + className={`${nickName ? '' : ((record?.NickName || record?.ProdName) + ' (' + record?.Size + ')')?.length > 12 ? 'text-clamp-2' : ''}`} > {record?.NickName || record?.ProdName} ({record?.Size} {record?.UomName}) @@ -4223,10 +4221,10 @@ const ProductList = () => { )) }) : Array.from({ length: copies })?.map((_, index) => ( -

+

12 ? 'text-ellipsis' : ''}`} + className={`${nickName ? '' : (proName + ' (' + size + ')')?.length > 12 ? 'text-clamp-2' : ''}`} > {proName} ({size})

@@ -4234,7 +4232,6 @@ const ProductList = () => {
))} @@ -4896,31 +4893,30 @@ const ProductList = () => {
-
+
{selectedRecords?.length > 0 ? selectedRecords?.map((record, recordIndex) => { const copyCount = generateQRCodeCopy(record?.QRCode); return Array.from({ length: copyCount })?.map((_, copyIndex) => (
-
+
{imageTagBarcodeAndQR( - templateOptions.codeType === 'B' ? '90%' : '35%', + templateOptions.codeType === 'B' ? '45mm' : '16mm', '6px', record?.QRCode || record?.ProdId )} {templateOptions.productName && (
12 ? 'text-ellipsis' : ''}`} + className={`label25x50-name ${record?.NickName ? '' : record?.ProdName?.length > 12 ? 'text-ellipsis' : ''}`} > {record?.NickName || record?.ProdName}
)} {templateOptions.mrp && ( -
{'MRP : ' + record?.MRP}
+
{'MRP : ' + record?.MRP}
)}
@@ -4930,23 +4926,22 @@ const ProductList = () => { ) : Array.from({ length: copies })?.map((_, index) => (
-
+
{imageTagBarcodeAndQR( - templateOptions.codeType === 'B' ? '90%' : '35%' + templateOptions.codeType === 'B' ? '45mm' : '16mm' )} {templateOptions.productName && (
12 ? 'text-ellipsis' : ''}`} + className={`label25x50-name ${nickName ? '' : proName?.length > 12 ? 'text-ellipsis' : ''}`} > {proName}
)} {templateOptions.mrp && ( -
{'MRP : ' + detail?.MRP}
+
{'MRP : ' + detail?.MRP}
)}
@@ -5433,107 +5428,29 @@ const ProductList = () => {
-
+
{selectedRecords?.length > 0 ? selectedRecords?.map((record, recordIndex) => { const copyCount = generateQRCodeCopy(record?.QRCode); return Array.from({ length: copyCount })?.map((_, copyIndex) => ( -
-
- {templateOptions.value === 'T' && - imageTagBarcodeAndQR( - templateOptions.codeType === 'B' ? '100%' : '50%', - '6px', - record?.QRCode || record?.ProdId - )} - {templateOptions.productName && ( -
- {record?.NickName - ? record?.NickName - : record?.ProdName} -
- )} - {templateOptions.value === 'C' && - imageTagBarcodeAndQR( - templateOptions.codeType === 'B' - ? '80%' - : !templateOptions.productName && - !templateOptions.mrp - ? '80%' - : '35%', - '6px', - record?.QRCode || record?.ProdId - )} - {templateOptions.mrp && ( -
- {'₹:' + record?.MRP} -
- )} - {templateOptions.value === 'B' && - imageTagBarcodeAndQR( - templateOptions.codeType === 'B' ? '100%' : '50%', - '6px', - record?.QRCode || record?.ProdId - )} -
-
- )) - } - - ) - : Array.from({ length: copies })?.map((_, index) => ( -
-
+
{templateOptions.value === 'T' && imageTagBarcodeAndQR( - templateOptions.codeType === 'B' ? '100%' : '50%' + templateOptions.codeType === 'B' ? '100%' : '6mm', + '6px', + record?.QRCode || record?.ProdId )} {templateOptions.productName && (
12 ? 'text-ellipsis' : ''}`} + className={`label-15x15-name ${record?.NickName ? '' : (record?.ProdName)?.length > 12 ? 'text-ellipsis' : ''}`} > - {nickName - ? nickName - : proName - ? proName - : 'Product Name'} + {record?.NickName + ? record?.NickName + : record?.ProdName}
)} {templateOptions.value === 'C' && @@ -5543,7 +5460,9 @@ const ProductList = () => { : !templateOptions.productName && !templateOptions.mrp ? '80%' - : '35%' + : '35%', + '6px', + record?.QRCode || record?.ProdId )} {templateOptions.mrp && (
{ }} className="MRPBQ" > - {'₹:' + (detail?.MRP ? detail?.MRP : 10.0)} + {'₹:' + record?.MRP}
)} {templateOptions.value === 'B' && imageTagBarcodeAndQR( - templateOptions.codeType === 'B' ? '100%' : '50%' + templateOptions.codeType === 'B' ? '100%' : '50%', + '6px', + record?.QRCode || record?.ProdId )} -
+
)) + }) + : Array.from({ length: copies })?.map((_, index) => ( +
+ {templateOptions.value === 'T' && + imageTagBarcodeAndQR( + templateOptions.codeType === 'B' ? '100%' : '6mm' + )} + {templateOptions.productName && ( +
12 ? 'text-ellipsis' : ''}`} + > + {nickName + ? nickName + : proName + ? proName + : 'Product Name'} +
+ )} + {templateOptions.value === 'C' && + imageTagBarcodeAndQR( + (templateOptions.codeType === 'B' + ? '80%' + : (!templateOptions.productName && + !templateOptions.mrp) + ? '80%' + : '7.5mm'), '5px' + )} + {templateOptions.mrp && ( +
+ {'₹:' + (detail?.MRP ? detail?.MRP : 10.0)} +
+ )} + {templateOptions.value === 'B' && + imageTagBarcodeAndQR( + templateOptions.codeType === 'B' ? '100%' : '7.5mm' + )}
))}
@@ -5630,7 +5589,6 @@ const ProductList = () => {
)) } - ) : Array.from({ length: copies })?.map((_, index) => (
{ ))}
-
+
{ isVisible={isOCRProcessing.Loader} imageCount={isOCRProcessing.Length || 1} /> -
+
); }; diff --git a/src/Pages/StockMaster/InvoiceImageExtractor.jsx b/src/Pages/StockMaster/InvoiceImageExtractor.jsx index ccb79ef..b55aced 100644 --- a/src/Pages/StockMaster/InvoiceImageExtractor.jsx +++ b/src/Pages/StockMaster/InvoiceImageExtractor.jsx @@ -35,6 +35,7 @@ import { DefaultModal } from '../../Components/Modal/DefaultModal.jsx'; import { Tables } from '../../Components/Tables/Table.jsx'; import { InputField } from '../../Components/Forms/InputField.jsx'; import TextAreaInput from '../../Components/Forms/TextArea.jsx'; +import { uploadImage } from '../../Features/upload/upload.js'; const { Option } = Select; const { Column } = Table; @@ -43,7 +44,7 @@ const CameraModal = ({ visible, onClose, onCapture, - setCameraModalVisible = () => {}, + setCameraModalVisible = () => { }, }) => { const videoRef = useRef(null); const canvasRef = useRef(null); @@ -250,12 +251,12 @@ const CameraModal = ({ const ScanModal = ({ visible = false, - onClose = () => {}, - onSubmit = () => {}, - handleUpload = () => {}, + onClose = () => { }, + onSubmit = () => { }, + handleUpload = () => { }, processingStep = null, ocrLoading = false, - handleClearImage = () => {}, + handleClearImage = () => { }, uploadedImage = null, selectedFile = null, }) => { @@ -487,7 +488,7 @@ const InvoiceImageExtractorModal = ({ productData = [], supplierData = [], uomData = [], - setVisible = () => {}, + setVisible = () => { }, }) => { const extractedTableRef = useRef(null); const [form] = Form.useForm(); @@ -641,7 +642,7 @@ const InvoiceImageExtractorModal = ({ if (uploadedImage) { try { URL.revokeObjectURL(uploadedImage); - } catch {} + } catch { } setUploadedImage(null); } }; @@ -723,6 +724,7 @@ const InvoiceImageExtractorModal = ({ const data = response.data[0]; setExtractedText(JSON.stringify(data, null, 2)); setParsedData(data); + const uploadImgData = await dispatch(uploadImage(fileToProcess)).unwrap(); const supplierInfo = { name: form.getFieldValue('supplierName') || data?.supplier || '', @@ -770,7 +772,7 @@ const InvoiceImageExtractorModal = ({ mergedProducts?.map((item, index) => ({ ...item, srNo: index + 1, - image: item?.image ? item?.image : response?.file, + image: item?.image ? item?.image : (uploadImgData?.data?.status ? uploadImgData?.data?.image : null), })) ); SetTotalAmtData( diff --git a/src/Pages/StockMaster/StockList.jsx b/src/Pages/StockMaster/StockList.jsx index 0f3a0ee..b7bad33 100644 --- a/src/Pages/StockMaster/StockList.jsx +++ b/src/Pages/StockMaster/StockList.jsx @@ -2,7 +2,7 @@ import { useState, useEffect, useCallback } from 'react'; import { useNavigate, useLocation } from 'react-router-dom'; import { useDispatch, useSelector } from 'react-redux'; import { PlusOutlined, EyeOutlined } from '@ant-design/icons'; -import { Table } from 'antd'; +import { Image, Table } from 'antd'; import { changeBreadCrumb, getEmpAccess, @@ -95,6 +95,9 @@ const StockList = () => { const [ImeiSerialModal, setImeiSerialModal] = useState(false); const [allowDecimal, setAllowDecimal] = useState(false); const [PurcProddetail, setPrucProddetail] = useState([]); + const [productImageDetails, setProductImageDetails] = useState([]); + const [imageModal, setImageModal] = useState(false); + const [currentImageIndex, setCurrentImageIndex] = useState(0); const [IMEISeriandata, setIMEISeriandata] = useState([]); useEffect(() => { try { @@ -189,6 +192,21 @@ const StockList = () => { setPrucProddetail(proddetails); setProddtlModal(true); }; + + const viewImages = (imageDetails) => { + setProductImageDetails(imageDetails); + setCurrentImageIndex(0); + setImageModal(true); + }; + + const handlePrevImage = () => { + setCurrentImageIndex(prev => prev > 0 ? prev - 1 : productImageDetails.length - 1); + }; + + const handleNextImage = () => { + setCurrentImageIndex(prev => prev < productImageDetails.length - 1 ? prev + 1 : 0); + }; + const handleProductmodalCancel = () => { setPrucProddetail([]); setProddtlModal(false); @@ -196,6 +214,11 @@ const StockList = () => { const handleIMEISerialmodalCancel = () => { setImeiSerialModal(false); }; + const handleImageClose = () => { + setImageModal(false); + setProductImageDetails([]); + setCurrentImageIndex(0); + } // WRITED BY SREE function safeRound(amountStr) { if (amountStr == null) return allowDecimal ? '0.00' : '0'; @@ -293,6 +316,24 @@ const StockList = () => { /> ), }, + { + title: 'Image', + key: 'ImageDetails', + dataIndex: 'ImageDetails', + align: 'center', + render: (data, record) => { + if (data?.length > 0) { + return viewImages(data)} + /> + } else { + return

-

+ } + } + + , + } ]; const Proddetailcolumns = [ { @@ -856,6 +897,52 @@ const StockList = () => {
} /> + + {productImageDetails?.length > 0 && ( +
+ {productImageDetails.length > 1 && ( + <> + + + )} +
+ Preview +
+ {productImageDetails.length > 1 && ( + <> + + + )} +
+ )} +
+ {currentImageIndex + 1} of {productImageDetails.length} +
+
+ } + />
); }; diff --git a/src/Pages/StockPriceUpdate/StockPriceUpdate.jsx b/src/Pages/StockPriceUpdate/StockPriceUpdate.jsx index e362b38..9e93125 100644 --- a/src/Pages/StockPriceUpdate/StockPriceUpdate.jsx +++ b/src/Pages/StockPriceUpdate/StockPriceUpdate.jsx @@ -4,72 +4,76 @@ import React, { useRef, useContext, useCallback, -} from 'react'; -import { useDispatch, useSelector } from 'react-redux'; -import { Select, Tooltip } from 'antd'; -import { Form, Input, Table } from 'antd'; +} from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Select, Tooltip } from "antd"; +import { Form, Input, Table } from "antd"; import { EditFilled, DeleteFilled, ArrowRightOutlined, -} from '@ant-design/icons'; +} from "@ant-design/icons"; import { PutStockPrice, bulkPriceUpdate, getStockNames, -} from '../../Features/StockPriceUpdate/StockPriceUpdateMaster'; +} from "../../Features/StockPriceUpdate/StockPriceUpdateMaster"; import { dateFormatChange, ExtractDateFormate, getSession, -} from '../../Services/Others'; -import { DefaultModal } from '../../Components/Modal/DefaultModal'; -import { Tables } from '../../Components/Tables/Table'; -import Buttons from '../../Components/Forms/Buttons'; -import { Messages } from '../../Components/Notifications/Messages'; +} from "../../Services/Others"; +import { DefaultModal } from "../../Components/Modal/DefaultModal"; +import { Tables } from "../../Components/Tables/Table"; +import Buttons from "../../Components/Forms/Buttons"; +import { Messages } from "../../Components/Notifications/Messages"; import { changeBreadCrumb, getEmpAccess, -} from '../../Features/AppPage/CenterPage.js'; -import FormHeader from '../PageComponents/FormHeader'; -import Search from '../../Components/Forms/Search'; -import { RadioGrpButton } from '../../Components/Forms/RadioGroup.jsx'; -import { useAuth } from '../../AuthContext.jsx'; -import '../../Styles/OverAllStyle/OverAllStyle.scss'; -import { getPreferenceData } from '../../Features/BookingScreen/BookingData/BookingData.js'; -import { DropDowns } from '../../Components/Forms/DropDown.jsx'; -import { FiDelete, FiUploadCloud } from 'react-icons/fi'; -import { CiExport } from 'react-icons/ci'; -import Excelupldimg from '../../Images/Excel.png'; +} from "../../Features/AppPage/CenterPage.js"; +import FormHeader from "../PageComponents/FormHeader"; +import Search from "../../Components/Forms/Search"; +import { RadioGrpButton } from "../../Components/Forms/RadioGroup.jsx"; +import { useAuth } from "../../AuthContext.jsx"; +import "../../Styles/OverAllStyle/OverAllStyle.scss"; +import { getPreferenceData } from "../../Features/BookingScreen/BookingData/BookingData.js"; +import { DropDowns } from "../../Components/Forms/DropDown.jsx"; +import { FiDelete, FiUploadCloud } from "react-icons/fi"; +import { CiExport } from "react-icons/ci"; +import Excelupldimg from "../../Images/Excel.png"; import { emptyExcelData, fileInputRefSelector, -} from '../../Features/ExcelUploadPage/ExcelUploadPage.js'; +} from "../../Features/ExcelUploadPage/ExcelUploadPage.js"; const subDirectory = import.meta.env.BASE_URL; -import ExcelJS from 'exceljs'; -import { read, utils } from 'xlsx'; -import { v4 as uuidv4 } from 'uuid'; -import { InputField } from '../../Components/Forms/InputField.jsx'; -import { MdOutlineAppRegistration } from 'react-icons/md'; +import ExcelJS from "exceljs"; +import { read, utils } from "xlsx"; +import { v4 as uuidv4 } from "uuid"; +import { InputField } from "../../Components/Forms/InputField.jsx"; +import { MdOutlineAppRegistration } from "react-icons/md"; import { getFieldSetupData, postFieldSetup, -} from '../../Features/ProductPage/ProductPage.js'; +} from "../../Features/ProductPage/ProductPage.js"; import { ApplicationPreferences, getCommonAppPreference, -} from '../../Features/BrachLogin/BranchLogin.js'; -import { IoClose } from 'react-icons/io5'; +} from "../../Features/BrachLogin/BranchLogin.js"; +import { IoClose } from "react-icons/io5"; const StockPriceUpdate = () => { const { SadminuserAccess } = useAuth(); let SAAccessCommonMaster = SadminuserAccess?.find( - (e) => e?.MenuName === 'Price Change' + (e) => e?.MenuName === "Price Change", ); const ApplicationPreferenceData = useSelector(ApplicationPreferences); const categoryId = ApplicationPreferenceData?.find( - (p) => p?.PreferredCatName?.toLowerCase() === 'price change fields' + (p) => p?.PreferredCatName?.toLowerCase() === "price change fields", + )?.PreferredCatId; + + const excelCategoryId = ApplicationPreferenceData?.find( + (p) => p?.PreferredCatName?.toLowerCase() === "price change sheet fields", )?.PreferredCatId; const fileInputRef = useRef(fileInputRefSelector); @@ -77,24 +81,30 @@ const StockPriceUpdate = () => { const formRef = useRef(null); const allowedExcelTypes = [ - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', // .xlsx - 'application/vnd.ms-excel', // .xls + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", // .xlsx + "application/vnd.ms-excel", // .xls ]; const dispatch = useDispatch(); const [selectedFields, setSelectedFields] = useState([]); + const [selectedExcelFields, setSelectedExcelFields] = useState([]); const [tableFieldPreferences, setTableFieldPreferences] = useState([]); + const [tableExcelFieldPreferences, setTableExcelFieldPreferences] = useState( + [], + ); const [messageType, setMessageType] = useState(null); const [messageData, setMessageData] = useState(null); const [StockNames, setStockNames] = useState([]); const [ProductName, setProductName] = useState(null); + const [fieldSetup, setFieldSetup] = useState(false); + const [excelFieldSetup, setExcelFieldSetup] = useState(false); const [StockDetails, setStockDetails] = useState([]); const [dataSource, setDataSource] = useState([]); const [sortedInfo, setSortedInfo] = useState({}); const [BulksortedInfo, setBulksortedInfo] = useState({}); - const [searchedText, setSearchedText] = useState(''); - const [BulksearchedText, setBulksearchedText] = useState(''); + const [searchedText, setSearchedText] = useState(""); + const [BulksearchedText, setBulksearchedText] = useState(""); const [filteredInfo, setFilteredInfo] = useState({}); const [page, setpage] = useState(1); const [Bulkchangepage, setBulkchangepage] = useState(1); @@ -104,93 +114,121 @@ const StockPriceUpdate = () => { const [open, setOpen] = useState(false); const [excelModalOpen, setExcelModalOpen] = useState(false); const [priceChangeModalOpen, setPriceChangeModalOpen] = useState(false); - const [stockVariantBased, setStockVariantBased] = useState('Yes'); + const [stockVariantBased, setStockVariantBased] = useState("Yes"); const [exportLoading, setExportLoading] = useState(false); + const [fileLoading, setFileLoading] = useState(false); const [loading, setLoading] = useState(false); + const [headers, setHeaders] = useState([]); const [uploadedData, setUploadedData] = useState([]); - const CompId = getSession('CompId'); - const BranchId = getSession('BranchId'); - const AppId = getSession('AppId'); - const UserId = getSession('UserId'); - const UserType = getSession('UserType'); + const CompId = getSession("CompId"); + const BranchId = getSession("BranchId"); + const AppId = getSession("AppId"); + const UserId = getSession("UserId"); + const UserType = getSession("UserType"); const [empData, setEmpData] = useState(); const [addnewAccess, setaddnewAccess] = useState(true); - const [RadioSelection, setRadioSelection] = useState('Single'); + const [RadioSelection, setRadioSelection] = useState("Single"); const [BulkProductData, setBulkProductData] = useState([]); const [allowDecimal, setAllowDecimal] = useState(false); + const hasFieldExists = (label) => + headers.some((h) => h.toLowerCase() === label.toLowerCase()); + const hasField = (label) => + tableFieldPreferences?.some((f) => f.label === label && f.access === "Y"); + const hasExcelField = (label) => + tableExcelFieldPreferences?.some( + (f) => f.label === label && f.access === "Y", + ); const items = [ { - name: 'Home', + name: "Home", link: `${subDirectory}app-page/home`, }, ]; - - const handleRemoveRecord = (index) => { setUploadedData((prev) => prev.filter((_, i) => i !== index)); }; const columns = [ { - title: 'Product Name', - dataIndex: 'ProductName', - key: 'ProductName', + title: "Product Name", + dataIndex: "ProductName", + key: "ProductName", width: 180, render: (value, record, index) => (

{`${value} (${record?.Size} ${record?.UOMName})`}

), }, { - title: 'Variant Name', - dataIndex: 'VariantName', - key: 'VariantName', + title: "Variant Name", + dataIndex: "VariantName", + key: "VariantName", width: 180, }, { - title: 'Batch No', - dataIndex: 'BatchRef', - key: 'BatchRef', + title: "Batch No", + dataIndex: "BatchRef", + key: "BatchRef", width: 180, }, - { - title: 'Stock', - dataIndex: 'Stock', - key: 'Stock', - width: 80, - }, - { - title: 'Stock Date', - dataIndex: 'StockDate', - key: 'StockDate', - width: 80, - }, - { - title: 'Old MRP', - dataIndex: 'OldMRP', - key: 'OldMRP', - width: 100, - }, - { - title: 'Old SP', - dataIndex: 'OldSP', - key: 'OldSP', - width: 100, - }, - { - title: 'Old Wholesale Price', - dataIndex: 'OldWholeSalePrice', - key: 'OldWholeSalePrice', - width: 140, - }, + ...(hasFieldExists("Stock") + ? [ + { + title: "Stock", + dataIndex: "Stock", + key: "Stock", + width: 80, + }, + ] + : []), + ...(hasFieldExists("Stock Date") + ? [ + { + title: "Stock Date", + dataIndex: "StockDate", + key: "StockDate", + width: 80, + }, + ] + : []), + ...(hasFieldExists("Old MRP") + ? [ + { + title: "Old MRP", + dataIndex: "OldMRP", + key: "OldMRP", + width: 100, + }, + ] + : []), + ...(hasFieldExists("Old SP") + ? [ + { + title: "Old SP", + dataIndex: "OldSP", + key: "OldSP", + width: 100, + }, + ] + : []), + ...(hasFieldExists("Old Wholesale Price") + ? [ + { + title: "Old Wholesale Price", + dataIndex: "OldWholeSalePrice", + key: "OldWholeSalePrice", + width: 140, + }, + ] + : []), // ✅ EDITABLE { - title: 'New MRP', - dataIndex: 'NewMRP', - key: 'NewMRP', + title: "New MRP", + dataIndex: "NewMRP", + key: "NewMRP", width: 120, render: (_, record, index) => ( @@ -198,17 +236,17 @@ const StockPriceUpdate = () => { placeholder="New MRP" inputMode="decimal" onChange={(e) => - handlePriceChange(index, 'NewMRP', e.target.value, record.localId) + handlePriceChange(index, "NewMRP", e.target.value, record.localId) } onInput={(e) => { - let cleanedValue = e.target.value.replace(/[^0-9.]/g, ''); - if (cleanedValue.startsWith('.')) { - cleanedValue = '0' + cleanedValue; + let cleanedValue = e.target.value.replace(/[^0-9.]/g, ""); + if (cleanedValue.startsWith(".")) { + cleanedValue = "0" + cleanedValue; } - const parts = cleanedValue.split('.'); + const parts = cleanedValue.split("."); e.target.value = parts.length > 2 - ? `${parts[0]}.${parts.slice(1).join('')}` + ? `${parts[0]}.${parts.slice(1).join("")}` : cleanedValue; }} /> @@ -216,38 +254,38 @@ const StockPriceUpdate = () => { ), }, { - title: 'New SP', - dataIndex: 'NewSellPrice', - key: 'NewSellPrice', + title: "New SP", + dataIndex: "NewSellPrice", + key: "NewSellPrice", width: 120, render: (_, record, index) => ( ({ validator(_, value) { const mrp = getFieldValue(`NewMRP${record.localId}`); - if (mrp === undefined || mrp === null || mrp === '') { + if (mrp === undefined || mrp === null || mrp === "") { return Promise.resolve(); } const numMRP = Number(mrp); const numSP = - value === undefined || value === null || value === '' + value === undefined || value === null || value === "" ? null : Number(value); if (numSP === null) { return Promise.reject( - new Error('New SP is required when New MRP is provided') + new Error("New SP is required when New MRP is provided"), ); } if (numSP > numMRP) { return Promise.reject( - new Error('New SP cannot be greater than New MRP') + new Error("New SP cannot be greater than New MRP"), ); } @@ -260,76 +298,80 @@ const StockPriceUpdate = () => { placeholder="New SP" inputMode="decimal" onInput={(e) => { - let cleanedValue = e.target.value.replace(/[^0-9.]/g, ''); - const parts = cleanedValue.split('.'); - if (cleanedValue.startsWith('.')) { - cleanedValue = '0' + cleanedValue; + let cleanedValue = e.target.value.replace(/[^0-9.]/g, ""); + const parts = cleanedValue.split("."); + if (cleanedValue.startsWith(".")) { + cleanedValue = "0" + cleanedValue; } e.target.value = parts.length > 2 - ? `${parts[0]}.${parts.slice(1).join('')}` + ? `${parts[0]}.${parts.slice(1).join("")}` : cleanedValue; }} onChange={(e) => { { handlePriceChange( index, - 'NewSellPrice', + "NewSellPrice", e.target.value, - record.localId + record.localId, ); excelDataRef.current ?.validateFields([`NewSellPrice${record.localId}`]) - .catch(() => {}); + .catch(() => { }); } }} /> ), }, + ...(hasFieldExists("New Wholesale Price") + ? [ + { + title: "New Wholesale Price", + dataIndex: "NewWholeSalePrice", + key: "NewWholeSalePrice", + width: 160, + render: (value, record, index) => ( + + + handlePriceChange( + index, + "NewWholeSalePrice", + e.target.value, + record.localId, + ) + } + placeholder="New Wholesale" + inputMode="decimal" + onInput={(e) => { + let cleanedValue = e.target.value.replace(/[^0-9.]/g, ""); + const parts = cleanedValue.split("."); + if (cleanedValue.startsWith(".")) { + cleanedValue = "0" + cleanedValue; + } + e.target.value = + parts.length > 2 + ? `${parts[0]}.${parts.slice(1).join("")}` + : cleanedValue; + }} + /> + + ), + }, + ] + : []), { - title: 'New Wholesale Price', - dataIndex: 'NewWholeSalePrice', - key: 'NewWholeSalePrice', - width: 160, - render: (value, record, index) => ( - - - handlePriceChange( - index, - 'NewWholeSalePrice', - e.target.value, - record.localId - ) - } - placeholder="New Wholesale" - inputMode="decimal" - onInput={(e) => { - let cleanedValue = e.target.value.replace(/[^0-9.]/g, ''); - const parts = cleanedValue.split('.'); - if (cleanedValue.startsWith('.')) { - cleanedValue = '0' + cleanedValue; - } - e.target.value = - parts.length > 2 - ? `${parts[0]}.${parts.slice(1).join('')}` - : cleanedValue; - }} - /> - - ), - }, - { - title: 'Action', - key: 'action', + title: "Action", + key: "action", width: 80, - align: 'center', + align: "center", render: (_, record, index) => ( handleRemoveRecord(index)} /> @@ -345,19 +387,87 @@ const StockPriceUpdate = () => { // } }, []); useEffect(() => { - if (UserType === 'Employee') { + dispatch(getCommonAppPreference(AppId)); + }, [AppId, dispatch]); + useEffect(() => { + if (UserType === "Employee") { fetchApi(); } }, [UserType]); + + useEffect(() => { + getFieldSetup(); + }, [categoryId]); + + useEffect(() => { + getExcelFieldSetup(); + }, [excelCategoryId]); + + const getFieldSetup = async () => { + try { + const response = await dispatch( + getFieldSetupData({ AppId, CompId, BranchId, categoryId, Type: "GB" }), + ).unwrap(); + if (response?.data?.statusCode === 1) { + console.log(response?.data?.data?.[0]?.ConfigDtl, "Field Setup Data"); + setSelectedFields( + response?.data?.data?.[0]?.ConfigDtl?.filter( + (c) => c.ConfigId && c.Access === "Y", + )?.map((c) => c.ConfigId) || [], + ); + setTableFieldPreferences( + response?.data?.data?.[0]?.ConfigDtl?.map((c) => ({ + value: c.ConfigId, + label: c.ConfigName, + access: c.Access, + })) || [], + ); + } + } catch (error) { + console.error("Error fetching field setup:", error); + } + }; + + const getExcelFieldSetup = async () => { + try { + const response = await dispatch( + getFieldSetupData({ + AppId, + CompId, + BranchId, + categoryId: excelCategoryId, + Type: "GB", + }), + ).unwrap(); + if (response?.data?.statusCode === 1) { + console.log(response?.data?.data?.[0]?.ConfigDtl, "Field Setup Data"); + setSelectedExcelFields( + response?.data?.data?.[0]?.ConfigDtl?.filter( + (c) => c.ConfigId && c.Access === "Y", + )?.map((c) => c.ConfigId) || [], + ); + setTableExcelFieldPreferences( + response?.data?.data?.[0]?.ConfigDtl?.map((c) => ({ + value: c.ConfigId, + label: c.ConfigName, + access: c.Access, + })) || [], + ); + } + } catch (error) { + console.error("Error fetching field setup:", error); + } + }; + useEffect(() => { let hasAccess = false; - if (UserType === 'Admin' || UserType === 'Super Admin') { + if (UserType === "Admin" || UserType === "Super Admin") { hasAccess = true; - } else if (UserType === 'Employee') { - hasAccess = empData?.AddAccess === 'Y'; - } else if (UserType === 'Super Admin User') { - hasAccess = SAAccessCommonMaster?.AddAccess === 'Y'; + } else if (UserType === "Employee") { + hasAccess = empData?.AddAccess === "Y"; + } else if (UserType === "Super Admin User") { + hasAccess = SAAccessCommonMaster?.AddAccess === "Y"; } setaddnewAccess(!hasAccess); @@ -380,7 +490,7 @@ const StockPriceUpdate = () => { }; let response = await dispatch(getEmpAccess(data)).unwrap(); let datas = response?.data?.data?.[0]?.EmpAccessDetails?.filter( - (item) => item.ConfigName === 'Price Change' + (item) => item.ConfigName === "Price Change", ); setEmpData(datas?.[0]); }; @@ -443,7 +553,7 @@ const StockPriceUpdate = () => { ...values, }); } catch (errInfo) { - console.log('Save failed:', errInfo); + console.log("Save failed:", errInfo); } }; @@ -459,12 +569,12 @@ const StockPriceUpdate = () => { rules={[ { pattern: /^(?!0$)(\d+)(\.\d{1,2})?$/, - message: 'Invalid format (Max 2 decimals, No zero)', + message: "Invalid format (Max 2 decimals, No zero)", }, { validator: (_, value) => value?.length > 10 - ? Promise.reject('Max 10 characters allowed') + ? Promise.reject("Max 10 characters allowed") : Promise.resolve(), }, ]} @@ -480,11 +590,11 @@ const StockPriceUpdate = () => { } inputMode="decimal" onInput={(e) => { - const cleanedValue = e.target.value.replace(/[^0-9.]/g, ''); - const parts = cleanedValue.split('.'); + const cleanedValue = e.target.value.replace(/[^0-9.]/g, ""); + const parts = cleanedValue.split("."); e.target.value = parts.length > 2 - ? `${parts[0]}.${parts.slice(1).join('')}` + ? `${parts[0]}.${parts.slice(1).join("")}` : cleanedValue; }} /> @@ -550,7 +660,7 @@ const StockPriceUpdate = () => { ...values, }); } catch (errInfo) { - console.log('Save failed:', errInfo); + console.log("Save failed:", errInfo); } }; @@ -566,12 +676,12 @@ const StockPriceUpdate = () => { rules={[ { pattern: /^(?!0$)(\d+)(\.\d{1,2})?$/, - message: 'Invalid format (Max 2 decimals, No zero)', + message: "Invalid format (Max 2 decimals, No zero)", }, { validator: (_, value) => value?.length > 10 - ? Promise.reject('Max 10 characters allowed') + ? Promise.reject("Max 10 characters allowed") : Promise.resolve(), }, ]} @@ -586,11 +696,11 @@ const StockPriceUpdate = () => { } inputMode="decimal" onInput={(e) => { - const cleanedValue = e.target.value.replace(/[^0-9.]/g, ''); - const parts = cleanedValue.split('.'); + const cleanedValue = e.target.value.replace(/[^0-9.]/g, ""); + const parts = cleanedValue.split("."); e.target.value = parts.length > 2 - ? `${parts[0]}.${parts.slice(1).join('')}` + ? `${parts[0]}.${parts.slice(1).join("")}` : cleanedValue; }} /> @@ -626,8 +736,8 @@ const StockPriceUpdate = () => { const { data: res } = await dispatch(getPreferenceData(data)).unwrap(); const decimalSetting = res?.data?.[0]?.SettingDtlDetails?.find( (setting) => - setting?.SettingIdName?.toLowerCase() === 'decimal' && - setting?.SettingValue === 'Y' + setting?.SettingIdName?.toLowerCase() === "decimal" && + setting?.SettingValue === "Y", ); if (decimalSetting) { setAllowDecimal(true); @@ -671,7 +781,7 @@ const StockPriceUpdate = () => { ProdVariantName: detail?.ProdVariantName, BatchRef: detail?.BatchRef, key: `${product.ProdId}_${detail.InwardDtlId}`, - })) + })), ); setBulkProductData(flattenedArray); }; @@ -689,7 +799,7 @@ const StockPriceUpdate = () => { const currentRow = { ...updated[rowIndex] }; // If changing New MRP, clear New SP - if (field === 'NewMRP') { + if (field === "NewMRP") { currentRow.NewSellPrice = null; excelDataRef.current?.setFieldsValue({ [`NewSellPrice${localId}`]: null, @@ -702,13 +812,13 @@ const StockPriceUpdate = () => { }); // Validate New SP against New MRP - if (field === 'NewSellPrice' && numValue) { + if (field === "NewSellPrice" && numValue) { const currentRow = uploadedData[rowIndex]; const newMRP = currentRow?.NewMRP; if (newMRP && numValue > newMRP) { - setMessageType('error'); - setMessageData('New SP cannot be greater than New MRP'); + setMessageType("error"); + setMessageData("New SP cannot be greater than New MRP"); return; } } @@ -720,7 +830,7 @@ const StockPriceUpdate = () => { const statusFormatter = async (row) => { const updatedData = StockDetails?.filter( - (item) => item?.InwardDtlId !== row?.InwardDtlId + (item) => item?.InwardDtlId !== row?.InwardDtlId, ); setStockDetails(updatedData); }; @@ -728,7 +838,7 @@ const StockPriceUpdate = () => { let tableValue = StockNames?.[0]?.stockDetails; let DataSource = StockNames?.map((name, index) => ({ value: index + 1, - label: name?.ProdName + '(' + (name?.Size + ' ' + name?.UOMName) + ')', + label: name?.ProdName + "(" + (name?.Size + " " + name?.UOMName) + ")", ProdId: name?.ProdId, stockDetails: name?.stockDetails, Quantity: name?.Size, @@ -754,8 +864,8 @@ const StockPriceUpdate = () => { }); setStockDetails(newData); } else { - setMessageType('error'); - setMessageData('MRP is must be greater than or equal to selling price'); + setMessageType("error"); + setMessageData("MRP is must be greater than or equal to selling price"); } } else { const newData = StockDetails?.map((item) => { @@ -784,9 +894,9 @@ const StockPriceUpdate = () => { }); setBulkProductData(newData); } else { - setMessageType('error'); + setMessageType("error"); setMessageData( - 'MRP is must be greater than or equal to selling price' + "MRP is must be greater than or equal to selling price", ); } } else { @@ -816,31 +926,31 @@ const StockPriceUpdate = () => { }; function safeRound(amountStr) { - if (amountStr == null) return allowDecimal ? '0.00' : '0'; + if (amountStr == null) return allowDecimal ? "0.00" : "0"; - const cleaned = String(amountStr).replace(/[^0-9.-]+/g, ''); + const cleaned = String(amountStr).replace(/[^0-9.-]+/g, ""); const num = Number(cleaned); - if (isNaN(num)) return allowDecimal ? '0.00' : '0'; + if (isNaN(num)) return allowDecimal ? "0.00" : "0"; return allowDecimal ? num.toFixed(2) : Math.round(num).toString(); } const columns2 = [ { - title: 'Sl.No', - align: 'center', - key: 'sno', - width: '60px', + title: "Sl.No", + align: "center", + key: "sno", + width: "60px", render: (text, object, index) => ( - {index + 1} + {index + 1} ), }, { - title: 'Product Name', - dataIndex: 'ProdName', - key: 'ProdName', - width: '20%', + title: "Product Name", + dataIndex: "ProdName", + key: "ProdName", + width: "20%", filteredValue: [searchedText], onFilter: (value, record) => { return String(record.ProdName) @@ -848,7 +958,7 @@ const StockPriceUpdate = () => { .includes(value?.toLowerCase()); }, sorter: (a, b) => a?.ProdName?.localeCompare(b.ProdName), - sortOrder: sortedInfo.columnKey === 'ProdName' ? sortedInfo.order : null, + sortOrder: sortedInfo.columnKey === "ProdName" ? sortedInfo.order : null, ellipsis: true, render: (_, record) => ( @@ -858,65 +968,65 @@ const StockPriceUpdate = () => { ), }, { - title: 'stock Date', - dataIndex: 'InwardDate', - key: 'InwardDate', - align: 'right', - width: '150px', + title: "stock Date", + dataIndex: "InwardDate", + key: "InwardDate", + align: "right", + width: "150px", render: (InwardDate) => - InwardDate !== null ? ExtractDateFormate(InwardDate) : '-', + InwardDate !== null ? ExtractDateFormate(InwardDate) : "-", }, { - title: 'Old MRP', - dataIndex: 'MRP', - key: 'MRP', - align: 'right', - render: (MRP) => (safeRound(MRP) !== null ? safeRound(MRP) : '-'), + title: "Old MRP", + dataIndex: "MRP", + key: "MRP", + align: "right", + render: (MRP) => (safeRound(MRP) !== null ? safeRound(MRP) : "-"), }, { - title: 'Old Price', - dataIndex: 'SellPrice', - key: 'SellPrice', - align: 'right', + title: "Old Price", + dataIndex: "SellPrice", + key: "SellPrice", + align: "right", render: (SellPrice) => - safeRound(SellPrice) !== null ? safeRound(SellPrice) : '-', + safeRound(SellPrice) !== null ? safeRound(SellPrice) : "-", }, { - title: 'New MRP', - dataIndex: 'CurrentMRP', - key: 'CurrentMRP', - align: 'right', + title: "New MRP", + dataIndex: "CurrentMRP", + key: "CurrentMRP", + align: "right", editable: true, - render: (text, record) =>

{text ? text : 'Enter MRP'}

, + render: (text, record) =>

{text ? text : "Enter MRP"}

, width: 100, }, { - title: 'New SP', - dataIndex: 'CurrentAmt', - key: 'CurrentAmt', - align: 'right', + title: "New SP", + dataIndex: "CurrentAmt", + key: "CurrentAmt", + align: "right", editable: true, - render: (text, record) =>

{text ? text : 'Enter Price'}

, + render: (text, record) =>

{text ? text : "Enter Price"}

, width: 100, }, { - title: 'Action', - dataIndex: 'SellPrice', - key: 'SellPrice', - align: 'center', - width: '100px', + title: "Action", + dataIndex: "SellPrice", + key: "SellPrice", + align: "center", + width: "100px", render: (_, record, index) => (
statusFormatter(record, index)} />
@@ -925,20 +1035,21 @@ const StockPriceUpdate = () => { ]; const BulkPricechangeColumns = [ { - title: 'Sl.No', - align: 'center', - key: 'sno', + title: "Sl.No", + align: "center", + key: "sno", + width: "50px", render: (text, object, index) => ( - + {(Bulkchangepage - 1) * 10 + index + 1} ), }, { - title: 'Name', - dataIndex: 'ProdName', - key: 'ProdName', - width: '20%', + title: "Name", + dataIndex: "ProdName", + key: "ProdName", + width: "20%", filteredValue: [BulksearchedText], onFilter: (value, record) => { return String(record.ProdName) @@ -947,7 +1058,7 @@ const StockPriceUpdate = () => { }, sorter: (a, b) => a?.ProdName?.localeCompare(b.ProdName), sortOrder: - BulksortedInfo.columnKey === 'ProdName' ? BulksortedInfo.order : null, + BulksortedInfo.columnKey === "ProdName" ? BulksortedInfo.order : null, ellipsis: true, render: (_, record) => ( @@ -956,66 +1067,132 @@ const StockPriceUpdate = () => { ), }, { - title: 'stock Date', - dataIndex: 'InwardDate', - key: 'InwardDate', - align: 'right', - width: '150px', - render: (InwardDate) => - InwardDate !== null ? ExtractDateFormate(InwardDate) : '-', + title: "Variant Name", + dataIndex: "ProdVariantName", + key: "ProdVariantName", + align: "left", + width: "120px", }, { - title: 'Exp date', - dataIndex: 'ExpDate', - key: 'ExpDate', - align: 'right', - render: (ExpDate) => - ExpDate !== null ? ExtractDateFormate(ExpDate) : '-', + title: "Batch No", + dataIndex: "BatchRef", + key: "BatchRef", + align: "left", + width: "120px", }, + ...(hasField("Stock Date") + ? [ + { + title: "stock Date", + dataIndex: "InwardDate", + key: "InwardDate", + align: "center", + width: "100px", + render: (InwardDate) => + InwardDate !== null ? ExtractDateFormate(InwardDate) : "-", + }, + ] + : []), + ...(hasField("Expiry Date") + ? [ + { + title: "Exp date", + dataIndex: "ExpDate", + key: "ExpDate", + align: "center", + width: "100px", + render: (ExpDate) => + ExpDate !== null ? ExtractDateFormate(ExpDate) : "-", + }, + ] + : []), + ...(hasField("Stock") + ? [ + { + title: "stock", + dataIndex: "BalanceQty", + key: "BalanceQty", + align: "right", + width: "60px", + render: (BalanceQty) => (BalanceQty !== null ? BalanceQty : "-"), + }, + ] + : []), + ...(hasField("Old MRP") + ? [ + { + title: "Old MRP", + dataIndex: "MRP", + key: "MRP", + align: "right", + width: "70px", + render: (MRP) => (safeRound(MRP) !== null ? safeRound(MRP) : "-"), + }, + ] + : []), + ...(hasField("Old SP") + ? [ + { + title: "Old SP", + dataIndex: "SellPrice", + key: "SellPrice", + align: "right", + width: "70px", + render: (SellPrice) => + safeRound(SellPrice) !== null ? safeRound(SellPrice) : "-", + }, + ] + : []), + ...(hasField("Old Wholesale Price") + ? [ + { + title: "Old Wholesale Price", + dataIndex: "WhSalePrice", + key: "WhSalePrice", + align: "right", + width: "120px", + render: (WhSalePrice) => + safeRound(WhSalePrice) !== null ? safeRound(WhSalePrice) : "-", + }, + ] + : []), { - title: 'stock', - dataIndex: 'BalanceQty', - key: 'BalanceQty', - align: 'right', - render: (BalanceQty) => (BalanceQty !== null ? BalanceQty : '-'), - }, - { - title: 'Old MRP', - dataIndex: 'MRP', - key: 'MRP', - align: 'right', - render: (MRP) => (safeRound(MRP) !== null ? safeRound(MRP) : '-'), - }, - - { - title: 'Old SP', - dataIndex: 'SellPrice', - key: 'SellPrice', - align: 'right', - render: (SellPrice) => - safeRound(SellPrice) !== null ? safeRound(SellPrice) : '-', - }, - { - title: 'New MRP', - dataIndex: 'CurrentMRP', - key: 'CurrentMRP', - align: 'center', - with: '4rem', + title: "New MRP", + dataIndex: "CurrentMRP", + key: "CurrentMRP", + align: "center", + with: "4rem", editable: true, - render: (text, record) =>

{text ? text : 'Enter MRP'}

, + render: (text, record) =>

{text ? text : "Enter MRP"}

, width: 100, }, { - title: 'New SP', - dataIndex: 'CurrentAmt', - key: 'CurrentAmt', - align: 'center', - with: '4rem', + title: "New SP", + dataIndex: "CurrentAmt", + key: "CurrentAmt", + align: "center", + with: "4rem", editable: true, - render: (text, record) =>

{text ? text : 'Enter Price'}

, + render: (text, record) =>

{text ? text : "Enter Price"}

, width: 100, }, + ...(hasField("New Wholesale Price") + ? [ + { + title: "New Wholesale Price", + dataIndex: "CurrentWhAmt", + key: "CurrentWhAmt", + align: "center", + with: "4rem", + editable: true, + render: (text, record) => ( +

{text ? text : "Enter Wholesale Price"}

+ ), + width: 120, + }, + ] + : []), ]; const HandleStockNames = (e, option) => { @@ -1023,7 +1200,7 @@ const StockPriceUpdate = () => { // Check if any of the new products already exist in StockDetails setStockDetails((prevStockDetails) => { const existingInwardDtlIds = new Set( - prevStockDetails?.map((item) => item.InwardDtlId) + prevStockDetails?.map((item) => item.InwardDtlId), ); const uniqueNewStockDetails = newStockDetails @@ -1078,17 +1255,18 @@ const StockPriceUpdate = () => { // }; const HandlePutData = async () => { - if (RadioSelection == 'Bulk') { + if (RadioSelection == "Bulk") { const filteredCurrentAmtData = BulkProductData?.filter( (item) => - item.CurrentAmt !== undefined && - item.CurrentAmt !== null && - item.CurrentMRP !== '' && - item.CurrentAmt !== '' && - item.CurrentMRP !== undefined && - item.CurrentMRP !== null && - item.CurrentMRP !== '' && - item.CurrentAmt !== '' + (item.CurrentAmt !== undefined && + item.CurrentAmt !== null && + item.CurrentAmt !== "" && + item.CurrentMRP !== undefined && + item.CurrentMRP !== null && + item.CurrentMRP !== "") || + (item.CurrentWhAmt !== undefined && + item.CurrentWhAmt !== null && + item.CurrentWhAmt !== ""), ); const hasInvalidData = BulkProductData.every((item) => { const isAbsent = item.CurrentAmt == null && item.CurrentMRP == null; @@ -1102,45 +1280,47 @@ const StockPriceUpdate = () => { let Postdata = { CompId: CompId, BranchId: BranchId, + Type: "Variant", ProductDetails: filteredCurrentAmtData?.map((item) => ({ ProdId: item?.ProdId, - MRP: item?.CurrentMRP, - SellPrice: item?.CurrentAmt, - AdjComment: 'string', + NewMRP: item?.CurrentMRP, + NewSellPrice: item?.CurrentAmt, + AdjComment: "string", InwardDtlId: item?.InwardDtlId, + NewWholeSalePrice: item.CurrentWhAmt, })), }; - let response = await dispatch(PutStockPrice(Postdata)).unwrap(); + let response = await dispatch(bulkPriceUpdate(Postdata)).unwrap(); if (response?.data?.statusCode == 1) { setProductName(); - setMessageType('success'); + setMessageType("success"); setMessageData(response?.data?.response); fetchData(); - setBulksearchedText(''); + setBulksearchedText(""); setStockDetails([]); setBulkProductData([]); } else { - setMessageType('error'); + setMessageType("error"); setMessageData(response?.data?.response); } } else { - setMessageType('error'); - setMessageData('Please give all details'); + setMessageType("error"); + setMessageData("Please give all details"); } } else { const filteredStockDetails = StockDetails?.filter( (item) => item?.CurrentMRP && - item?.CurrentMRP !== '' && + item?.CurrentMRP !== "" && item?.CurrentAmt && - item?.CurrentAmt !== '' + item?.CurrentAmt !== "", ); if (filteredStockDetails?.length === 0) { - setMessageType('error'); - setMessageData('Please enter price details for at least one product'); + setMessageType("error"); + setMessageData("Please enter price details for at least one product"); return; } @@ -1151,7 +1331,7 @@ const StockPriceUpdate = () => { ProdId: item?.ProdId, MRP: item?.CurrentMRP, SellPrice: item?.CurrentAmt, - AdjComment: 'string', + AdjComment: "string", InwardDtlId: item?.InwardDtlId, })), UpdatedBy: 1, @@ -1163,11 +1343,11 @@ const StockPriceUpdate = () => { setStockNames(res?.data?.data); if (response?.data?.statusCode == 1) { setProductName(); - setMessageType('success'); + setMessageType("success"); setMessageData(response?.data?.response); fetchData(); } else { - setMessageType('error'); + setMessageType("error"); setMessageData(response?.data?.response); } setStockDetails([]); @@ -1276,108 +1456,140 @@ const StockPriceUpdate = () => { setFieldSetup(true); }; + const handleExcelFieldSetup = () => { + setExcelFieldSetup(true); + }; + const showPriceChangeModal = () => { setPriceChangeModalOpen(true); }; - const handleExport = async (isStockVariantBased = 'Yes') => { + const handleExport = async (isStockVariantBased = "Yes") => { setExportLoading(true); setPriceChangeModalOpen(false); const uniqueBulkProductData = - isStockVariantBased === 'Yes' + isStockVariantBased === "Yes" ? BulkProductData || [] : (BulkProductData || [])?.filter( - (item, index, self) => - index === self.findIndex((p) => p.ProdId === item.ProdId) - ); + (item, index, self) => + index === self.findIndex((p) => p.ProdId === item.ProdId), + ); if (!uniqueBulkProductData?.length) { - setMessageType('error'); - setMessageData('No data available to export'); + setMessageType("error"); + setMessageData("No data available to export"); setExportLoading(false); return; } const workbook = new ExcelJS.Workbook(); - const worksheet = workbook.addWorksheet('Products'); + const worksheet = workbook.addWorksheet("Products"); /* ---------------- COLUMN DEFINITIONS ---------------- */ const columns = [ - { header: 'Product Name', key: 'ProdName', width: 20 }, - ...(isStockVariantBased === 'Yes' - ? [{ header: 'Variant Name', key: 'ProdVariantName', width: 20 }] + { header: "Product Name", key: "ProdName", width: 20 }, + ...(isStockVariantBased === "Yes" + ? [{ header: "Variant Name", key: "ProdVariantName", width: 20 }] : []), - ...(isStockVariantBased === 'Yes' - ? [{ header: 'Batch No', key: 'BatchRef', width: 20 }] + ...(isStockVariantBased === "Yes" + ? [{ header: "Batch No", key: "BatchRef", width: 20 }] : []), - { header: 'Stock Date', key: 'StockDate', width: 15 }, - { header: 'Exp Date', key: 'ExpDate', width: 15 }, - { header: 'Stock', key: 'Stock', width: 10 }, - { header: 'Old MRP', key: 'OldMRP', width: 10 }, - { header: 'Old SP', key: 'OldSP', width: 10 }, - { header: 'Old Wholesale Price', key: 'WhSalePrice', width: 14 }, - { header: 'Size', key: 'Size', width: 10 }, - { header: 'Stock Maintainence', key: 'StockAvailable', width: 18 }, - { header: 'UOMName', key: 'UOMName', width: 15 }, - { header: 'New MRP', key: 'NewMRP', width: 12 }, - { header: 'New SP', key: 'NewSP', width: 12 }, - { header: 'New Wholesale Price', key: 'NewWhSalePrice', width: 14 }, - { header: 'ProdId', key: 'ProdId', width: 1 }, + ...(hasExcelField("Stock Date") + ? [{ header: "Stock Date", key: "StockDate", width: 15 }] + : []), + ...(hasExcelField("Expiry Date") + ? [{ header: "Exp Date", key: "ExpDate", width: 15 }] + : []), + ...(hasExcelField("Stock") + ? [{ header: "Stock", key: "Stock", width: 10 }] + : []), + ...(hasExcelField("Old MRP") + ? [{ header: "Old MRP", key: "OldMRP", width: 10 }] + : []), + ...(hasExcelField("Old SP") + ? [{ header: "Old SP", key: "OldSP", width: 10 }] + : []), + ...(hasExcelField("Old Wholesale Price") + ? [{ header: "Old Wholesale Price", key: "WhSalePrice", width: 14 }] + : []), + ...(hasExcelField("Size") + ? [{ header: "Size", key: "Size", width: 10 }] + : []), + ...(hasExcelField("Stock Maintainence") + ? [{ header: "Stock Maintainence", key: "StockAvailable", width: 18 }] + : []), + ...(hasExcelField("UOM Name") + ? [{ header: "UOMName", key: "UOMName", width: 15 }] + : []), + // ...(hasExcelField("New MRP & New SP") + // ? [ + { header: "New MRP", key: "NewMRP", width: 12 }, + { header: "New SP", key: "NewSP", width: 12 }, + // ] + // : []), - ...(isStockVariantBased === 'Yes' - ? [{ header: 'InwardDtlId', key: 'InwardDtlId', width: 1 }] + ...(hasExcelField("New Wholesale Price") + ? [{ header: "New Wholesale Price", key: "NewWhSalePrice", width: 14 }] : []), - { header: 'key', key: 'key', width: 1 }, - { header: 'downloadType', key: 'downloadType', width: 1 }, + // --- Hidden system columns (always included) --- + { header: "ProdId", key: "ProdId", width: 1 }, + + ...(isStockVariantBased === "Yes" + ? [{ header: "InwardDtlId", key: "InwardDtlId", width: 1 }] + : []), + + { header: "key", key: "key", width: 1 }, + { header: "downloadType", key: "downloadType", width: 1 }, ]; worksheet.columns = columns; - worksheet.views = [{ state: 'frozen', xSplit: 1, ySplit: 1 }]; + worksheet.views = [{ state: "frozen", xSplit: 1, ySplit: 1 }]; const headerRow = worksheet.getRow(1); - const newMRPCol = headerRow.values.indexOf('New MRP'); - const newSPCol = headerRow.values.indexOf('New SP'); + const newMRPCol = headerRow.values.indexOf("New MRP"); + const newSPCol = headerRow.values.indexOf("New SP"); + const hasNewMRPAndSP = newMRPCol > 0 && newSPCol > 0; /* ---------------- HEADER STYLE ---------------- */ worksheet.getRow(1).eachCell((cell) => { const header = cell.value; const isHiddenCol = - header === 'key' || - header === 'ProdId' || - header === 'InwardDtlId' || - header === 'downloadType'; + header === "key" || + header === "ProdId" || + header === "InwardDtlId" || + header === "downloadType"; cell.font = { bold: true, size: isHiddenCol ? 1 : 11, - color: { argb: isHiddenCol ? 'FFFFFFFF' : 'FF000000' }, + color: { argb: isHiddenCol ? "FFFFFFFF" : "FF000000" }, }; cell.alignment = { - horizontal: 'center', - vertical: 'middle', + horizontal: "center", + vertical: "middle", wrapText: true, // ✅ prevents overflow in header }; cell.fill = { - type: 'pattern', - pattern: 'solid', + type: "pattern", + pattern: "solid", fgColor: { - argb: isHiddenCol ? 'FFFFFFFF' : 'FF52C41A', + argb: isHiddenCol ? "FFFFFFFF" : "FF52C41A", }, }; cell.border = isHiddenCol ? undefined : { - right: { style: 'thin', color: { argb: 'FF000000' } }, - bottom: { style: 'thin', color: { argb: 'FF000000' } }, - }; + right: { style: "thin", color: { argb: "FF000000" } }, + bottom: { style: "thin", color: { argb: "FF000000" } }, + }; }); /* ---------------- ADD DATA ---------------- */ @@ -1387,7 +1599,7 @@ const StockPriceUpdate = () => { ProdVariantName: product?.ProdVariantName, BatchRef: product?.BatchRef, StockDate: product?.InwardDate, - ExpDate: product?.ExpDate || '-', + ExpDate: product?.ExpDate || "-", Stock: product?.BalanceQty, OldMRP: product?.MRP, OldSP: product?.SellPrice, @@ -1396,35 +1608,37 @@ const StockPriceUpdate = () => { StockAvailable: product?.StockAvailable, UOMName: product?.UOMName, key: product?.key, - downloadType: isStockVariantBased === 'Yes' ? 'Variant' : 'Product', - NewMRP: '', - NewSP: '', - NewWhSalePrice: '', + downloadType: isStockVariantBased === "Yes" ? "Variant" : "Product", + NewMRP: "", + NewSP: "", + NewWhSalePrice: "", ProdId: product?.ProdId, InwardDtlId: - isStockVariantBased === 'Yes' ? product?.InwardDtlId : undefined, + isStockVariantBased === "Yes" ? product?.InwardDtlId : undefined, }); }); // ---------------- VALIDATION: New SP <= New MRP ---------------- - worksheet.eachRow({ includeEmpty: true }, (row, rowNumber) => { - if (rowNumber === 1) return; // skip header + if (hasNewMRPAndSP) { + worksheet.eachRow({ includeEmpty: true }, (row, rowNumber) => { + if (rowNumber === 1) return; // skip header - const newMRPCell = row.getCell(newMRPCol); - const newSPCell = row.getCell(newSPCol); + const newMRPCell = row.getCell(newMRPCol); + const newSPCell = row.getCell(newSPCol); - newSPCell.dataValidation = { - type: 'custom', - allowBlank: true, - formulae: [ - `IFERROR(VALUE(${newSPCell.address}),0) <= IFERROR(VALUE(${newMRPCell.address}),0)`, - ], - showErrorMessage: true, - errorStyle: 'stop', - errorTitle: 'Invalid Selling Price', - error: 'New SP cannot be greater than New MRP', - }; - }); + newSPCell.dataValidation = { + type: "custom", + allowBlank: true, + formulae: [ + `IFERROR(VALUE(${newSPCell.address}),0) <= IFERROR(VALUE(${newMRPCell.address}),0)`, + ], + showErrorMessage: true, + errorStyle: "stop", + errorTitle: "Invalid Selling Price", + error: "New SP cannot be greater than New MRP", + }; + }); + } /* ---------------- UNLOCK EVERYTHING ---------------- */ worksheet.eachRow({ includeEmpty: true }, (row) => { @@ -1448,38 +1662,38 @@ const StockPriceUpdate = () => { const header = worksheet.getRow(1).getCell(colNumber).value; const isHiddenCol = - header === 'key' || - header === 'ProdId' || - header === 'InwardDtlId' || - header === 'downloadType'; + header === "key" || + header === "ProdId" || + header === "InwardDtlId" || + header === "downloadType"; const isEditable = - header === 'New MRP' || - header === 'New SP' || - header === 'New Wholesale Price'; + header === "New MRP" || + header === "New SP" || + header === "New Wholesale Price"; cell.protection = { locked: !isEditable }; cell.alignment = { - vertical: 'middle', + vertical: "middle", wrapText: true, }; if (isHiddenCol) { cell.font = { size: 1, - color: { argb: 'FFFFFFFF' }, + color: { argb: "FFFFFFFF" }, }; cell.fill = { - type: 'pattern', - pattern: 'solid', - fgColor: { argb: 'FFFFFFFF' }, + type: "pattern", + pattern: "solid", + fgColor: { argb: "FFFFFFFF" }, }; } }); }); /* ---------------- PROTECT SHEET ---------------- */ - await worksheet.protect('', { + await worksheet.protect("", { selectLockedCells: false, selectUnlockedCells: true, formatCells: false, @@ -1491,12 +1705,12 @@ const StockPriceUpdate = () => { /* ---------------- DOWNLOAD ---------------- */ const buffer = await workbook.xlsx.writeBuffer(); const blob = new Blob([buffer], { - type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", }); - const link = document.createElement('a'); + const link = document.createElement("a"); link.href = URL.createObjectURL(blob); - link.download = 'PriceChange_Data.xlsx'; + link.download = "PriceChange_Data.xlsx"; link.click(); setExportLoading(false); @@ -1507,20 +1721,23 @@ const StockPriceUpdate = () => { }; const handleFileUpload = (e) => { + setFileLoading(true); const file = e.target.files[0]; if (!file) { dispatch(emptyExcelData()); + setFileLoading(false); return; } const isAllowed = allowedExcelTypes?.includes(file.type); if (!isAllowed) { Modal.error({ - title: 'Invalid File Type', - content: 'Only Excel files (.xls, .xlsx) are allowed.', + title: "Invalid File Type", + content: "Only Excel files (.xls, .xlsx) are allowed.", }); handleCancelData(); + setFileLoading(false); return; } @@ -1531,14 +1748,16 @@ const StockPriceUpdate = () => { const extractedData = extractPriceChangeDataFromExcel(arrayBuffer); - console.log(extractedData, 'extractedData'); + console.log(extractedData, "extractedData"); if ((extractedData || [])?.length === 0) { - setMessageData('No Data Found in Uploaded Sheet'); - setMessageType('error'); + setMessageData("No Data Found in Uploaded Sheet"); + setMessageType("error"); handleCancelData(); + setFileLoading(false); return; } setUploadedData(extractedData); + setFileLoading(false); // setFormValuesFromExtractedData(extractedData); }; @@ -1571,40 +1790,41 @@ const StockPriceUpdate = () => { }; const extractPriceChangeDataFromExcel = (arrayBuffer) => { - const workbook = read(arrayBuffer, { type: 'array' }); + const workbook = read(arrayBuffer, { type: "array" }); const worksheet = workbook.Sheets[workbook.SheetNames[0]]; const rows = utils.sheet_to_json(worksheet, { header: 1, raw: false, - defval: '', + defval: "", }); if (!rows.length) return []; const header = rows[0]; + setHeaders(header); const dataRows = rows.slice(1); // Helper to safely get column value const getVal = (row, colName) => { const idx = header.indexOf(colName); - return idx !== -1 ? row[idx] : ''; + return idx !== -1 ? row[idx] : ""; }; const result = dataRows .map((row) => { - const prodId = getVal(row, 'ProdId')?.toString().trim(); + const prodId = getVal(row, "ProdId")?.toString().trim(); if (!prodId) return null; const newMRP = - getVal(row, 'New MRP') !== '' ? Number(getVal(row, 'New MRP')) : null; + getVal(row, "New MRP") !== "" ? Number(getVal(row, "New MRP")) : null; const newSP = - getVal(row, 'New SP') !== '' ? Number(getVal(row, 'New SP')) : null; + getVal(row, "New SP") !== "" ? Number(getVal(row, "New SP")) : null; const newWholesale = - getVal(row, 'New Wholesale Price') !== '' - ? Number(getVal(row, 'New Wholesale Price')) + getVal(row, "New Wholesale Price") !== "" + ? Number(getVal(row, "New Wholesale Price")) : null; // ❌ Must have at least one change @@ -1616,37 +1836,37 @@ const StockPriceUpdate = () => { // 🔹 Product identity localId: uuidv4(), ProdId: prodId, - InwardDtlId: getVal(row, 'InwardDtlId') - ? getVal(row, 'InwardDtlId').toString() + InwardDtlId: getVal(row, "InwardDtlId") + ? getVal(row, "InwardDtlId").toString() : null, // 🔹 Product info - VariantName: getVal(row, 'Variant Name') || null, - BatchRef: getVal(row, 'Batch No') || null, - ProductName: getVal(row, 'Product Name') || null, - Size: getVal(row, 'Size') || null, - UOMName: getVal(row, 'UOMName') || null, - StockMaintainence: getVal(row, 'Stock Maintainence') || null, + VariantName: getVal(row, "Variant Name") || null, + BatchRef: getVal(row, "Batch No") || null, + ProductName: getVal(row, "Product Name") || null, + Size: getVal(row, "Size") || null, + UOMName: getVal(row, "UOMName") || null, + StockMaintainence: getVal(row, "Stock Maintainence") || null, // 🔹 Stock / dates - StockDate: getVal(row, 'Stock Date') || null, - ExpDate: getVal(row, 'Exp Date') || null, - downloadType: getVal(row, 'downloadType') || null, + StockDate: getVal(row, "Stock Date") || null, + ExpDate: getVal(row, "Exp Date") || null, + downloadType: getVal(row, "downloadType") || null, Stock: - getVal(row, 'Stock') !== '' ? Number(getVal(row, 'Stock')) : null, + getVal(row, "Stock") !== "" ? Number(getVal(row, "Stock")) : null, // 🔹 Old prices OldMRP: - getVal(row, 'Old MRP') !== '' - ? Number(getVal(row, 'Old MRP')) + getVal(row, "Old MRP") !== "" + ? Number(getVal(row, "Old MRP")) : null, OldSP: - getVal(row, 'Old SP') !== '' ? Number(getVal(row, 'Old SP')) : null, + getVal(row, "Old SP") !== "" ? Number(getVal(row, "Old SP")) : null, OldWholeSalePrice: - getVal(row, 'Old Wholesale Price') !== '' - ? Number(getVal(row, 'Old Wholesale Price')) + getVal(row, "Old Wholesale Price") !== "" + ? Number(getVal(row, "Old Wholesale Price")) : null, // 🔹 New prices (normalized) @@ -1663,13 +1883,14 @@ const StockPriceUpdate = () => { const handleCancelData = () => { dispatch(emptyExcelData()); if (fileInputRef.current) { - fileInputRef.current.value = ''; + fileInputRef.current.value = ""; } setUploadedData([]); }; const handleSubmit = async () => { try { + setLoading(true); const formValues = excelDataRef.current?.getFieldsValue(); // Validate all records @@ -1680,26 +1901,26 @@ const StockPriceUpdate = () => { // If MRP is present, SP must also be present if (newMRP && !newSP) { - setMessageType('error'); + setMessageType("error"); setMessageData( - 'If New MRP is provided, New SP must also be provided' + "If New MRP is provided, New SP must also be provided", ); return; } // If SP is present, MRP must also be present if (newSP && !newMRP) { - setMessageType('error'); + setMessageType("error"); setMessageData( - 'If New SP is provided, New MRP must also be provided' + "If New SP is provided, New MRP must also be provided", ); return; } // New SP cannot be greater than New MRP if (newMRP && newSP && parseFloat(newSP) > parseFloat(newMRP)) { - setMessageType('error'); - setMessageData('New SP cannot be greater than New MRP'); + setMessageType("error"); + setMessageData("New SP cannot be greater than New MRP"); return; } } @@ -1722,7 +1943,7 @@ const StockPriceUpdate = () => { NewSellPrice: data?.NewSellPrice, NewMRP: data?.NewMRP, NewWholeSalePrice: data?.NewWholeSalePrice, - AdjComment: 'string', + AdjComment: "string", })); const putData = { @@ -1737,26 +1958,86 @@ const StockPriceUpdate = () => { const res = await dispatch(bulkPriceUpdate(putData))?.unwrap(); if (res?.data?.statusCode === 1) { - setMessageData(res?.data?.response || 'Price Updated Successfully'); - setMessageType('success'); + setMessageData(res?.data?.response || "Price Updated Successfully"); + setMessageType("success"); setUploadedData([]); handleCancelData(); setExcelModalOpen(false); await fetchData(); } else { setMessageData(res?.data?.response); - setMessageType('error'); + setMessageType("error"); } // If validation passes, proceed with submission - console.log('Form validation passed', updatedData); + console.log("Form validation passed", updatedData); } catch (error) { - setMessageType('error'); - setMessageData('Please check all fields and try again'); + setMessageType("error"); + setMessageData("Please check all fields and try again"); + } finally { + setLoading(false); + } + }; + + const handleFieldSetupSubmit = async () => { + const postData = { + AppId: AppId, + CompId: CompId, + BranchId: BranchId, + Type: "GB", + FormType: fieldSetup ? "Price Change" : "Price Change Sheet", + TypeId: fieldSetup ? categoryId : excelCategoryId, + ConfigDtl: (fieldSetup ? selectedFields : selectedExcelFields)?.map( + (field) => ({ + ConfigId: field, + Access: "Y", + }), + ), + CreatedBy: UserId, + }; + + const response = await dispatch(postFieldSetup(postData))?.unwrap(); + + if (response?.data?.statusCode === 1) { + setMessageType("success"); + setMessageData(response?.data?.response); + if (fieldSetup) { + await getFieldSetup(); + } else { + await getExcelFieldSetup(); + } + } else { + setMessageType("error"); + setMessageData("Failed to set up fields"); + } + }; + + const handleFieldSelect = (value) => { + if (fieldSetup) { + setSelectedFields((prev) => { + if (prev.includes(value)) { + return prev; + } + return [value, ...prev]; + }); + } else { + setSelectedExcelFields((prev) => { + if (prev.includes(value)) { + return prev; + } + return [value, ...prev]; + }); + } + }; + + const handleFieldRemove = (id) => { + if (fieldSetup) { + setSelectedFields((prev) => prev.filter((field) => field !== id)); + } else { + setSelectedExcelFields((prev) => prev.filter((field) => field !== id)); } }; - return (
@@ -1768,24 +2049,24 @@ const StockPriceUpdate = () => {
- +
- {RadioSelection == 'Bulk' && ( + {RadioSelection == "Bulk" && (
@@ -1805,25 +2086,29 @@ const StockPriceUpdate = () => { icon={} />
- + +
+ +
+
)}
- {RadioSelection == 'Single' && ( + {RadioSelection == "Single" && (
-
+
@@ -1834,7 +2119,7 @@ const StockPriceUpdate = () => { onChangeFunction={(value, option) => HandleStockNames(value, option) } - style={{ width: '240px' }} + style={{ width: "240px" }} options={DataSource} isOnchanges={ProductName ? true : false} /> @@ -1863,17 +2148,17 @@ const StockPriceUpdate = () => {
{
- {(RadioSelection == 'Bulk' || - (RadioSelection == 'Single' && StockDetails.length > 0)) && ( -
- } - disabled={addnewAccess} - > -
- )} + {(RadioSelection == "Bulk" || + (RadioSelection == "Single" && StockDetails.length > 0)) && ( +
+ } + disabled={addnewAccess} + > +
+ )}
- {RadioSelection == 'Single' && ( + {RadioSelection == "Single" && (
{ StockDetails?.length < 11 ? false : { - current: page, - pageSize: pageSize, - onChange: handlePageChange, - } + current: page, + pageSize: pageSize, + onChange: handlePageChange, + } } onChange={handleChange} >
)} - {RadioSelection == 'Bulk' && ( + {RadioSelection == "Bulk" && (
{ pagination={{ current: Bulkchangepage, pageSize: pageSize, - pageSizeOptions: ['10', '20', '30'], + pageSizeOptions: ["10", "20", "30"], onChange: handlePageChangeBulk, showSizeChanger: false, }} @@ -1947,31 +2232,51 @@ const StockPriceUpdate = () => { open={excelModalOpen} title="Bulk Upload" footer={false} - className={'bulkuploadmodal'} + className={"bulkuploadmodal padding-less-modal"} handleCancel={() => { setExcelModalOpen(false); handleCancelData(); }} - width={uploadedData?.length > 0 ? 2500 : 600} + width={uploadedData?.length > 0 ? 1200 : 600} children={ <> {uploadedData?.length === 0 && (
+ +
+ +
+
{ } : () => showPriceChangeModal() + } >
-
+
Export Excel
@@ -1979,128 +2284,238 @@ const StockPriceUpdate = () => { )} {(!uploadedData || uploadedData?.length === 0) && ( <> -
+ {!fileLoading && ( -
+ )} + {fileLoading && ( +
+
+

+ Processing file... +

+ +
+ )} )} -
- {uploadedData && uploadedData?.length > 0 ? ( + {uploadedData && uploadedData?.length > 0 && !loading ? ( +
-
record.localId} - // components={components} - // bordered - dataSource={uploadedData} - // className="tableExcelUpload" - // onChange={handleTableChange} - className="price-change-data" - /> +
+
record.localId} + // components={components} + // bordered + dataSource={uploadedData} + // className="tableExcelUpload" + // onChange={handleTableChange} + className="price-change-data" + /> +
} disabled={addnewAccess} />
- ) : ( -

- )} - + + ) : ( +

+ )} + {loading && ( +
+
+

+ Submitting... +

+ +
+ )} + setExcelFieldSetup(false)} + footer={false} + title={"Select the columns you want to include in the sheet"} + children={ +
+ {/*
+ +
*/} +
+
+ + + !selectedExcelFields?.some((s) => s === p.value), + )} + /> + +
+ {selectedExcelFields + ?.map((id) => + tableExcelFieldPreferences?.find( + (p) => p.value === id, + ), + ) + .filter(Boolean) + .map((field) => ( +
+
{field.label}
+
handleFieldRemove(field.value)} + > + +
+
+ ))} +
+
+ } + htmlType={true} + /> +
+ +
+
+ } + /> } /> Stock/Variant Based Price Change?

+

Stock/Variant Based Price Change?

} footer={true} width={500} handleCancel={() => setPriceChangeModalOpen(false)} handleSubmit={() => handleExport(stockVariantBased)} children={ -
+
{
} /> - + setFieldSetup(false)} + footer={false} + title={"Select the fields you want to include in the table"} + children={ +
+ {/*
+ +
*/} +
+
+ + !selectedFields?.some((s) => s === p.value), + )} + /> + +
+ {selectedFields + ?.map((id) => + tableFieldPreferences?.find((p) => p.value === id), + ) + .filter(Boolean) + .map((field) => ( +
+
{field.label}
+
handleFieldRemove(field.value)} + > + +
+
+ ))} +
+
+ } + htmlType={true} + /> +
+ +
+
+ } + />
); }; diff --git a/src/Styles/Employee/EmpMaster.scss b/src/Styles/Employee/EmpMaster.scss index 659a1d7..1525651 100644 --- a/src/Styles/Employee/EmpMaster.scss +++ b/src/Styles/Employee/EmpMaster.scss @@ -18,7 +18,7 @@ border: none; } -.subinputForm .ant-input-affix-wrapper > input.ant-input { +.subinputForm .ant-input-affix-wrapper>input.ant-input { font-size: inherit; border: none; padding: 18px 14px 6px 1px !important; @@ -87,6 +87,7 @@ letter-spacing: -0.3px; } } + .EmpDOJMain { .ant-picker-input { input::placeholder { @@ -94,3 +95,61 @@ } } } + + +.image-preview__content { + background-color: #f5f5f5; + margin: 1rem; + border: 2px solid #dfdfdf; + display: flex; + align-items: flex-start; + justify-content: center; + padding: 1rem; + border-radius: 4px; + + img { + width: 100%; + height: 90%; + } +} + +.image-preview { + display: flex; + width: 100%; + align-items: center; + justify-content: space-between; + gap: 1rem; +} + +.image-preview__nav-btn { + border: none; + outline: none; + width: 40px; + height: 40px; + display: flex; + align-items: center; + cursor: pointer; + justify-content: center; + border-radius: 10pc; + background-color: #acacac; + color: #fff; + font-size: 18px; + transition: all 0.3s; + + &:hover { + background-color: #979797; + transform: scale(1.05); + } + + &:active { + background-color: #5e5e5e; + } + + +} + +.padding-less-modal { + .ant-modal-content { + padding: 34px !important; + } +} \ No newline at end of file diff --git a/src/Styles/OverAllStyle/OverAllStyle.scss b/src/Styles/OverAllStyle/OverAllStyle.scss index a4a0a88..180542c 100644 --- a/src/Styles/OverAllStyle/OverAllStyle.scss +++ b/src/Styles/OverAllStyle/OverAllStyle.scss @@ -811,6 +811,11 @@ } .pricechangeTable { + width: 83vw; + scrollbar-width: thin; + overflow-x: auto; + overflow-y: auto; + .ant-input { padding: 4px 11px 4px 11px !important; width: 80px !important; @@ -1337,6 +1342,12 @@ table { width: 100%; } +.pricechangedata { + width: 100%; + overflow: auto; + scrollbar-width: thin; +} + .ProductList-pwiseQrcode { height: max-content !important; max-height: 70vh; diff --git a/src/Styles/Product/excel.scss b/src/Styles/Product/excel.scss index fff0711..682e6c1 100644 --- a/src/Styles/Product/excel.scss +++ b/src/Styles/Product/excel.scss @@ -30,51 +30,70 @@ border-radius: 4px; font-family: 'Poppins'; font-size: 16px; + svg { margin-top: -2px; font-size: 20px; display: flex; } + + &.is-loading { + cursor: not-allowed; + opacity: 0.7; + pointer-events: none; + background-color: #9ca3af; + } } .tableExcelUpload { .ant-table-cell { padding: 0 8px !important; } + .ant-select-selection-placeholder { padding-inline-end: 16px !important; } + .ant-table-thead { th { text-align: left; vertical-align: baseline; } } + thead { height: 100px !important; } + th { height: 100px !important; } + .ant-select { width: 150px !important; } + .ant-select-selection-item { padding-inline-end: 14px !important; } + .ant-select-selector { height: 40px !important; } + .ant-select-selection-item { font-size: 12px !important; } + .ant-upload-select { height: 50px !important; width: 85px !important; } + .uploadText { margin-top: 0 !important; } + .ant-upload-picture-card-wrapper { border-spacing: 0 !important; } diff --git a/vite.config.js.timestamp-1747646973077-8436f678165ee.mjs b/vite.config.js.timestamp-1747646973077-8436f678165ee.mjs deleted file mode 100644 index e69de29..0000000 diff --git a/vite.config.js.timestamp-1765166822050-2734cdcb62983.mjs b/vite.config.js.timestamp-1765166822050-2734cdcb62983.mjs deleted file mode 100644 index fc05b12..0000000 --- a/vite.config.js.timestamp-1765166822050-2734cdcb62983.mjs +++ /dev/null @@ -1,38 +0,0 @@ -// vite.config.js -import { defineConfig } from "file:///D:/KarthigaLakshmi/A.Dec/retail%20dec%201/node_modules/vite/dist/node/index.js"; -import react from "file:///D:/KarthigaLakshmi/A.Dec/retail%20dec%201/node_modules/@vitejs/plugin-react/dist/index.js"; -import { terser } from "file:///D:/KarthigaLakshmi/A.Dec/retail%20dec%201/node_modules/rollup-plugin-terser/rollup-plugin-terser.mjs"; -var vite_config_default = defineConfig(({ command, mode }) => { - if (mode === "production") { - return { - plugins: [ - react() - // terser({ // Add terser plugin for production - // compress: { - // drop_console: true, // This removes all console.* statements - // }, - // }), - ], - base: "/apps/retail/", - envDir: "src", - envPrefix: "ENV_" - }; - } else { - return { - plugins: [react()], - envDir: "src", - envPrefix: "ENV_", - server: { - host: "192.168.1.22", - port: process.env.PORT || 3015 - }, - optimizeDeps: { - exclude: ["console.log"] - } - }; - } -}); -export { - vite_config_default as default -}; -//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcuanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJEOlxcXFxLYXJ0aGlnYUxha3NobWlcXFxcQS5EZWNcXFxccmV0YWlsIGRlYyAxXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ZpbGVuYW1lID0gXCJEOlxcXFxLYXJ0aGlnYUxha3NobWlcXFxcQS5EZWNcXFxccmV0YWlsIGRlYyAxXFxcXHZpdGUuY29uZmlnLmpzXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ltcG9ydF9tZXRhX3VybCA9IFwiZmlsZTovLy9EOi9LYXJ0aGlnYUxha3NobWkvQS5EZWMvcmV0YWlsJTIwZGVjJTIwMS92aXRlLmNvbmZpZy5qc1wiO2ltcG9ydCB7IGRlZmluZUNvbmZpZyB9IGZyb20gXCJ2aXRlXCI7XG5pbXBvcnQgcmVhY3QgZnJvbSBcIkB2aXRlanMvcGx1Z2luLXJlYWN0XCI7XG5pbXBvcnQgeyB0ZXJzZXIgfSBmcm9tIFwicm9sbHVwLXBsdWdpbi10ZXJzZXJcIjtcblxuZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKCh7IGNvbW1hbmQsIG1vZGUgfSkgPT4ge1xuICBpZiAobW9kZSA9PT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICByZXR1cm4ge1xuICAgICAgcGx1Z2luczogW1xuICAgICAgICByZWFjdCgpLFxuICAgICAgICAvLyB0ZXJzZXIoeyAgLy8gQWRkIHRlcnNlciBwbHVnaW4gZm9yIHByb2R1Y3Rpb25cbiAgICAgICAgLy8gICBjb21wcmVzczoge1xuICAgICAgICAvLyAgICAgZHJvcF9jb25zb2xlOiB0cnVlLCAgLy8gVGhpcyByZW1vdmVzIGFsbCBjb25zb2xlLiogc3RhdGVtZW50c1xuICAgICAgICAvLyAgIH0sXG4gICAgICAgIC8vIH0pLFxuICAgICAgXSxcbiAgICAgIGJhc2U6IFwiL2FwcHMvcmV0YWlsL1wiLFxuICAgICAgZW52RGlyOiBcInNyY1wiLFxuICAgICAgZW52UHJlZml4OiBcIkVOVl9cIixcbiAgICB9O1xuICB9IGVsc2UgeyBcbiAgICByZXR1cm4ge1xuICAgICAgcGx1Z2luczogW3JlYWN0KCldLFxuICAgICAgZW52RGlyOiBcInNyY1wiLFxuICAgICAgZW52UHJlZml4OiBcIkVOVl9cIixcbiAgICAgIHNlcnZlcjoge1xuICAgICAgICBob3N0OiBcIjE5Mi4xNjguMS4yMlwiLFxuICAgICAgICBwb3J0OiBwcm9jZXNzLmVudi5QT1JUIHx8IDMwMTUsXG4gICAgICB9LFxuICAgICAgb3B0aW1pemVEZXBzOiB7XG4gICAgICAgIGV4Y2x1ZGU6IFtcImNvbnNvbGUubG9nXCJdLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG59KTtcbiJdLAogICJtYXBwaW5ncyI6ICI7QUFBNlMsU0FBUyxvQkFBb0I7QUFDMVUsT0FBTyxXQUFXO0FBQ2xCLFNBQVMsY0FBYztBQUV2QixJQUFPLHNCQUFRLGFBQWEsQ0FBQyxFQUFFLFNBQVMsS0FBSyxNQUFNO0FBQ2pELE1BQUksU0FBUyxjQUFjO0FBQ3pCLFdBQU87QUFBQSxNQUNMLFNBQVM7QUFBQSxRQUNQLE1BQU07QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsTUFNUjtBQUFBLE1BQ0EsTUFBTTtBQUFBLE1BQ04sUUFBUTtBQUFBLE1BQ1IsV0FBVztBQUFBLElBQ2I7QUFBQSxFQUNGLE9BQU87QUFDTCxXQUFPO0FBQUEsTUFDTCxTQUFTLENBQUMsTUFBTSxDQUFDO0FBQUEsTUFDakIsUUFBUTtBQUFBLE1BQ1IsV0FBVztBQUFBLE1BQ1gsUUFBUTtBQUFBLFFBQ04sTUFBTTtBQUFBLFFBQ04sTUFBTSxRQUFRLElBQUksUUFBUTtBQUFBLE1BQzVCO0FBQUEsTUFDQSxjQUFjO0FBQUEsUUFDWixTQUFTLENBQUMsYUFBYTtBQUFBLE1BQ3pCO0FBQUEsSUFDRjtBQUFBLEVBQ0Y7QUFDRixDQUFDOyIsCiAgIm5hbWVzIjogW10KfQo=