Get Chart of Account Types
This commit is contained in:
parent
76ee71e7fe
commit
9cbb41c2ad
36
src/services/queries/chartOfAccountType.ts
Normal file
36
src/services/queries/chartOfAccountType.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { ChartOfAccountTypes } from '@/types/services/chartOfAccount'
|
||||||
|
import { useQuery } from '@tanstack/react-query'
|
||||||
|
import { api } from '../api'
|
||||||
|
|
||||||
|
interface ChartOfAccountQueryParams {
|
||||||
|
page?: number
|
||||||
|
limit?: number
|
||||||
|
search?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useChartOfAccountTypes(params: ChartOfAccountQueryParams = {}) {
|
||||||
|
const { page = 1, limit = 10, search = '', ...filters } = params
|
||||||
|
|
||||||
|
return useQuery<ChartOfAccountTypes>({
|
||||||
|
queryKey: ['chart-of-account-types', { page, limit, search, ...filters }],
|
||||||
|
queryFn: async () => {
|
||||||
|
const queryParams = new URLSearchParams()
|
||||||
|
|
||||||
|
queryParams.append('page', page.toString())
|
||||||
|
queryParams.append('limit', limit.toString())
|
||||||
|
|
||||||
|
if (search) {
|
||||||
|
queryParams.append('search', search)
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.entries(filters).forEach(([key, value]) => {
|
||||||
|
if (value !== undefined && value !== null && value !== '') {
|
||||||
|
queryParams.append(key, value.toString())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const res = await api.get(`/chart-of-account-types?${queryParams.toString()}`)
|
||||||
|
return res.data.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
16
src/types/services/chartOfAccount.ts
Normal file
16
src/types/services/chartOfAccount.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
export interface ChartOfAccountType {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
code: string
|
||||||
|
description: string
|
||||||
|
is_active: boolean
|
||||||
|
created_at: string
|
||||||
|
updated_at: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ChartOfAccountTypes {
|
||||||
|
data: ChartOfAccountType[]
|
||||||
|
limit: number
|
||||||
|
page: number
|
||||||
|
total: number
|
||||||
|
}
|
||||||
@ -15,6 +15,7 @@ import { useForm, Controller } from 'react-hook-form'
|
|||||||
// Component Imports
|
// Component Imports
|
||||||
import CustomTextField from '@core/components/mui/TextField'
|
import CustomTextField from '@core/components/mui/TextField'
|
||||||
import CustomAutocomplete from '@/@core/components/mui/Autocomplete'
|
import CustomAutocomplete from '@/@core/components/mui/Autocomplete'
|
||||||
|
import { useChartOfAccountTypes } from '@/services/queries/chartOfAccountType'
|
||||||
|
|
||||||
// Account Type
|
// Account Type
|
||||||
export type AccountType = {
|
export type AccountType = {
|
||||||
@ -25,6 +26,16 @@ export type AccountType = {
|
|||||||
balance: string
|
balance: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ChartOfAccountType {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
code: string
|
||||||
|
description: string
|
||||||
|
is_active: boolean
|
||||||
|
created_at: string
|
||||||
|
updated_at: string
|
||||||
|
}
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
open: boolean
|
open: boolean
|
||||||
handleClose: () => void
|
handleClose: () => void
|
||||||
@ -40,8 +51,8 @@ type FormValidateType = {
|
|||||||
parentAccount?: string
|
parentAccount?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Categories available for accounts
|
// Fallback categories (used when API data is not available)
|
||||||
const accountCategories = [
|
const fallbackAccountCategories = [
|
||||||
'Kas & Bank',
|
'Kas & Bank',
|
||||||
'Piutang',
|
'Piutang',
|
||||||
'Persediaan',
|
'Persediaan',
|
||||||
@ -80,6 +91,25 @@ const AccountFormDrawer = (props: Props) => {
|
|||||||
// Determine if we're editing
|
// Determine if we're editing
|
||||||
const isEdit = !!editingAccount
|
const isEdit = !!editingAccount
|
||||||
|
|
||||||
|
const { data: accountTypes, isLoading } = useChartOfAccountTypes()
|
||||||
|
|
||||||
|
// Process account types for the dropdown
|
||||||
|
const categoryOptions = accountTypes?.data.length
|
||||||
|
? accountTypes.data
|
||||||
|
.filter(type => type.is_active) // Only show active types
|
||||||
|
.map(type => ({
|
||||||
|
id: type.id,
|
||||||
|
name: type.name,
|
||||||
|
code: type.code,
|
||||||
|
description: type.description
|
||||||
|
}))
|
||||||
|
: fallbackAccountCategories.map(category => ({
|
||||||
|
id: category.toLowerCase().replace(/\s+/g, '_'),
|
||||||
|
name: category,
|
||||||
|
code: category,
|
||||||
|
description: category
|
||||||
|
}))
|
||||||
|
|
||||||
// Hooks
|
// Hooks
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
@ -237,17 +267,29 @@ const AccountFormDrawer = (props: Props) => {
|
|||||||
render={({ field: { onChange, value, ...field } }) => (
|
render={({ field: { onChange, value, ...field } }) => (
|
||||||
<CustomAutocomplete
|
<CustomAutocomplete
|
||||||
{...field}
|
{...field}
|
||||||
options={accountCategories}
|
loading={isLoading}
|
||||||
value={value || null}
|
options={categoryOptions}
|
||||||
onChange={(_, newValue) => onChange(newValue || '')}
|
value={categoryOptions.find(option => option.name === value) || null}
|
||||||
|
onChange={(_, newValue) => onChange(newValue?.name || '')}
|
||||||
|
getOptionLabel={option => option.name}
|
||||||
|
renderOption={(props, option) => (
|
||||||
|
<Box component='li' {...props}>
|
||||||
|
<div>
|
||||||
|
<Typography variant='body2'>
|
||||||
|
{option.code} - {option.name}
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
renderInput={params => (
|
renderInput={params => (
|
||||||
<CustomTextField
|
<CustomTextField
|
||||||
{...params}
|
{...params}
|
||||||
placeholder='Pilih kategori'
|
placeholder={isLoading ? 'Loading categories...' : 'Pilih kategori'}
|
||||||
{...(errors.category && { error: true, helperText: 'Field ini wajib diisi.' })}
|
{...(errors.category && { error: true, helperText: 'Field ini wajib diisi.' })}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
isOptionEqualToValue={(option, value) => option === value}
|
isOptionEqualToValue={(option, value) => option.name === value.name}
|
||||||
|
disabled={isLoading}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user