fixing Add+ delete+ managetransferfee
This commit is contained in:
@ -50,9 +50,18 @@ interface TransactionTypeProps {
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface WalletProps {
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
interface CustomerProps {
|
||||
id: string;
|
||||
username: string;
|
||||
msisdn: string;
|
||||
}
|
||||
const API_URL = apiConfig.service_transaction;
|
||||
|
||||
const API_URL_MASTER_DATA = apiConfig.service_master_data;
|
||||
const API_URL_CUSTOMER = apiConfig.service_customer;
|
||||
const AddFeeDialog = () => {
|
||||
const parentRef = useRef<any | null>(null);
|
||||
const { reload } = useDataGrid();
|
||||
@ -64,6 +73,9 @@ const AddFeeDialog = () => {
|
||||
message: ''
|
||||
});
|
||||
const [transactionTypes, setTransactionTypes] = useState<TransactionTypeProps[]>([]);
|
||||
const [wallets, setWallets] = useState<WalletProps[]>([]);
|
||||
const [customers, setCustomers] = useState<CustomerProps[]>([]);
|
||||
const [defaultCustomer, setDefaultCustomer] = useState('');
|
||||
|
||||
const initialState = {
|
||||
name: '',
|
||||
@ -75,11 +87,17 @@ const AddFeeDialog = () => {
|
||||
period_end: '',
|
||||
deduct_amount: 0,
|
||||
deduct_percentage: 0,
|
||||
fee_amount: 0,
|
||||
priority: '',
|
||||
status: '',
|
||||
status_include: '',
|
||||
created_by: '',
|
||||
created_at: ''
|
||||
created_at: '',
|
||||
deduct_from: '',
|
||||
deduct_from_account: '',
|
||||
credit_to: '',
|
||||
credit_destination: '00000000-0000-0000-0000-000000000000',
|
||||
credit_destination_account: ''
|
||||
};
|
||||
|
||||
const [formField, setFormField] = useState(initialState);
|
||||
@ -104,12 +122,19 @@ const AddFeeDialog = () => {
|
||||
maximum_amount: formField.maximum_amount,
|
||||
deduct_amount: formField.deduct_amount,
|
||||
deduct_percentage: formField.deduct_percentage,
|
||||
fee_amount: formField.fee_amount,
|
||||
transaction_type: formField.transaction_type,
|
||||
status: formField.status,
|
||||
status_include: formField.status_include,
|
||||
priority: formField.priority
|
||||
priority: formField.priority,
|
||||
deduct_from: formField.deduct_from,
|
||||
deduct_from_account: formField.deduct_from_account,
|
||||
credit_to: formField.credit_to,
|
||||
credit_destination: formField.credit_destination,
|
||||
credit_destination_account: formField.credit_destination_account
|
||||
};
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const created_time = new Date();
|
||||
const formattedTime = created_time.toISOString().slice(0, 19).replace('T', ' ');
|
||||
@ -138,38 +163,134 @@ const AddFeeDialog = () => {
|
||||
});
|
||||
setTransactionTypes(response?.data.list || []);
|
||||
} catch (error) {
|
||||
console.error('Error fetching customer', error);
|
||||
console.error('Error fetching transaction types', error);
|
||||
}
|
||||
};
|
||||
|
||||
getTransactionTypeList([{ id: 'id', desc: false }]);
|
||||
}, [showAddFeeDialog]);
|
||||
|
||||
const fetchWallets = useCallback(async () => {
|
||||
const params = {
|
||||
limit: 100,
|
||||
page: 1,
|
||||
with_deleted: false,
|
||||
order_field: 'Wallets.name',
|
||||
order_direction: 'ASC',
|
||||
};
|
||||
try {
|
||||
const response = await GetData(`${API_URL_MASTER_DATA}/wallet/list`, params);
|
||||
if (response?.status && response?.data) {
|
||||
setWallets(response.data.list);
|
||||
} else {
|
||||
setWallets([]);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching wallets', error);
|
||||
setWallets([]);
|
||||
}
|
||||
}, [GetData]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!showAddFeeDialog) return;
|
||||
fetchWallets();
|
||||
}, [showAddFeeDialog, fetchWallets]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!showAddFeeDialog) return;
|
||||
const getCustomerList = async (sorting: any) => {
|
||||
try {
|
||||
sorting = sorting.length === 0 ? [{ id: 'name', desc: false }] : sorting;
|
||||
|
||||
const response = await GetData(`${API_URL_CUSTOMER}/customer/list`, {
|
||||
limit: 100,
|
||||
page: 1,
|
||||
with_deleted: false,
|
||||
order_field: sorting[0].id,
|
||||
order_direction: sorting[0].desc ? 'DESC' : 'ASC'
|
||||
});
|
||||
const customerList = response?.data.list || [];
|
||||
setCustomers(customerList);
|
||||
|
||||
if (customerList.length > 0) {
|
||||
setDefaultCustomer(customerList[0].id);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching customers', error);
|
||||
setCustomers([]);
|
||||
}
|
||||
};
|
||||
|
||||
getCustomerList([{ id: 'id', desc: false }]);
|
||||
}, [showAddFeeDialog, GetData]);
|
||||
|
||||
const doCreateTransferType = useCallback(
|
||||
async (e: React.FormEvent<HTMLFormElement>) => {
|
||||
e.preventDefault();
|
||||
for (const key in formField) {
|
||||
if (
|
||||
formField[key as keyof typeof formField] === '' ) {
|
||||
setAlert({ show: true, message: 'All fields must be filled out' });
|
||||
setIsSubmitting(true);
|
||||
|
||||
const requiredFields = [
|
||||
'name',
|
||||
'description',
|
||||
'period_start',
|
||||
'period_end',
|
||||
'transaction_type',
|
||||
'status',
|
||||
'status_include',
|
||||
'priority',
|
||||
'deduct_from',
|
||||
'deduct_from_account',
|
||||
'credit_to',
|
||||
'credit_destination_account'
|
||||
];
|
||||
|
||||
for (const field of requiredFields) {
|
||||
if (formField[field as keyof typeof formField] === '') {
|
||||
setAlert({
|
||||
show: true,
|
||||
message: `All required fields must be filled out. Missing: ${field.replace(/_/g, ' ')}`
|
||||
});
|
||||
setIsSubmitting(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (formField.credit_to === 'I' && !formField.credit_destination) {
|
||||
setAlert({
|
||||
show: true,
|
||||
message: 'Credit destination is required when Input Customer is selected'
|
||||
});
|
||||
setIsSubmitting(false);
|
||||
return;
|
||||
}
|
||||
|
||||
setAlert({ show: false, message: '' });
|
||||
const response = await PostData(`${API_URL}/transactionfees/create`, {
|
||||
...formField
|
||||
});
|
||||
if (response?.status) {
|
||||
// toast.success('Success Create Transfer Fee');
|
||||
reload();
|
||||
resetForm();
|
||||
handleAddFeeDialog(false);
|
||||
} else {
|
||||
setAlert({ show: true, message: response?.message || 'Failed to create transfer fee' });
|
||||
|
||||
const payload = { ...formField };
|
||||
|
||||
if (formField.credit_to !== 'I') {
|
||||
payload.credit_destination = '00000000-0000-0000-0000-000000000000';
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await PostData(`${API_URL}/transactionfees/create`, payload);
|
||||
|
||||
if (response?.status) {
|
||||
toast.success('Successfully created transfer fee');
|
||||
reload();
|
||||
resetForm();
|
||||
handleAddFeeDialog(false);
|
||||
} else {
|
||||
setAlert({ show: true, message: response?.message || 'Failed to create transfer fee' });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error creating transfer fee', error);
|
||||
setAlert({ show: true, message: 'An error occurred while creating the transfer fee' });
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
},
|
||||
[formField]
|
||||
[formField, PostData, reload, handleAddFeeDialog]
|
||||
);
|
||||
|
||||
return (
|
||||
@ -194,7 +315,13 @@ const AddFeeDialog = () => {
|
||||
</div>
|
||||
</DialogHeader>
|
||||
<DialogBody className="max-h-[1080px] overflow-y-auto">
|
||||
{alert.show && <Alert variant="danger">{alert.message}</Alert>}
|
||||
{alert.show && (
|
||||
<div className="sticky top-0 z-10 bg-white p-3">
|
||||
<Alert variant="danger" className="mb-3">
|
||||
<h3>{alert.message}</h3>
|
||||
</Alert>
|
||||
</div>
|
||||
)}
|
||||
<form action="" onSubmit={doCreateTransferType}>
|
||||
<div className="card flex flex-col gap-5">
|
||||
<div className="card-body grid gap-5 p-0">
|
||||
@ -236,7 +363,7 @@ const AddFeeDialog = () => {
|
||||
minimum_amount: values.floatValue || 0
|
||||
}));
|
||||
}}
|
||||
placeholder="Enter Max Transaction Per Day"
|
||||
placeholder="Enter Minimum Amount"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-full">
|
||||
@ -253,7 +380,7 @@ const AddFeeDialog = () => {
|
||||
maximum_amount: values.floatValue || 0
|
||||
}));
|
||||
}}
|
||||
placeholder="Enter Max Transaction Per Day"
|
||||
placeholder="Enter Maximum Amount"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-full">
|
||||
@ -294,7 +421,7 @@ const AddFeeDialog = () => {
|
||||
deduct_amount: values.floatValue || 0
|
||||
}));
|
||||
}}
|
||||
placeholder="Enter Max Transaction Per Day"
|
||||
placeholder="Enter Deduct Amount"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-full">
|
||||
@ -311,11 +438,119 @@ const AddFeeDialog = () => {
|
||||
deduct_percentage: values.floatValue || 0
|
||||
}));
|
||||
}}
|
||||
placeholder="Enter Max Transaction Per Day"
|
||||
placeholder="Enter Deduct Percentage"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<label className="form-label">Transacsion Type ID <span className="text-red-500">*</span></label>
|
||||
<label className="form-label">Fee Amount</label>
|
||||
<NumericFormat
|
||||
className="input"
|
||||
value={formField.fee_amount}
|
||||
thousandSeparator="."
|
||||
decimalSeparator=","
|
||||
allowNegative={false}
|
||||
onValueChange={(values) => {
|
||||
setFormField((prev) => ({
|
||||
...prev,
|
||||
fee_amount: values.floatValue || 0
|
||||
}));
|
||||
}}
|
||||
placeholder="Enter Fee Amount"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<label className="form-label">Deduct From <span className="text-red-500">*</span></label>
|
||||
<Select
|
||||
value={formField.deduct_from}
|
||||
onValueChange={(value) => setFormField({ ...formField, deduct_from: value })}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select Deduct From" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="D">Destination Member</SelectItem>
|
||||
<SelectItem value="S">Source Member</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<label className="form-label">Deduct From Destination <span className="text-red-500">*</span></label>
|
||||
<Select
|
||||
value={formField.deduct_from_account}
|
||||
onValueChange={(value) => setFormField({ ...formField, deduct_from_account: value })}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select Wallet" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{wallets.map((wallet) => (
|
||||
<SelectItem value={wallet.id} key={wallet.id}>
|
||||
{wallet.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<label className="form-label">Credit To <span className="text-red-500">*</span></label>
|
||||
<Select
|
||||
value={formField.credit_to}
|
||||
onValueChange={(value) => setFormField({
|
||||
...formField,
|
||||
credit_to: value,
|
||||
credit_destination: value === 'I' ? '' : '00000000-0000-0000-0000-000000000000'
|
||||
})}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select Credit To" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="D">Destination Member</SelectItem>
|
||||
<SelectItem value="S">Source Member</SelectItem>
|
||||
<SelectItem value="I">Input Customer</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
{formField.credit_to === 'I' && (
|
||||
<div className="w-full">
|
||||
<label className="form-label">Credit Destination <span className="text-red-500">*</span></label>
|
||||
<Select
|
||||
value={formField.credit_destination}
|
||||
onValueChange={(value) => setFormField({ ...formField, credit_destination: value })}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select Customer" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{customers.map((customer) => (
|
||||
<SelectItem value={customer.id} key={customer.id}>
|
||||
{customer.username} - {customer.msisdn}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
)}
|
||||
<div className="w-full">
|
||||
<label className="form-label">Credit Destination Account <span className="text-red-500">*</span></label>
|
||||
<Select
|
||||
value={formField.credit_destination_account}
|
||||
onValueChange={(value) => setFormField({ ...formField, credit_destination_account: value })}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select Wallet" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{wallets.map((wallet) => (
|
||||
<SelectItem value={wallet.id} key={wallet.id}>
|
||||
{wallet.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<label className="form-label">Transaction Type ID <span className="text-red-500">*</span></label>
|
||||
<Select
|
||||
value={formField.transaction_type}
|
||||
onValueChange={(transaction_type) =>
|
||||
@ -323,10 +558,10 @@ const AddFeeDialog = () => {
|
||||
}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select Wallet" />
|
||||
<SelectValue placeholder="Select Transaction Type" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{transactionTypes.map((transactiontype, idx) => (
|
||||
{transactionTypes.map((transactiontype) => (
|
||||
<SelectItem value={transactiontype.id} key={transactiontype.id}>
|
||||
{transactiontype.name}
|
||||
</SelectItem>
|
||||
@ -402,4 +637,4 @@ const AddFeeDialog = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default AddFeeDialog;
|
||||
export default AddFeeDialog;
|
||||
Reference in New Issue
Block a user