Android_Retail/src/Pages/WholeSaleReport/WholeSalePurchaseReport.jsx

910 lines
24 KiB
React
Raw Normal View History

2026-01-27 18:27:29 +05:30
import React, { useEffect, useState, useRef } from 'react';
import { useDispatch } from 'react-redux';
import { Tooltip, Form } from 'antd';
import moment from 'moment';
import { DatePicProd } from '../../Components/Forms/DatePickerProduct.jsx';
import { Tables } from '../../Components/Tables/Table.jsx';
import { BiSolidPrinter } from 'react-icons/bi';
import './WholeSalePurchaseReport.scss';
import { changeBreadCrumb } from '../../Features/AppPage/CenterPage.js';
import { getWholeSalePurchaseReport } from '../../Features/BookingScreen/BookingData/BookingData.js';
import { extractLastNumber, getSession } from '../../Services/Others.js';
import { printDiv, RoundOffFun } from '../../Services/WSOthers.js';
import PurchaseReportPdf from '../PurchaseScreen/WholeSalePrint/wholeSalePurchaseReportpdf.jsx';
import { isMobile } from 'react-device-detect';
import { DefaultModal } from '../../Components/Modal/DefaultModal.jsx';
import Search from '../../Components/Forms/Search.jsx';
const subDirectory = import.meta.env.BASE_URL;
const WholeSalePurchaseReport = () => {
const formRef = useRef();
const dispatch = useDispatch();
const [datewiseData, setDatewiseData] = useState();
const CompId = getSession('CompId');
const BranchId = getSession('BranchId');
const UserRole = getSession('UserType');
const AppId = getSession('AppId');
const [OrderFromDate, setOrderFromDate] = useState();
const [OrderToDate, setOrderToDate] = useState();
const [UserId, setUserId] = useState(
UserRole != 'Employee' ? 0 : getSession('UserId')
);
const [page, setpage] = useState(1);
const [receiptText, setreceiptText] = useState(null);
const [WholeDataSource, setWholeDataSource] = useState([]);
const ExtraChargeDetails =
datewiseData?.ExtraChargeDetails?.length > 0
? datewiseData?.ExtraChargeDetails
: [];
const [insideWholeDataSource, setinsideWholeDataSource] = useState([]);
const [openDenomination, setOpenDenomination] = useState(false);
const [isPurchaseReportModel, SetisPurchaseReportModel] = useState(false);
const [searchedText, setSearchedText] = useState('');
useEffect(() => {
if (WholeDataSource?.length > 0) {
mobileDateWisePrintFun(WholeDataSource);
}
}, [WholeDataSource]);
const reprintDate = (date) => {
const salesDate = new Date(date);
const formattedDate = salesDate.toLocaleDateString('en-GB', {
day: '2-digit',
month: '2-digit',
year: 'numeric',
});
return formattedDate;
};
const mobileDateWisePrintFun = async (data) => {
let Dataa = WholeDataSource;
let Tabledata = Dataa?.map((data, index) => {
const snoSpacing = Math.max(0, 3 - String(index + 1).length);
// Calculate dynamic spacing for Rate
const rateSpacing = Math.max(0, 9 - String(data?.NetAmount).length);
const QtySpacing = Math.max(
0,
3 - String(data?.CountOfPaymentType).length
);
// Generate formatted string with dynamic spacings
const formattedString =
' '.repeat(snoSpacing) +
parseInt(index + 1) +
' ' +
(data?.PaymentMethod + ' '.repeat(22)).substring(0, 22) +
' ' +
' '.repeat(QtySpacing) +
String(data?.CountOfPaymentType) +
' ' +
' '.repeat(rateSpacing) +
String(data?.NetAmount) +
' ' +
'\n';
return formattedString;
});
const AmountSpace = Math.max(
0,
6 - String(parseFloat(TotalBill).toFixed(2)).length
);
const Billamountspace = Math.max(
0,
6 -
String(datewiseData?.[0]?.WholeSaleExpenseNetAmount?.toFixed(2)).length
);
const Taxamountspace = Math.max(
0,
6 -
String(datewiseData?.[0]?.WholeSaleExpenseTaxAmount?.toFixed(2)).length
);
const Netamountspace = Math.max(
0,
6 -
String(datewiseData?.[0]?.WholeSaleExpenseNetAmount?.toFixed(2)).length
);
var receiptTextdata =
"[C]<b><font size='big'>" +
'Datewise Sales' +
'</font></b>\n' +
'[L]<b>From Date :' +
reprintDate(OrderFromDate) +
'[R]<b>' +
' ' +
'To Date :' +
reprintDate(OrderToDate) +
'</b>\n' +
'[C]------------------------------------------------\n' +
'[L]<b>' +
'' +
'S.No' +
' ' +
' Payment Type ' +
' ' +
'Count ' +
' ' +
'Amount ' +
'' +
'</b>' +
'[L]\n' +
'[C]------------------------------------------------\n' +
Tabledata.join('') +
'[C]<b>------------------------------------------------</b>\n' +
'[L]<b>' +
'Total Orders:' +
datewiseData?.[0]?.Orders +
'</b>' +
'[R]<b>' +
'TotalAmount:' +
parseFloat(TotalBill).toFixed(2) +
' '.repeat(AmountSpace) +
'</b>\n' +
'[R]<b>' +
'Total Bill:' +
parseFloat(datewiseData?.[0]?.WholeSaleExpenseNetAmount).toFixed(2) +
' '.repeat(Billamountspace) +
'</b>\n' +
'[R]<b>' +
'Total Tax:' +
parseFloat(datewiseData?.[0]?.WholeSaleExpenseTaxAmount).toFixed(2) +
' '.repeat(Taxamountspace) +
'</b>\n' +
'[L]<b>------------------------------------------------</b>\n' +
'[R]<b>' +
'Net:' +
parseFloat(datewiseData?.[0]?.WholeSaleExpenseNetAmount).toFixed(2) +
' '.repeat(Netamountspace) +
'</b>\n';
setreceiptText(receiptTextdata);
};
const items = [
{
name: 'Home',
link: `${subDirectory}app-page/home`,
},
];
const style = `<style>
@import url('https://fonts.googleapis.com/css2?family=Calistoga&display=swap');
@media print {
body {
font-family:"Calistoga", serif;
font-size: 10px;
margin: 0;
padding: 0;
}
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family:"Calistoga", serif;
}
.purchase-report {
font-family:"Calistoga", serif;
max-width: max-content;
margin: 0 auto;
border: 1px solid #000;
padding: 1px 1px;
text-align: center;
background-color: #ffffff;
}
.wc-header {
display: flex;
align-items: flex-start;
gap: 4px;
padding: 4px 4px;
}
.imagelogo {
width: 65px;
height: 60px;
}
.mandiName {
font-size: 13px;
font-weight: 700;
width: 100%;
}
.wcadd1 {
font-size: 10px;
font-weight: 600;
}
.wcadd2 {
font-size: 10px;
font-weight: 600;
}
.wcphone {
font-size: 8px;
font-weight: 600;
}
.infoOfMandi {
width: 100%;
// text-align: center;
}
.wc-datetime {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 8px;
width: 95%;
}
.wc-date {
font-size: 11px;
font-weight: 600;
padding: 1px 0;
}
.wc-supName {
font-size: 11px;
font-weight: 600;
}
.header {
text-align: center;
margin-bottom: 1px;
padding-bottom: 10px;
display: flex;
gap: 10px;
}
.logo {
width: 65px;
height: 90px;
margin-bottom: 1px;
}
.date-time {
display: flex;
font-size: 10px;
align-items: center;
justify-content: space-between;
width: 95%;
padding: 0px 1px;
padding-bottom: 2px;
border-bottom: 1px solid #000;
}
.table-container {
width: 100%;
}
.table {
width: 95%;
border-collapse: collapse;
margin-left:2px;
}
.table th, .table td {
border: 1px solid #000;
padding: 1px 1px;
text-align: center;
}
.total {
text-align: right;
}
.footer {
margin-top: 20px;
text-align: center;
// border-top: 1px solid #000;
padding-top: 10px;
}
.summary {
text-align: right;
margin-bottom: 10px;
font-size: 16px;
font-weight: bold;
}
.boldText {
}
.noneBorder {
border: none !important;
}
.infoOfMandi {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 2px;
}
.printmandiName {
border-bottom: 1px solid #000;
text-align: left;
font-size: 20px;
word-wrap: break-word;
padding: 6px 0;
font-weight: 500;
}
.databody {
> tr:nth-child(1) {
width: 10%;
}
> tr:nth-child(2) {
width: 30%;
}
> tr:nth-child(3) {
width: 30%;
}
> tr:nth-child(4) {
width: 30%;
}
> tr > td {
font-size: 10px !important;
}
}
.prtTitle {
font-size: 16px;
width: 100%;
text-align: center;
padding:4px 4px;
}
.tableHead {
font-size: 10px !important;
}
table th, .table td {
text-align: center;
border-width: 1px;
border-style: solid;
border-color: rgb(0, 0, 0);
border-image: initial;
padding: 4px 5px !important;
}
.Add-Shortname{
display: flex;
width: 95%;
justify-content: space-between;
}
.Address{
display:flex;
flex-direction:column;
width:77%
}
.ShortNameDiv{
display:flex;
width:23%;
font-size: 16px;
font-weight: 700;
background: #252525 !important;
color:white;
text-align:center;
justify-content:center;
align-items:center;
margin:2px ;
padding: 0px 5px;
border: 1px solid black;
border-radius:5px;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
</style>`;
useEffect(() => {
dispatch(changeBreadCrumb({ items: items }));
fetchInitialData();
}, []);
const fetchInitialData = async () => {
let currentDate = new Date().toJSON().slice(0, 10);
formRef?.current?.setFieldsValue({
Fromdate: currentDate,
Todate: currentDate,
});
setOrderFromDate(currentDate + 'T00:00:00');
setOrderToDate(currentDate + 'T00:00:00');
let data = {
CompId: CompId,
BranchId: BranchId,
AppId: AppId,
OrderFromDate: currentDate,
OrderToDate: currentDate,
};
let response = await dispatch(getWholeSalePurchaseReport(data)).unwrap();
if (response?.data?.statusCode === 1) {
setDatewiseData(response?.data?.data?.[0]);
setWholeDataSource(response?.data?.data?.[0]?.ProductDetails);
} else {
setDatewiseData([]);
}
};
const columns = [
{
title: 'SI NO',
dataIndex: 'SINO',
key: 'SINO',
align: 'center',
width: '100px',
render: (text, object, index) => (
<a style={{ color: 'black' }}>{(page - 1) * 10 + index + 1}</a>
),
onCell: (record) => ({
onClick: () => {
SetisPurchaseReportModel(true),
setinsideWholeDataSource(record?.SupplierList);
},
}),
},
{
title: 'Name',
dataIndex: 'ProdName',
key: 'ProdName',
align: 'left',
width: '150px',
render: (text, record, index) => (
<a style={{ color: 'black' }}>
{`${record?.ProdName} - ${
record?.QualityName.includes('Grade')
? record?.QualityName.split('Grade')[1].trim().replace(/^-/, '')
: record?.QualityName
} `}
</a>
),
onCell: (record) => ({
onClick: () => {
SetisPurchaseReportModel(true),
setinsideWholeDataSource(record?.SupplierList);
},
}),
filteredValue: [searchedText],
onFilter: (value, record) => {
return String(record.ProdName)
?.toLowerCase()
?.includes(value?.toLowerCase());
},
},
{
title: 'Qty',
dataIndex: 'GradeOverAllCount',
key: 'GradeOverAllCount',
width: '100px',
align: 'right',
onCell: (record) => ({
onClick: () => {
SetisPurchaseReportModel(true),
setinsideWholeDataSource(record?.SupplierList);
},
}),
},
{
title: 'Amount',
dataIndex: 'GradeOverAllAmount',
key: 'GradeOverAllAmount',
width: '100px',
align: 'right',
onCell: (record) => ({
onClick: () => {
SetisPurchaseReportModel(true),
setinsideWholeDataSource(record?.SupplierList);
},
}),
},
];
const Otherscolumns = [
{
title: 'SI NO',
dataIndex: 'SINO',
key: 'SINO',
align: 'center',
render: (text, object, index) => (
<a style={{ color: 'black' }}>{(page - 1) * 10 + index + 1}</a>
),
},
{
title: 'Charge Name',
dataIndex: 'ExtraChargeTypeName',
width: '150px',
key: 'ExtraChargeTypeName',
align: 'left',
render: (text, record, index) => (
<a style={{ color: 'black' }}>{record?.ExtraChargeTypeName}</a>
),
},
{
title: 'Amount',
dataIndex: 'TotalAmt',
key: 'TotalAmt',
align: 'right',
},
];
const insidecolumns = [
{
title: 'SI NO',
dataIndex: 'SINO',
key: 'SINO',
align: 'center',
render: (text, object, index) => (
<a style={{ color: 'black' }}>{(page - 1) * 10 + index + 1}</a>
),
},
{
title: 'Receipt No',
dataIndex: 'ProdName',
key: 'ProdName',
align: 'left',
render: (text, record, index) => (
<a style={{ color: 'black' }}>{extractLastNumber(record?.OrderId)}</a>
),
},
{
title: 'Name',
dataIndex: 'CustSuppName',
key: 'CustSuppName',
align: 'left',
render: (text, record, index) => (
<a style={{ color: 'black' }}>{`${record?.CustSuppName}`}</a>
),
},
{
title: 'Qty',
dataIndex: 'SalesQty',
key: 'SalesQty',
align: 'right',
},
{
title: 'Rate',
dataIndex: 'Rate',
key: 'Rate',
align: 'right',
},
{
title: 'Amt',
dataIndex: 'TotalAmt',
key: 'TotalAmt',
align: 'right',
},
];
const OrderFromDatefetch = async (date, dateString) => {
if (dateString === '') {
setOrderFromDate();
}
if (dateString) {
const Date3 = moment(dateString, ['DD-MM-YYYY']).format(
'YYYY-MM-DDTHH:mm:ss'
);
formRef.current?.setFieldsValue({ Fromdate: Date3 });
await setOrderFromDate(Date3);
}
};
const OrderToDatefetch = async (date, dateString) => {
if (dateString === '') {
setOrderToDate();
}
if (dateString) {
const Date4 = moment(dateString, ['DD-MM-YYYY']).format(
'YYYY-MM-DDTHH:mm:ss'
);
formRef.current?.setFieldsValue({ Todate: Date4 });
await setOrderToDate(Date4);
}
};
const Print = async () => {
let LogoImage = '';
let OrderId = '';
let UpiId = '';
let TokenData = '';
let FooterPrint = '';
if (isMobile) {
var textEncoded = encodeURI(receiptText);
var TypeCheck = 'PrintReceipt';
var scheme = 'pozoprinter';
var packageName = 'com.example.pozoprinter';
window.location.href =
scheme +
'://' +
textEncoded +
'#Intent;scheme=' +
scheme +
';package=' +
packageName +
'ImgS' +
LogoImage +
'ImgE' +
TypeCheck +
'TokenS' +
TokenData +
'TokenE' +
'EstimateS' +
'' +
'EstimateE' +
'HasFooterTextS' +
FooterPrint +
'HasFooterTextE' +
';end;';
} else {
await printDiv('RePrint', style);
}
};
const onFinish = async (values) => {
let data = {
CompId: CompId,
BranchId: BranchId,
AppId: AppId,
OrderFromDate: OrderFromDate?.split('T')?.[0],
OrderToDate: OrderToDate?.split('T')?.[0],
UserId: UserId,
};
let response = await dispatch(getWholeSalePurchaseReport(data)).unwrap();
if (response?.data?.statusCode === 1) {
setDatewiseData(response?.data?.data?.[0]);
setWholeDataSource(response?.data?.data?.[0]?.ProductDetails);
} else {
setDatewiseData([]);
setWholeDataSource([]);
}
};
const TotalBill = datewiseData?.[0]?.WholeSaleExpenseNetAmount;
const handlePageChange = (current) => {
setpage(current);
};
const onSearch = (value) => {
setSearchedText(value);
};
const onSearchChange = (e) => {
setSearchedText(e?.target?.value);
};
let NetAmt =
datewiseData?.OverAllAmount - datewiseData?.OverAllExtraChargesAmount;
return (
<div className="PurchaseReport-container">
<div style={{ display: 'none' }}>
<PurchaseReportPdf
OrderFromDate={OrderFromDate?.split('T')?.[0]}
OrderToDate={OrderToDate?.split('T')?.[0]}
dataSource={WholeDataSource}
TotalBill={datewiseData?.OverAllAmount}
TotalOrders={datewiseData?.OverAllCount}
TotalCharges={datewiseData?.OverAllExtraChargesAmount}
TaxAmount={datewiseData?.[0]?.WholeSaleExpenseTaxAmount}
TotalNetAmount={datewiseData?.OverAllAmount}
AddressDetails={datewiseData?.AddressDetails}
ExtraChargeDetails={ExtraChargeDetails}
/>
</div>
<Form ref={formRef} onFinish={onFinish}>
<div
className="PurchaseReport-dateandheading"
style={{ display: 'flex' }}
>
<p className="PurchaseReport-heading">Purchase Report</p>
<div className="PurchaseReport-dateaAnd-buttons">
<div
className="PurchaseReport-Date-picker"
style={{ display: 'flex', flexDirection: 'row', rowGap: '1rem' }}
>
<div className="PurchaseReport-datepic">
<div className="PurchaseReport-DateFrom">
<div className="PurchaseReport-Date">
<p className="PurchaseReport-Date-from-heading">
From Date
</p>
</div>
<Form.Item
name="Fromdate"
rules={[
{
required: true,
pattern: /^(?!\s*$).+/,
message: 'Please Enter the From Date ',
},
]}
>
<DatePicProd
onChange={OrderFromDatefetch}
style={{ width: '24vw', height: '2.6rem' }}
valueData={OrderFromDate}
canSelectPast={true}
cancelFuture={true}
/>
</Form.Item>
</div>
<div>
<div>
<p>To Date</p>
</div>
<Form.Item
name="Todate"
rules={[
{
required: true,
pattern: /^(?!\s*$).+/,
message: 'Please Enter the To Date ',
},
]}
>
<DatePicProd
onChange={OrderToDatefetch}
style={{ width: '24vw', height: '2.6rem' }}
valueData={OrderToDate}
canSelectPast={true}
cancelFuture={true}
minDate={OrderFromDate}
/>
</Form.Item>
</div>
<div className="datewise-userDropDown"></div>
</div>
</div>
<div className="PurchaseReport-submit-prnt">
<div>
<Tooltip title="Submit to search">
<button type="submit" className="PurchaseReport-submit-btn">
SUBMIT
</button>
</Tooltip>
</div>
<div className="PurchaseSearch">
<Search
placeholder="Search"
onSearch={onSearch}
onSearchChange={onSearchChange}
/>
</div>
<div>
<Tooltip title="Print">
<BiSolidPrinter
className={
WholeDataSource?.length > 0
? 'PurchaseReport-printerIcon'
: 'PurchaseReport-printerIcon-disabled'
}
onClick={Print}
/>
</Tooltip>
</div>
</div>
</div>
</div>
<div className="PurchaseReport-coontent-body">
<div
className={
openDenomination
? 'PurchaseReport-table-withDenom'
: 'PurchaseReport-table-withoutDenom'
}
>
<div className="tables-container">
<div
style={{ height: isMobile && 'auto' }}
className="PurchaseReport-table"
>
<Tables
columns={columns}
data={WholeDataSource}
pagination={handlePageChange}
/>
</div>
<div className="OthersReport-table">
<Tables
columns={Otherscolumns}
data={ExtraChargeDetails}
pagination={handlePageChange}
/>
</div>
</div>
<div className="PurchaseReport-Amount-Collected-container">
<div className="PurchaseReport-Amount-Collected-table">
<table className="PurchaseReport-Amount-Collected-table-div">
<thead>
<tr>
<th className="reportHeaderEnd">
Qty <span>:</span>
</th>
<th className="reportValueEnd">
{datewiseData?.OverAllCount || 0}
</th>
</tr>
<tr>
<th className="reportHeaderEnd">
Amount <span>:</span>
</th>
<th className="reportValueEnd">
{datewiseData?.OverAllAmount || 0}
</th>
</tr>
<tr>
<th className="reportHeaderEnd">
Charges (-) <span>:</span>
</th>
<th className="reportValueEnd">
{datewiseData?.OverAllExtraChargesAmount || 0}
</th>
</tr>
<tr>
<th className="reportHeaderEnd">
Total <span>:</span>
</th>
<th className="reportValueEnd">
{datewiseData?.OverAllAmount -
datewiseData?.OverAllExtraChargesAmount || 0}
</th>
</tr>
<tr>
<th className="reportHeaderEnd">
Round off <span>:</span>
</th>
<th className="reportValueEnd">
{RoundOffFun(NetAmt || 0)}
</th>
</tr>
<tr>
<th className="reportHeaderEnd">
Total <span>:</span>
</th>
<th className="reportValueEnd">
{Math.round(NetAmt) || 0}
</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
</div>
</Form>
<DefaultModal
open={isPurchaseReportModel}
title={'Purchase Details'}
handleCancel={() => {
SetisPurchaseReportModel(false);
}}
footer={false}
width={750}
className={'WholeSalePurchaseList'}
children={
<div className="PurchaseReport-table-inside">
<Tables columns={insidecolumns} data={insideWholeDataSource} />
</div>
}
></DefaultModal>
</div>
);
};
export default WholeSalePurchaseReport;