Merge pull request 'added customer search based, Ledger Download Excel, Branch Login, Edit item-wise limit' (#251) from temp/customer-searche-based into main
Reviewed-on: Pozomind/pozo-retail-app#251
This commit is contained in:
commit
7b115d7261
|
|
@ -391,9 +391,27 @@ export const getAllCustomer = createAsyncThunk(
|
|||
}
|
||||
}
|
||||
);
|
||||
export const getSearchedCustomer = createAsyncThunk(
|
||||
'product/getSearchedCustomer',
|
||||
async ({ CompId, AppId, branchId, searchValue }) => {
|
||||
if (
|
||||
CompId !== null &&
|
||||
CompId !== undefined &&
|
||||
branchId !== null &&
|
||||
branchId !== undefined &&
|
||||
AppId !== null &&
|
||||
AppId !== undefined
|
||||
&& searchValue !== '' && searchValue !== null && searchValue !== undefined
|
||||
) {
|
||||
return await axiosRetailInstanceData.get(
|
||||
`/Customer?compId=${CompId}&branchId=${branchId}&appId=${AppId}&custName=${encodeURIComponent(searchValue)}`
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
export const getCustomerForHold = createAsyncThunk(
|
||||
'product/getAllCustomer',
|
||||
'product/getCustomerForHold',
|
||||
async ({ CompId, AppId, branchId, OrderId }) => {
|
||||
if (
|
||||
CompId != null &&
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
|
|
@ -469,6 +469,14 @@ const BSBillingEditQuantity = (props) => {
|
|||
setMessageType('warning');
|
||||
return;
|
||||
}
|
||||
} else if (itemWiseLimitPreferenece) {
|
||||
const exceptEditedItemCart = calculateOverAllQtyLimit(CartOrderDetails?.filter((_, index) => index !== editedProductIndex && _.ProdId === editedProduct?.ProdId && _.InwardDtlId === editedProduct?.InwardDtlId));
|
||||
const totalQtyForItem = ((exceptEditedItemCart || 0) + (editedQty || 0));
|
||||
if (totalQtyForItem > maxQtyLimit) {
|
||||
setMessageData(`Item Quantity Limit Exceeds than ${maxQtyLimit}`);
|
||||
setMessageType('warning');
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1146,6 +1146,8 @@ const BSBillingTable1 = () => {
|
|||
e?.BookingTypeName != item?.BookingTypeName
|
||||
);
|
||||
if (tableData?.length <= 1) {
|
||||
await dispatch(changeSelectedOption(null));
|
||||
await dispatch(ChangeSelectedCustDisable(false));
|
||||
await dispatch(changeReorderHoldDetails({}));
|
||||
await dispatch(changeReorderProductDetails([]));
|
||||
await dispatch(changeUnpaidData(false));
|
||||
|
|
|
|||
|
|
@ -1062,6 +1062,8 @@ const BsBill2 = () => {
|
|||
await dispatch(changeSelProdWiseEst([]));
|
||||
await dispatch(ChangeTotalAmount([]));
|
||||
dispatch(changeBillEditingMode(false));
|
||||
await dispatch(changeSelectedOption(null));
|
||||
await dispatch(ChangeSelectedCustDisable(false));
|
||||
await dispatch(changePreviousOrderPayment([]));
|
||||
await dispatch(changePreviousOrderOfferDetail([]));
|
||||
}
|
||||
|
|
@ -1101,6 +1103,8 @@ const BsBill2 = () => {
|
|||
await dispatch(changeSelProdWiseEst([]));
|
||||
await dispatch(ChangeTotalAmount([]));
|
||||
dispatch(changeBillEditingMode(false));
|
||||
await dispatch(changeSelectedOption(null));
|
||||
await dispatch(ChangeSelectedCustDisable(false));
|
||||
await dispatch(changePreviousOrderPayment([]));
|
||||
await dispatch(changePreviousOrderOfferDetail([]));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1107,6 +1107,8 @@ const BSBillingTable3 = () => {
|
|||
);
|
||||
|
||||
if (tableData?.length <= 1) {
|
||||
await dispatch(changeSelectedOption(null));
|
||||
await dispatch(ChangeSelectedCustDisable(false));
|
||||
await dispatch(changeReorderHoldDetails({}));
|
||||
await dispatch(changeReorderProductDetails([]));
|
||||
await dispatch(changeUnpaidData(false));
|
||||
|
|
@ -2360,7 +2362,7 @@ const BSBillingTable3 = () => {
|
|||
fontSize: '16px',
|
||||
}}
|
||||
>
|
||||
{(tableData?.length > 0)? (
|
||||
{(tableData?.length > 0) ? (
|
||||
<Popconfirm
|
||||
title="Delete the items"
|
||||
description="Are you sure you want to clear these items?"
|
||||
|
|
|
|||
|
|
@ -1050,6 +1050,8 @@ const BSBillingTable4 = () => {
|
|||
);
|
||||
|
||||
if (tableData?.length <= 1) {
|
||||
await dispatch(changeSelectedOption(null));
|
||||
await dispatch(ChangeSelectedCustDisable(false));
|
||||
await dispatch(changeReorderHoldDetails({}));
|
||||
await dispatch(changeReorderProductDetails([]));
|
||||
await dispatch(changeUnpaidData(false));
|
||||
|
|
|
|||
|
|
@ -870,6 +870,8 @@ const BsBill = () => {
|
|||
);
|
||||
|
||||
if (TableData?.length <= 1) {
|
||||
await dispatch(changeSelectedOption(null));
|
||||
await dispatch(ChangeSelectedCustDisable(false));
|
||||
await dispatch(changeReorderHoldDetails({}));
|
||||
await dispatch(changeReorderProductDetails([]));
|
||||
await dispatch(changeUnpaidData(false));
|
||||
|
|
@ -2944,6 +2946,8 @@ const BsBill = () => {
|
|||
|
||||
// if the quantity of the item is 1, remove the item from the cart
|
||||
if (TableData?.length <= 1) {
|
||||
await dispatch(changeSelectedOption(null));
|
||||
await dispatch(ChangeSelectedCustDisable(false));
|
||||
await dispatch(changeReorderHoldDetails({}));
|
||||
await dispatch(changeReorderProductDetails([]));
|
||||
await dispatch(changeUnpaidData(false));
|
||||
|
|
@ -2975,6 +2979,8 @@ const BsBill = () => {
|
|||
|
||||
// if the quantity of the item is 1, remove the item from the cart
|
||||
if (TableData?.length <= 1) {
|
||||
await dispatch(changeSelectedOption(null));
|
||||
await dispatch(ChangeSelectedCustDisable(false));
|
||||
await dispatch(changeReorderHoldDetails({}));
|
||||
await dispatch(changeReorderProductDetails([]));
|
||||
await dispatch(changeUnpaidData(false));
|
||||
|
|
@ -3013,6 +3019,7 @@ const BsBill = () => {
|
|||
await dispatch(ChangeOverAllDiscEstimate(null));
|
||||
await dispatch(changeSelProdWiseEst([]));
|
||||
await dispatch(ChangeTotalAmount([]));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1106,6 +1106,8 @@ const BSBillingTable6 = () => {
|
|||
dispatch(changeBillEditingMode(false));
|
||||
await dispatch(changePreviousOrderPayment([]));
|
||||
await dispatch(changePreviousOrderOfferDetail([]));
|
||||
await dispatch(changeSelectedOption(null));
|
||||
await dispatch(ChangeSelectedCustDisable(false));
|
||||
}
|
||||
|
||||
if (item?.Offer > 0) {
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ import {
|
|||
changeBillEditingMode,
|
||||
changePreviousOrderPayment,
|
||||
changePreviousOrderOfferDetail,
|
||||
ChangeSelectedCustDisable,
|
||||
} from '../../../../../Features/BookingScreen/BookingData/BookingData';
|
||||
import {
|
||||
ChangeFullFreeProductList,
|
||||
|
|
@ -985,6 +986,8 @@ const BSBillingTable7 = () => {
|
|||
dispatch(changeBillEditingMode(false));
|
||||
await dispatch(changePreviousOrderPayment([]));
|
||||
await dispatch(changePreviousOrderOfferDetail([]));
|
||||
await dispatch(changeSelectedOption(null));
|
||||
await dispatch(ChangeSelectedCustDisable(false));
|
||||
}
|
||||
if (item?.Offer > 0) {
|
||||
//check is Buyxgetx Or something
|
||||
|
|
@ -2188,12 +2191,11 @@ const BSBillingTable7 = () => {
|
|||
? () => handleEditQuantity(item)
|
||||
: editdelete === 'Delete'
|
||||
? () => removeFromCart(item)
|
||||
: () => {}
|
||||
: () => { }
|
||||
}
|
||||
// onClick={editdelete === "Edit" ? () => handleEditQuantity(item) : editdelete === "Delete" ? () => removeFromCart(item) : ""}
|
||||
|
||||
className={`${
|
||||
item?.SalesId && OrderType !== 'Hold'
|
||||
className={`${item?.SalesId && OrderType !== 'Hold'
|
||||
? 'BSBill-Table7-content-disabled'
|
||||
: 'BSBill-Table7-content'
|
||||
}
|
||||
|
|
@ -2418,12 +2420,11 @@ const BSBillingTable7 = () => {
|
|||
? () => handleEditQuantity(item)
|
||||
: editdelete === 'Delete'
|
||||
? () => removeFromCart(item)
|
||||
: () => {}
|
||||
: () => { }
|
||||
}
|
||||
// onClick={editdelete === "Edit" ? () => handleEditQuantity(item) : editdelete === "Delete" ? () => removeFromCart(item) : ""}
|
||||
|
||||
className={`${
|
||||
item?.SalesId
|
||||
className={`${item?.SalesId
|
||||
? 'BSBill-Table7-content-disabled'
|
||||
: 'BSBill-Table7-content'
|
||||
}
|
||||
|
|
@ -2687,12 +2688,11 @@ const BSBillingTable7 = () => {
|
|||
: ''
|
||||
: editdelete === 'Delete'
|
||||
? () => removeFromCart(item)
|
||||
: () => {}
|
||||
: () => { }
|
||||
}
|
||||
// onClick={editdelete === "Edit" ? () => handleEditQuantity(item) : editdelete === "Delete" ? () => removeFromCart(item) : ""}
|
||||
|
||||
className={`${
|
||||
BookingType === 'Dine In' && item?.SalesId
|
||||
className={`${BookingType === 'Dine In' && item?.SalesId
|
||||
? 'BSBill-Table7-content-disabled'
|
||||
: 'BSBill-Table7-content'
|
||||
}
|
||||
|
|
@ -2955,12 +2955,11 @@ const BSBillingTable7 = () => {
|
|||
? () => handleEditQuantity(item)
|
||||
: editdelete === 'Delete'
|
||||
? () => removeFromCart(item)
|
||||
: () => {}
|
||||
: () => { }
|
||||
}
|
||||
// onClick={editdelete === "Edit" ? () => handleEditQuantity(item) : editdelete === "Delete" ? () => removeFromCart(item) : ""}
|
||||
|
||||
className={`${
|
||||
BookingType === 'Dine In' && item?.SalesId
|
||||
className={`${BookingType === 'Dine In' && item?.SalesId
|
||||
? 'BSBill-Table7-content-disabled'
|
||||
: 'BSBill-Table7-content'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -341,6 +341,16 @@ const ComboEditQtyAndRate = (props) => {
|
|||
setQuantity(removeProds1?.OrderQty || 1)
|
||||
return;
|
||||
}
|
||||
} else if (itemWiseLimitPreferenece) {
|
||||
let editedProduct = CartOrderDetails?.find((_, index) => index === editedProductIndex)
|
||||
const exceptEditedItemCart = calculateOverAllQtyLimit(CartOrderDetails?.filter((_, index) => index !== editedProductIndex && _.ProdId === editedProduct?.ProdId && _.InwardDtlId === editedProduct?.InwardDtlId));
|
||||
const totalQtyForItem = ((exceptEditedItemCart || 0) + (editedQty || 0));
|
||||
if (totalQtyForItem > maxQtyLimit) {
|
||||
setMessageData(`Item Quantity Limit Exceeds than ${maxQtyLimit}`);
|
||||
setMessageType('warning');
|
||||
setQuantity(editedProduct?.OrderQty || 1)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
const editedProduct = CartOrderDetails[editedProductIndex];
|
||||
|
|
|
|||
|
|
@ -1292,6 +1292,8 @@ const ComboSalesBillTable = () => {
|
|||
await dispatch(ChangeOverAllDiscEstimate(null));
|
||||
await dispatch(changeSelProdWiseEst([]));
|
||||
dispatch(changeBillEditingMode(false));
|
||||
await dispatch(changeSelectedOption(null));
|
||||
await dispatch(ChangeSelectedCustDisable(false));
|
||||
await dispatch(changePreviousOrderPayment([]));
|
||||
await dispatch(changePreviousOrderOfferDetail([]));
|
||||
}
|
||||
|
|
@ -2610,8 +2612,7 @@ const ComboSalesBillTable = () => {
|
|||
}}
|
||||
key={`qty-${index}`}
|
||||
tabIndex={0}
|
||||
className={`${
|
||||
EditQtyCombo && row?.localId === Index
|
||||
className={`${EditQtyCombo && row?.localId === Index
|
||||
? 'EditQTYcomboTD'
|
||||
: 'qtyTd'
|
||||
} ${isActiveCell ? 'active-cell' : ''}`}
|
||||
|
|
|
|||
|
|
@ -1170,6 +1170,8 @@ const StandardTable = () => {
|
|||
await dispatch(changeUnpaidData(false));
|
||||
await dispatch(changeBookingType('TakeAway'));
|
||||
await dispatch(changeTokenOnly(false));
|
||||
await dispatch(changeSelectedOption(null));
|
||||
await dispatch(ChangeSelectedCustDisable(false));
|
||||
await dispatch(ChangeTotalAmount([]));
|
||||
await dispatch(changeAllProductTokenAvailable(false));
|
||||
await dispatch(ChangeOverAllDiscSales(null));
|
||||
|
|
|
|||
|
|
@ -312,6 +312,8 @@ export const useRemoveFromCart = () => {
|
|||
dispatch(changeBillEditingMode(false));
|
||||
await dispatch(changePreviousOrderPayment([]));
|
||||
await dispatch(changePreviousOrderOfferDetail([]));
|
||||
await dispatch(changeSelectedOption(null));
|
||||
await dispatch(ChangeSelectedCustDisable(false));
|
||||
} else {
|
||||
let putData = { OrderId: [ReportholdData?.OrderId] };
|
||||
let response = await dispatch(puttinghold(putData)).unwrap();
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@
|
|||
padding: 10px 10px;
|
||||
border-radius: 8px;
|
||||
width: 60%;
|
||||
|
||||
@media (max-width: 768px) {
|
||||
width: 100%;
|
||||
}
|
||||
|
|
@ -105,6 +106,7 @@
|
|||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.BSOTPKioskPayment-dailpad-1,
|
||||
.BSOTPKioskPayment-dailpad-2,
|
||||
.BSOTPKioskPayment-dailpad-3 {
|
||||
|
|
@ -330,7 +332,7 @@
|
|||
}
|
||||
|
||||
.paymentCardMain .ant-radio-group,
|
||||
.ant-radio-wrapper span.ant-radio + * {
|
||||
.ant-radio-wrapper span.ant-radio+* {
|
||||
padding: 10px 10px;
|
||||
}
|
||||
|
||||
|
|
@ -338,10 +340,7 @@
|
|||
padding: 54px 35px !important;
|
||||
}
|
||||
|
||||
.paymentCardMain
|
||||
.ant-collapse
|
||||
.ant-collapse-item:last-child
|
||||
> .ant-collapse-content {
|
||||
.paymentCardMain .ant-collapse .ant-collapse-item:last-child>.ant-collapse-content {
|
||||
overflow: scroll;
|
||||
height: 26vh;
|
||||
}
|
||||
|
|
@ -465,6 +464,7 @@
|
|||
color: #fff;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
|
||||
@media (max-width: 768px) {
|
||||
width: 100%;
|
||||
}
|
||||
|
|
@ -573,6 +573,7 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.BSOTPItem3Warning {
|
||||
position: fixed;
|
||||
top: 0%;
|
||||
|
|
@ -635,12 +636,14 @@
|
|||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
|
||||
.input-err {
|
||||
font-family: 'Poppins', sans-serif;
|
||||
font-size: 12px;
|
||||
margin-top: 6px;
|
||||
color: rgb(224, 0, 0);
|
||||
}
|
||||
|
||||
input {
|
||||
width: 60%;
|
||||
outline: none;
|
||||
|
|
@ -652,11 +655,13 @@
|
|||
border-radius: 6px;
|
||||
border: 1px solid #333;
|
||||
font-size: 20px;
|
||||
|
||||
@media (max-width: 768px) {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.BSOTPdailpad-main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
|
@ -688,11 +693,14 @@
|
|||
.BSOTPotp-box.active {
|
||||
border: 2px solid #28a745;
|
||||
}
|
||||
|
||||
.BSOTPpaymentModal-Master {
|
||||
scrollbar-width: thin;
|
||||
height: 90vh;
|
||||
height: max-content;
|
||||
max-height: 90vh;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.optEnterResendOTP {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import {
|
|||
changeOrderCardDetails,
|
||||
changeCustomerID,
|
||||
changeCombofocus,
|
||||
getSearchedCustomer,
|
||||
} from '../../../../Features/BookingScreen/BookingData/BookingData';
|
||||
import Select from 'react-select';
|
||||
import {
|
||||
|
|
@ -45,6 +46,7 @@ import {
|
|||
FaPlus,
|
||||
FaMinus,
|
||||
FaEye,
|
||||
FaLessThanEqual,
|
||||
} from 'react-icons/fa';
|
||||
import { DefaultModal } from '../../../../Components/Modal/DefaultModal';
|
||||
import WsPreOrderForm from '../../../Wholesalespreorder/WholesalePreorderForm';
|
||||
|
|
@ -246,10 +248,16 @@ const BSCustomerSelect = ({ TopName = null }) => {
|
|||
|
||||
// Customer data
|
||||
const [allCustomers, setAllCustomers] = useState([]);
|
||||
// useEffect(() => {
|
||||
// dispatch(getAllCustomer({ CompId, AppId, branchId: BranchId }))
|
||||
// .unwrap()
|
||||
// .then((res) => setAllCustomers(res?.data?.data || []));
|
||||
// setProductQuantities({});
|
||||
// }, [CompId, AppId, BranchId, dispatch, customerRefreshTrigger]);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(getAllCustomer({ CompId, AppId, branchId: BranchId }))
|
||||
.unwrap()
|
||||
.then((res) => setAllCustomers(res?.data?.data || []));
|
||||
if (!CompId || !AppId || !BranchId) return;
|
||||
setAllCustomers([]);
|
||||
setProductQuantities({});
|
||||
}, [CompId, AppId, BranchId, dispatch, customerRefreshTrigger]);
|
||||
|
||||
|
|
@ -540,6 +548,9 @@ const BSCustomerSelect = ({ TopName = null }) => {
|
|||
)
|
||||
);
|
||||
}
|
||||
if (selectedOption === undefined || selectedOption === null) {
|
||||
setAllCustomers([]);
|
||||
}
|
||||
setCustomerpreorder(true);
|
||||
};
|
||||
|
||||
|
|
@ -978,6 +989,33 @@ const BSCustomerSelect = ({ TopName = null }) => {
|
|||
setMessageType(null);
|
||||
}, []);
|
||||
|
||||
let debounceTimer;
|
||||
|
||||
const debounceSearch = (value) => {
|
||||
clearTimeout(debounceTimer);
|
||||
|
||||
debounceTimer = setTimeout(() => {
|
||||
handleSearchCustomer(value, false);
|
||||
}, 500);
|
||||
};
|
||||
|
||||
const handleSearchCustomer = async (value, open = true) => {
|
||||
const data = {
|
||||
AppId,
|
||||
CompId,
|
||||
branchId: BranchId,
|
||||
searchValue: value,
|
||||
}
|
||||
const response = await dispatch(getSearchedCustomer(data))?.unwrap(); // your API
|
||||
if (response?.data?.data?.length > 0 && response?.data?.statusCode === 1) {
|
||||
setAllCustomers(response?.data?.data || []);
|
||||
} else if (open) {
|
||||
handleAddCustomer(value);
|
||||
} else if (!open) {
|
||||
setAllCustomers([]);
|
||||
}
|
||||
};
|
||||
|
||||
// Render
|
||||
return (
|
||||
<>
|
||||
|
|
@ -1078,14 +1116,25 @@ const BSCustomerSelect = ({ TopName = null }) => {
|
|||
className="customer-select-option"
|
||||
onInputChange={(value) => {
|
||||
if (!value) return;
|
||||
|
||||
const onlyNumbers = /^\d+$/.test(value);
|
||||
const isIndianMobile =
|
||||
/^\d{10}$/.test(value) && /^[6-9]/.test(value);
|
||||
|
||||
const existingCustomer = options?.filter(
|
||||
(option) => option?.value === value || option?.label === value
|
||||
);
|
||||
if (isIndianMobile && existingCustomer?.length === 0) {
|
||||
handleAddCustomer(value);
|
||||
// const existingCustomer = options?.filter(
|
||||
// (option) => option?.value === value || option?.label === value
|
||||
// );
|
||||
// if (isIndianMobile && existingCustomer?.length === 0) {
|
||||
// handleAddCustomer(value);
|
||||
// }
|
||||
|
||||
if (onlyNumbers && isIndianMobile) {
|
||||
handleSearchCustomer(value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (/[a-zA-Z]/.test(value)) {
|
||||
debounceSearch(value);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -433,11 +433,16 @@ const BranchLogin = () => {
|
|||
{CompBranchData?.map((branch) => (
|
||||
<div
|
||||
key={branch.BrId}
|
||||
style={{ cursor: 'pointer' }}
|
||||
className={
|
||||
branch?.LocationType === 'W'
|
||||
? 'GodownLoginCard'
|
||||
: 'brachLoginCard'
|
||||
}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onChangeBranch(branch?.BrId);
|
||||
}}
|
||||
>
|
||||
<div className="branchLoginCardContent">
|
||||
{branch?.LocationType === 'W' ? (
|
||||
|
|
@ -477,7 +482,7 @@ const BranchLogin = () => {
|
|||
? 'openGodownBTN'
|
||||
: 'openBrachBTN'
|
||||
}
|
||||
onClick={() => onChangeBranch(branch?.BrId)}
|
||||
// onClick={() => onChangeBranch(branch?.BrId)}
|
||||
>
|
||||
{branch?.LocationType === 'W'
|
||||
? 'Open Warehouse'
|
||||
|
|
@ -562,13 +567,11 @@ const BranchLogin = () => {
|
|||
{SelectTypeName === 'OTP'
|
||||
? !FirstTimeOtp
|
||||
? `send ${SelectTypeName.toLocaleLowerCase()}`
|
||||
: `resend ${SelectTypeName.toLocaleLowerCase()}${
|
||||
seconds > 0 ? ` in ${seconds}s` : ''
|
||||
: `resend ${SelectTypeName.toLocaleLowerCase()}${seconds > 0 ? ` in ${seconds}s` : ''
|
||||
}`
|
||||
: !FirstTimePin
|
||||
? `send ${SelectTypeName.toLocaleLowerCase()}`
|
||||
: `resend ${SelectTypeName.toLocaleLowerCase()}${
|
||||
seconds > 0 ? ` in ${seconds}s` : ''
|
||||
: `resend ${SelectTypeName.toLocaleLowerCase()}${seconds > 0 ? ` in ${seconds}s` : ''
|
||||
}`}
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@ import '../../../Styles/Reports/LedgerReport/LedgerReport.scss';
|
|||
import { isMobile } from 'react-device-detect';
|
||||
import { ReportMobilePDFPrint } from '../../paymentpdfPage/ReportMobilePDFPrint.js';
|
||||
import { useSelector } from 'react-redux';
|
||||
import excelExport from '../../../Images/xls-export.png';
|
||||
import ExcelJS from 'exceljs';
|
||||
import { saveAs } from 'file-saver';
|
||||
|
||||
dayjs.extend(customParseFormat);
|
||||
|
||||
|
|
@ -403,6 +406,215 @@ const LedgerReport = () => {
|
|||
}
|
||||
};
|
||||
|
||||
const exportToExcel = async () => {
|
||||
if (!LedgerData || LedgerData.length === 0) return;
|
||||
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
const worksheet = workbook.addWorksheet("Ledger Report");
|
||||
|
||||
worksheet.views = [
|
||||
{
|
||||
state: "frozen",
|
||||
ySplit: 2
|
||||
}
|
||||
];
|
||||
|
||||
// HEADER ROW 1
|
||||
worksheet.addRow([
|
||||
"SI No",
|
||||
"Type",
|
||||
"Cus-Id",
|
||||
"Cus-Name",
|
||||
"RC.NO",
|
||||
"Mob.No",
|
||||
"Address",
|
||||
"Payment Mode",
|
||||
"Date",
|
||||
"Debit",
|
||||
"Credit",
|
||||
"Balance in",
|
||||
""
|
||||
]);
|
||||
|
||||
// HEADER ROW 2
|
||||
worksheet.addRow([
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Credit",
|
||||
"Debit"
|
||||
]);
|
||||
|
||||
// MERGE CELLS
|
||||
worksheet.mergeCells("A1:A2");
|
||||
worksheet.mergeCells("B1:B2");
|
||||
worksheet.mergeCells("C1:C2");
|
||||
worksheet.mergeCells("D1:D2");
|
||||
worksheet.mergeCells("E1:E2");
|
||||
worksheet.mergeCells("F1:F2");
|
||||
worksheet.mergeCells("G1:G2");
|
||||
worksheet.mergeCells("H1:H2");
|
||||
worksheet.mergeCells("I1:I2");
|
||||
worksheet.mergeCells("J1:J2");
|
||||
worksheet.mergeCells("K1:K2");
|
||||
worksheet.mergeCells("L1:M1");
|
||||
|
||||
// worksheet.eachRow((row) => {
|
||||
// row.eachCell((cell) => {
|
||||
// cell.protection = {
|
||||
// locked: true
|
||||
// };
|
||||
// });
|
||||
// });
|
||||
|
||||
// Lock header rows
|
||||
[1, 2].forEach((rowNumber) => {
|
||||
const row = worksheet.getRow(rowNumber);
|
||||
row.eachCell((cell) => {
|
||||
cell.protection = { locked: true };
|
||||
});
|
||||
});
|
||||
|
||||
// HEADER STYLE
|
||||
const headerRows = [1, 2];
|
||||
|
||||
headerRows.forEach((rowNumber) => {
|
||||
const row = worksheet.getRow(rowNumber);
|
||||
|
||||
row.eachCell((cell) => {
|
||||
cell.font = {
|
||||
bold: true,
|
||||
color: { argb: "FFFFFFFF" } // white text
|
||||
};
|
||||
|
||||
cell.alignment = {
|
||||
vertical: "middle",
|
||||
horizontal: "center"
|
||||
};
|
||||
|
||||
cell.fill = {
|
||||
type: "pattern",
|
||||
pattern: "solid",
|
||||
fgColor: { argb: "FF2E7D32" } // green header
|
||||
};
|
||||
|
||||
cell.border = {
|
||||
top: { style: "thin" },
|
||||
left: { style: "thin" },
|
||||
bottom: { style: "thin" },
|
||||
right: { style: "thin" }
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
// specifically ensure Balance in header center
|
||||
worksheet.getCell("L1").alignment = { horizontal: "center", vertical: "middle" };
|
||||
|
||||
// COLUMN WIDTH
|
||||
worksheet.columns = [
|
||||
{ width: 8 },
|
||||
{ width: 10 },
|
||||
{ width: 12 },
|
||||
{ width: 20 },
|
||||
{ width: 12 },
|
||||
{ width: 15 },
|
||||
{ width: 25 },
|
||||
{ width: 15 },
|
||||
{ width: 15 },
|
||||
{ width: 12 },
|
||||
{ width: 12 },
|
||||
{ width: 12 },
|
||||
{ width: 12 }
|
||||
];
|
||||
|
||||
// DATA ROWS
|
||||
LedgerData.forEach((row, index) => {
|
||||
const r = worksheet.addRow([
|
||||
index + 1,
|
||||
row.TypeName === "OB" ? "OB" : row.TypeName,
|
||||
row.CustId ? extractLastNumber(row.CustId) : "GEN",
|
||||
row.CustName || "",
|
||||
row.ReceiptNo || "",
|
||||
row.MobileNo || "",
|
||||
row.Address1 || "",
|
||||
row.PaymentTypeName || "",
|
||||
ExtractDateFormate(row.Date) || "",
|
||||
row.Debit > 0 ? row.Debit : "",
|
||||
row.Credit > 0 ? row.Credit : "",
|
||||
row.BalCredit > 0 ? row.BalCredit : "",
|
||||
row.BalDebit > 0 ? row.BalDebit : ""
|
||||
]);
|
||||
|
||||
// 🔓 Unlock every cell in this row
|
||||
r.eachCell({ includeEmpty: true }, (cell) => {
|
||||
cell.protection = { locked: false };
|
||||
});
|
||||
|
||||
// Credit red
|
||||
if (row.BalCredit > 0) {
|
||||
r.getCell(12).font = { color: { argb: "FFFF0000" } };
|
||||
}
|
||||
|
||||
// Debit green
|
||||
if (row.BalDebit > 0) {
|
||||
r.getCell(13).font = { color: { argb: "FF008000" } };
|
||||
}
|
||||
});
|
||||
|
||||
// Unlock all data rows
|
||||
worksheet.eachRow((row, rowNumber) => {
|
||||
if (rowNumber > 2) {
|
||||
row.eachCell((cell) => {
|
||||
cell.protection = { locked: false };
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
await worksheet.protect("ledger123", {
|
||||
selectLockedCells: true,
|
||||
selectUnlockedCells: true,
|
||||
formatColumns: true, // allow column resize
|
||||
formatRows: false,
|
||||
insertColumns: false,
|
||||
insertRows: false,
|
||||
deleteColumns: false,
|
||||
deleteRows: false
|
||||
});
|
||||
|
||||
const buffer = await workbook.xlsx.writeBuffer();
|
||||
|
||||
const blob = new Blob([buffer], {
|
||||
type: "application/vnd.openxmlformats-of ficedocument.spreadsheetml.sheet"
|
||||
});
|
||||
|
||||
const now = new Date();
|
||||
|
||||
const day = String(now.getDate()).padStart(2, "0");
|
||||
const month = String(now.getMonth() + 1).padStart(2, "0");
|
||||
const year = now.getFullYear();
|
||||
|
||||
let hours = now.getHours();
|
||||
const minutes = String(now.getMinutes()).padStart(2, "0");
|
||||
|
||||
const ampm = hours >= 12 ? "PM" : "AM";
|
||||
hours = hours % 12;
|
||||
hours = hours ? hours : 12;
|
||||
|
||||
hours = String(hours).padStart(2, "0");
|
||||
|
||||
const fileName = `Ledger Report_${day}-${month}-${year}_${hours}-${minutes}-${ampm}.xlsx`;
|
||||
|
||||
saveAs(blob, fileName);
|
||||
};
|
||||
|
||||
const FirstOrderLedgerDateRaw = dayjs(FirstOrderLedgerDate);
|
||||
|
||||
const disabledDate = (current) => {
|
||||
|
|
@ -621,13 +833,24 @@ const LedgerReport = () => {
|
|||
</div>
|
||||
<div className="ledger-PrintIcon">
|
||||
<BiSolidPrinter
|
||||
onClick={Print}
|
||||
onClick={LedgerData?.length > 0 ? () => Print() : (() => { })}
|
||||
className={
|
||||
LedgerData?.length > 0
|
||||
? 'ItemWiseReport-printerIcon'
|
||||
: 'ItemWiseReport-printerIcon-disabled'
|
||||
}
|
||||
/>
|
||||
<Tooltip title={LedgerData?.length > 0 ? "Export as Excel" : "No data to Export"} placement="top">
|
||||
<div style={{ width: '35px', height: '35px', display: 'flex', justifyContent: 'center', alignItems: 'center', cursor: LedgerData?.length > 0 ? 'pointer' : 'not-allowed', opacity: LedgerData?.length > 0 ? 1 : 0.5 }}>
|
||||
<img
|
||||
width={'95%'}
|
||||
height={'95%'}
|
||||
src={excelExport}
|
||||
alt="Excel Export"
|
||||
onClick={LedgerData?.length > 0 ? () => exportToExcel() : (() => { })}
|
||||
/>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -88,8 +88,30 @@
|
|||
// overflow-x: scroll;
|
||||
}
|
||||
|
||||
.ItemWiseReport-printerIcon-disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
.ItemWiseReport-printerIcon {
|
||||
font-size: 25px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ItemWiseReport-printerIcon:hover {
|
||||
color: #414141;
|
||||
}
|
||||
|
||||
.ItemWiseReport-printerIcon {
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
.ledger-PrintIcon {
|
||||
font-size: xx-large;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.RadioButton-DMYPicker {
|
||||
|
|
@ -120,8 +142,8 @@
|
|||
width: 72px;
|
||||
}
|
||||
|
||||
.LedgerTable .ant-table-wrapper .ant-table-thead > tr > th,
|
||||
.ant-table-wrapper .ant-table-thead > tr > td {
|
||||
.LedgerTable .ant-table-wrapper .ant-table-thead>tr>th,
|
||||
.ant-table-wrapper .ant-table-thead>tr>td {
|
||||
color: #000000;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
|
|
@ -152,7 +174,7 @@
|
|||
}
|
||||
|
||||
.MasterLedger-Report .ant-table-wrapper .ant-table-cell,
|
||||
.MasterLedger-Report .ant-table-wrapper .ant-table-thead > tr > th {
|
||||
.MasterLedger-Report .ant-table-wrapper .ant-table-thead>tr>th {
|
||||
padding: 1px 13px;
|
||||
width: 100px;
|
||||
}
|
||||
|
|
@ -243,7 +265,7 @@
|
|||
border: 1px solid #909090;
|
||||
font-family: "Poppins", sans-serif;
|
||||
|
||||
> thead {
|
||||
>thead {
|
||||
position: sticky;
|
||||
top: -1px;
|
||||
}
|
||||
|
|
@ -314,7 +336,7 @@
|
|||
justify-content: flex-end;
|
||||
gap: 1rem;
|
||||
|
||||
> div {
|
||||
>div {
|
||||
border-radius: 6px;
|
||||
padding: 5px 10px;
|
||||
color: #fff;
|
||||
|
|
@ -322,16 +344,17 @@
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
> div:nth-child(1) {
|
||||
>div:nth-child(1) {
|
||||
background-color: #28aa3a;
|
||||
}
|
||||
|
||||
> div:nth-child(2) {
|
||||
>div:nth-child(2) {
|
||||
background-color: #ff0000;
|
||||
}
|
||||
}
|
||||
|
||||
.custom-table {
|
||||
|
||||
Button:disabled,
|
||||
Button[disabled] {
|
||||
width: unset !important;
|
||||
|
|
|
|||
Loading…
Reference in New Issue