Android_Retail/src/Pages/StockMaster/StockList.jsx

1421 lines
43 KiB
JavaScript

import { useState, useEffect, useRef, useCallback } from 'react';
import { useNavigate, useLocation } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import { PlusOutlined, EyeOutlined, PrinterFilled } from '@ant-design/icons';
import { Image, Pagination, Space, Table, Tooltip } from 'antd';
import {
changeBreadCrumb,
getEmpAccess,
} from '../../Features/AppPage/CenterPage.js';
import QRCode from 'qrcode';
import { Tables } from '../../Components/Tables/Table';
import FormHeader from '../PageComponents/FormHeader.jsx';
import Search from '../../Components/Forms/Search.jsx';
import { style, getPageStyle } from '../Product/Printstyles.js';
import Buttons from '../../Components/Forms/Buttons';
import {
getSession,
dateFormatChange,
ExtractDateFormate,
printDiv,
} from '../../Services/Others';
import { Messages } from '../../Components/Notifications/Messages';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import dayjs from 'dayjs';
import {
getStockData,
getProductData,
getalltVariantData,
Bulkstockpost,
purchaseDataSelector,
getPurchaseData,
} from '../../Features/StockMaster/StockMaster.js';
import {
supplierSelector,
getSupplierData,
productDataSelector,
taxSelector,
getAdmin,
} from '../../Features/ProductPage/ProductPage.js';
import {
emptyExcelData,
excelDataSelector,
} from '../../Features/ExcelUploadPage/ExcelUploadPage.js';
import moment from 'moment';
import StockExcel from '../StockMaster/StockBulkUpload.jsx';
import { DefaultModal } from '../../Components/Modal/DefaultModal.jsx';
import TertiaryButton from '../../Components/Forms/tertiaryButton.jsx';
import { extractLastNumberOrderId } from '../../Services/Others.js';
import '../../Styles/Employee/EmpMaster.scss';
import { IoEye } from 'react-icons/io5';
import { useAuth } from '../../AuthContext.jsx';
import { getPreferenceData } from '../../Features/BookingScreen/BookingData/BookingData.js';
import {
getBarcodeSessionsIDs,
getBarcodeTemplate,
} from '../../Features/Barcode/Barcode.js';
import StickerPrintModel from '../Product/StickerPrintModal.jsx';
import StickerPrintTemplates from '../Product/StickerTemplates.jsx';
import QRCodeCopiesModal from '../Product/QRCodeCopiesModal.jsx';
import { DatePicker } from 'antd';
import {
formatDateForAPI,
generateBarcode,
generateCodeImage,
generateQRCode,
generateQRCodeCopy,
} from '../../Services/utils.js';
const { RangePicker } = DatePicker;
const barCodeImage =
'https://cdn.pixabay.com/photo/2014/04/02/16/19/barcode-306926_1280.png';
const qrCodeImage =
'https://cdn.pixabay.com/photo/2015/03/21/09/34/qr-683354_640.png';
const subDirectory = import.meta.env.BASE_URL;
const previewText = 'Barcode Preview';
const items = [
{
name: 'Home',
link: `${subDirectory}app-page/home`,
},
{
name: 'Product Receipt',
link: `${subDirectory}setting/purchase-entry`,
},
];
const StockList = () => {
const formRef = useRef();
const { SadminuserAccess } = useAuth();
let SAAccessCommonMaster = SadminuserAccess?.find(
(e) => e?.MenuName === 'Product Receipt'
);
const navigate = useNavigate();
const location = useLocation();
const dispatch = useDispatch();
const CompId = getSession('CompId');
const BranchId = getSession('BranchId');
const AppId = getSession('AppId');
const UserId = getSession('UserId');
const UserType = getSession('UserType');
const [printReady, setPrintReady] = useState(false);
const StockData = useSelector(purchaseDataSelector);
console.log(StockData, 'StockData');
const SupplierData = useSelector(supplierSelector);
const excelDataValues = useSelector(excelDataSelector);
const TaxData = useSelector(taxSelector);
const [filteredInfo, setFilteredInfo] = useState({});
const [sortedInfo, setSortedInfo] = useState({});
const [messageType, setMessageType] = useState(null);
const [messageData, setMessageData] = useState(null);
const [empData, setEmpData] = useState();
const [addnewAccess, setaddnewAccess] = useState(true);
const [page, setpage] = useState(1);
const [open, setOpen] = useState(false);
const [Exceldatasubmit, setExceldatasubmit] = useState(null);
const [Totaltax, setTotaltax] = useState(null);
const [Totalamount, setTotalamount] = useState(null);
const [Taxdatas, setTaxdatas] = useState();
const [Billamount, setBillamount] = useState(null);
const [Productdata, setProductdata] = useState();
const [Varientdata, setVarientdata] = useState();
const [ProddtlModal, setProddtlModal] = useState(false);
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([]);
const [base64Image, setBase64Image] = useState(null);
const [barcodeBase64Image, setBarcodeBase64Image] = useState(null);
const [dropdownValue, setDropdownValue] = useState();
const [QrandbarcodeDatas, setQrandbarcodeDatas] = useState([]);
const [printProductName, setPrintProductName] = useState(false);
const [copies, setCopies] = useState();
const [coresdata, setCoresdata] = useState([]);
const [barcodeTemplateDetails, setBarcodeTemplateDetails] = useState([]);
const [stockWiseQrcode, setstockWiseQrcode] = useState(false);
const [productWiseQrcode, setProductWiseQrcode] = useState(false);
const [selectedRecords, setSelectedRecords] = useState([]);
const [activeTab, setActiveTab] = useState('stock');
const [MultiCode, setMultiCode] = useState(true);
const [dateStrings, setDateStrings] = useState([
dayjs().format('YYYY-MM-DD'),
dayjs().format('YYYY-MM-DD'),
]);
const [SearchText, setSearchText] = useState(null);
const [debouncedSearchText, setDebouncedSearchText] = useState(null);
useEffect(() => {
const timer = setTimeout(() => {
setDebouncedSearchText(SearchText);
}, 500);
return () => clearTimeout(timer);
}, [SearchText]);
console.log(QrandbarcodeDatas, 'QrandbarcodeDatas');
const [templateOptions, setTemplateOptions] = useState({
mrp: false,
barcode: false,
color: false,
eDate: false,
mDate: false,
sellingPrice: false,
productName: false,
value: '',
secondValue: '',
qrcode: false,
codeType: '',
});
useEffect(() => {
try {
fetchData();
} catch (err) {
console.log(err, 'err');
}
getPreference();
getBarcodeSessionData();
}, []);
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]);
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 === 'Product Receipt'
);
setEmpData(datas?.[0]);
};
useEffect(() => {
dispatch(changeBreadCrumb({ items: items }));
barcodeApiData();
}, []);
async function fetchData() {
if (location?.state?.Notiffy) {
setMessageType(location?.state?.Notiffy.messageType);
setMessageData(location?.state?.Notiffy.messageData);
}
}
const fetchDataget = async ({ queryKey }) => {
const [_, dates, page] = queryKey;
const Response = await dispatch(
getPurchaseData({
AppId: AppId,
BranchId: BranchId,
CompId: CompId,
OrderFromDate: formatDateForAPI(dates?.[0]) ?? '',
OrderToDate: formatDateForAPI(dates?.[1]) ?? '',
PageNumber: page,
})
).unwrap();
if (Response?.data?.statusCode === 1) {
return Response?.data?.data;
} else {
return [];
}
};
const handleDateChange = (dates, dateStrings) => {
// setDateRange(dateStrings);
if (dateStrings[0] && dateStrings[1]) {
setDateStrings(dateStrings);
setpage(1);
}
};
const { data, isLoading, error } = useQuery({
queryKey: ['purchaseEntry', dateStrings, page],
queryFn: fetchDataget,
enabled: true,
staleTime: 1000 * 60 * 5,
cacheTime: 1000 * 60 * 30,
keepPreviousData: true,
refetchOnMount: 'always',
refetchOnWindowFocus: true,
refetchOnReconnect: true,
});
const { data: countData } = useQuery({
queryKey: ['searchPurchaseEntry', debouncedSearchText],
queryFn: searchData,
enabled: !!debouncedSearchText,
staleTime: 1000 * 60 * 5,
cacheTime: 1000 * 60 * 30,
keepPreviousData: true,
refetchOnMount: 'always',
refetchOnWindowFocus: true,
refetchOnReconnect: true,
});
const filteredData = debouncedSearchText ? countData || [] : data || [];
console.log(data, countData, '1111111111111111', filteredData);
async function searchData({ queryKey }) {
const [_, SearchText] = queryKey;
const Response = await dispatch(
getPurchaseData({
AppId: AppId,
BranchId: BranchId,
CompId: CompId,
// OrderFromDate: dateStrings?.[0] ?? '',
// OrderToDate: dateStrings?.[1] ?? '',
search: SearchText,
})
).unwrap();
if (Response?.data?.statusCode === 1) {
setpage(1);
return Response?.data?.data;
} else {
return [];
}
}
const handleChange = (pagination, filters, sorter) => {
setFilteredInfo(filters);
setSortedInfo(sorter);
};
const handlePageChange = (current) => {
setpage(current);
};
const onSearch = (value) => {
setSearchText(e?.target?.value);
};
const onSearchChange = (e) => {
setSearchText(e?.target?.value);
};
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 actionsFormatter = async (row, rowIndex) => {
navigate(
`${subDirectory}setting/purchase-entry/update`,
{ state: { editstate: row } },
{ key: rowIndex }
);
};
const ViewProductdetails = (proddetails) => {
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);
};
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';
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 QrandBarcodeDats = async (ProdDetails) => {
const result = await Promise.all(
ProdDetails.map(async (item) => {
const data = await QRCode.toDataURL(item.QRCode);
return {
key: item.QRCode,
url: data,
productName: item.ProdName,
copiesCount: item.AcceptedQty,
StockAvailable: item.StockAvailable,
};
})
);
setQrandbarcodeDatas((prev) => [...prev, ...result]);
};
const Qrcode = (record) => {
setSelectedRecords(record?.ProdDetails);
QrandBarcodeDats(record?.ProdDetails);
setOpen(true);
};
const barcodeApiData = async () => {
const getResponse = await dispatch(
getBarcodeTemplate({ compId: CompId, appId: AppId, branchId: BranchId })
).unwrap();
if (getResponse?.data?.statusCode === 1) {
if (getResponse?.data?.data?.length > 0) {
const { TemplateDetails } = getResponse?.data?.data?.[0];
setBarcodeTemplateDetails(TemplateDetails);
}
}
};
const columns = [
{
title: 'Sl.No',
key: 'sno',
align: 'center',
render: (text, object, index) => (
<a style={{ color: 'black' }}>{(page - 1) * 10 + index + 1}</a>
),
},
{
title: 'Invoice No',
dataIndex: 'InvoiceNo',
key: 'InvoiceNo',
align: 'center',
render: (text, row) => (
<a style={{ color: 'black' }}>
{extractLastNumberOrderId(text, row?.FYStatus)}
</a>
),
},
{
title: 'Invoice Amount',
dataIndex: 'NetAmount',
key: 'NetAmount',
align: 'right',
// ellipsis: true,
render: (text) => <a style={{ color: 'black' }}>{safeRound(text)}</a>,
},
{
title: 'Supp Name',
dataIndex: 'CustSuppName',
key: 'CustSuppName',
align: 'center',
render: (text, row) => (
<a style={{ color: 'black' }}>{row?.CustSuppName || '-'}</a>
),
},
{
title: 'Supp Invoice No',
dataIndex: 'SuppInvoiceNo',
key: 'SuppInvoiceNo',
align: 'center',
render: (text, row) => (
<a style={{ color: 'black' }}>{row?.SuppInvoiceNo || '-'}</a>
),
},
{
title: 'Date',
dataIndex: 'InvoiceDate',
key: 'InvoiceDate',
align: 'center',
render: (text) => (
<a style={{ color: 'black' }}>{ExtractDateFormate(text)}</a>
),
},
{
title: 'Product Details',
key: 'ProdDetails',
dataIndex: 'ProdDetails',
align: 'center',
render: (ProdDetails, record) => (
<IoEye
style={{ color: '#1292EE', fontSize: '25px', cursor: 'pointer' }}
onClick={() => ViewProductdetails(ProdDetails)}
/>
),
},
{
title: 'Image',
key: 'ImageDetails',
dataIndex: 'ImageDetails',
align: 'center',
render: (data, record) => {
if (data?.length > 0) {
return (
<IoEye
style={{ color: '#1292EE', fontSize: '25px', cursor: 'pointer' }}
onClick={() => viewImages(data)}
/>
);
} else {
return <p>-</p>;
}
},
},
{
title: 'Print',
key: 'Print',
dataIndex: 'Print',
width: '100px',
align: 'center',
render: (_, record) => (
// productData.length >= 1 ? (
<Space size="middle">
{record?.ProdDetails?.some((item) => item?.QRCode != null) ? (
<a>
<PrinterFilled
style={{ fontSize: '20px' }}
onClick={() => Qrcode(record)}
/>
</a>
) : (
'-'
)}
</Space>
),
// ) : null,
},
];
const Proddetailcolumns = [
{
title: 'Sl.No',
key: 'sno',
align: 'center',
render: (text, object, index) => (
<a style={{ color: 'black' }}>{(page - 1) * 10 + index + 1}</a>
),
},
{
title: 'Product Name',
dataIndex: 'ProdName',
key: 'ProdName',
},
{
title: 'UOM',
dataIndex: 'UOMName',
key: 'UOMName',
align: 'center',
render: (text, row) => (
<a style={{ color: 'black' }}>
{row.Size} {row.UOMName}
</a>
),
},
{
title: 'MRP',
dataIndex: 'MRP',
key: 'MRP',
align: 'right',
render: (text) => <a style={{ color: 'black' }}>{safeRound(text)}</a>,
},
{
title: 'Retail Price',
dataIndex: 'SellPrice',
key: 'SellPrice',
align: 'right',
render: (text) => <a style={{ color: 'black' }}>{safeRound(text)}</a>,
},
{
title: 'Accepted Quantity',
dataIndex: 'AcceptedQty',
key: 'AcceptedQty',
align: 'right',
render: (text) => <a style={{ color: 'black' }}>{text}</a>,
},
{
title: 'IMEI/SERIAL-NO',
dataIndex: 'AcceptedQty',
key: 'AcceptedQty',
align: 'right',
render: (text, record, index) => {
return (
<>
{' '}
<EyeOutlined
onClick={() => HandleimedSerialData(record)}
className="shape-preview"
/>
</>
);
},
},
];
const HandleimedSerialData = (record) => {
setImeiSerialModal(true);
const merged = record.ProductIdentifierDtls.map((device, index) => ({
...device,
...record.ProductIdentifierDtls[index], // Add ProductIdentifierDtls data if it exists
}));
setIMEISeriandata(merged);
};
const IMEISerialcolumns = [
{
title: 'Sl.No',
key: 'sno',
align: 'center',
render: (text, object, index) => (
<a style={{ color: 'black' }}>{(page - 1) * 10 + index + 1}</a>
),
},
{
title: 'IMEI1',
dataIndex: 'IMEI1',
key: 'IMEI1',
render: (text) => <a style={{ color: 'black' }}>{text ? text : '-'}</a>,
},
{
title: 'IMEI2',
dataIndex: 'IMEI2',
key: 'IMEI2',
align: 'center',
render: (text) => <a style={{ color: 'black' }}>{text ? text : '-'}</a>,
},
{
title: 'Mac Id',
dataIndex: 'MacId',
key: 'MacId',
align: 'center',
render: (text) => <a style={{ color: 'black' }}>{text ? text : '-'}</a>,
},
{
title: 'SerialNumber',
dataIndex: 'SerialNumber',
key: 'SerialNumber',
align: 'center',
render: (text) => <a style={{ color: 'black' }}>{text ? text : '-'}</a>,
},
];
const onComplete = useCallback(() => {
setMessageData(null);
setMessageType(null);
}, []);
const handelAddButton = () => {
navigate(`${subDirectory}setting/purchase-entry/new`);
};
//------------------------------------------------------------------------------------------------------------------------------
const getBarcodeSessionData = async () => {
try {
let resp = await dispatch(getBarcodeSessionsIDs()).unwrap();
if (resp?.data?.statusCode === 1) {
setCoresdata(
resp?.data?.data?.filter(
(item) => !item.ConfigName?.includes('100X13 (55MM Printable Gold)')
) || []
);
} else {
setCoresdata([]);
}
} catch (error) {
console.error('Error fetching barcode session data:', error);
}
};
useEffect(() => {
Bulkuploadsubdata();
}, []);
const imageUrlToBase64 = async (url) => {
try {
const response = await fetch(url);
const blob = await response.blob();
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result);
reader.onerror = reject;
reader.readAsDataURL(blob);
});
} catch (error) {
console.error('Error fetching or converting image:', error);
throw error;
}
};
const Bulkuploadsubdata = async () => {
dispatch(
getSupplierData({ AppId: AppId, BranchId: BranchId, CompId: CompId })
);
// dispatch(
// getPurchaseData({ AppId: AppId, BranchId: BranchId, CompId: CompId })
// );
let ProdData = {
AppId: AppId,
BranchId: BranchId,
CompId: CompId,
StockAvailable: 'Y',
};
let res = await dispatch(getProductData(ProdData)).unwrap();
setProductdata(res?.data?.data);
let data = { CompId: CompId, BranchId: BranchId, AppId: AppId };
let Varientdatas = await dispatch(getalltVariantData(data)).unwrap();
setVarientdata(Varientdatas.data?.data);
dispatch(getAdmin({ AppId: AppId, CompId: CompId }));
};
const handleCancel = () => {
setOpen(false);
handleResetExcelData();
};
const openModal = () => {
setOpen(true);
// setEditState(false);
};
const handleResetExcelData = () => {
dispatch(emptyExcelData());
};
useEffect(() => {
let Totaltax = Taxdatas?.reduce((accumulator, currentValue) => {
return accumulator + (currentValue.TaxAmt || 0);
}, 0);
let Totalamount = Taxdatas?.reduce((accumulator, currentValue) => {
return accumulator + parseInt(currentValue.Amount, 10);
}, 0);
let Billamount = Totalamount - Totaltax;
setTotaltax(Totaltax);
setTotalamount(Totalamount);
setBillamount(Billamount);
}, [Taxdatas]);
useEffect(() => {
let updatedExceldatasubmit = Exceldatasubmit?.map((excelItem) => {
const [productName, sizeAndUom] =
excelItem?.ProductName?.split(' (') || [];
const [size, uomName] = sizeAndUom
? sizeAndUom.slice(0, -1).split(' ')
: [];
const matchingProduct = Productdata?.find(
(product) =>
product.ProdName === productName &&
product.Size.toString() === size &&
product.UomName === uomName
);
if (matchingProduct) {
const TaxAmt =
(parseInt(excelItem?.Amount) *
parseInt(matchingProduct.TaxPercentage)) /
(100 + parseInt(matchingProduct.TaxPercentage))?.toFixed(2);
return {
...excelItem,
TaxId: matchingProduct.TaxId,
TaxPercentage: matchingProduct.TaxPercentage,
TaxAmt: TaxAmt,
};
}
return excelItem;
});
setTaxdatas(updatedExceldatasubmit);
}, [Exceldatasubmit]);
const handleSubmitbulk = (excelData) => {
setExceldatasubmit(excelData);
};
const createGroupKey = (data) => {
if (data.OwnWithPaid === 'Own') {
// For "Own", only check OwnWithPaid, InwardDate, and DueDate
return `Own|${data.InwardDate}|${data.DueDate}`;
} else {
// For "With Paid", check all fields
let key = `WithPaid|${data.InwardDate}|${data.DueDate}|${data.PaymentType}|${data.PaymentMode}`;
if (data.InvoiceDeliveryChallan === 'Invoice') {
key += `|Invoice|${data.SupplierInvoiceNumber}|${data.SupplierInvoiceDate}`;
} else if (data.InvoiceDeliveryChallan === 'Delivery Challan') {
key += `|DeliveryChallan|${data.DeliveryChallanNo}|${data.DeliveryInvoiceDate}`;
}
return key;
}
};
// Helper function to check if product already exists in ProdDetails
const isDuplicateProduct = (prodDetails, newItem) => {
return prodDetails.some(
(item) =>
item.ProdName === newItem.ProdName &&
item.VariantName === newItem.VariantName &&
item.MRP === newItem.MRP &&
item.SalesPrice === newItem.SalesPrice &&
item.Quantity === newItem.Quantity &&
item.RejectedQty === newItem.RejectedQty
);
};
const handleSubmit = async () => {
let FilterData = Exceldatasubmit?.filter((a) => a['ProductName'] != '');
if (FilterData && FilterData.length > 0) {
const groupedData = {};
FilterData.forEach((data) => {
const groupKey = createGroupKey(data);
if (!groupedData[groupKey]) {
groupedData[groupKey] = {
groupInfo: {
Supplier: data.Supplier,
OwnWithPaid: data.OwnWithPaid,
InvoiceDeliveryChallan: data.InvoiceDeliveryChallan,
PaymentType: data.PaymentType,
PaymentMode: data.PaymentMode,
InwardDate: data.InwardDate,
SupplierInvoiceNumber: data.SupplierInvoiceNumber,
SupplierInvoiceDate: data.SupplierInvoiceDate,
DeliveryChallanNo: data.DeliveryChallanNo,
DeliveryInvoiceDate: data.DeliveryInvoiceDate,
DueDate: data.DueDate,
},
products: [],
};
}
// Check if product is not duplicate before adding
if (!isDuplicateProduct(groupedData[groupKey].products, data)) {
groupedData[groupKey].products.push(data);
}
});
const commonData = {
AppId: getSession('AppId'),
CompId: getSession('CompId'),
BranchId: getSession('BranchId'),
CreatedBy: getSession('UserId'),
};
const formattedData = Object.values(groupedData).map((group) => {
const { groupInfo, products } = group;
// Calculate totals based on products
const Totaltax = products.reduce((acc, item) => {
return acc + (parseFloat(item.TaxAmt?.replace(/,/g, '')) || 0);
}, 0);
const Totalamount = products.reduce((acc, item) => {
return acc + parseFloat(item.Amount?.replace(/,/g, '') || 0);
}, 0);
const Billamount = Totalamount - Totaltax;
// Calculate PaymentAmount from products
const PaymentAmount = products.reduce((acc, item) => {
const amount = parseFloat(item.PaymentAmount?.replace(/,/g, '') || 0);
return acc + amount;
}, 0);
return {
...commonData, // Assuming commonData is defined elsewhere
SuppName: groupInfo.Supplier,
OwnWithPaid: groupInfo.OwnWithPaid,
InvoiceDeliveryChallan: groupInfo.InvoiceDeliveryChallan,
PayType: groupInfo.PaymentType,
PaymentType: groupInfo.PaymentMode || groupInfo.PaymentType,
PaymentMode: groupInfo.PaymentMode,
PaymentAmount: PaymentAmount.toFixed(2),
InvoiceDate: groupInfo.InwardDate
? moment(groupInfo.InwardDate, 'YYYY-MM-DD').format(
'YYYY-MM-DDTHH:mm:ss'
)
: null,
SuppInvoiceNo: groupInfo.SupplierInvoiceNumber,
SuppInvoiceDate: groupInfo.SupplierInvoiceDate
? moment(groupInfo.SupplierInvoiceDate, 'YYYY-MM-DD').format(
'YYYY-MM-DDTHH:mm:ss'
)
: null,
DeliveryChallanNo: groupInfo.DeliveryChallanNo,
DeliveryInvoiceDate: groupInfo.DeliveryInvoiceDate
? moment(groupInfo.DeliveryInvoiceDate, 'YYYY-MM-DD').format(
'YYYY-MM-DDTHH:mm:ss'
)
: null,
DueDate: groupInfo.DueDate
? moment(groupInfo.DueDate, 'YYYY-MM-DD').format(
'YYYY-MM-DDTHH:mm:ss'
)
: null,
InvoiceAmount: Totalamount.toFixed(2),
TaxAmount: Totaltax.toFixed(2),
TotalAmount: Totalamount.toFixed(2),
BillAmount: Billamount.toFixed(2),
PaymentStatus: 'S',
PurOrderStatus: 'P',
ProdDetails: products.map((item) => ({
ProdName: item.ProductName,
ProdVariantName: item.VariantName,
Quantity: item.Quantity,
ReceivedQty: item.ReceivedQty,
RejectedQty: item.RejectedQty,
AcceptedQty: item.AcceptedQty,
FreeQty: item.FreeQty,
ManufDate: item.ManufactureDate
? moment(item.ManufactureDate, 'YYYY-MM-DD').format(
'YYYY-MM-DDTHH:mm:ss'
)
: null,
ExpDate: item.ExpireDate
? moment(item.ExpireDate, 'YYYY-MM-DD').format(
'YYYY-MM-DDTHH:mm:ss'
)
: null,
BatchNo: item.BatchNo,
ModelNo: item.ModelNo,
InwardPrice: item.PurchaseRate,
Amount: item.Amount,
MRP: item.MRP,
SellPrice: item.SalesPrice,
OnePcsPrice: item.AmountPerPiece,
NoOfPcs: item.NumberofPieceInside,
WhSalePrice: item.WholesalePrice,
})),
};
});
let postDatas = { ...commonData, StockDetails: formattedData };
let response = await dispatch(Bulkstockpost(postDatas)).unwrap();
if (response?.data?.statusCode == 1) {
setMessageType('success');
setMessageData(response?.data?.response);
// dispatch(
// getStockData({
// AppId: AppId,
// BranchId: BranchId,
// CompId: CompId,
// StockAvailable: 'Y',
// })
// );
await Bulkuploadsubdata();
} else {
setMessageType('error');
setMessageData(response?.data?.response);
}
handleResetExcelData();
handleCancel();
} else {
setMessageType('error');
setMessageData('No data to submit. Please upload an Excel file.');
}
};
const CoresOnChange = (params) => {
setDropdownValue(params);
formRef.current?.setFieldsValue({ Cross: params });
const template = barcodeTemplateDetails?.find(
(find) => find.SessionName === params
);
const checkComponent = (name) =>
template?.OptionDetails?.some((some) => some.OptionName === name);
const productName = checkComponent('Product Name');
setPrintProductName(productName);
};
const ProductName = Productdata?.map(
(e) => `${e.ProdName} (${e.Size} ${e.UomName})`
);
const SupplierNames = SupplierData?.map((e) => e.SuppName);
const TaxDatas = TaxData.map((e) => e.TaxIdName);
const TaxData1 = TaxData.map((e) => e.TaxPercentage);
const combinedTaxData = TaxDatas.map(
(taxIdName, index) => `${taxIdName} - ${TaxData1[index]}%`
);
// const ProductName = Productdata?.map((e) => `${e.ProdName} (${e.Size} ${e.UomName})`);
const ProductId = Productdata?.map((e) => e.ProdId);
const VarientName = Varientdata?.map((e) => e.ProdVariantName);
const InwardDtlIds = Varientdata?.map((e) => e.InwardDtlId);
const StockProductId = Varientdata?.map((e) => e.ProdId);
const onFinish = async () => {
const template = barcodeTemplateDetails?.find(
(find) => find.SessionName === dropdownValue
);
const templateAvailable = template === undefined ? false : true;
if (templateAvailable) {
const checkComponent = (name) =>
template?.OptionDetails?.some((some) => some.OptionName === name);
const mrp = checkComponent('MRP');
const barcode = checkComponent('Barcode');
const color = checkComponent('Color');
const eDate = checkComponent('E Date');
const mDate = checkComponent('M Date');
const sellingPrice = checkComponent('Selling Price');
const productName = checkComponent('Product Name');
const qrcode = checkComponent('Qrcode');
const position = template.Position !== '' ? template.Position : '';
const positionString =
template.PositionString !== '' ? template.PositionString : '';
setTemplateOptions({
mrp: mrp,
barcode: barcode,
color: color,
eDate: eDate,
mDate: mDate,
sellingPrice: sellingPrice,
productName: productName,
value: position,
secondValue: positionString,
qrcode: qrcode,
codeType: template?.CodeType,
});
}
setPrintReady(true);
setTimeout(async () => {
switch (dropdownValue) {
case '15X15 6cross':
await printDiv(
templateAvailable ? 'label-15X156cross' : 'StickerPrints0',
style + getPageStyle(92)
);
break;
case '22X35 3cross':
await printDiv(
templateAvailable ? '22X353cross' : 'StickerPrints1',
style + getPageStyle(105)
);
break;
case '25X25 4cross':
await printDiv(
templateAvailable ? '25X254cross' : 'StickerPrints2',
style + getPageStyle(100)
);
break;
case '25X50 2cross':
await printDiv(
templateAvailable ? '25X502cross' : 'StickerPrints3',
style + getPageStyle(100)
);
break;
case '50X30 Single':
await printDiv(
templateAvailable ? '50X30Single' : 'StickerPrints4',
style
);
break;
case '50X25 Single':
await printDiv(
templateAvailable ? '50X25Single' : 'StickerPrints5',
style
);
break;
case '100X13 (55MM Printable)':
await printDiv(
templateAvailable ? '100X13(55MMPrintable)' : 'StickerPrints6',
style
);
break;
case '100X15 (70MM Printable)':
await printDiv(
templateAvailable ? '100X15(70MMPrintable)' : 'StickerPrints7',
style
);
break;
case '100X150':
await printDiv(
templateAvailable ? '100X150' : 'StickerPrints8',
style
);
break;
default:
alert('! Select correct cross ');
}
handleQRStickerPrinterModelCancel();
setPrintReady(false);
}, 100);
};
const handleQRStickerPrinterModelCancel = () => {
setDropdownValue();
setCopies();
setOpen(false);
formRef?.current?.resetFields();
setSelectedRecords([]);
setQrandbarcodeDatas([]);
// setMultiCode(false);
};
const totalCopies = QrandbarcodeDatas?.reduce(
(sum, item) => sum + Number(item?.copiesCount || 0),
0
);
const CopiesOnChange = (params) => {
setCopies(params);
formRef.current?.setFieldsValue({ Copies: params });
};
const imageTagBarcodeAndQR = useCallback(
(w = 'auto', fs = '6px', codeData = null) => {
const currentCode = codeData;
return (
(templateOptions.barcode || templateOptions.qrcode) && (
<>
<img
style={{ width: w }}
src={
templateOptions.codeType === 'B'
? !MultiCode
? barcodeBase64Image
: generateBarcode(currentCode)
: !MultiCode
? base64Image
: generateQRCode(QrandbarcodeDatas, currentCode)
}
alt="Barcode"
/>
{templateOptions.codeType !== 'B' && (
<p style={{ margin: '0', padding: '0', fontSize: fs }}>
{currentCode}
</p>
)}
</>
)
);
},
[templateOptions, MultiCode, barcodeBase64Image, base64Image]
);
const countOfProduct = debouncedSearchText
? countData?.length
? countData?.length
: 0
: data?.[0]?.TotalCount;
console.log(debouncedSearchText, countData, data, 'kkkk', countOfProduct);
return (
<div className="userPageTable">
<div className="userPageContent">
<Messages
messageType={messageType}
messageData={messageData}
onComplete={onComplete}
/>
<div className="formAddNew">
<div>
<FormHeader title={'Product Receipt'} />
</div>
<div
className="StocklistsearchAddDiv"
style={{ justifyContent: 'flex-start', flexWrap: 'wrap' }}
>
<Tooltip title="Search using Invoice No,Supp Name">
<div className="formSearch" style={{ Width: '200px' }}>
<Search
placeholder="Search by Invoice No"
onSearch={onSearch}
onSearchChange={onSearchChange}
/>
</div>
</Tooltip>
<div style={{ width: '200px' }}>
<RangePicker
placeholder={['Start Date', 'End Date']}
format="DD-MMM-YY"
defaultValue={[dayjs(), dayjs()]}
onChange={handleDateChange}
disabledDate={(current) =>
current && current > dayjs().startOf('day')
}
/>
</div>
<div className="commonMaster-btn" style={{ display: 'flex' }}>
<div>
<TertiaryButton
buttonText="Import / Export Excel"
className="tertiary_Button"
disabled={addnewAccess}
handleSubmit={openModal}
></TertiaryButton>
</div>
<div className="productMaster-input">
<Buttons
buttonText={'Add New'}
handleSubmit={() => handelAddButton()}
disabled={addnewAccess}
color="901D77"
icon={<PlusOutlined />}
>
OPEN
</Buttons>
</div>
</div>
</div>
</div>
<div className="reportTable">
<Tables
columns={columns}
data={filteredData}
dataSource={filteredData}
onChange={handleChange}
// pagination={handlePageChange}
/>{' '}
{countOfProduct > 10 && (
<Pagination
className="producttablepagination"
current={page}
total={countOfProduct}
pageSize={10}
onChange={handlePageChange}
showSizeChanger={false}
// showQuickJumper={true}
showTotal={(total) =>
`Total ${countOfProduct ? countOfProduct : 0} items`
}
/>
)}{' '}
</div>
</div>
<DefaultModal
open={open}
title="Bulk Upload"
footer={true}
width={excelDataValues?.length > 0 ? 3000 : 600}
children={
<>
<StockExcel
SupplierNames={SupplierNames}
ProductName={ProductName}
ProductId={ProductId}
// ProductSize={ProductSize}
// ProductUomName={ProductUomName}
TaxDatas={combinedTaxData}
Allproductdatas={Productdata}
VarientName={VarientName}
InwardDtlIds={InwardDtlIds}
StockProductId={StockProductId}
handleSubmit={handleSubmitbulk}
/>
</>
}
handleSubmit={handleSubmit}
handleCancel={handleCancel}
/>
<DefaultModal
open={ProddtlModal}
title="Product Details"
handleCancel={handleProductmodalCancel}
footer={false}
children={
<div style={{ height: '400px', overflowY: 'scroll' }}>
<Table
dataSource={PurcProddetail}
columns={Proddetailcolumns}
pagination={handlePageChange}
/>
</div>
}
/>
<DefaultModal
open={ImeiSerialModal}
title="IMEI/SerialNO Details"
handleCancel={handleIMEISerialmodalCancel}
footer={false}
children={
<div style={{ height: '400px', overflowY: 'scroll' }}>
<Table
dataSource={IMEISeriandata}
columns={IMEISerialcolumns}
pagination={handlePageChange}
/>
</div>
}
/>
<DefaultModal
open={imageModal}
title="Uploaded Image"
handleCancel={handleImageClose}
footer={false}
width={600}
className={'padding-less-modal'}
children={
<div>
{productImageDetails?.length > 0 && (
<div className="image-preview">
{productImageDetails.length > 1 && (
<>
<button
onClick={handlePrevImage}
className="image-preview__nav-btn"
>
<FaAngleLeft />
</button>
</>
)}
<div className="image-preview__content">
<Image
src={productImageDetails[currentImageIndex]?.ImageUrl}
alt="Preview"
style={{
maxWidth: '100%',
maxHeight: '400px',
objectFit: 'contain',
}}
/>
</div>
{productImageDetails.length > 1 && (
<>
<button
onClick={handleNextImage}
className="image-preview__nav-btn"
>
<FaAngleRight />
</button>
</>
)}
</div>
)}
<div
style={{
marginTop: '10px',
color: '#666',
textAlign: 'center',
fontFamily: 'Poppins',
}}
>
{currentImageIndex + 1} of {productImageDetails.length}
</div>
</div>
}
/>
<StickerPrintModel
open={open}
handleCancel={handleQRStickerPrinterModelCancel}
formRef={formRef}
onFinish={onFinish}
MultiCode={true}
activeTab={activeTab}
setActiveTab={setActiveTab}
selectedRecords={selectedRecords}
coresdata={coresdata}
dropdownValue={dropdownValue}
CoresOnChange={CoresOnChange}
barcodeTemplateDetails={barcodeTemplateDetails}
detail={null}
CopiesOnChange={CopiesOnChange}
printProductName={printProductName}
totalCopies={totalCopies}
setstockWiseQrcode={setstockWiseQrcode}
setProductWiseQrcode={setProductWiseQrcode}
templateOptions={templateOptions}
/>
{printReady && (
<StickerPrintTemplates
selectedRecords={selectedRecords}
copies={copies || totalCopies}
detail={null}
templateOptions={templateOptions}
base64Image={base64Image}
QrandbarcodeDatas={QrandbarcodeDatas}
MultiCode={true}
generateQRCodeCopy={(code) =>
generateQRCodeCopy(QrandbarcodeDatas, code)
}
generateCodeImage={(code, codeType = 'Q') =>
generateCodeImage(code, codeType, QrandbarcodeDatas)
}
imageTagBarcodeAndQR={imageTagBarcodeAndQR}
dropdownValue={dropdownValue}
barcodeTemplateDetails={barcodeTemplateDetails}
/>
)}
<QRCodeCopiesModal
open={stockWiseQrcode}
onClose={() => setstockWiseQrcode(false)}
type="stock"
onFinish={onFinish}
QrandbarcodeDatas={QrandbarcodeDatas}
setQrandbarcodeDatas={setQrandbarcodeDatas}
/>
<QRCodeCopiesModal
open={productWiseQrcode}
onClose={() => setProductWiseQrcode(false)}
type="product"
onFinish={onFinish}
QrandbarcodeDatas={QrandbarcodeDatas}
setQrandbarcodeDatas={setQrandbarcodeDatas}
/>
</div>
);
};
export default StockList;