Android_Retail/src/Pages/ExtraCharges/ExtraChargesList.jsx

725 lines
23 KiB
JavaScript

import React, { useCallback, useEffect, useState, useRef } from 'react';
import { useDispatch } from 'react-redux';
import { Messages } from '../../Components/Notifications/Messages.jsx';
import { Tables } from '../../Components/Tables/Table.jsx';
import { Search } from '../../Components/Forms/Search.jsx';
import FormHeader from '../PageComponents/FormHeader.jsx';
import { Checkbox, Form, Space } from 'antd';
import { InputField } from '../../Components/Forms/InputField.jsx';
import Buttons from '../../Components/Forms/Buttons.jsx';
import {
changeBreadCrumb,
getEmpAccess,
} from '../../Features/AppPage/CenterPage.js';
import {
getExtTabledata,
putExtTabledata,
postExtTabledata,
deleteExtTabledata,
} from '../../Features/ExteraCharges/ExtraCharges.js';
import {
EditFilled,
DeleteFilled,
PlusOutlined,
ReloadOutlined,
ArrowRightOutlined,
} from '@ant-design/icons';
import { DefaultModal } from '../../Components/Modal/DefaultModal.jsx';
import { getSession, validateSafeInput } from '../../Services/Others.js';
import { DropDowns } from '../../Components/Forms/DropDown.jsx';
import { getAdmin } from '../../Features/ProductPage/ProductPage.js';
import { useAuth } from '../../AuthContext.jsx';
import { getPreferenceData } from '../../Features/BookingScreen/BookingData/BookingData.js';
import Imageupload from '../../Components/Forms/Upload.jsx';
// src\Styles\OverAllStyle\OverAllStyle.scss
import '../../Styles/OverAllStyle/OverAllStyle.scss';
const subDirectory = import.meta.env.ENV_BASE_URL;
const items = [
{
name: 'Home',
link: `${subDirectory}app-page/home`,
},
];
function ExtraChargesList() {
const { SadminuserAccess } = useAuth();
let SAAccessCommonMaster = SadminuserAccess?.find(
(e) => e?.MenuName === 'Extra Charges'
);
console.log(SAAccessCommonMaster, 'SAAccessCommonMaster', SadminuserAccess);
const formRef = useRef();
const dispatch = useDispatch();
const [messageType, setMessageType] = useState(null);
const [messageData, setMessageData] = useState(null);
const [searchedText, setSearchedText] = useState('');
const [uniqueId, setUniqueId] = useState('');
const [editState, setEditState] = useState(false);
const [tabledata, setTabledata] = useState();
const [empData, setEmpData] = useState();
const [addnewAccess, setaddnewAccess] = useState(true);
const [filteredInfo, setFilteredInfo] = useState({});
const [sortedInfo, setSortedInfo] = useState({});
const [open, setOpen] = useState(false);
const [page, setpage] = useState(1);
const [SelectedTaxId, setSelectedTaxId] = useState(null);
const [SelectedTaxamount, setSelectedTaxamount] = useState(null);
const [SelectedPrice, setSelectedPrice] = useState(null);
const [TaxData, setTaxData] = useState([]);
const CompId = getSession('CompId');
const BranchId = getSession('BranchId');
const AppId = getSession('AppId');
const UserId = getSession('UserId');
const UserType = getSession('UserType');
const [allowDecimal, setAllowDecimal] = useState(false);
const [ImageUrl, setImageUrl] = useState(null);
useEffect(() => {
fetchData();
Table();
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]);
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 === 'Extra Charges'
);
setEmpData(datas?.[0]);
};
async function fetchData() {
const gettingAdminTax = await dispatch(
getAdmin({ CompId: CompId, AppId: AppId })
).unwrap();
if (gettingAdminTax.data?.statusCode === 1) {
await setTaxData(gettingAdminTax.data?.data);
}
}
const Table = async () => {
const data = {
CompId: CompId,
BranchId: BranchId,
AppId: AppId,
};
let response = await dispatch(getExtTabledata(data)).unwrap();
if (response?.data?.statusCode == 1) {
setTabledata(response?.data?.data);
}
};
const actionsFormatter = async (row, rowIndex) => {
if (row.ActiveStatus !== 'D') {
fetchData();
setOpen(true);
setEditState(true);
await setSelectedTaxId(row.TaxId);
setUniqueId(row.UniqueId);
formRef?.current?.setFieldsValue(row);
let taxAmount = TaxData.filter((value) => value.TaxId === row.TaxId);
const finalTaxAmount = formRef.current?.getFieldsValue()?.Price
? Math.round(
(formRef.current?.getFieldsValue()?.Price *
taxAmount[0]?.TaxPercentage) /
(taxAmount[0]?.TaxPercentage + 100),
2
)
: 0;
const netPrice =
parseInt(formRef.current?.getFieldsValue()?.Price) -
parseInt(finalTaxAmount);
formRef.current?.setFieldsValue({
TaxAmount: finalTaxAmount,
PriceWithoutTax: netPrice ? netPrice : 0,
});
setSelectedPrice(netPrice ? netPrice : 0);
setSelectedTaxamount(finalTaxAmount);
}
};
const statusFormatter = async (row) => {
let deleteData = {
UniqueId: row.UniqueId,
ActiveStatus: row.ActiveStatus == 'A' ? 'D' : 'A',
UpdatedBy: getSession('UserId'),
};
let response = await dispatch(deleteExtTabledata(deleteData)).unwrap();
if (response?.data?.statusCode == 1) {
Table();
setMessageType('success');
setMessageData(
row.ActiveStatus == 'A'
? 'In-Activated Successfully'
: 'Activated Successfully'
);
}
};
const columns = [
{
title: 'Sl.No',
key: 'sno',
align: 'center',
width: '60px',
render: (text, object, index) => (
<a style={{ color: 'black' }}>{(page - 1) * 10 + index + 1}</a>
),
},
{
title: 'Extra Charges Type',
dataIndex: 'ExtraChargeType',
key: 'ExtraChargeType',
width: '100px',
filteredValue: [searchedText],
render: (text) => <a style={{ color: 'black' }}>{text}</a>,
onFilter: (value, record) => {
return (
String(record.ExtraChargeType)
?.toLowerCase()
?.includes(value?.toLowerCase()) ||
String(record.Price)?.toLowerCase()?.includes(value?.toLowerCase())
);
},
},
{
title: 'Price',
dataIndex: 'Price',
key: 'Price',
align: 'right',
width: '100px',
render: (text) => <a style={{ color: 'black' }}>{safeRound(text)}</a>,
},
{
title: 'Action',
key: 'Action',
dataIndex: 'Action',
width: '100px',
align: 'center',
render: (_, record, index) =>
tabledata.length >= 1 ? (
<Space size="middle">
{record.ActiveStatus === 'A' ? (
<a>
<EditFilled
style={{ color: '#1292EE' }}
onClick={() =>
UserType === 'Super Admin' ||
(UserType === 'Super Admin User' &&
SAAccessCommonMaster?.UpdateAccess === 'Y') ||
(UserType === 'Employee' &&
empData?.UpdateAccess === 'Y') ||
UserType === 'Admin'
? actionsFormatter(record, index)
: null
}
/>
</a>
) : (
''
)}
<a>
{record.ActiveStatus === 'A' ? (
<DeleteFilled
style={{
color: '#FF4D4F',
}}
onClick={() =>
UserType === 'Super Admin' ||
(UserType === 'Super Admin User' &&
SAAccessCommonMaster?.DeleteAccess === 'Y') ||
(UserType === 'Employee' &&
empData?.DeleteAccess === 'Y') ||
UserType === 'Admin'
? statusFormatter(record)
: null
}
/>
) : (
<ReloadOutlined
style={{
color: '#52C41A',
}}
onClick={() =>
UserType === 'Super Admin' ||
(UserType === 'Super Admin User' &&
SAAccessCommonMaster?.DeleteAccess === 'Y') ||
(UserType === 'Employee' &&
empData?.DeleteAccess === 'Y') ||
UserType === 'Admin'
? statusFormatter(record)
: null
}
/>
)}
</a>
</Space>
) : null,
},
];
const onSearch = (value) => {
setSearchedText(value);
};
const onSearchChange = (e) => {
setSearchedText(e?.target?.value);
};
const handleChange = (pagination, filters, sorter) => {
setFilteredInfo(filters);
setSortedInfo(sorter);
};
const handlePageChange = (current) => {
setpage(current);
};
const onFinish = async () => {
const ExtraChargeType = formRef?.current?.getFieldsValue().ExtraChargeType;
const Price = formRef?.current?.getFieldsValue().Price;
const TaxId = formRef?.current?.getFieldsValue().TaxId;
const isPackageAvilable =
formRef?.current?.getFieldsValue().PackageAvilable;
const ImageUrlData = formRef?.current?.getFieldsValue().ImageUrl;
if (!editState) {
const Postdata = {
CompId: CompId,
BranchId: BranchId,
AppId: AppId,
Price: Price,
ExtraChargeType: ExtraChargeType,
TaxId: TaxId,
PackageAvilable: isPackageAvilable,
ImageUrl: ImageUrlData,
CreatedBy: UserId,
};
let response = await dispatch(postExtTabledata(Postdata)).unwrap();
if (response?.data?.statusCode == 1) {
setOpen(false);
formRef?.current?.resetFields();
setSelectedTaxId(null);
Table();
setMessageType('success');
setMessageData('Data Added Succesfully');
} else {
setMessageType('error');
setMessageData('Data already exist');
}
} else {
const Putdata = {
CompId: CompId,
BranchId: BranchId,
AppId: AppId,
Price: Price,
ExtraChargeType: ExtraChargeType,
UniqueId: uniqueId,
PackageAvilable: isPackageAvilable,
ImageUrl: ImageUrlData,
TaxId: TaxId,
UpdatedBy: getSession('UserId'),
};
let response = await dispatch(putExtTabledata(Putdata)).unwrap();
if (response?.data?.statusCode == 1) {
formRef?.current?.resetFields();
setSelectedTaxId(null);
setOpen(false);
Table();
setMessageType('success');
setMessageData('Data Updated Succesfully');
setEditState(false);
} else {
setMessageType('error');
setMessageData('Data Not Updated');
}
}
};
const onComplete = useCallback(() => {
setMessageData(null);
setMessageType(null);
}, []);
// const handleTaxDropDownChange = async (TaxId) =>{
// formRef.current?.setFieldsValue({ TaxId: TaxId })
// await setSelectedTaxId(TaxId)
// }
const handleTaxDropDownChange = async (e) => {
// setselectedTaxId(null)
await setSelectedTaxId(e);
formRef.current?.setFieldsValue({ TaxId: e });
let taxAmount = TaxData.filter((value) => value.TaxId === e);
const finalTaxAmount = formRef.current?.getFieldsValue()?.Price
? Math.round(
(formRef.current?.getFieldsValue()?.Price *
taxAmount[0]?.TaxPercentage) /
(100 + parseInt(taxAmount[0]?.TaxPercentage)),
2
)
: 0;
const netPrice =
parseInt(formRef.current?.getFieldsValue()?.Price) -
parseInt(finalTaxAmount);
formRef.current?.setFieldsValue({
TaxAmount: finalTaxAmount,
PriceWithoutTax: netPrice ? netPrice : 0,
});
setSelectedPrice(netPrice ? netPrice : 0);
setSelectedTaxamount(finalTaxAmount);
};
const getOptionLabel = (option, selected) => {
return selected
? option.TaxPercentage + ' %'
: option.TaxIdName + ' - ' + option.TaxPercentage + ' % ';
};
const PriceOnChange = async () => {
const TaxId = formRef.current?.getFieldsValue()?.TaxId;
const tax = TaxData.find((value) => value.TaxId === TaxId) || {
TaxPercentage: 0,
};
const netPrice = parseInt(formRef.current?.getFieldsValue()?.Price || 0);
const finalTaxAmount = Math.round(
(netPrice * tax.TaxPercentage) / (100 + tax.TaxPercentage),
2
);
formRef.current?.setFieldsValue({
TaxAmount: finalTaxAmount,
PriceWithoutTax: netPrice - finalTaxAmount,
});
setSelectedPrice(netPrice - finalTaxAmount);
setSelectedTaxamount(finalTaxAmount);
};
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);
}
};
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();
}
return (
<div className="userPageTable ClassExtraChargesList">
<div className="userPageContent">
<div className="formAddNew">
<Messages
messageType={messageType}
messageData={messageData}
onComplete={onComplete}
/>
<div>
<FormHeader title={'Extra Charges'} />
</div>
<div className="searchAddDiv">
<div className="formSearch">
<Search
placeholder="Search by ExtraCharge Type"
onSearch={onSearch}
onSearchChange={onSearchChange}
/>
</div>
<Buttons
buttonText={'Add New'}
handleSubmit={() => setOpen(true)}
disabled={addnewAccess}
color="901D77"
icon={<PlusOutlined />}
>
OPEN
</Buttons>
</div>
</div>
<div className="reportTable">
<Tables
columns={columns}
data={tabledata}
dataSource={tabledata}
pagination={handlePageChange}
onChange={handleChange}
/>
</div>
</div>
<DefaultModal
open={open}
title="Extra Charges"
handleCancel={() => {
(setOpen(false),
setEditState(false),
formRef?.current?.resetFields(),
setSelectedTaxId(null),
setSelectedTaxamount(null),
setSelectedPrice(null));
}}
footer={false}
children={
<div className="formDiv">
<Form ref={formRef} onFinish={onFinish}>
<div className="formDivS">
<div className="inputForm">
<Form.Item
name="ExtraChargeType"
rules={[
{
required: true,
pattern: /^(?!\s*$).+/,
message: 'Please Enter Extra Charges',
},
{
validator: async (_, value) => {
await validateSafeInput(value);
if (value && value.length > 30) {
return Promise.reject(
'Extra Charge Name should not exceed 30 characters'
);
}
return Promise.resolve();
},
},
]}
>
<InputField
autoComplete="off"
label={<label class="required">Extra Charge Name</label>}
isOnChange={editState ? true : false}
/>
</Form.Item>
<Form.Item
name="Price"
rules={[
{
required: true,
pattern: /^(?!0$)(0\d+|\d+)(\.\d+)?$/,
message: 'Please Enter Net Price',
},
{
validator: async (_, value) => {
await validateSafeInput(value);
if (value && value.length > 10) {
return Promise.reject(
'Net Price should not exceed 10 characters'
);
}
return Promise.resolve();
},
},
]}
>
<InputField
autoComplete="off"
label={<label class="required">Net Price</label>}
isOnChange={editState ? true : false}
onChange={PriceOnChange}
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>
<Form.Item
name="TaxId"
rules={[
{
required: true,
message: 'Please Enter TaxId',
},
]}
>
<DropDowns
options={TaxData?.map((option) => ({
value: option.TaxId,
label: getOptionLabel(
option,
SelectedTaxId === option.TaxId
),
// label: option.TaxIdName + ' - ' + option.TaxPercentage + ' % ',
}))}
label={<label class="required">Tax</label>}
className="field-DropDown"
// isOnchanges={SelectedTaxId ? true:false}
onChangeFunction={handleTaxDropDownChange}
valueData={SelectedTaxId}
/>
</Form.Item>
<Form.Item
name="TaxAmount"
rules={[
{
required: false,
validator: async (_, value) => {
await validateSafeInput(value);
if (value >= 0) {
return Promise.resolve();
} else {
return Promise.reject(
'Valid Tax Amount is Required '
);
}
},
},
]}
>
<InputField
field="TaxAmount"
name="Tax Amount"
type="number"
label="Tax Amount"
fieldState={true}
fieldApi={true}
disabled
id="error2"
autocomplete="off"
isOnChange={SelectedTaxamount != null ? true : false}
/>
</Form.Item>
<Form.Item
name="PriceWithoutTax"
rules={[
{
required: false,
validator: async (_, value) => {
await validateSafeInput(value);
if (value >= 0) {
return Promise.resolve();
} else {
return Promise.reject(' Valid Price is Required ');
}
},
},
]}
>
<InputField
field="Price"
name="Price"
type="number"
label="Price"
fieldState={true}
fieldApi={true}
id="error2"
autocomplete="off"
isOnChange={SelectedPrice != null ? true : false}
disabled
/>
</Form.Item>
<Form.Item
name="PackageAvilable"
valuePropName="checked"
getValueFromEvent={(e) => e.target.checked}
normalize={(value) => (value ? 'Y' : 'N')}
getValueProps={(value) => ({ checked: value === 'Y' })}
>
<Checkbox>Packing Charge</Checkbox>
</Form.Item>
<div className="upload_btn">
<p>Upload Image</p>
<Form.Item name="ImageUrl">
<Imageupload
singleImage={true}
updateImageUrl={(url) => {
setImageUrl(url);
formRef.current?.setFieldsValue({
ImageUrl: url ?? null,
});
}}
ImageLink={
formRef.current?.getFieldValue('ImageUrl') || ImageUrl
}
/>
</Form.Item>
</div>
</div>
</div>
<div
style={{
display: 'flex',
justifyContent: 'flex-end',
marginTop: 10,
}}
>
<Buttons
buttonText="SUBMIT"
color="901D77"
icon={<ArrowRightOutlined />}
/>
</div>
</Form>
</div>
}
/>
</div>
);
}
export default ExtraChargesList;