Commit 35b40fb3 authored by Rais Aryaguna's avatar Rais Aryaguna

feat: enhance PDF generation by integrating user data and refining document reference handling

parent 0b56200e
...@@ -4,6 +4,7 @@ import DialogContent from '@mui/material/DialogContent'; ...@@ -4,6 +4,7 @@ import DialogContent from '@mui/material/DialogContent';
import { enqueueSnackbar } from 'notistack'; import { enqueueSnackbar } from 'notistack';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import DialogUmum from 'src/shared/components/dialog/DialogUmum'; import DialogUmum from 'src/shared/components/dialog/DialogUmum';
import { useAppSelector } from 'src/store';
import { useCetakBulanan } from '../../../cetakpdf'; import { useCetakBulanan } from '../../../cetakpdf';
interface ModalCetakPdfDnProps { interface ModalCetakPdfDnProps {
...@@ -15,6 +16,7 @@ interface ModalCetakPdfDnProps { ...@@ -15,6 +16,7 @@ interface ModalCetakPdfDnProps {
const ModalCetakPdfBulanan: React.FC<ModalCetakPdfDnProps> = ({ payload, isOpen, onClose }) => { const ModalCetakPdfBulanan: React.FC<ModalCetakPdfDnProps> = ({ payload, isOpen, onClose }) => {
const [pdfUrl, setPdfUrl] = useState<string | null>(null); const [pdfUrl, setPdfUrl] = useState<string | null>(null);
const [loading, setLoading] = useState<boolean>(false); const [loading, setLoading] = useState<boolean>(false);
const AppSelector = useAppSelector((selector) => selector.user.data);
const { mutateAsync } = useCetakBulanan({ const { mutateAsync } = useCetakBulanan({
onError: (error: any) => { onError: (error: any) => {
...@@ -42,7 +44,13 @@ const ModalCetakPdfBulanan: React.FC<ModalCetakPdfDnProps> = ({ payload, isOpen, ...@@ -42,7 +44,13 @@ const ModalCetakPdfBulanan: React.FC<ModalCetakPdfDnProps> = ({ payload, isOpen,
try { try {
console.log('Payload final cetak PDF:', payload); console.log('Payload final cetak PDF:', payload);
await mutateAsync(payload as any); await mutateAsync({
...payload,
npwpPemotong: AppSelector.npwp_trial,
namaPemotong: AppSelector.company_name,
nitkuPemotong: AppSelector.nitku_trial,
namaPenandatangan: AppSelector.signer,
} as any);
} catch (err) { } catch (err) {
console.error('❌ Error cetak PDF:', err); console.error('❌ Error cetak PDF:', err);
enqueueSnackbar('Gagal generate PDF', { variant: 'error' }); enqueueSnackbar('Gagal generate PDF', { variant: 'error' });
......
...@@ -4,7 +4,8 @@ import DialogContent from '@mui/material/DialogContent'; ...@@ -4,7 +4,8 @@ import DialogContent from '@mui/material/DialogContent';
import { enqueueSnackbar } from 'notistack'; import { enqueueSnackbar } from 'notistack';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import DialogUmum from 'src/shared/components/dialog/DialogUmum'; import DialogUmum from 'src/shared/components/dialog/DialogUmum';
import { useCetakBulanan } from '../../../cetakpdf'; import { useCetakFinalTidakFinal } from '../../../cetakpdf';
import { useAppSelector } from 'src/store';
interface ModalCetakPdfDnProps { interface ModalCetakPdfDnProps {
payload?: Record<string, any>; payload?: Record<string, any>;
...@@ -15,8 +16,9 @@ interface ModalCetakPdfDnProps { ...@@ -15,8 +16,9 @@ interface ModalCetakPdfDnProps {
const ModalCetakPdfBulanan: React.FC<ModalCetakPdfDnProps> = ({ payload, isOpen, onClose }) => { const ModalCetakPdfBulanan: React.FC<ModalCetakPdfDnProps> = ({ payload, isOpen, onClose }) => {
const [pdfUrl, setPdfUrl] = useState<string | null>(null); const [pdfUrl, setPdfUrl] = useState<string | null>(null);
const [loading, setLoading] = useState<boolean>(false); const [loading, setLoading] = useState<boolean>(false);
const AppSelector = useAppSelector((selector) => selector.user.data);
const { mutateAsync } = useCetakBulanan({ const { mutateAsync } = useCetakFinalTidakFinal({
onError: (error: any) => { onError: (error: any) => {
enqueueSnackbar(error?.message || 'Gagal memuat PDF', { variant: 'error' }); enqueueSnackbar(error?.message || 'Gagal memuat PDF', { variant: 'error' });
setLoading(false); setLoading(false);
...@@ -42,7 +44,13 @@ const ModalCetakPdfBulanan: React.FC<ModalCetakPdfDnProps> = ({ payload, isOpen, ...@@ -42,7 +44,13 @@ const ModalCetakPdfBulanan: React.FC<ModalCetakPdfDnProps> = ({ payload, isOpen,
try { try {
console.log('Payload final cetak PDF:', payload); console.log('Payload final cetak PDF:', payload);
await mutateAsync(payload as any); await mutateAsync({
...payload,
npwpPemotong: AppSelector.npwp_trial,
namaPemotong: AppSelector.company_name,
nitkuPemotong: AppSelector.nitku_trial,
namaPenandatangan: AppSelector.signer,
} as any);
} catch (err) { } catch (err) {
console.error('❌ Error cetak PDF:', err); console.error('❌ Error cetak PDF:', err);
enqueueSnackbar('Gagal generate PDF', { variant: 'error' }); enqueueSnackbar('Gagal generate PDF', { variant: 'error' });
...@@ -51,7 +59,7 @@ const ModalCetakPdfBulanan: React.FC<ModalCetakPdfDnProps> = ({ payload, isOpen, ...@@ -51,7 +59,7 @@ const ModalCetakPdfBulanan: React.FC<ModalCetakPdfDnProps> = ({ payload, isOpen,
}; };
runCetak(); runCetak();
}, [isOpen, payload, mutateAsync]); }, [isOpen, payload, mutateAsync, AppSelector]);
return ( return (
<DialogUmum <DialogUmum
......
...@@ -2,19 +2,17 @@ import { Divider, Grid } from '@mui/material'; ...@@ -2,19 +2,17 @@ import { Divider, Grid } from '@mui/material';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { useFormContext } from 'react-hook-form'; import { useFormContext } from 'react-hook-form';
import { Field } from 'src/components/hook-form'; import { Field } from 'src/components/hook-form';
import { import { MockNitku } from 'src/sections/bupot-21-26/constant';
BUPOT_REFERENSI,
BUPOT_REFERENSI_TEXT,
MockNitku,
} from 'src/sections/bupot-21-26/constant';
function DokumenReferensi() { function DokumenReferensi({
JnsDokRefOptions,
}: {
JnsDokRefOptions: {
value: string;
label: string;
}[];
}) {
const { setValue } = useFormContext(); const { setValue } = useFormContext();
const options = Object.entries(BUPOT_REFERENSI).map(([key, value]) => ({
value,
label: BUPOT_REFERENSI_TEXT[value],
}));
return ( return (
<Grid container rowSpacing={2} alignItems="center" columnSpacing={2} sx={{ mb: 4 }}> <Grid container rowSpacing={2} alignItems="center" columnSpacing={2} sx={{ mb: 4 }}>
<Grid size={{ md: 12 }}> <Grid size={{ md: 12 }}>
...@@ -26,15 +24,12 @@ function DokumenReferensi() { ...@@ -26,15 +24,12 @@ function DokumenReferensi() {
<Field.Autocomplete <Field.Autocomplete
name="namaDokumenReferensi" name="namaDokumenReferensi"
label="Jenis Dokumen Referensi" label="Jenis Dokumen Referensi"
options={options} options={JnsDokRefOptions}
onChange={(_, value) => setValue('namaDokumenReferensi', value)} onChange={(_, value) => setValue('namaDokumenReferensi', value)}
/> />
</Grid> </Grid>
<Grid size={{ md: 6 }}> <Grid size={{ md: 6 }}>
<Field.Text <Field.Text name="nomorDokumenReferensi" label="Nomor Dokumen Referensi" />
name="nomorDokumenReferensi"
label="Nomor Dokumen Referensi"
/>
</Grid> </Grid>
<Grid size={{ md: 6 }}> <Grid size={{ md: 6 }}>
<Field.DatePicker <Field.DatePicker
......
...@@ -63,7 +63,7 @@ export const transformSortModelToSortApiPayload = (transformedModel: any) => ({ ...@@ -63,7 +63,7 @@ export const transformSortModelToSortApiPayload = (transformedModel: any) => ({
const normalisePropsGetBupotFinal = (params: TGetListDataTableBupotFinalResult[0]) => ({ const normalisePropsGetBupotFinal = (params: TGetListDataTableBupotFinalResult[0]) => ({
...params, ...params,
namaDokumenReferensi: params.dokumen_referensi[0].dokReferensi, namaDokumenReferensi: params.dokumen_referensi[0].dokReferensi || '',
nomorDokumenReferensi: params.dokumen_referensi[0].nomorDokumen, nomorDokumenReferensi: params.dokumen_referensi[0].nomorDokumen,
tanggalDokumenReferensi: params.dokumen_referensi[0].tanggal_Dokumen, tanggalDokumenReferensi: params.dokumen_referensi[0].tanggal_Dokumen,
fgSignStatus: transformFgStatusToFgSignStatus(params.fgStatus), fgSignStatus: transformFgStatusToFgSignStatus(params.fgStatus),
...@@ -76,6 +76,7 @@ const normalisPropsParmas = (params: any) => { ...@@ -76,6 +76,7 @@ const normalisPropsParmas = (params: any) => {
return { return {
...params, ...params,
revNo: parseInt(params.revNo, 10),
masaPajak: params.msPajak || null, masaPajak: params.msPajak || null,
tahunPajak: params.thnPajak || null, tahunPajak: params.thnPajak || null,
npwp: params.idDipotong || null, npwp: params.idDipotong || null,
......
...@@ -164,7 +164,7 @@ export type TGetListDataTableBupotFinalResult = { ...@@ -164,7 +164,7 @@ export type TGetListDataTableBupotFinalResult = {
id: number; id: number;
idBupot: null | string; idBupot: null | string;
noBupot: null | string; noBupot: null | string;
revNo:string; revNo: number;
fgTransaction:string; fgTransaction:string;
npwpPemotong:string; npwpPemotong:string;
namaPemotong: null | string; namaPemotong: null | string;
......
...@@ -40,31 +40,32 @@ import ModalUploadBupotfinal from '../components/dialog/ModalUploadBupotFinal'; ...@@ -40,31 +40,32 @@ import ModalUploadBupotfinal from '../components/dialog/ModalUploadBupotFinal';
import { CustomToolbar } from '../components/table/CustomToolbar'; import { CustomToolbar } from '../components/table/CustomToolbar';
import { useAdvancedFilter } from '../hooks/useAdvancedFilter'; import { useAdvancedFilter } from '../hooks/useAdvancedFilter';
import useGetBupotfinal from '../hooks/useGetBupotFinal'; import useGetBupotfinal from '../hooks/useGetBupotFinal';
import { useKodeObjekPajak } from 'src/actions/master-data';
export type IColumnGrid = GridColDef & { export type IColumnGrid = GridColDef & {
field: field:
| 'fgStatus' | 'fgStatus'
| 'noBupot' | 'noBupot'
| 'masaPajak' | 'masaPajak'
| 'tahunPajak' | 'tahunPajak'
| 'kodeObjekPajak' | 'kodeObjekPajak'
| 'pasalPPh' | 'pasalPPh'
| 'npwp' | 'npwp'
| 'nama' | 'nama'
| 'penghasilanKotor' | 'penghasilanKotor'
| 'pph21ditanggungperusahaan' | 'pph21ditanggungperusahaan'
| 'pphDipotong' | 'pphDipotong'
| 'npwpPemotong' | 'npwpPemotong'
| 'created' | 'created'
| 'created_at' | 'created_at'
| 'updated' | 'updated'
| 'updated_at' | 'updated_at'
| 'internal_id'; | 'internal_id';
// | 'keterangan1' // | 'keterangan1'
// | 'keterangan2' // | 'keterangan2'
// | 'keterangan3' // | 'keterangan3'
// | 'keterangan4' // | 'keterangan4'
// | 'keterangan5'; // | 'keterangan5';
valueOptions?: string[]; valueOptions?: string[];
}; };
...@@ -95,7 +96,9 @@ const columns: IColumnGrid[] = [ ...@@ -95,7 +96,9 @@ const columns: IColumnGrid[] = [
const option = statusOptions.find((opt) => opt.value === params.value); const option = statusOptions.find((opt) => opt.value === params.value);
return option ? option.label : (params.value as string); return option ? option.label : (params.value as string);
}, },
renderCell: ({ value, row }) => <StatusChip value={value} revNo={parseInt(`${row.revNo}`, 10)} />, renderCell: ({ value, row }) => (
<StatusChip value={value} revNo={parseInt(`${row.revNo}`, 10)} />
),
}, },
{ {
field: 'noBupot', field: 'noBupot',
...@@ -359,7 +362,7 @@ export function BupotfinalListView() { ...@@ -359,7 +362,7 @@ export function BupotfinalListView() {
enqueueSnackbar('Pilih data yang akan diubah', { variant: 'warning' }); enqueueSnackbar('Pilih data yang akan diubah', { variant: 'warning' });
return; return;
} }
navigate(paths.pph21.bupotFinalEdit(selectedRow.id,type)); navigate(paths.pph21.bupotFinalEdit(selectedRow.id, type));
}, },
[navigate] [navigate]
); );
......
...@@ -12,6 +12,8 @@ import { CustomBreadcrumbs } from 'src/components/custom-breadcrumbs'; ...@@ -12,6 +12,8 @@ import { CustomBreadcrumbs } from 'src/components/custom-breadcrumbs';
import { DashboardContent } from 'src/layouts/dashboard'; import { DashboardContent } from 'src/layouts/dashboard';
import { paths } from 'src/routes/paths'; import { paths } from 'src/routes/paths';
import { import {
BUPOT_REFERENSI,
BUPOT_REFERENSI_TEXT,
FG_FASILITAS, FG_FASILITAS,
FG_FASILITAS_PPH_21, FG_FASILITAS_PPH_21,
FG_FASILITAS_PPH_21_TEXT, FG_FASILITAS_PPH_21_TEXT,
...@@ -212,6 +214,11 @@ export const FinalTidakFinalRekamView = () => { ...@@ -212,6 +214,11 @@ export const FinalTidakFinalRekamView = () => {
[] []
); );
const JnsDokRefOptions = Object.entries(BUPOT_REFERENSI).map(([key, value]) => ({
value,
label: BUPOT_REFERENSI_TEXT[value],
}));
const { data: existingBulanan, isLoading: isLoadingBulanan } = useGetBupotFinal({ const { data: existingBulanan, isLoading: isLoadingBulanan } = useGetBupotFinal({
params: { params: {
page: 1, page: 1,
...@@ -268,7 +275,10 @@ export const FinalTidakFinalRekamView = () => { ...@@ -268,7 +275,10 @@ export const FinalTidakFinalRekamView = () => {
defaultValues, defaultValues,
}); });
console.log('🚀 ~ FinalTidakFinalRekamView:', { data: methods.getValues() }); console.log('🚀 ~ FinalTidakFinalRekamView:', {
data: methods.getValues(),
error: methods.formState.errors,
});
useEffect(() => { useEffect(() => {
if ((isEdit || isPengganti) && existingBulanan.data.length !== 0 && kodeObjekPajakOption) { if ((isEdit || isPengganti) && existingBulanan.data.length !== 0 && kodeObjekPajakOption) {
...@@ -280,6 +290,9 @@ export const FinalTidakFinalRekamView = () => { ...@@ -280,6 +290,9 @@ export const FinalTidakFinalRekamView = () => {
const normalized = { const normalized = {
...dataResDetail, ...dataResDetail,
idBupot: '',
noBupot: '',
revNo: 0,
tglPemotongan: dataResDetail.tglpemotongan, tglPemotongan: dataResDetail.tglpemotongan,
tahunPajak: dataResDetail.tahunPajak, tahunPajak: dataResDetail.tahunPajak,
masaPajak: dataResDetail.masaPajak, masaPajak: dataResDetail.masaPajak,
...@@ -297,10 +310,14 @@ export const FinalTidakFinalRekamView = () => { ...@@ -297,10 +310,14 @@ export const FinalTidakFinalRekamView = () => {
fgFasilitas: fgFasilitasOptions.filter( fgFasilitas: fgFasilitasOptions.filter(
(val) => val.value === dataResDetail.sertifikatInsentifDipotong (val) => val.value === dataResDetail.sertifikatInsentifDipotong
)[0], )[0],
noDokLainnya: dataResDetail.nomorSertifikatInsentif,
ptkp: ptkpOptions.filter((val) => val.value === `${dataResDetail.statusPPh}`)[0], ptkp: ptkpOptions.filter((val) => val.value === `${dataResDetail.statusPPh}`)[0],
phBruto: dataResDetail.penghasilanKotor, phBruto: dataResDetail.penghasilanKotor,
tunjanganPPh: dataResDetail.tunjanganPPh || 0, tunjanganPPh: dataResDetail.tunjanganPPh || 0,
pph21: dataResDetail.pphDipotong, pph21: dataResDetail.pphDipotong,
namaDokumenReferensi: JnsDokRefOptions.filter(
(val) => val.value === dataResDetail.dokumen_referensi[0].dokReferensi
)[0] || { value: '', label: '' },
idTku: MockNitku.filter((val) => val.value === dataResDetail.idTku)[0], idTku: MockNitku.filter((val) => val.value === dataResDetail.idTku)[0],
}; };
...@@ -308,8 +325,8 @@ export const FinalTidakFinalRekamView = () => { ...@@ -308,8 +325,8 @@ export const FinalTidakFinalRekamView = () => {
if (isPengganti) { if (isPengganti) {
normalized['idBupot'] = dataResDetail.idBupot || ''; normalized['idBupot'] = dataResDetail.idBupot || '';
normalized['idBupot'] = dataResDetail.noBupot || ''; normalized['noBupot'] = dataResDetail.noBupot || '';
normalized['revNo'] = `${dataResDetail.revNo || 0}`; normalized['revNo'] = parseInt(`${dataResDetail.revNo}`, 10) || 0;
} }
methods.reset(normalized as any); methods.reset(normalized as any);
...@@ -324,14 +341,13 @@ export const FinalTidakFinalRekamView = () => { ...@@ -324,14 +341,13 @@ export const FinalTidakFinalRekamView = () => {
id: isEdit || isPengganti ? data.id : undefined, id: isEdit || isPengganti ? data.id : undefined,
statusPtkp: data.ptkp?.value || '', statusPtkp: data.ptkp?.value || '',
kdObjPjk: data.kdObjPjk.value, kdObjPjk: data.kdObjPjk.value,
namaDokumenReferensi: data.namaDokumenReferensi?.label, namaDokumenReferensi: data.namaDokumenReferensi?.value || '',
pphDipotong: data.pph21, pphDipotong: data.pph21,
fgFasilitas: data.fgFasilitas.value, fgFasilitas: data.fgFasilitas.value,
fgGrossUp: parseInt(data.fgPerhitungan || '1', 10), fgGrossUp: parseInt(data.fgPerhitungan || '1', 10),
idTku: data.idTku.value, idTku: data.idTku.value,
isPengganti, isPengganti,
}; };
console.log('🚀 ~ handleDraft:', { transformedData, data });
const response = await saveBupotFnlTdkFnl(transformedData); const response = await saveBupotFnlTdkFnl(transformedData);
...@@ -408,7 +424,7 @@ export const FinalTidakFinalRekamView = () => { ...@@ -408,7 +424,7 @@ export const FinalTidakFinalRekamView = () => {
<JumlahPerhitunganForm ptkpOptions={ptkpOptions} /> <JumlahPerhitunganForm ptkpOptions={ptkpOptions} />
<DokumenReferensi /> <DokumenReferensi JnsDokRefOptions={JnsDokRefOptions} />
<Grid size={12}> <Grid size={12}>
<Agreement <Agreement
......
...@@ -6,7 +6,7 @@ import { ...@@ -6,7 +6,7 @@ import {
import type { AxiosError } from 'axios'; import type { AxiosError } from 'axios';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { endpoints, fetcherCetakPDF } from 'src/lib/axios-ctas-box'; import { endpoints, fetcherCetakPDF } from 'src/lib/axios-ctas-box';
import { FG_FASILITAS_PPH_21_TEXT, KODE_OBJEK_PAJAK_TEXT } from './constant'; import { BUPOT_REFERENSI_TEXT, FG_FASILITAS_PPH_21_TEXT, KODE_OBJEK_PAJAK_TEXT } from './constant';
import queryKey from './constant/queryKey'; import queryKey from './constant/queryKey';
interface ApiCetakResponse { interface ApiCetakResponse {
...@@ -56,6 +56,7 @@ export interface transFromPramsCetakBupotFinalTidakFinalProps { ...@@ -56,6 +56,7 @@ export interface transFromPramsCetakBupotFinalTidakFinalProps {
statusPPh: string; statusPPh: string;
npwp: string; npwp: string;
namaDipotong: string; namaDipotong: string;
npwpDipotong: string;
nitkuDipotong: string; nitkuDipotong: string;
sertifikatInsentifDipotong: string; sertifikatInsentifDipotong: string;
kodeObjekPajak: string; kodeObjekPajak: string;
...@@ -178,6 +179,53 @@ const transformParamsBulanan = ({ ...@@ -178,6 +179,53 @@ const transformParamsBulanan = ({
link: '', link: '',
}); });
const kodeObjekPajakFinal = [
'21-100-27',
'21-100-29',
'21-100-31',
'21-100-37',
'21-401-01',
'21-401-02',
'21-402-02',
'21-402-03',
'21-402-04',
];
const transformParamsFinalTidakFinal = ({
keterangan1,
keterangan2,
keterangan3,
keterangan4,
...params
}: any): transFromPramsCetakBupotFinalTidakFinalProps => ({
...params,
noBupot: params.noBupot,
pasalPPh: 'Final/Tidak Fianl',
statusPPh: kodeObjekPajakFinal.includes(params.kdObjPjk) ? 'Final' : 'Tidak Final', // Final atau Tidak Final
status: 'Proforma',
npwpDipotong: params.npwp,
namaDipotong: params.nama,
nitkuDipotong: params.idDipotong,
sertifikatInsentifDipotong: FG_FASILITAS_PPH_21_TEXT[params.sertifikatInsentifDipotong],
nomorDokumen: params.nomorDokumenReferensi || '-',
tanggal_Dokumen: dayjs(params.tanggalDokumenReferensi).format('DD MM YYYY') || '-',
dokReferensi: BUPOT_REFERENSI_TEXT[params.namaDokumenReferensi] || '-',
namaObjekPajak: KODE_OBJEK_PAJAK_TEXT[params.kdObjPjk],
penghasilanBruto: params.penghasilanKotor,
tarif: `${params.tarif}`,
pphDipotong: `${params.pphDipotong}`,
npwpPemotong: params.npwpPemotong || '-',
namaPemotong: params.namaPemotong || '-',
nitkuPemotong: params.nitkuPemotong || '-',
tglPemotongan: dayjs(params.tglpemotongan).format('DD MMMM YYYY'),
namaPenandatangan: params.namaPenandatangan || '-',
nomorSertifikatInsentif: params.noDokLainnya,
metodePembayaranBendahara: 'metodePembayaranBendahara',
nomorSP2D: '',
qrcode: 'qrcode',
mixcode: 'mixcode',
});
const { bulanan, finalTidakFinal, tahunanA1 } = endpoints.cetak; const { bulanan, finalTidakFinal, tahunanA1 } = endpoints.cetak;
const cetakBulanan = async ( const cetakBulanan = async (
...@@ -205,7 +253,7 @@ const cetakFinalTidakFinal = async ( ...@@ -205,7 +253,7 @@ const cetakFinalTidakFinal = async (
finalTidakFinal, finalTidakFinal,
{ {
method: 'POST', method: 'POST',
data: params, data: transformParamsFinalTidakFinal(params),
}, },
]); ]);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment