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';
import { enqueueSnackbar } from 'notistack';
import { useEffect, useState } from 'react';
import DialogUmum from 'src/shared/components/dialog/DialogUmum';
import { useAppSelector } from 'src/store';
import { useCetakBulanan } from '../../../cetakpdf';
interface ModalCetakPdfDnProps {
......@@ -15,6 +16,7 @@ interface ModalCetakPdfDnProps {
const ModalCetakPdfBulanan: React.FC<ModalCetakPdfDnProps> = ({ payload, isOpen, onClose }) => {
const [pdfUrl, setPdfUrl] = useState<string | null>(null);
const [loading, setLoading] = useState<boolean>(false);
const AppSelector = useAppSelector((selector) => selector.user.data);
const { mutateAsync } = useCetakBulanan({
onError: (error: any) => {
......@@ -42,7 +44,13 @@ const ModalCetakPdfBulanan: React.FC<ModalCetakPdfDnProps> = ({ payload, isOpen,
try {
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) {
console.error('❌ Error cetak PDF:', err);
enqueueSnackbar('Gagal generate PDF', { variant: 'error' });
......
......@@ -4,7 +4,8 @@ import DialogContent from '@mui/material/DialogContent';
import { enqueueSnackbar } from 'notistack';
import { useEffect, useState } from 'react';
import DialogUmum from 'src/shared/components/dialog/DialogUmum';
import { useCetakBulanan } from '../../../cetakpdf';
import { useCetakFinalTidakFinal } from '../../../cetakpdf';
import { useAppSelector } from 'src/store';
interface ModalCetakPdfDnProps {
payload?: Record<string, any>;
......@@ -15,8 +16,9 @@ interface ModalCetakPdfDnProps {
const ModalCetakPdfBulanan: React.FC<ModalCetakPdfDnProps> = ({ payload, isOpen, onClose }) => {
const [pdfUrl, setPdfUrl] = useState<string | null>(null);
const [loading, setLoading] = useState<boolean>(false);
const AppSelector = useAppSelector((selector) => selector.user.data);
const { mutateAsync } = useCetakBulanan({
const { mutateAsync } = useCetakFinalTidakFinal({
onError: (error: any) => {
enqueueSnackbar(error?.message || 'Gagal memuat PDF', { variant: 'error' });
setLoading(false);
......@@ -42,7 +44,13 @@ const ModalCetakPdfBulanan: React.FC<ModalCetakPdfDnProps> = ({ payload, isOpen,
try {
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) {
console.error('❌ Error cetak PDF:', err);
enqueueSnackbar('Gagal generate PDF', { variant: 'error' });
......@@ -51,7 +59,7 @@ const ModalCetakPdfBulanan: React.FC<ModalCetakPdfDnProps> = ({ payload, isOpen,
};
runCetak();
}, [isOpen, payload, mutateAsync]);
}, [isOpen, payload, mutateAsync, AppSelector]);
return (
<DialogUmum
......
......@@ -2,19 +2,17 @@ import { Divider, Grid } from '@mui/material';
import dayjs from 'dayjs';
import { useFormContext } from 'react-hook-form';
import { Field } from 'src/components/hook-form';
import {
BUPOT_REFERENSI,
BUPOT_REFERENSI_TEXT,
MockNitku,
} from 'src/sections/bupot-21-26/constant';
import { MockNitku } from 'src/sections/bupot-21-26/constant';
function DokumenReferensi() {
function DokumenReferensi({
JnsDokRefOptions,
}: {
JnsDokRefOptions: {
value: string;
label: string;
}[];
}) {
const { setValue } = useFormContext();
const options = Object.entries(BUPOT_REFERENSI).map(([key, value]) => ({
value,
label: BUPOT_REFERENSI_TEXT[value],
}));
return (
<Grid container rowSpacing={2} alignItems="center" columnSpacing={2} sx={{ mb: 4 }}>
<Grid size={{ md: 12 }}>
......@@ -26,15 +24,12 @@ function DokumenReferensi() {
<Field.Autocomplete
name="namaDokumenReferensi"
label="Jenis Dokumen Referensi"
options={options}
options={JnsDokRefOptions}
onChange={(_, value) => setValue('namaDokumenReferensi', value)}
/>
</Grid>
<Grid size={{ md: 6 }}>
<Field.Text
name="nomorDokumenReferensi"
label="Nomor Dokumen Referensi"
/>
<Field.Text name="nomorDokumenReferensi" label="Nomor Dokumen Referensi" />
</Grid>
<Grid size={{ md: 6 }}>
<Field.DatePicker
......
......@@ -63,7 +63,7 @@ export const transformSortModelToSortApiPayload = (transformedModel: any) => ({
const normalisePropsGetBupotFinal = (params: TGetListDataTableBupotFinalResult[0]) => ({
...params,
namaDokumenReferensi: params.dokumen_referensi[0].dokReferensi,
namaDokumenReferensi: params.dokumen_referensi[0].dokReferensi || '',
nomorDokumenReferensi: params.dokumen_referensi[0].nomorDokumen,
tanggalDokumenReferensi: params.dokumen_referensi[0].tanggal_Dokumen,
fgSignStatus: transformFgStatusToFgSignStatus(params.fgStatus),
......@@ -76,6 +76,7 @@ const normalisPropsParmas = (params: any) => {
return {
...params,
revNo: parseInt(params.revNo, 10),
masaPajak: params.msPajak || null,
tahunPajak: params.thnPajak || null,
npwp: params.idDipotong || null,
......
......@@ -164,7 +164,7 @@ export type TGetListDataTableBupotFinalResult = {
id: number;
idBupot: null | string;
noBupot: null | string;
revNo:string;
revNo: number;
fgTransaction:string;
npwpPemotong:string;
namaPemotong: null | string;
......
......@@ -40,31 +40,32 @@ import ModalUploadBupotfinal from '../components/dialog/ModalUploadBupotFinal';
import { CustomToolbar } from '../components/table/CustomToolbar';
import { useAdvancedFilter } from '../hooks/useAdvancedFilter';
import useGetBupotfinal from '../hooks/useGetBupotFinal';
import { useKodeObjekPajak } from 'src/actions/master-data';
export type IColumnGrid = GridColDef & {
field:
| 'fgStatus'
| 'noBupot'
| 'masaPajak'
| 'tahunPajak'
| 'kodeObjekPajak'
| 'pasalPPh'
| 'npwp'
| 'nama'
| 'penghasilanKotor'
| 'pph21ditanggungperusahaan'
| 'pphDipotong'
| 'npwpPemotong'
| 'created'
| 'created_at'
| 'updated'
| 'updated_at'
| 'internal_id';
// | 'keterangan1'
// | 'keterangan2'
// | 'keterangan3'
// | 'keterangan4'
// | 'keterangan5';
| 'fgStatus'
| 'noBupot'
| 'masaPajak'
| 'tahunPajak'
| 'kodeObjekPajak'
| 'pasalPPh'
| 'npwp'
| 'nama'
| 'penghasilanKotor'
| 'pph21ditanggungperusahaan'
| 'pphDipotong'
| 'npwpPemotong'
| 'created'
| 'created_at'
| 'updated'
| 'updated_at'
| 'internal_id';
// | 'keterangan1'
// | 'keterangan2'
// | 'keterangan3'
// | 'keterangan4'
// | 'keterangan5';
valueOptions?: string[];
};
......@@ -95,7 +96,9 @@ const columns: IColumnGrid[] = [
const option = statusOptions.find((opt) => opt.value === params.value);
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',
......@@ -359,7 +362,7 @@ export function BupotfinalListView() {
enqueueSnackbar('Pilih data yang akan diubah', { variant: 'warning' });
return;
}
navigate(paths.pph21.bupotFinalEdit(selectedRow.id,type));
navigate(paths.pph21.bupotFinalEdit(selectedRow.id, type));
},
[navigate]
);
......
......@@ -12,6 +12,8 @@ import { CustomBreadcrumbs } from 'src/components/custom-breadcrumbs';
import { DashboardContent } from 'src/layouts/dashboard';
import { paths } from 'src/routes/paths';
import {
BUPOT_REFERENSI,
BUPOT_REFERENSI_TEXT,
FG_FASILITAS,
FG_FASILITAS_PPH_21,
FG_FASILITAS_PPH_21_TEXT,
......@@ -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({
params: {
page: 1,
......@@ -268,7 +275,10 @@ export const FinalTidakFinalRekamView = () => {
defaultValues,
});
console.log('🚀 ~ FinalTidakFinalRekamView:', { data: methods.getValues() });
console.log('🚀 ~ FinalTidakFinalRekamView:', {
data: methods.getValues(),
error: methods.formState.errors,
});
useEffect(() => {
if ((isEdit || isPengganti) && existingBulanan.data.length !== 0 && kodeObjekPajakOption) {
......@@ -280,6 +290,9 @@ export const FinalTidakFinalRekamView = () => {
const normalized = {
...dataResDetail,
idBupot: '',
noBupot: '',
revNo: 0,
tglPemotongan: dataResDetail.tglpemotongan,
tahunPajak: dataResDetail.tahunPajak,
masaPajak: dataResDetail.masaPajak,
......@@ -297,10 +310,14 @@ export const FinalTidakFinalRekamView = () => {
fgFasilitas: fgFasilitasOptions.filter(
(val) => val.value === dataResDetail.sertifikatInsentifDipotong
)[0],
noDokLainnya: dataResDetail.nomorSertifikatInsentif,
ptkp: ptkpOptions.filter((val) => val.value === `${dataResDetail.statusPPh}`)[0],
phBruto: dataResDetail.penghasilanKotor,
tunjanganPPh: dataResDetail.tunjanganPPh || 0,
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],
};
......@@ -308,8 +325,8 @@ export const FinalTidakFinalRekamView = () => {
if (isPengganti) {
normalized['idBupot'] = dataResDetail.idBupot || '';
normalized['idBupot'] = dataResDetail.noBupot || '';
normalized['revNo'] = `${dataResDetail.revNo || 0}`;
normalized['noBupot'] = dataResDetail.noBupot || '';
normalized['revNo'] = parseInt(`${dataResDetail.revNo}`, 10) || 0;
}
methods.reset(normalized as any);
......@@ -324,14 +341,13 @@ export const FinalTidakFinalRekamView = () => {
id: isEdit || isPengganti ? data.id : undefined,
statusPtkp: data.ptkp?.value || '',
kdObjPjk: data.kdObjPjk.value,
namaDokumenReferensi: data.namaDokumenReferensi?.label,
namaDokumenReferensi: data.namaDokumenReferensi?.value || '',
pphDipotong: data.pph21,
fgFasilitas: data.fgFasilitas.value,
fgGrossUp: parseInt(data.fgPerhitungan || '1', 10),
idTku: data.idTku.value,
isPengganti,
};
console.log('🚀 ~ handleDraft:', { transformedData, data });
const response = await saveBupotFnlTdkFnl(transformedData);
......@@ -408,7 +424,7 @@ export const FinalTidakFinalRekamView = () => {
<JumlahPerhitunganForm ptkpOptions={ptkpOptions} />
<DokumenReferensi />
<DokumenReferensi JnsDokRefOptions={JnsDokRefOptions} />
<Grid size={12}>
<Agreement
......
......@@ -6,7 +6,7 @@ import {
import type { AxiosError } from 'axios';
import dayjs from 'dayjs';
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';
interface ApiCetakResponse {
......@@ -56,6 +56,7 @@ export interface transFromPramsCetakBupotFinalTidakFinalProps {
statusPPh: string;
npwp: string;
namaDipotong: string;
npwpDipotong: string;
nitkuDipotong: string;
sertifikatInsentifDipotong: string;
kodeObjekPajak: string;
......@@ -178,6 +179,53 @@ const transformParamsBulanan = ({
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 cetakBulanan = async (
......@@ -205,7 +253,7 @@ const cetakFinalTidakFinal = async (
finalTidakFinal,
{
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