Merge branch 'fix/finance' into 'development'

[FIX/FE] Fixing Form State in Module Finance

See merge request mbugroup/lti-web-client!218
This commit is contained in:
Rivaldi A N S
2026-01-20 08:52:47 +00:00
4 changed files with 126 additions and 82 deletions
@@ -64,7 +64,7 @@ const FinanceDetail = ({ finance }: { finance: Finance }) => {
}, },
{ {
label: 'Nominal', label: 'Nominal',
value: formatCurrency(finance.nominal), value: formatCurrency(Math.abs(finance.nominal)),
}, },
].filter((item) => { ].filter((item) => {
// Hide party account number row if transaction type is INJECTION // Hide party account number row if transaction type is INJECTION
+111 -80
View File
@@ -19,6 +19,7 @@ import {
FINANCE_INITIAL_BALANCE_STATUS, FINANCE_INITIAL_BALANCE_STATUS,
FINANCE_INJECTION_STATUS, FINANCE_INJECTION_STATUS,
FINANCE_TRANSACTION_STATUS, FINANCE_TRANSACTION_STATUS,
FINANCE_TRANSACTION_TYPE_OPTIONS,
} from '@/config/constant'; } from '@/config/constant';
import { FinanceApi } from '@/services/api/finance'; import { FinanceApi } from '@/services/api/finance';
import { isResponseSuccess } from '@/lib/api-helper'; import { isResponseSuccess } from '@/lib/api-helper';
@@ -65,24 +66,19 @@ const RowOptionsMenu = ({
{FINANCE_TRANSACTION_STATUS.includes( {FINANCE_TRANSACTION_STATUS.includes(
props.row.original.transaction_type props.row.original.transaction_type
) && ) && (
props.row.original.party?.type !== 'SUPPLIER' && ( <RequirePermission permissions='lti.finance.payments.update'>
<RequirePermission permissions='lti.finance.payments.update'> <Button
<Button href={`/finance/detail/edit?financeId=${props.row.original.id}`}
href={`/finance/detail/edit?financeId=${props.row.original.id}`} variant='ghost'
variant='ghost' color='warning'
color='warning' className='justify-start text-sm'
className='justify-start text-sm' >
> <Icon icon='material-symbols:edit-outline' width={16} height={16} />
<Icon Edit
icon='material-symbols:edit-outline' </Button>
width={16} </RequirePermission>
height={16} )}
/>
Edit
</Button>
</RequirePermission>
)}
{FINANCE_INITIAL_BALANCE_STATUS.includes( {FINANCE_INITIAL_BALANCE_STATUS.includes(
props.row.original.transaction_type props.row.original.transaction_type
@@ -148,7 +144,8 @@ const FinanceTable = () => {
search: '', search: '',
transactionType: '', transactionType: '',
bankId: '', bankId: '',
partyType: '', customerId: '',
supplierId: '',
sortBy: '', sortBy: '',
startDate: '', startDate: '',
endDate: '', endDate: '',
@@ -158,7 +155,8 @@ const FinanceTable = () => {
pageSize: 'limit', pageSize: 'limit',
transactionType: 'transaction_type', transactionType: 'transaction_type',
bankId: 'bank_id', bankId: 'bank_id',
partyType: 'party_type', customerId: 'customer_id',
supplierId: 'supplier_id',
sortBy: 'sort_date', sortBy: 'sort_date',
startDate: 'start_date', startDate: 'start_date',
endDate: 'end_date', endDate: 'end_date',
@@ -172,17 +170,24 @@ const FinanceTable = () => {
search: '', search: '',
transactionType: '', transactionType: '',
bankId: '', bankId: '',
partyType: '', customerId: '',
supplierId: '',
sortBy: '', sortBy: '',
startDate: '', startDate: '',
endDate: '', endDate: '',
}); });
const [selectedTransactionType, setSelectedTransactionType] = const [selectedTransactionType, setSelectedTransactionType] = useState<
useState<OptionType | null>(null); OptionType | OptionType[] | null
const [selectedBank, setSelectedBank] = useState<OptionType | null>(null); >(null);
const [selectedPartyType, setSelectedPartyType] = useState<OptionType | null>( const [selectedBank, setSelectedBank] = useState<
null OptionType | OptionType[] | null
); >(null);
const [selectedCustomerId, setSelectedCustomerId] = useState<
OptionType | OptionType[] | null
>(null);
const [selectedSupplierId, setSelectedSupplierId] = useState<
OptionType | OptionType[] | null
>(null);
const [selectedSortBy, setSelectedSortBy] = useState<OptionType | null>(null); const [selectedSortBy, setSelectedSortBy] = useState<OptionType | null>(null);
const [selectedFinance, setSelectedFinance] = useState<Finance | null>(null); const [selectedFinance, setSelectedFinance] = useState<Finance | null>(null);
const [isDeleteLoading, setIsDeleteLoading] = useState(false); const [isDeleteLoading, setIsDeleteLoading] = useState(false);
@@ -197,27 +202,18 @@ const FinanceTable = () => {
FinanceApi.getAllFetcher FinanceApi.getAllFetcher
); );
// ===== Options =====
const transactionTypeOptions = useMemo(() => {
return [
{ label: 'Customer', value: 'CUSTOMER' },
{ label: 'Supplier', value: 'SUPPLIER' },
];
}, []);
const { const {
options: partyTypeOptions, options: customerOptions,
isLoadingOptions: partyTypeIsLoadingOptions, isLoadingOptions: customerIsLoadingOptions,
setInputValue: partyTypeInputValue, setInputValue: customerInputValue,
loadMore: partyTypeLoadMore, loadMore: customerLoadMore,
} = useSelect( } = useSelect(CustomerApi.basePath, 'id', 'name');
selectedTransactionType const {
? selectedTransactionType.value === 'CUSTOMER' options: supplierOptions,
? CustomerApi.basePath isLoadingOptions: supplierIsLoadingOptions,
: SupplierApi.basePath setInputValue: supplierInputValue,
: '', loadMore: supplierLoadMore,
'id', } = useSelect(SupplierApi.basePath, 'id', 'name');
'name'
);
const sortByOptions = useMemo(() => { const sortByOptions = useMemo(() => {
return [ return [
{ label: 'Tanggal Pembayaran', value: 'payment_date' }, { label: 'Tanggal Pembayaran', value: 'payment_date' },
@@ -238,24 +234,47 @@ const FinanceTable = () => {
const transactionTypeChangeHandler = ( const transactionTypeChangeHandler = (
val: OptionType | OptionType[] | null val: OptionType | OptionType[] | null
) => { ) => {
setSelectedTransactionType(val as OptionType); setSelectedTransactionType(val);
setPendingFilters((prev) => ({ setPendingFilters((prev) => ({
...prev, ...prev,
transactionType: val ? ((val as OptionType).value as string) : '', transactionType: val
? Array.isArray(val)
? val.map((item) => item.value).join(',')
: (val.value as string)
: '',
})); }));
}; };
const bankChangeHandler = (val: OptionType | OptionType[] | null) => { const bankChangeHandler = (val: OptionType | OptionType[] | null) => {
setSelectedBank(val as OptionType); setSelectedBank(val);
setPendingFilters((prev) => ({ setPendingFilters((prev) => ({
...prev, ...prev,
bankId: val ? ((val as OptionType).value as string) : '', bankId: val
? Array.isArray(val)
? val.map((item) => item.value).join(',')
: (val.value as string)
: '',
})); }));
}; };
const partyTypeChangeHandler = (val: OptionType | OptionType[] | null) => { const customerIdChangeHandler = (val: OptionType | OptionType[] | null) => {
setSelectedPartyType(val as OptionType); setSelectedCustomerId(val);
setPendingFilters((prev) => ({ setPendingFilters((prev) => ({
...prev, ...prev,
partyType: val ? ((val as OptionType).value as string) : '', customerId: val
? Array.isArray(val)
? val.map((item) => item.value).join(',')
: (val.value as string)
: '',
}));
};
const supplierIdChangeHandler = (val: OptionType | OptionType[] | null) => {
setSelectedSupplierId(val);
setPendingFilters((prev) => ({
...prev,
supplierId: val
? Array.isArray(val)
? val.map((item) => item.value).join(',')
: (val.value as string)
: '',
})); }));
}; };
const sortByChangeHandler = (val: OptionType | OptionType[] | null) => { const sortByChangeHandler = (val: OptionType | OptionType[] | null) => {
@@ -279,7 +298,8 @@ const FinanceTable = () => {
updateFilter('search', pendingFilters.search); updateFilter('search', pendingFilters.search);
updateFilter('transactionType', pendingFilters.transactionType); updateFilter('transactionType', pendingFilters.transactionType);
updateFilter('bankId', pendingFilters.bankId); updateFilter('bankId', pendingFilters.bankId);
updateFilter('partyType', pendingFilters.partyType); updateFilter('customerId', pendingFilters.customerId);
updateFilter('supplierId', pendingFilters.supplierId);
updateFilter('sortBy', pendingFilters.sortBy); updateFilter('sortBy', pendingFilters.sortBy);
updateFilter('startDate', pendingFilters.startDate); updateFilter('startDate', pendingFilters.startDate);
updateFilter('endDate', pendingFilters.endDate); updateFilter('endDate', pendingFilters.endDate);
@@ -287,14 +307,16 @@ const FinanceTable = () => {
const resetFilterHandler = () => { const resetFilterHandler = () => {
setSelectedTransactionType(null); setSelectedTransactionType(null);
setSelectedBank(null); setSelectedBank(null);
setSelectedPartyType(null); setSelectedCustomerId(null);
setSelectedSupplierId(null);
setSelectedSortBy(null); setSelectedSortBy(null);
const emptyFilters = { const emptyFilters = {
search: '', search: '',
transactionType: '', transactionType: '',
bankId: '', bankId: '',
partyType: '', customerId: '',
supplierId: '',
sortBy: '', sortBy: '',
startDate: '', startDate: '',
endDate: '', endDate: '',
@@ -304,7 +326,8 @@ const FinanceTable = () => {
updateFilter('search', ''); updateFilter('search', '');
updateFilter('transactionType', ''); updateFilter('transactionType', '');
updateFilter('bankId', ''); updateFilter('bankId', '');
updateFilter('partyType', ''); updateFilter('customerId', '');
updateFilter('supplierId', '');
updateFilter('sortBy', ''); updateFilter('sortBy', '');
updateFilter('startDate', ''); updateFilter('startDate', '');
updateFilter('endDate', ''); updateFilter('endDate', '');
@@ -477,27 +500,34 @@ const FinanceTable = () => {
> >
<div className='grid grid-cols-4 gap-6'> <div className='grid grid-cols-4 gap-6'>
<SelectInput <SelectInput
options={transactionTypeOptions} options={FINANCE_TRANSACTION_TYPE_OPTIONS}
label='Tipe Transaksi' label='Jenis Transaksi'
value={selectedTransactionType} value={selectedTransactionType}
onChange={transactionTypeChangeHandler} onChange={transactionTypeChangeHandler}
isClearable isClearable
isMulti
/> />
<SelectInput <SelectInput
options={partyTypeOptions} options={customerOptions}
label={ label={'Customer'}
selectedTransactionType value={selectedCustomerId}
? selectedTransactionType.value === 'CUSTOMER' onChange={customerIdChangeHandler}
? 'Pelanggan' onInputChange={customerInputValue}
: 'Supplier' onMenuScrollToBottom={customerLoadMore}
: 'Pihak' isLoading={customerIsLoadingOptions}
}
value={selectedPartyType}
onChange={partyTypeChangeHandler}
onInputChange={partyTypeInputValue}
onMenuScrollToBottom={partyTypeLoadMore}
isLoading={partyTypeIsLoadingOptions}
isClearable isClearable
isMulti
/>
<SelectInput
options={supplierOptions}
label={'Supplier'}
value={selectedSupplierId}
onChange={supplierIdChangeHandler}
onInputChange={supplierInputValue}
onMenuScrollToBottom={supplierLoadMore}
isLoading={supplierIsLoadingOptions}
isClearable
isMulti
/> />
<SelectInput <SelectInput
options={ options={
@@ -522,13 +552,7 @@ const FinanceTable = () => {
onInputChange={bankInputValue} onInputChange={bankInputValue}
onMenuScrollToBottom={bankLoadMore} onMenuScrollToBottom={bankLoadMore}
isClearable isClearable
/> isMulti
<DebouncedTextInput
name='search'
label='Cari'
placeholder='Cari'
value={pendingFilters.search}
onChange={searchChangeHandler}
/> />
<SelectInput <SelectInput
options={sortByOptions} options={sortByOptions}
@@ -549,6 +573,13 @@ const FinanceTable = () => {
value={pendingFilters.endDate} value={pendingFilters.endDate}
onChange={endDateChangeHandler} onChange={endDateChangeHandler}
/> />
<DebouncedTextInput
name='search'
label='Cari'
placeholder='Cari'
value={pendingFilters.search}
onChange={searchChangeHandler}
/>
</div> </div>
</Card> </Card>
<Table<Finance> <Table<Finance>
@@ -245,7 +245,11 @@ const FormFinanceAddInitialBalance = ({
} }
required required
isClearable isClearable
isDisabled={!formik.values.party_type_option?.value} isDisabled={
!formik.values.party_type_option?.value ||
(type === 'edit' &&
formik.values.party_type_option?.value == 'SUPPLIER')
}
/> />
<SelectInput <SelectInput
label='Bank' label='Bank'
@@ -323,6 +327,7 @@ const FormFinanceAddInitialBalance = ({
} }
required required
isClearable isClearable
isDisabled={type == 'edit'}
/> />
<NumberInput <NumberInput
label='Nominal' label='Nominal'
+8
View File
@@ -389,6 +389,14 @@ export const FINANCE_INITIAL_BALANCE_TYPE_OPTIONS = [
{ label: 'Saldo Awal Negatif', value: 'NEGATIVE' }, { label: 'Saldo Awal Negatif', value: 'NEGATIVE' },
]; ];
export const FINANCE_TRANSACTION_TYPE_OPTIONS = [
{ label: 'Pembelian', value: 'PEMBELIAN' },
{ label: 'Penjualan', value: 'PENJUALAN' },
{ label: 'Biaya', value: 'BIAYA' },
{ label: 'Saldo Awal', value: 'SALDO_AWAL' },
{ label: 'Injection', value: 'INJECTION' },
];
export const FINANCE_TRANSACTION_STATUS = ['PENJUALAN', 'PEMBELIAN', 'BIAYA']; export const FINANCE_TRANSACTION_STATUS = ['PENJUALAN', 'PEMBELIAN', 'BIAYA'];
export const FINANCE_INITIAL_BALANCE_STATUS = ['SALDO_AWAL']; export const FINANCE_INITIAL_BALANCE_STATUS = ['SALDO_AWAL'];