Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Sign in
Toggle navigation
C
ctas-box
Project overview
Project overview
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Container Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Fachri
ctas-box
Commits
25204a36
Commit
25204a36
authored
Oct 24, 2025
by
Rais Aryaguna
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix:
- validation form - call api create draft and upload - flow edit and pengganti
parent
b7ff97de
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
209 additions
and
122 deletions
+209
-122
src/actions/master-data.ts
src/actions/master-data.ts
+1
-1
src/sections/bupot-21-26/bupot-bulanan/components/DialogPenandatangan.tsx
...ot-21-26/bupot-bulanan/components/DialogPenandatangan.tsx
+1
-1
src/sections/bupot-21-26/bupot-bulanan/components/rekam/Identitas.tsx
.../bupot-21-26/bupot-bulanan/components/rekam/Identitas.tsx
+57
-40
src/sections/bupot-21-26/bupot-bulanan/components/rekam/JumlahPerhitunganForm.tsx
.../bupot-bulanan/components/rekam/JumlahPerhitunganForm.tsx
+8
-13
src/sections/bupot-21-26/bupot-bulanan/components/rekam/PerhitunganPPhPasal21.tsx
.../bupot-bulanan/components/rekam/PerhitunganPPhPasal21.tsx
+5
-16
src/sections/bupot-21-26/bupot-bulanan/hooks/useSaveBulanan.ts
...ections/bupot-21-26/bupot-bulanan/hooks/useSaveBulanan.ts
+12
-12
src/sections/bupot-21-26/bupot-bulanan/types/types.ts
src/sections/bupot-21-26/bupot-bulanan/types/types.ts
+8
-0
src/sections/bupot-21-26/bupot-bulanan/utils/api.tsx
src/sections/bupot-21-26/bupot-bulanan/utils/api.tsx
+2
-2
src/sections/bupot-21-26/bupot-bulanan/view/bulanan-rekam-view.tsx
...ons/bupot-21-26/bupot-bulanan/view/bulanan-rekam-view.tsx
+115
-37
No files found.
src/actions/master-data.ts
View file @
25204a36
...
...
@@ -9,7 +9,7 @@ interface ApiResponse<T> {
data
:
T
;
}
interface
KodeNegara
{
export
interface
KodeNegara
{
kode
:
string
;
nama
:
string
;
}
...
...
src/sections/bupot-21-26/bupot-bulanan/components/DialogPenandatangan.tsx
View file @
25204a36
...
...
@@ -55,7 +55,7 @@ const DialogPenandatangan: React.FC<DialogPenandatanganProps> = ({
})
=>
{
const
[
isOpenDialogProgressBar
,
setIsOpenDialogProgressBar
]
=
useState
(
false
);
const
[
isCheckedAgreement
,
setIsCheckedAgreement
]
=
useState
<
boolean
>
(
false
);
const
signer
=
useAppSelector
((
state
:
any
)
=>
state
.
user
.
data
.
signer
);
const
signer
=
useAppSelector
((
state
)
=>
state
.
user
.
data
.
signer
);
const
queryClient
=
useQueryClient
();
const
methods
=
useForm
({
...
...
src/sections/bupot-21-26/bupot-bulanan/components/rekam/Identitas.tsx
View file @
25204a36
import
Box
from
'
@mui/material/Box
'
;
import
Button
from
'
@mui/material/Button
'
;
import
Grid
from
'
@mui/material/Grid
'
;
import
dayjs
from
'
dayjs
'
;
import
{
useEffect
,
useState
}
from
'
react
'
;
import
{
useEffect
}
from
'
react
'
;
import
{
useFormContext
}
from
'
react-hook-form
'
;
// import { useParams } from 'react-router';
import
{
useKodeNegara
}
from
'
src/actions/master-data
'
;
import
{
Field
}
from
'
src/components/hook-form
'
;
type
IdentitasProps
=
{
isPengganti
?:
boolean
;
kodeNegetaOptions
:
{
label
:
string
;
value
:
string
;
}[];
};
const
Identitas
=
({
isPengganti
}:
IdentitasProps
)
=>
{
const
Identitas
=
({
isPengganti
,
kodeNegetaOptions
}:
IdentitasProps
)
=>
{
// const { dnId } = useParams();
const
{
setValue
,
watch
}
=
useFormContext
();
const
tanggalPemotongan
=
watch
(
'
tglPemotongan
'
);
const
fgKaryawanAsing
=
watch
(
'
fgKaryawanAsing
'
);
const
[
jumlahKeterangan
,
setJumlahKeterangan
]
=
useState
<
number
>
(
0
);
const
maxKeterangan
=
5
;
//
const [jumlahKeterangan, setJumlahKeterangan] = useState<number>(0);
//
const maxKeterangan = 5;
const
handleTambah
=
()
=>
{
if
(
jumlahKeterangan
<
maxKeterangan
)
{
setJumlahKeterangan
(
jumlahKeterangan
+
1
);
}
};
//
const handleTambah = () => {
//
if (jumlahKeterangan < maxKeterangan) {
//
setJumlahKeterangan(jumlahKeterangan + 1);
//
}
//
};
const
handleHapus
=
()
=>
{
if
(
jumlahKeterangan
>
0
)
{
const
newCount
=
jumlahKeterangan
-
1
;
setJumlahKeterangan
(
newCount
);
setValue
(
`keterangan
${
newCount
+
1
}
`
,
null
);
}
};
//
const handleHapus = () => {
//
if (jumlahKeterangan > 0) {
//
const newCount = jumlahKeterangan - 1;
//
setJumlahKeterangan(newCount);
//
setValue(`keterangan${newCount + 1}`, null);
//
}
//
};
// auto set thnPajak dan msPajak berdasarkan tanggalPemotongan
useEffect
(()
=>
{
if
(
tanggalPemotongan
)
{
const
date
=
dayjs
(
tanggalPemotongan
);
setValue
(
'
thnPajak
'
,
date
.
format
(
'
YYYY
'
));
setValue
(
'
msPajak
'
,
date
.
format
(
'
MM
'
));
}
else
{
setValue
(
'
thnPajak
'
,
''
);
setValue
(
'
msPajak
'
,
''
);
if
(
!
isPengganti
)
{
if
(
tanggalPemotongan
)
{
const
date
=
dayjs
(
tanggalPemotongan
);
setValue
(
'
tahunPajak
'
,
date
.
format
(
'
YYYY
'
));
setValue
(
'
masaPajak
'
,
date
.
format
(
'
MM
'
));
}
else
{
setValue
(
'
tahunPajak
'
,
''
);
setValue
(
'
masaPajak
'
,
''
);
}
}
},
[
tanggalPemotongan
,
setValue
]);
const
{
kodeNegara
}
=
useKodeNegara
();
// eslint-disable-next-line react-hooks/exhaustive-deps
},
[
tanggalPemotongan
,
!
isPengganti
]);
return
(
<>
...
...
@@ -62,54 +64,68 @@ const Identitas = ({ isPengganti }: IdentitasProps) => {
</
Grid
>
<
Grid
size=
{
{
md
:
3
}
}
>
<
Field
.
DatePicker
name=
"t
h
nPajak"
name=
"t
ahu
nPajak"
label=
"Tahun Pajak"
view=
"year"
format=
"YYYY"
readOnly
disabled=
{
isPengganti
}
/>
</
Grid
>
<
Grid
size=
{
{
md
:
3
}
}
>
<
Field
.
DatePicker
name=
"msPajak"
label=
"Masa Pajak"
view=
"month"
format=
"MM"
readOnly
/>
<
Field
.
DatePicker
name=
"masaPajak"
label=
"Masa Pajak"
view=
"month"
format=
"MM"
readOnly
disabled=
{
isPengganti
}
/>
</
Grid
>
{
/* NPWP dengan onChange langsung */
}
<
Grid
size=
{
{
md
:
6
}
}
>
<
Field
.
Text
name=
"
idDipotong
"
name=
"
npwp
"
label=
"NPWP"
onChange=
{
(
e
)
=>
{
const
value
=
e
.
target
.
value
.
replace
(
/
\D
/g
,
''
).
slice
(
0
,
16
);
// hanya angka, max 16
console
.
log
(
'
🚀 ~ value:
'
,
value
);
setValue
(
'
idDipotong
'
,
value
,
{
shouldValidate
:
true
,
shouldDirty
:
true
});
setValue
(
'
npwp
'
,
value
,
{
shouldValidate
:
true
,
shouldDirty
:
true
});
setValue
(
'
nitku
'
,
value
.
length
===
16
?
value
+
'
000000
'
:
value
,
{
shouldValidate
:
true
,
shouldDirty
:
true
,
});
}
}
disabled=
{
isPengganti
}
/>
</
Grid
>
<
Grid
size=
{
{
md
:
6
}
}
>
<
Field
.
Text
name=
"namaDipotong"
label=
"Nama"
/>
<
Field
.
Text
name=
"namaDipotong"
label=
"Nama"
disabled=
{
isPengganti
}
/>
</
Grid
>
<
Grid
size=
{
{
md
:
12
}
}
>
<
Field
.
Text
name=
"alamatDipotong"
label=
"Alamat"
/>
</
Grid
>
<
Grid
size=
{
{
md
:
6
}
}
>
<
Field
.
Text
name=
"email"
label=
"Email (optional)"
/>
<
Field
.
Text
name=
"email"
label=
"Email (optional)"
disabled=
{
isPengganti
}
/>
</
Grid
>
<
Grid
size=
{
{
md
:
6
}
}
>
<
Field
.
Text
name=
"posisiJabatan"
label=
"Jabatan"
/>
<
Field
.
Text
name=
"posisiJabatan"
label=
"Jabatan"
disabled=
{
isPengganti
}
/>
</
Grid
>
<
Grid
size=
{
{
md
:
3
}
}
alignSelf=
"center"
>
<
Field
.
Checkbox
name=
"fgKaryawanAsing"
label=
"Status Karyawan Asing"
/>
<
Field
.
Checkbox
name=
"fgKaryawanAsing"
label=
"Status Karyawan Asing"
disabled=
{
isPengganti
}
/>
</
Grid
>
<
Grid
size=
{
{
md
:
3
}
}
>
<
Field
.
Autocomplete
name=
"kodeNegara"
label=
"Negara"
options=
{
kodeNeg
ara
.
map
((
val
)
=>
({
label
:
val
.
nama
,
value
:
val
.
kode
}))
}
options=
{
kodeNeg
etaOptions
}
readOnly=
{
!
fgKaryawanAsing
}
disabled=
{
isPengganti
}
/>
</
Grid
>
<
Grid
size=
{
{
md
:
6
}
}
>
...
...
@@ -121,12 +137,13 @@ const Identitas = ({ isPengganti }: IdentitasProps) => {
readOnly
:
!
fgKaryawanAsing
,
},
}
}
disabled=
{
isPengganti
}
/>
</
Grid
>
</
Grid
>
{
/* Tambah / Hapus Keterangan */
}
<
Box
sx=
{
{
display
:
'
flex
'
,
gap
:
2
,
mb
:
3
}
}
>
{
/*
<Box sx={{ display: 'flex', gap: 2, mb: 3 }}>
<Box
sx={{
borderRadius: '18px',
...
...
@@ -163,7 +180,7 @@ const Identitas = ({ isPengganti }: IdentitasProps) => {
/>
</Grid>
))}
</
Box
>
</Box>
*/
}
</>
);
};
...
...
src/sections/bupot-21-26/bupot-bulanan/components/rekam/JumlahPerhitunganForm.tsx
View file @
25204a36
...
...
@@ -2,7 +2,6 @@ import { CalculateRounded } from '@mui/icons-material';
import
{
LoadingButton
}
from
'
@mui/lab
'
;
import
{
Grid
}
from
'
@mui/material
'
;
import
dayjs
from
'
dayjs
'
;
import
{
useMemo
}
from
'
react
'
;
import
{
useFormContext
}
from
'
react-hook-form
'
;
import
{
Field
}
from
'
src/components/hook-form
'
;
import
{
RHFNumeric
}
from
'
src/components/hook-form/rhf-numeric
'
;
...
...
@@ -12,9 +11,6 @@ import {
FG_PERHITUNGAN
,
FG_PERHITUNGAN_TEXT
,
METODE_POTONG
,
PTKP
,
PTKP_TEXT
,
PTKP_TITLE
,
}
from
'
../../constant
'
;
const
fgPerhitunganOptions
=
Object
.
values
(
FG_PERHITUNGAN
).
map
((
value
)
=>
({
...
...
@@ -22,17 +18,16 @@ const fgPerhitunganOptions = Object.values(FG_PERHITUNGAN).map((value) => ({
label
:
FG_PERHITUNGAN_TEXT
[
value
],
}));
function
JumlahPerhitunganForm
()
{
function
JumlahPerhitunganForm
({
ptkpOptions
,
}:
{
ptkpOptions
:
{
value
:
string
;
label
:
string
;
}[];
})
{
const
{
watch
,
getValues
,
setValue
}
=
useFormContext
();
const
ptkpOptions
=
useMemo
(
()
=>
Object
.
entries
(
PTKP
)
.
map
(([
key
,
value
])
=>
({
value
,
label
:
PTKP_TEXT
[
value
]
}))
.
filter
((
option
)
=>
!
option
.
value
.
includes
(
PTKP_TITLE
.
HB
)),
[]
);
const
{
mutate
,
isPending
}
=
useHitungBulanan
({
onSuccess
:
(
data
)
=>
{
console
.
log
(
'
✅ Berhasil hitung PPh21:
'
,
data
);
...
...
src/sections/bupot-21-26/bupot-bulanan/components/rekam/PerhitunganPPhPasal21.tsx
View file @
25204a36
import
Divider
from
'
@mui/material/Divider
'
;
import
Grid
from
'
@mui/material/Grid
'
;
import
{
useMemo
}
from
'
react
'
;
import
{
useFormContext
}
from
'
react-hook-form
'
;
import
{
Field
}
from
'
src/components/hook-form
'
;
import
{
FG_FASILITAS_PPH_21
,
FG_FASILITAS_PPH_21_TEXT
}
from
'
../../constant
'
;
type
PPHDipotongProps
=
{
kodeObjectPajak
:
{
value
:
string
;
label
:
string
;
}[];
fgFasilitasOptions
:
{
value
:
string
;
label
:
string
;
}[];
};
const
PerhitunganPPhPasal21
=
({
kodeObjectPajak
}:
PPHDipotongProps
)
=>
{
const
PerhitunganPPhPasal21
=
({
kodeObjectPajak
,
fgFasilitasOptions
}:
PPHDipotongProps
)
=>
{
const
{
watch
}
=
useFormContext
();
const
fgFasilitas
=
watch
(
'
fgFasilitas
'
);
const
fgFasilitasOptions
=
useMemo
(
()
=>
[
FG_FASILITAS_PPH_21
.
DTP
,
FG_FASILITAS_PPH_21
.
FASILITAS_LAINNYA
,
FG_FASILITAS_PPH_21
.
TANPA_FASILITAS
,
].
map
((
value
)
=>
({
value
,
label
:
FG_FASILITAS_PPH_21_TEXT
[
value
],
})),
[]
);
return
(
<
Grid
container
rowSpacing=
{
2
}
columnSpacing=
{
2
}
>
{
/* Divider */
}
...
...
src/sections/bupot-21-26/bupot-bulanan/hooks/useSaveBulanan.ts
View file @
25204a36
...
...
@@ -12,9 +12,9 @@ const transformParams = ({ isPengganti = false, ...Data }: any): TPostBulananReq
id
,
idBupot
,
noBupot
,
m
s
Pajak
,
t
h
nPajak
,
idDipotong
,
m
asa
Pajak
,
t
ahu
nPajak
,
npwp
,
nitku
,
namaDipotong
,
fgFasilitas
,
...
...
@@ -36,21 +36,21 @@ const transformParams = ({ isPengganti = false, ...Data }: any): TPostBulananReq
posisiJabatan
,
}
=
Data
;
console
.
log
(
'
🚀 ~ transformParams ~ Data:
'
,
Data
);
const
revNo
=
isPengganti
?
parseInt
(
initialRevNo
||
0
,
10
)
+
1
:
parseInt
(
initialRevNo
||
0
,
10
);
const
[
status
,
jmlPtkp
]
=
statusPtkp
.
split
(
'
/
'
);
const
npwpLog
=
localStorage
.
getItem
(
'
npwp_log
'
)
??
''
;
return
{
id
:
!
isPengganti
?
(
id
??
null
)
:
null
,
idBupot
:
isPengganti
?
(
idBupot
??
''
)
:
undefined
,
noBupot
:
isPengganti
?
(
noBupot
??
''
)
:
undefined
,
npwpPemotong
:
idTku
,
idBupot
,
noBupot
,
npwpPemotong
:
npwpLog
,
idTku
:
idTku
??
''
,
masaPajak
:
msPajak
?
dayjs
(
msPajak
).
format
(
'
MM
'
)
:
''
,
tahunPajak
:
thnPajak
?
dayjs
(
thnPajak
).
format
(
'
YYYY
'
)
:
''
,
npwp
:
idDipotong
??
''
,
nik
:
nitku
??
(
idDipotong
?
`
${
idDipotong
}
000000`
:
''
),
masaPajak
,
tahunPajak
,
npwp
:
npwp
??
''
,
nik
:
nitku
??
(
npwp
?
`
${
npwp
}
000000`
:
''
),
nama
:
namaDipotong
??
''
,
revNo
,
fgNpwpNik
:
true
,
...
...
src/sections/bupot-21-26/bupot-bulanan/types/types.ts
View file @
25204a36
...
...
@@ -8,6 +8,14 @@ export type TBaseResponseAPI<T> = {
total
?:
number
;
};
export
type
TBaseResponseCreateAPI
<
T
>
=
{
code
:
number
;
data
?:
T
;
message
:
string
;
status
:
string
;
time
:
Date
;
};
export
interface
BupotRecord
{
// --- Kunci numerik dinamis ("1" sampai "53") ---
// [key: `${number}`]: number | undefined;
...
...
src/sections/bupot-21-26/bupot-bulanan/utils/api.tsx
View file @
25204a36
import
{
fetcher
}
from
'
src/lib/axios
'
;
import
{
fetcher
}
from
'
src/lib/axios
-ctas-box
'
;
import
type
{
BupotRecord
,
TBaseResponseAPI
,
...
...
@@ -46,7 +46,7 @@ bulananApi.getKodeObjekPajak = async (params?: Record<string, any>) => {
};
bulananApi
.
save
=
async
(
config
:
TPostBulananRequest
)
=>
{
const
response
=
await
fetcher
<
TBaseResponseAPI
<
BupotRecord
>>
([
const
response
=
await
fetcher
<
TBaseResponseAPI
<
BupotRecord
[]
>>
([
'
/IF_TXR_028/a0
'
,
{
method
:
'
POST
'
,
...
...
src/sections/bupot-21-26/bupot-bulanan/view/bulanan-rekam-view.tsx
View file @
25204a36
...
...
@@ -4,8 +4,11 @@ import Divider from '@mui/material/Divider';
import
Grid
from
'
@mui/material/Grid
'
;
import
Stack
from
'
@mui/material/Stack
'
;
import
dayjs
from
'
dayjs
'
;
import
{
enqueueSnackbar
}
from
'
notistack
'
;
import
{
Suspense
,
useEffect
,
useMemo
,
useState
}
from
'
react
'
;
import
{
FormProvider
,
useForm
}
from
'
react-hook-form
'
;
import
{
useNavigate
,
useParams
}
from
'
react-router
'
;
import
{
useKodeNegara
}
from
'
src/actions/master-data
'
;
import
{
CustomBreadcrumbs
}
from
'
src/components/custom-breadcrumbs
'
;
import
{
Field
}
from
'
src/components/hook-form
'
;
import
{
DashboardContent
}
from
'
src/layouts/dashboard
'
;
...
...
@@ -14,6 +17,7 @@ import Agreement from 'src/shared/components/agreement/Agreement';
import
HeadingRekam
from
'
src/shared/components/HeadingRekam
'
;
import
FormSkeleton
from
'
src/shared/skeletons/FormSkeleton
'
;
import
z
from
'
zod
'
;
import
DialogPenandatangan
from
'
../components/DialogPenandatangan
'
;
import
Identitas
from
'
../components/rekam/Identitas
'
;
import
JumlahPerhitunganForm
from
'
../components/rekam/JumlahPerhitunganForm
'
;
import
PanduanDnRekam
from
'
../components/rekam/PanduanDnRekam
'
;
...
...
@@ -23,27 +27,34 @@ import {
FG_FASILITAS_PPH_21_TEXT
,
KODE_OBJEK_PAJAK
,
KODE_OBJEK_PAJAK_TEXT
,
PTKP
,
PTKP_TEXT
,
PTKP_TITLE
,
}
from
'
../constant
'
;
import
useGetBulanan
from
'
../hooks/useGetBulanan
'
;
import
useSaveBulanan
from
'
../hooks/useSaveBulanan
'
;
import
DialogPenandatangan
from
'
../components/DialogPenandatangan
'
;
import
useUploadBulanan
from
'
../hooks/useUploadeBulanan
'
;
import
{
useNavigate
,
useParams
}
from
'
react-router
'
;
import
{
enqueueSnackbar
}
from
'
notistack
'
;
import
useGetBulanan
from
'
../hooks/useGetBulanan
'
;
const
bulananSchema
=
z
.
object
({
idBupot
:
z
.
string
().
optional
(),
noBupot
:
z
.
string
().
optional
(),
revNo
:
z
.
number
().
optional
(),
tahunPajak
:
z
.
string
().
min
(
1
,
'
Tahun Pajak wajib diisi
'
),
masaPajak
:
z
.
string
().
min
(
1
,
'
Masa Pajak wajib diisi
'
),
feature
:
z
.
string
().
optional
(),
idDipotong
:
z
.
string
().
optional
(),
npwp
:
z
.
string
().
min
(
1
,
'
NPWP wajib diisi
'
),
nitku
:
z
.
string
().
length
(
22
,
'
NITKU harus 22 digit
'
),
namaDipotong
:
z
.
string
().
min
(
1
,
'
Nama wajib diisi
'
),
alamatDipotong
:
z
.
string
().
min
(
1
,
'
Alamat wajib diisi
'
),
posisiJabatan
:
z
.
string
().
min
(
1
,
'
Jabatan wajib diisi
'
),
alamat
:
z
.
string
().
nullable
().
optional
(),
fgKaryawanAsing
:
z
.
boolean
().
optional
(),
kodeNegara
:
z
.
string
().
optional
(),
kodeNegara
:
z
.
object
({
label
:
z
.
string
(),
value
:
z
.
string
(),
})
.
optional
(),
passport
:
z
.
string
().
optional
(),
kdObjPjk
:
z
.
object
({
...
...
@@ -172,7 +183,7 @@ export const BulananRekamView = () => {
const
{
id
,
type
}
=
useParams
<
{
id
?:
string
;
type
?:
'
ubah
'
|
'
pengganti
'
|
'
new
'
}
>
();
const
navigate
=
useNavigate
();
const
{
mutate
:
saveBulanan
,
isPending
:
isSaving
}
=
useSaveBulanan
({
const
{
mutate
Async
:
saveBulanan
,
isPending
:
isSaving
}
=
useSaveBulanan
({
onSuccess
:
()
=>
enqueueSnackbar
(
'
Data berhasil disimpan
'
,
{
variant
:
'
success
'
}),
});
const
{
mutate
:
uploadBulanan
,
isPending
:
isUpload
}
=
useUploadBulanan
();
...
...
@@ -195,13 +206,52 @@ export const BulananRekamView = () => {
[]
);
const
{
kodeNegara
}
=
useKodeNegara
();
const
kodeNegetaOptions
=
useMemo
(
()
=>
kodeNegara
.
map
((
val
)
=>
({
label
:
val
.
nama
,
value
:
val
.
kode
})),
[
kodeNegara
]
);
const
fgFasilitasOptions
=
useMemo
(
()
=>
[
FG_FASILITAS_PPH_21
.
DTP
,
FG_FASILITAS_PPH_21
.
FASILITAS_LAINNYA
,
FG_FASILITAS_PPH_21
.
TANPA_FASILITAS
,
].
map
((
value
)
=>
({
value
,
label
:
FG_FASILITAS_PPH_21_TEXT
[
value
],
})),
[]
);
const
ptkpOptions
=
useMemo
(
()
=>
Object
.
entries
(
PTKP
)
.
map
(([
key
,
value
])
=>
({
value
,
label
:
PTKP_TEXT
[
value
]
}))
.
filter
((
option
)
=>
!
option
.
value
.
includes
(
PTKP_TITLE
.
HB
)),
[]
);
const
MockNitku
=
[
{
value
:
'
1091031210912281000000
'
,
label
:
'
1091031210912281000000
'
,
},
{
value
:
'
1091031210912281000001
'
,
label
:
'
1091031210912281000001
'
,
},
];
const
{
data
:
existingBulanan
,
isLoading
:
isLoadingBulanan
}
=
useGetBulanan
({
params
:
{
page
:
1
,
limit
:
1
,
id
,
},
enabled
:
!!
id
,
enabled
:
!!
id
&&
(
isEdit
||
isPengganti
)
,
});
type
BpuFormData
=
z
.
infer
<
typeof
bulananSchema
>
;
...
...
@@ -211,12 +261,15 @@ export const BulananRekamView = () => {
const
defaultValues
=
{
tglPemotongan
:
dayjs
().
format
(
'
YYYY-MM-DD
'
),
tahunPajak
:
dayjs
().
format
(
'
YYYY
'
),
masaPajak
:
dayjs
().
format
(
'
YYYY-
MM
'
),
masaPajak
:
dayjs
().
format
(
'
MM
'
),
npwp
:
''
,
nitku
:
''
,
namaDipotong
:
''
,
fgKaryawanAsing
:
false
,
kodeNegara
:
''
,
kodeNegara
:
{
value
:
''
,
label
:
''
,
},
passport
:
''
,
posisiJabatan
:
''
,
kdObjPjk
:
{
...
...
@@ -251,12 +304,47 @@ export const BulananRekamView = () => {
defaultValues
,
});
console
.
log
(
'
🚀 ~ BulananRekamView:
'
,
{
methods
:
methods
.
getValues
(),
error
:
methods
.
formState
.
errors
,
});
useEffect
(()
=>
{
if
((
isEdit
||
isPengganti
)
&&
existingBulanan
&&
!
isLoadingBulanan
)
{
if
((
isEdit
||
isPengganti
)
&&
existingBulanan
.
data
.
length
!==
0
)
{
const
dataResDetail
=
existingBulanan
.
data
[
0
];
const
normalized
=
{
...
existingBulanan
,
...
dataResDetail
,
tglPemotongan
:
dataResDetail
.
tglpemotongan
,
tahunPajak
:
dataResDetail
.
thnPajak
,
masaPajak
:
dataResDetail
.
masaPajak
,
npwp
:
dataResDetail
.
npwp16Dipotong
,
nitku
:
`
${
dataResDetail
.
npwp16Dipotong
}
000000`
,
alamatDipotong
:
dataResDetail
.
alamat
,
email
:
dataResDetail
.
email
||
''
,
fgKaryawanAsing
:
!!
dataResDetail
.
countryCode
,
kodeNegara
:
kodeNegetaOptions
.
filter
(
(
val
)
=>
val
.
value
===
dataResDetail
.
countryCode
)[
0
]
||
{
value
:
''
,
label
:
''
,
},
passport
:
dataResDetail
.
passportNo
||
''
,
kdObjPjk
:
dataListKOP
.
filter
((
val
)
=>
val
.
value
===
dataResDetail
.
kdObjPjk
)[
0
],
fgFasilitas
:
fgFasilitasOptions
.
filter
((
val
)
=>
val
.
value
===
dataResDetail
.
fgFasilitas
)[
0
],
ptkp
:
ptkpOptions
.
filter
(
(
val
)
=>
val
.
value
===
`
${
dataResDetail
.
statusPtkp
}
/
${
dataResDetail
.
jmlPtkp
}
`
)[
0
],
phBruto
:
dataResDetail
.
bruto
,
pph21
:
dataResDetail
.
pphDipotong
,
idTku
:
MockNitku
.
filter
((
val
)
=>
val
.
value
===
dataResDetail
.
nitkuPemotong
)[
0
],
};
if
(
isPengganti
)
{
normalized
[
'
idBupot
'
]
=
dataResDetail
.
idBupot
||
''
;
normalized
[
'
idBupot
'
]
=
dataResDetail
.
noBupot
||
''
;
normalized
[
'
revNo
'
]
=
dataResDetail
.
revNo
||
0
;
}
methods
.
reset
(
normalized
as
any
);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
...
...
@@ -267,10 +355,8 @@ export const BulananRekamView = () => {
const
transformedData
=
{
...
data
,
id
:
isEdit
||
isPengganti
?
data
.
id
:
undefined
,
msPajak
:
data
.
masaPajak
,
thnPajak
:
data
.
tahunPajak
,
passportNo
:
data
.
passport
||
''
,
countryCode
:
data
.
kodeNegara
||
null
,
countryCode
:
data
.
kodeNegara
?.
value
||
null
,
statusPtkp
:
data
.
ptkp
?.
value
||
''
,
kdObjPjk
:
data
.
kdObjPjk
.
value
,
kdJnsPjk
:
'
PPh Pasal 21
'
,
// Sesuaikan dengan konstanta Anda
...
...
@@ -282,16 +368,19 @@ export const BulananRekamView = () => {
fgGrossUp
:
parseInt
(
data
.
fgPerhitungan
||
'
1
'
,
10
),
idTku
:
data
.
idTku
.
value
,
komponen
:
data
.
jumlahPenghasilan
||
[],
isPengganti
,
};
await
saveBulanan
(
transformedData
);
const
response
=
await
saveBulanan
(
transformedData
);
return
response
;
};
const
handleUploud
=
async
(
data
:
BpuFormData
)
=>
{
try
{
const
response
=
await
handleDraft
(
data
);
uploadBulanan
({
id
:
response
?.
id
??
''
,
id
:
`
${
response
[
0
].
id
}
`
,
});
enqueueSnackbar
(
'
Berhasil Menyimpan Data
'
,
{
variant
:
'
success
'
});
}
catch
(
error
:
any
)
{
...
...
@@ -307,8 +396,7 @@ export const BulananRekamView = () => {
const
SubmitRekam
=
async
(
data
:
BpuFormData
)
=>
{
try
{
const
respon
=
await
handleDraft
(
data
);
console
.
log
({
respon
});
await
handleDraft
(
data
);
enqueueSnackbar
(
isEdit
?
'
Data berhasil diperbarui
'
...
...
@@ -325,15 +413,6 @@ export const BulananRekamView = () => {
}
};
const
MockNitku
=
[
{
nama
:
'
1091031210912281000000
'
,
},
{
nama
:
'
1091031210912281000001
'
,
},
];
return
(
<>
<
DashboardContent
>
...
...
@@ -356,20 +435,19 @@ export const BulananRekamView = () => {
<
form
onSubmit=
{
methods
.
handleSubmit
(
SubmitRekam
)
}
>
<
FormProvider
{
...
methods
}
>
<
Suspense
fallback=
{
<
FormSkeleton
/>
}
>
<
Identitas
/>
<
Identitas
isPengganti=
{
isPengganti
}
kodeNegetaOptions=
{
kodeNegetaOptions
}
/>
<
Suspense
fallback=
{
<
FormSkeleton
/>
}
>
<
PerhitunganPPhPasal21
kodeObjectPajak=
{
dataListKOP
}
/>
<
PerhitunganPPhPasal21
kodeObjectPajak=
{
dataListKOP
}
fgFasilitasOptions=
{
fgFasilitasOptions
}
/>
</
Suspense
>
<
JumlahPerhitunganForm
/>
<
JumlahPerhitunganForm
ptkpOptions=
{
ptkpOptions
}
/>
<
Grid
size=
{
{
md
:
12
}
}
>
<
Field
.
Autocomplete
name=
"idTku"
label=
"NITKU Pemotong"
options=
{
MockNitku
.
map
((
a
)
=>
({
value
:
a
.
nama
,
label
:
a
.
nama
}))
}
/>
<
Field
.
Autocomplete
name=
"idTku"
label=
"NITKU Pemotong"
options=
{
MockNitku
}
/>
</
Grid
>
<
Divider
/>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment