Android_Retail/src/Pages/StockPriceUpdate/StockPriceUpdate.jsx

2118 lines
61 KiB
React
Raw Normal View History

2026-01-27 18:27:29 +05:30
import React, {
useEffect,
useState,
useRef,
useContext,
useCallback,
} 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';
import {
PutStockPrice,
bulkPriceUpdate,
getStockNames,
} 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';
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';
import {
emptyExcelData,
fileInputRefSelector,
} 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 {
getFieldSetupData,
postFieldSetup,
} from '../../Features/ProductPage/ProductPage.js';
import {
ApplicationPreferences,
getCommonAppPreference,
} 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'
);
const ApplicationPreferenceData = useSelector(ApplicationPreferences);
const categoryId = ApplicationPreferenceData?.find(
(p) => p?.PreferredCatName?.toLowerCase() === 'price change fields'
)?.PreferredCatId;
const fileInputRef = useRef(fileInputRefSelector);
const excelDataRef = useRef(null);
const formRef = useRef(null);
const allowedExcelTypes = [
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', // .xlsx
'application/vnd.ms-excel', // .xls
];
const dispatch = useDispatch();
const [selectedFields, setSelectedFields] = useState([]);
const [tableFieldPreferences, setTableFieldPreferences] = useState([]);
const [messageType, setMessageType] = useState(null);
const [messageData, setMessageData] = useState(null);
const [StockNames, setStockNames] = useState([]);
const [ProductName, setProductName] = useState(null);
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 [filteredInfo, setFilteredInfo] = useState({});
const [page, setpage] = useState(1);
const [Bulkchangepage, setBulkchangepage] = useState(1);
const [pageSize, setPageSize] = useState(10);
const [openEditModal, setOpenEditModal] = useState(false);
const [open, setOpen] = useState(false);
const [excelModalOpen, setExcelModalOpen] = useState(false);
const [priceChangeModalOpen, setPriceChangeModalOpen] = useState(false);
const [stockVariantBased, setStockVariantBased] = useState('Yes');
const [exportLoading, setExportLoading] = useState(false);
const [loading, setLoading] = useState(false);
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 [empData, setEmpData] = useState();
const [addnewAccess, setaddnewAccess] = useState(true);
const [RadioSelection, setRadioSelection] = useState('Single');
const [BulkProductData, setBulkProductData] = useState([]);
const [allowDecimal, setAllowDecimal] = useState(false);
const items = [
{
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',
width: 180,
render: (value, record, index) => (
<p>{`${value} (${record?.Size} ${record?.UOMName})`}</p>
),
},
{
title: 'Variant Name',
dataIndex: 'VariantName',
key: 'VariantName',
width: 180,
},
{
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,
},
// ✅ EDITABLE
{
title: 'New MRP',
dataIndex: 'NewMRP',
key: 'NewMRP',
width: 120,
render: (_, record, index) => (
<Form.Item name={`NewMRP${record.localId}`}>
<Input
placeholder="New MRP"
inputMode="decimal"
onChange={(e) =>
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;
}
const parts = cleanedValue.split('.');
e.target.value =
parts.length > 2
? `${parts[0]}.${parts.slice(1).join('')}`
: cleanedValue;
}}
/>
</Form.Item>
),
},
{
title: 'New SP',
dataIndex: 'NewSellPrice',
key: 'NewSellPrice',
width: 120,
render: (_, record, index) => (
<Form.Item
name={`NewSellPrice${record.localId}`}
validateTrigger={['onChange', 'onBlur']}
rules={[
({ getFieldValue }) => ({
validator(_, value) {
const mrp = getFieldValue(`NewMRP${record.localId}`);
if (mrp === undefined || mrp === null || mrp === '') {
return Promise.resolve();
}
const numMRP = Number(mrp);
const numSP =
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')
);
}
if (numSP > numMRP) {
return Promise.reject(
new Error('New SP cannot be greater than New MRP')
);
}
return Promise.resolve();
},
}),
]}
>
<Input
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;
}
e.target.value =
parts.length > 2
? `${parts[0]}.${parts.slice(1).join('')}`
: cleanedValue;
}}
onChange={(e) => {
{
handlePriceChange(
index,
'NewSellPrice',
e.target.value,
record.localId
);
excelDataRef.current
?.validateFields([`NewSellPrice${record.localId}`])
.catch(() => {});
}
}}
/>
</Form.Item>
),
},
{
title: 'New Wholesale Price',
dataIndex: 'NewWholeSalePrice',
key: 'NewWholeSalePrice',
width: 160,
render: (value, record, index) => (
<Form.Item name={`NewWholeSalePrice${record?.localId}`}>
<Input
onChange={(e) =>
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;
}}
/>
</Form.Item>
),
},
{
title: 'Action',
key: 'action',
width: 80,
align: 'center',
render: (_, record, index) => (
<DeleteFilled
style={{
color: '#EF4443',
cursor: 'pointer',
}}
onClick={() => handleRemoveRecord(index)}
/>
),
},
];
useEffect(() => {
dispatch(changeBreadCrumb({ items: items }));
getPreference();
// if (UserType === "Employee") {
// fetchApi()
// }
}, []);
useEffect(() => {
if (UserType === 'Employee') {
fetchApi();
}
}, [UserType]);
useEffect(() => {
let hasAccess = false;
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';
}
setaddnewAccess(!hasAccess);
}, [empData, SAAccessCommonMaster, UserType]);
useEffect(() => {
if (uploadedData?.length) {
setFormValuesFromExtractedData(uploadedData);
} else {
excelDataRef?.current?.resetFields();
}
}, [uploadedData]);
const fetchApi = async () => {
let data = {
CompId: CompId,
BranchId: BranchId,
AppId: AppId,
EmpId: UserId,
};
let response = await dispatch(getEmpAccess(data)).unwrap();
let datas = response?.data?.data?.[0]?.EmpAccessDetails?.filter(
(item) => item.ConfigName === 'Price Change'
);
setEmpData(datas?.[0]);
};
const EditableContext = React.createContext(null);
const EditableRow = ({ index, ...props }) => {
const [form] = Form.useForm();
return (
<Form form={form} component={false}>
<EditableContext.Provider value={form}>
<tr {...props} />
</EditableContext.Provider>
</Form>
);
};
const BulkEditableRow = ({ index, ...props }) => {
const [form] = Form.useForm();
return (
<Form form={form} component={false}>
<EditableContext.Provider value={form}>
<tr {...props} />
</EditableContext.Provider>
</Form>
);
};
const EditableCell = ({
title,
editable,
children,
dataIndex,
record,
handleSave,
...restProps
}) => {
const [editing, setEditing] = useState(false);
const inputRef = useRef(null);
const form = useContext(EditableContext);
useEffect(() => {
if (editing) {
inputRef?.current?.focus();
}
}, [editing]);
const toggleEdit = () => {
setEditing(!editing);
form.setFieldsValue({
[dataIndex]: record[dataIndex],
});
};
const save = async () => {
try {
const values = await form.validateFields();
toggleEdit();
handleSave({
...record,
...values,
});
} catch (errInfo) {
console.log('Save failed:', errInfo);
}
};
let childNode = children;
if (editable) {
childNode = editing ? (
<Form.Item
style={{
margin: 0,
}}
name={dataIndex}
rules={[
{
pattern: /^(?!0$)(\d+)(\.\d{1,2})?$/,
message: 'Invalid format (Max 2 decimals, No zero)',
},
{
validator: (_, value) =>
value?.length > 10
? Promise.reject('Max 10 characters allowed')
: Promise.resolve(),
},
]}
>
<Input
className="editable-table-input"
ref={inputRef}
onPressEnter={save}
onBlur={save}
// onMouseLeave={save}
value={
Array.isArray(record[dataIndex]) ? undefined : record[dataIndex]
}
inputMode="decimal"
onInput={(e) => {
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('')}`
: cleanedValue;
}}
/>
</Form.Item>
) : (
<div className="editable-cell-value-wrap" onClick={toggleEdit}>
{/* {dataIndex === 'CurrentAmt' && Array.isArray(record[dataIndex])
? record[dataIndex]?.map((item, index) => (
<span key={index}>
{item.CurrentAmt + '-' + item.CurrentAmt}
</span>
))
: children} */}
<Input
ref={inputRef}
className="editable-table-input"
onPressEnter={save}
onBlur={save}
value={
Array.isArray(record[dataIndex]) ? undefined : record[dataIndex]
}
/>
</div>
);
}
return <td {...restProps}>{childNode}</td>;
};
const BulkEditableCell = ({
title,
editable,
children,
dataIndex,
record,
handleSave,
...restProps
}) => {
const [editing, setEditing] = useState(false);
const inputRef = useRef(null);
const form = useContext(EditableContext);
useEffect(() => {
if (editing) {
inputRef?.current?.focus();
}
}, [editing]);
const toggleEdit = () => {
setEditing(!editing);
form.setFieldsValue({
[dataIndex]: record[dataIndex],
});
};
const Bulksave = async () => {
try {
const values = await form.validateFields();
toggleEdit();
handleBulkSave({
...record,
...values,
});
} catch (errInfo) {
console.log('Save failed:', errInfo);
}
};
let childNode = children;
if (editable) {
childNode = editing ? (
<Form.Item
style={{
margin: 0,
}}
name={dataIndex}
rules={[
{
pattern: /^(?!0$)(\d+)(\.\d{1,2})?$/,
message: 'Invalid format (Max 2 decimals, No zero)',
},
{
validator: (_, value) =>
value?.length > 10
? Promise.reject('Max 10 characters allowed')
: Promise.resolve(),
},
]}
>
<Input
ref={inputRef}
onPressEnter={Bulksave}
onBlur={Bulksave}
// onMouseLeave={Bulksave}
value={
Array.isArray(record[dataIndex]) ? undefined : record[dataIndex]
}
inputMode="decimal"
onInput={(e) => {
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('')}`
: cleanedValue;
}}
/>
</Form.Item>
) : (
<div className="editable-cell-value-wrap" onClick={toggleEdit}>
{/* {dataIndex === "CurrentAmt" && Array.isArray(record[dataIndex])
? record[dataIndex]?.map((item, index) => (
<span key={index}>
{item.CurrentAmt + "-" + item.CurrentAmt}
</span>
))
: children} */}
<Input
ref={inputRef}
onPressEnter={Bulksave}
onBlur={Bulksave}
value={
Array.isArray(record[dataIndex]) ? undefined : record[dataIndex]
}
/>
</div>
);
}
return <td {...restProps}>{childNode}</td>;
};
useEffect(() => {
fetchData();
}, []);
const getPreference = async () => {
const data = { AppId: AppId, CompId: CompId, BranchId: BranchId };
const { data: res } = await dispatch(getPreferenceData(data)).unwrap();
const decimalSetting = res?.data?.[0]?.SettingDtlDetails?.find(
(setting) =>
setting?.SettingIdName?.toLowerCase() === 'decimal' &&
setting?.SettingValue === 'Y'
);
if (decimalSetting) {
setAllowDecimal(true);
}
};
const fetchData = async () => {
let data = {
CompId: CompId,
BranchId: BranchId,
AppId: AppId,
};
let res = await dispatch(getStockNames(data)).unwrap();
const stockNamesWithKeys = res?.data?.data?.map((stockName) => ({
...stockName,
stockDetails: stockName?.stockDetails?.map((item, index) => ({
...item,
key: `${stockName.ProdId}_${index}`,
})),
}));
setStockNames(stockNamesWithKeys);
const flattenedArray = res?.data?.data?.flatMap((product) =>
product.stockDetails.map((detail) => ({
ProdName: product.ProdName,
InwardDtlId: detail.InwardDtlId,
InwardDate: detail.InwardDate,
ExpDate: detail.ExpDate,
BalanceQty: detail.BalanceQty,
MRP: detail.MRP,
SellPrice: detail.SellPrice,
ProdId: product.ProdId,
Size: product.Size,
StockAvailable: product.StockAvailable,
CompId: product.CompId,
BranchId: product.BranchId,
AppId: product.AppId,
UOM: product.UOM,
UOMName: product.UOMName,
WhSalePrice: detail?.WhSalePrice,
ProdVariantName: detail?.ProdVariantName,
BatchRef: detail?.BatchRef,
key: `${product.ProdId}_${detail.InwardDtlId}`,
}))
);
setBulkProductData(flattenedArray);
};
const actionsFormatter = async (row) => {
setOpenEditModal(true);
setDataSource([row]);
};
const handlePriceChange = (rowIndex, field, value, localId) => {
const numValue = value ? parseFloat(value) : null;
setUploadedData((prev) => {
const updated = [...prev];
const currentRow = { ...updated[rowIndex] };
// If changing New MRP, clear New SP
if (field === 'NewMRP') {
currentRow.NewSellPrice = null;
excelDataRef.current?.setFieldsValue({
[`NewSellPrice${localId}`]: null,
});
}
currentRow[field] = numValue;
updated[rowIndex] = currentRow;
return updated;
});
// Validate New SP against New MRP
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');
return;
}
}
excelDataRef.current?.setFieldsValue({
[`${field}${localId}`]: numValue,
});
};
const statusFormatter = async (row) => {
const updatedData = StockDetails?.filter(
(item) => item?.InwardDtlId !== row?.InwardDtlId
);
setStockDetails(updatedData);
};
let tableValue = StockNames?.[0]?.stockDetails;
let DataSource = StockNames?.map((name, index) => ({
value: index + 1,
label: name?.ProdName + '(' + (name?.Size + ' ' + name?.UOMName) + ')',
ProdId: name?.ProdId,
stockDetails: name?.stockDetails,
Quantity: name?.Size,
QuantityName: name?.UOMName,
ExpDate: name.stockDetails?.[0]?.ExpDate,
}));
useEffect(() => {
setDataSource(tableValue);
}, [tableValue]);
const handleSave = (row) => {
if (row?.CurrentAmt && row?.CurrentMRP) {
if (parseFloat(row?.CurrentMRP) >= parseFloat(row?.CurrentAmt)) {
const newData = StockDetails?.map((item) => {
return item.key === row.key ? { ...item, ...row } : item;
});
const index = newData?.findIndex((item) => row.key === item.key);
const item = newData[index];
newData?.splice(index, 1, {
...item,
...row,
});
setStockDetails(newData);
} else {
setMessageType('error');
setMessageData('MRP is must be greater than or equal to selling price');
}
} else {
const newData = StockDetails?.map((item) => {
return item.key === row.key ? { ...item, ...row } : item;
});
const index = newData?.findIndex((item) => row.key === item.key);
const item = newData[index];
newData?.splice(index, 1, {
...item,
...row,
});
setStockDetails(newData);
}
};
const handleBulkSave = (row) => {
if (row?.CurrentAmt && row?.CurrentMRP) {
if (parseFloat(row?.CurrentMRP) >= parseFloat(row?.CurrentAmt)) {
const newData = BulkProductData?.map((item) => {
return item.key === row.key ? { ...item, ...row } : item;
});
const index = newData?.findIndex((item) => row.key === item.key);
const item = newData[index];
newData?.splice(index, 1, {
...item,
...row,
});
setBulkProductData(newData);
} else {
setMessageType('error');
setMessageData(
'MRP is must be greater than or equal to selling price'
);
}
} else {
const newData = BulkProductData?.map((item) => {
return item.key === row.key ? { ...item, ...row } : item;
});
const index = newData?.findIndex((item) => row.key === item.key);
const item = newData[index];
newData?.splice(index, 1, {
...item,
...row,
});
setBulkProductData(newData);
}
};
const components = {
body: {
row: EditableRow,
cell: EditableCell,
},
};
const BulkComponents = {
body: {
row: BulkEditableRow,
cell: BulkEditableCell,
},
};
function safeRound(amountStr) {
if (amountStr == null) return allowDecimal ? '0.00' : '0';
const cleaned = String(amountStr).replace(/[^0-9.-]+/g, '');
const num = Number(cleaned);
if (isNaN(num)) return allowDecimal ? '0.00' : '0';
return allowDecimal ? num.toFixed(2) : Math.round(num).toString();
}
const columns2 = [
{
title: 'Sl.No',
align: 'center',
key: 'sno',
width: '60px',
render: (text, object, index) => (
<a style={{ color: 'black' }}>{index + 1}</a>
),
},
{
title: 'Product Name',
dataIndex: 'ProdName',
key: 'ProdName',
width: '20%',
filteredValue: [searchedText],
onFilter: (value, record) => {
return String(record.ProdName)
?.toLowerCase()
.includes(value?.toLowerCase());
},
sorter: (a, b) => a?.ProdName?.localeCompare(b.ProdName),
sortOrder: sortedInfo.columnKey === 'ProdName' ? sortedInfo.order : null,
ellipsis: true,
render: (_, record) => (
<span>
{record.ProdName} ({record.UOM} {record.UOMName})
</span>
),
},
{
title: 'stock Date',
dataIndex: 'InwardDate',
key: 'InwardDate',
align: 'right',
width: '150px',
render: (InwardDate) =>
InwardDate !== null ? ExtractDateFormate(InwardDate) : '-',
},
{
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',
render: (SellPrice) =>
safeRound(SellPrice) !== null ? safeRound(SellPrice) : '-',
},
{
title: 'New MRP',
dataIndex: 'CurrentMRP',
key: 'CurrentMRP',
align: 'right',
editable: true,
render: (text, record) => <p>{text ? text : 'Enter MRP'}</p>,
width: 100,
},
{
title: 'New SP',
dataIndex: 'CurrentAmt',
key: 'CurrentAmt',
align: 'right',
editable: true,
render: (text, record) => <p>{text ? text : 'Enter Price'}</p>,
width: 100,
},
{
title: 'Action',
dataIndex: 'SellPrice',
key: 'SellPrice',
align: 'center',
width: '100px',
render: (_, record, index) => (
<div
style={{
display: 'flex',
justifyContent: 'center',
columnGap: '1rem',
}}
>
<DeleteFilled
style={{ color: '#FF4D4F' }}
onClick={() => statusFormatter(record, index)}
/>
</div>
),
},
];
const BulkPricechangeColumns = [
{
title: 'Sl.No',
align: 'center',
key: 'sno',
render: (text, object, index) => (
<a style={{ color: 'black' }}>
{(Bulkchangepage - 1) * 10 + index + 1}
</a>
),
},
{
title: 'Name',
dataIndex: 'ProdName',
key: 'ProdName',
width: '20%',
filteredValue: [BulksearchedText],
onFilter: (value, record) => {
return String(record.ProdName)
?.toLowerCase()
.includes(value?.toLowerCase());
},
sorter: (a, b) => a?.ProdName?.localeCompare(b.ProdName),
sortOrder:
BulksortedInfo.columnKey === 'ProdName' ? BulksortedInfo.order : null,
ellipsis: true,
render: (_, record) => (
<span>
{record.ProdName} ({record.Size} {record.UOMName})
</span>
),
},
{
title: 'stock Date',
dataIndex: 'InwardDate',
key: 'InwardDate',
align: 'right',
width: '150px',
render: (InwardDate) =>
InwardDate !== null ? ExtractDateFormate(InwardDate) : '-',
},
{
title: 'Exp date',
dataIndex: 'ExpDate',
key: 'ExpDate',
align: 'right',
render: (ExpDate) =>
ExpDate !== null ? ExtractDateFormate(ExpDate) : '-',
},
{
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',
editable: true,
render: (text, record) => <p>{text ? text : 'Enter MRP'}</p>,
width: 100,
},
{
title: 'New SP',
dataIndex: 'CurrentAmt',
key: 'CurrentAmt',
align: 'center',
with: '4rem',
editable: true,
render: (text, record) => <p>{text ? text : 'Enter Price'}</p>,
width: 100,
},
];
const HandleStockNames = (e, option) => {
const newStockDetails = option?.stockDetails || [];
// Check if any of the new products already exist in StockDetails
setStockDetails((prevStockDetails) => {
const existingInwardDtlIds = new Set(
prevStockDetails?.map((item) => item.InwardDtlId)
);
const uniqueNewStockDetails = newStockDetails
?.filter((item) => !existingInwardDtlIds.has(item.InwardDtlId))
?.map((detail) => ({
...detail,
UOMName: option?.QuantityName,
UOM: option?.Quantity,
}));
return [...prevStockDetails, ...uniqueNewStockDetails];
});
setProductName(option?.label);
};
// const handleCancel = () => {
// setOpen(false);
// setOpenEditModal(false);
// };
// const HandleSubmit = () => {
// const newStockDetails = dataSource || [];
// const filteredCurrentAmtData = newStockDetails?.filter(
// (item) =>
// item.CurrentAmt !== undefined &&
// item.CurrentAmt !== null &&
// item.CurrentMRP !== undefined &&
// item.CurrentMRP !== null
// );
// if (filteredCurrentAmtData?.length > 0) {
// setStockDetails((prevStockDetails) => {
// const existingInwardDtlIds = new Set(
// prevStockDetails?.map((item) => item.InwardDtlId)
// );
// const uniqueNewStockDetails = filteredCurrentAmtData?.filter(
// (item) => !existingInwardDtlIds.has(item.InwardDtlId)
// );
// let beforeFinal = [...prevStockDetails, ...uniqueNewStockDetails];
// const existingInwardDtlIds2 = new Set(
// filteredCurrentAmtData?.map((item) => item.InwardDtlId)
// );
// const uniqueNewStockDetails2 = beforeFinal?.filter(
// (item) => !existingInwardDtlIds2.has(item.InwardDtlId)
// );
// return [...filteredCurrentAmtData, ...uniqueNewStockDetails2];
// });
// setOpen(false);
// } else {
// setMessageType('error');
// setMessageData('Please give all details');
// }
// };
const HandlePutData = async () => {
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 !== ''
);
const hasInvalidData = BulkProductData.every((item) => {
const isAbsent = item.CurrentAmt == null && item.CurrentMRP == null;
const isPresent = item.CurrentAmt != null && item.CurrentMRP != null;
return isAbsent || isPresent;
});
if (filteredCurrentAmtData?.length > 0 && hasInvalidData) {
let Postdata = {
CompId: CompId,
BranchId: BranchId,
ProductDetails: filteredCurrentAmtData?.map((item) => ({
ProdId: item?.ProdId,
MRP: item?.CurrentMRP,
SellPrice: item?.CurrentAmt,
AdjComment: 'string',
InwardDtlId: item?.InwardDtlId,
})),
};
let response = await dispatch(PutStockPrice(Postdata)).unwrap();
if (response?.data?.statusCode == 1) {
setProductName();
setMessageType('success');
setMessageData(response?.data?.response);
fetchData();
setBulksearchedText('');
setStockDetails([]);
setBulkProductData([]);
} else {
setMessageType('error');
setMessageData(response?.data?.response);
}
} else {
setMessageType('error');
setMessageData('Please give all details');
}
} else {
const filteredStockDetails = StockDetails?.filter(
(item) =>
item?.CurrentMRP &&
item?.CurrentMRP !== '' &&
item?.CurrentAmt &&
item?.CurrentAmt !== ''
);
if (filteredStockDetails?.length === 0) {
setMessageType('error');
setMessageData('Please enter price details for at least one product');
return;
}
let data = {
CompId: CompId,
BranchId: BranchId,
ProductDetails: filteredStockDetails?.map((item) => ({
ProdId: item?.ProdId,
MRP: item?.CurrentMRP,
SellPrice: item?.CurrentAmt,
AdjComment: 'string',
InwardDtlId: item?.InwardDtlId,
})),
UpdatedBy: 1,
AppId: AppId,
};
let response = await dispatch(PutStockPrice(data)).unwrap();
let res = await dispatch(getStockNames(data)).unwrap();
setStockNames(res?.data?.data);
if (response?.data?.statusCode == 1) {
setProductName();
setMessageType('success');
setMessageData(response?.data?.response);
fetchData();
} else {
setMessageType('error');
setMessageData(response?.data?.response);
}
setStockDetails([]);
}
};
// const HandleEditSubmit = () => {
// let newStockDetails = dataSource || [];
// let filteredInverd = StockDetails?.filter(
// (item) => item.InwardDtlId !== newStockDetails?.[0].InwardDtlId
// );
// filteredInverd.push(newStockDetails?.[0]);
// setStockDetails(filteredInverd);
// setOpenEditModal(false);
// };
// const columns = defaultColumns?.map((col) => {
// if (!col.editable) {
// return col;
// }
// return {
// ...col,
// onCell: (record) => ({
// record,
// editable: col.editable,
// dataIndex: col.dataIndex,
// title: col.title,
// handleSave,
// }),
// };
// });
const columns2WithEditable = columns2?.map((col) => {
if (!col.editable) {
return col;
}
return {
...col,
onCell: (record) => ({
record,
editable: col.editable,
dataIndex: col.dataIndex,
title: col.title,
handleSave,
}),
};
});
const BulkPriceColumns = BulkPricechangeColumns?.map((col) => {
if (!col.editable) {
return col;
}
return {
...col,
onCell: (record) => ({
record,
editable: col.editable,
dataIndex: col.dataIndex,
title: col.title,
handleSave,
}),
};
});
const handlePageChange = (current) => {
setpage(current);
};
const handlePageChangeBulk = (current) => {
setBulkchangepage(current);
setPageSize(pageSize);
};
const onComplete = useCallback(() => {
setMessageData(null);
setMessageType(null);
}, []);
const onSearch = (value) => {
setSearchedText(value);
};
const onSearchBulk = (value) => {
setBulksearchedText(value);
};
const onSearchChange = (e) => {
setSearchedText(e?.target?.value);
};
const onSearchChangeBulk = (e) => {
setBulksearchedText(e?.target?.value);
};
const handleChange = (pagination, filters, sorter) => {
setFilteredInfo(filters);
setSortedInfo(sorter);
};
const handleChangeBulk = (pagination, filters, sorter) => {
setBulksortedInfo(sorter);
};
const onRadioChange = (data) => {
setRadioSelection(data);
};
const handleUploadExcel = () => {
setExcelModalOpen(true);
};
const handleFieldSetup = () => {
setFieldSetup(true);
};
const showPriceChangeModal = () => {
setPriceChangeModalOpen(true);
};
const handleExport = async (isStockVariantBased = 'Yes') => {
setExportLoading(true);
setPriceChangeModalOpen(false);
const uniqueBulkProductData =
isStockVariantBased === 'Yes'
? BulkProductData || []
: (BulkProductData || [])?.filter(
(item, index, self) =>
index === self.findIndex((p) => p.ProdId === item.ProdId)
);
if (!uniqueBulkProductData?.length) {
setMessageType('error');
setMessageData('No data available to export');
setExportLoading(false);
return;
}
const workbook = new ExcelJS.Workbook();
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 }]
: []),
...(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 },
...(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 }];
const headerRow = worksheet.getRow(1);
const newMRPCol = headerRow.values.indexOf('New MRP');
const newSPCol = headerRow.values.indexOf('New SP');
/* ---------------- HEADER STYLE ---------------- */
worksheet.getRow(1).eachCell((cell) => {
const header = cell.value;
const isHiddenCol =
header === 'key' ||
header === 'ProdId' ||
header === 'InwardDtlId' ||
header === 'downloadType';
cell.font = {
bold: true,
size: isHiddenCol ? 1 : 11,
color: { argb: isHiddenCol ? 'FFFFFFFF' : 'FF000000' },
};
cell.alignment = {
horizontal: 'center',
vertical: 'middle',
wrapText: true, // ✅ prevents overflow in header
};
cell.fill = {
type: 'pattern',
pattern: 'solid',
fgColor: {
argb: isHiddenCol ? 'FFFFFFFF' : 'FF52C41A',
},
};
cell.border = isHiddenCol
? undefined
: {
right: { style: 'thin', color: { argb: 'FF000000' } },
bottom: { style: 'thin', color: { argb: 'FF000000' } },
};
});
/* ---------------- ADD DATA ---------------- */
uniqueBulkProductData.forEach((product) => {
worksheet.addRow({
ProdName: product?.ProdName,
ProdVariantName: product?.ProdVariantName,
BatchRef: product?.BatchRef,
StockDate: product?.InwardDate,
ExpDate: product?.ExpDate || '-',
Stock: product?.BalanceQty,
OldMRP: product?.MRP,
OldSP: product?.SellPrice,
WhSalePrice: product?.WhSalePrice,
Size: product?.Size,
StockAvailable: product?.StockAvailable,
UOMName: product?.UOMName,
key: product?.key,
downloadType: isStockVariantBased === 'Yes' ? 'Variant' : 'Product',
NewMRP: '',
NewSP: '',
NewWhSalePrice: '',
ProdId: product?.ProdId,
InwardDtlId:
isStockVariantBased === 'Yes' ? product?.InwardDtlId : undefined,
});
});
// ---------------- VALIDATION: New SP <= New MRP ----------------
worksheet.eachRow({ includeEmpty: true }, (row, rowNumber) => {
if (rowNumber === 1) return; // skip header
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',
};
});
/* ---------------- UNLOCK EVERYTHING ---------------- */
worksheet.eachRow({ includeEmpty: true }, (row) => {
row.eachCell({ includeEmpty: true }, (cell) => {
cell.protection = { locked: false };
});
});
/* ---------------- LOCK HEADER ---------------- */
worksheet.getRow(1).eachCell((cell) => {
cell.protection = { locked: true };
});
worksheet.getRow(1).height = 32;
/* ---------------- LOCK ALL EXCEPT New MRP & New SP ---------------- */
worksheet.eachRow({ includeEmpty: true }, (row, rowNumber) => {
if (rowNumber === 1) return;
row.eachCell((cell, colNumber) => {
const header = worksheet.getRow(1).getCell(colNumber).value;
const isHiddenCol =
header === 'key' ||
header === 'ProdId' ||
header === 'InwardDtlId' ||
header === 'downloadType';
const isEditable =
header === 'New MRP' ||
header === 'New SP' ||
header === 'New Wholesale Price';
cell.protection = { locked: !isEditable };
cell.alignment = {
vertical: 'middle',
wrapText: true,
};
if (isHiddenCol) {
cell.font = {
size: 1,
color: { argb: 'FFFFFFFF' },
};
cell.fill = {
type: 'pattern',
pattern: 'solid',
fgColor: { argb: 'FFFFFFFF' },
};
}
});
});
/* ---------------- PROTECT SHEET ---------------- */
await worksheet.protect('', {
selectLockedCells: false,
selectUnlockedCells: true,
formatCells: false,
formatColumns: false,
insertRows: false,
deleteRows: false,
});
/* ---------------- DOWNLOAD ---------------- */
const buffer = await workbook.xlsx.writeBuffer();
const blob = new Blob([buffer], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
});
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = 'PriceChange_Data.xlsx';
link.click();
setExportLoading(false);
};
const handleClick = () => {
fileInputRef.current.click();
};
const handleFileUpload = (e) => {
const file = e.target.files[0];
if (!file) {
dispatch(emptyExcelData());
return;
}
const isAllowed = allowedExcelTypes?.includes(file.type);
if (!isAllowed) {
Modal.error({
title: 'Invalid File Type',
content: 'Only Excel files (.xls, .xlsx) are allowed.',
});
handleCancelData();
return;
}
const reader = new FileReader();
reader.onload = (event) => {
const arrayBuffer = event.target.result;
const extractedData = extractPriceChangeDataFromExcel(arrayBuffer);
console.log(extractedData, 'extractedData');
if ((extractedData || [])?.length === 0) {
setMessageData('No Data Found in Uploaded Sheet');
setMessageType('error');
handleCancelData();
return;
}
setUploadedData(extractedData);
// setFormValuesFromExtractedData(extractedData);
};
reader.readAsArrayBuffer(file); // ✅ THIS IS REQUIRED
};
const setFormValuesFromExtractedData = (data) => {
const formValues = {};
data.forEach((item) => {
const id = item.localId;
if (item.NewMRP !== null && item.NewMRP !== undefined) {
formValues[`NewMRP${id}`] = item.NewMRP;
}
if (item.NewSellPrice !== null && item.NewSellPrice !== undefined) {
formValues[`NewSellPrice${id}`] = item.NewSellPrice;
}
if (
item.NewWholeSalePrice !== null &&
item.NewWholeSalePrice !== undefined
) {
formValues[`NewWholeSalePrice${id}`] = item.NewWholeSalePrice;
}
});
excelDataRef.current?.setFieldsValue(formValues);
};
const extractPriceChangeDataFromExcel = (arrayBuffer) => {
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: '',
});
if (!rows.length) return [];
const header = rows[0];
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] : '';
};
const result = dataRows
.map((row) => {
const prodId = getVal(row, 'ProdId')?.toString().trim();
if (!prodId) return null;
const newMRP =
getVal(row, 'New MRP') !== '' ? Number(getVal(row, 'New MRP')) : null;
const newSP =
getVal(row, 'New SP') !== '' ? Number(getVal(row, 'New SP')) : null;
const newWholesale =
getVal(row, 'New Wholesale Price') !== ''
? Number(getVal(row, 'New Wholesale Price'))
: null;
// ❌ Must have at least one change
if (newMRP === null && newSP === null && newWholesale === null) {
return null;
}
return {
// 🔹 Product identity
localId: uuidv4(),
ProdId: prodId,
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,
// 🔹 Stock / dates
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,
// 🔹 Old prices
OldMRP:
getVal(row, 'Old MRP') !== ''
? Number(getVal(row, 'Old MRP'))
: null,
OldSP:
getVal(row, 'Old SP') !== '' ? Number(getVal(row, 'Old SP')) : null,
OldWholeSalePrice:
getVal(row, 'Old Wholesale Price') !== ''
? Number(getVal(row, 'Old Wholesale Price'))
: null,
// 🔹 New prices (normalized)
NewMRP: newMRP,
NewSellPrice: newSP,
NewWholeSalePrice: newWholesale,
};
})
.filter(Boolean);
return result;
};
const handleCancelData = () => {
dispatch(emptyExcelData());
if (fileInputRef.current) {
fileInputRef.current.value = '';
}
setUploadedData([]);
};
const handleSubmit = async () => {
try {
const formValues = excelDataRef.current?.getFieldsValue();
// Validate all records
for (let i = 0; i < uploadedData.length; i++) {
const record = uploadedData[i];
const newMRP = formValues[`NewMRP${record.localId}`];
const newSP = formValues[`NewSellPrice${record.localId}`];
// If MRP is present, SP must also be present
if (newMRP && !newSP) {
setMessageType('error');
setMessageData(
'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');
setMessageData(
'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');
return;
}
}
const updatedData = uploadedData
?.filter((data) => {
const hasMRP = !!data?.NewMRP;
const hasSell = !!data?.NewSellPrice;
const hasWholesale = !!data?.NewWholeSalePrice;
// valid cases
if (hasMRP && hasSell) return true;
if (!hasMRP && !hasSell && hasWholesale) return true;
return false;
})
?.map((data) => ({
ProdId: data?.ProdId,
InwardDtlId: data?.InwardDtlId,
NewSellPrice: data?.NewSellPrice,
NewMRP: data?.NewMRP,
NewWholeSalePrice: data?.NewWholeSalePrice,
AdjComment: 'string',
}));
const putData = {
AppId: AppId,
CompId: CompId,
BranchId: BranchId,
Type: uploadedData?.[0]?.downloadType,
ProductDetails: updatedData,
CreatedBy: UserId,
};
const res = await dispatch(bulkPriceUpdate(putData))?.unwrap();
if (res?.data?.statusCode === 1) {
setMessageData(res?.data?.response || 'Price Updated Successfully');
setMessageType('success');
setUploadedData([]);
handleCancelData();
setExcelModalOpen(false);
await fetchData();
} else {
setMessageData(res?.data?.response);
setMessageType('error');
}
// If validation passes, proceed with submission
console.log('Form validation passed', updatedData);
} catch (error) {
setMessageType('error');
setMessageData('Please check all fields and try again');
}
};
return (
<div className="userPageTable">
<div className="userPageContent">
<Messages
messageType={messageType}
messageData={messageData}
onComplete={onComplete}
/>
<div className="formAddNew">
<div>
<FormHeader title={'Price Change'} />
</div>
<div
style={{
display: 'flex',
flexWrap: 'wrap',
justifyContent: 'space-between',
}}
>
{RadioSelection == 'Bulk' && (
<div
className="toolbar"
style={{
display: 'flex',
gap: '1rem',
alignItems: 'center',
justifyContent: 'space-between',
width: '100%',
}}
>
<div className="formSearch">
<Search
value={BulksearchedText}
placeholder="Search"
onSearch={onSearchBulk}
onSearchChange={onSearchChangeBulk}
/>
</div>
<div className="uploadexcelBtn">
<Buttons
buttonText="Upload Excel"
className="tertiary_Button"
handleSubmit={handleUploadExcel}
disabled={addnewAccess}
icon={<FiUploadCloud size={18} />}
/>
</div>
</div>
)}
</div>
{RadioSelection == 'Single' && (
<div
style={{ width: '100%', marginBottom: '0' }}
className="searchAddDiv"
>
<div style={{ width: '100%' }} className="formSearch">
<div
style={{
display: 'flex',
gap: '1rem',
flexWrap: 'wrap',
rowGap: '1.5rem',
marginBottom: '0.5rem',
// justifyContent: 'space-between',
width: '100%',
}}
className="PricePrice-input"
>
<DropDowns
label="Select Product"
valueData={ProductName}
showSearch
onChangeFunction={(value, option) =>
HandleStockNames(value, option)
}
style={{ width: '240px' }}
options={DataSource}
isOnchanges={ProductName ? true : false}
/>
<div className="formSearch">
<Search
placeholder="Search"
onSearch={onSearch}
onSearchChange={onSearchChange}
/>
</div>
</div>
</div>
</div>
)}
{/* {RadioSelection == "Bulk" &&
<div style={{ padding: "5px 5px" }}>
<Search
value={BulksearchedText}
placeholder="Search"
onSearch={onSearchBulk}
onSearchChange={onSearchChangeBulk}
/>
</div>
} */}
</div>
<div
style={{
display: 'flex',
gap: '1rem',
alignItems: 'center',
justifyContent: 'space-between',
}}
>
<div>
<RadioGrpButton
content={[
{ value: 'Single', label: 'Single Product' },
{ value: 'Bulk', label: 'Bulk Product' },
]}
fieldState={true}
defaultSelect={RadioSelection}
onSelectFuntion={(e) => onRadioChange(e)}
/>
</div>
<div>
{(RadioSelection == 'Bulk' ||
(RadioSelection == 'Single' && StockDetails.length > 0)) && (
<div className="samplereportTableButton">
<Buttons
buttonText="Submit"
color="901D77"
palcement={'right'}
handleSubmit={HandlePutData}
icon={<ArrowRightOutlined />}
disabled={addnewAccess}
></Buttons>
</div>
)}
</div>
</div>
{RadioSelection == 'Single' && (
<div
className="samplereportTable reportTable pricechangeTable"
style={{ height: '61vh !important' }}
>
<Table
columns={columns2WithEditable}
components={components}
bordered
dataSource={StockDetails}
data={StockDetails}
pagination={
StockDetails?.length < 11
? false
: {
current: page,
pageSize: pageSize,
onChange: handlePageChange,
}
}
onChange={handleChange}
></Table>
</div>
)}
{RadioSelection == 'Bulk' && (
<div
className="samplereportTable reportTable pricechangeTable"
style={{ height: '65vh !important' }}
>
<Table
columns={BulkPriceColumns}
components={BulkComponents}
data={BulkProductData}
dataSource={BulkProductData}
onChange={handleChangeBulk}
pagination={{
current: Bulkchangepage,
pageSize: pageSize,
pageSizeOptions: ['10', '20', '30'],
onChange: handlePageChangeBulk,
showSizeChanger: false,
}}
></Table>
</div>
)}
</div>
<DefaultModal
open={excelModalOpen}
title="Bulk Upload"
footer={false}
className={'bulkuploadmodal'}
handleCancel={() => {
setExcelModalOpen(false);
handleCancelData();
}}
width={uploadedData?.length > 0 ? 2500 : 600}
children={
<>
{uploadedData?.length === 0 && (
<div
style={{
width: '100%',
display: 'flex',
justifyContent: 'flex-end',
marginBottom: '1rem',
}}
>
<div
className="export-excel-div"
onClick={showPriceChangeModal}
>
<div>
<CiExport size={20} strokeWidth={1} />
</div>
<div style={{ fontSize: '14px', letterSpacing: '0.2px' }}>
Export Excel
</div>
</div>
</div>
)}
{(!uploadedData || uploadedData?.length === 0) && (
<>
<div
style={{
display: 'flex',
alignItems: 'center',
border: '1px dashed #000',
width: 'max-content',
padding: '10px',
borderRadius: '6px',
}}
>
<div
style={{ position: 'relative', display: 'inline-block' }}
>
{/* <Imageupload size="2x" /> */}
<div
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
}}
>
<img
src={Excelupldimg}
width={'80px'}
style={{ cursor: 'pointer', margin: '0 0 1rem 0' }}
onClick={handleClick}
/>
<input
type="file"
className="form-control"
onChange={handleFileUpload}
ref={fileInputRef}
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
opacity: 0,
cursor: 'pointer',
}}
/>
<a style={{ color: '#000', fontSize: '12px' }}>
{' '}
Upload Sheet{' '}
</a>
</div>
</div>
</div>
</>
)}
<div
className="viewerExcelupload"
style={{ maxHeight: '90vh', overflowX: 'auto' }}
>
{uploadedData && uploadedData?.length > 0 ? (
<Form ref={excelDataRef} onFinish={handleSubmit}>
<Table
columns={columns}
rowKey={(record) => record.localId}
// components={components}
// bordered
dataSource={uploadedData}
// className="tableExcelUpload"
// onChange={handleTableChange}
className="price-change-data"
/>
<div
className="cancel-link"
onClick={handleCancelData}
style={{
display: 'flex',
alignItems: 'center',
gap: '.5rem',
padding: '0.3rem 0.4rem',
borderRadius: '6px',
backgroundColor: 'ghostwhite',
width: 'max-content',
}}
>
<FiDelete style={{ fontSize: '20px', color: '#1292EE' }} />
<a style={{ color: '#000' }}> Remove File</a>
</div>
<div
style={{
display: 'flex',
justifyContent: 'flex-end',
gap: '1rem',
marginTop: '1rem',
}}
>
<Buttons
buttonText="Submit"
color="901D77"
placement={'right'}
icon={<ArrowRightOutlined />}
disabled={addnewAccess}
/>
</div>
</Form>
) : (
<p></p>
)}
</div>
</>
}
/>
<DefaultModal
open={priceChangeModalOpen}
title={
<p style={{ fontSize: '18px' }}>Stock/Variant Based Price Change?</p>
}
footer={true}
width={500}
handleCancel={() => setPriceChangeModalOpen(false)}
handleSubmit={() => handleExport(stockVariantBased)}
children={
<div style={{ padding: '0.1rem 0' }}>
<RadioGrpButton
content={[
{ value: 'Yes', label: 'Yes' },
{ value: 'No', label: 'No' },
]}
fieldState={true}
defaultSelect={stockVariantBased}
onSelectFuntion={(e) => setStockVariantBased(e)}
/>
</div>
}
/>
</div>
);
};
export default StockPriceUpdate;