mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-21 13:55:45 +00:00
Merge branch 'development' of https://gitlab.com/mbugroup/lti-web-client into dev/randy
This commit is contained in:
@@ -48,6 +48,13 @@ const ExpenseRealizationContent = ({
|
||||
|
||||
const realizationDocumentsChangeHandler = (val: File[]) => {
|
||||
formik.setFieldTouched('documents', true);
|
||||
|
||||
const invalidFiles = val.filter((file) => file.size > 5 * 1024 * 1024);
|
||||
if (invalidFiles.length > 0) {
|
||||
toast.error('Ukuran dokumen maksimal 5 MB!');
|
||||
return;
|
||||
}
|
||||
|
||||
formik.setFieldValue('documents', val);
|
||||
};
|
||||
|
||||
|
||||
@@ -251,6 +251,13 @@ const ExpenseRequestContent = ({
|
||||
|
||||
const requestDocumentsChangeHandler = (val: File[]) => {
|
||||
formik.setFieldTouched('documents', true);
|
||||
|
||||
const invalidFiles = val.filter((file) => file.size > 5 * 1024 * 1024);
|
||||
if (invalidFiles.length > 0) {
|
||||
toast.error('Ukuran dokumen maksimal 5 MB!');
|
||||
return;
|
||||
}
|
||||
|
||||
formik.setFieldValue('documents', val);
|
||||
};
|
||||
|
||||
|
||||
@@ -39,6 +39,10 @@ const ExpenseStatusBadge = ({ approval }: ExpenseStatusBadgeProps) => {
|
||||
case 5:
|
||||
expenseStatusPillBadgeColor = 'green';
|
||||
break;
|
||||
|
||||
case 6:
|
||||
expenseStatusPillBadgeColor = 'green';
|
||||
break;
|
||||
}
|
||||
|
||||
if (isLatestApprovalRejected) {
|
||||
|
||||
@@ -223,6 +223,13 @@ const ExpenseRealizationForm = ({
|
||||
|
||||
const realizationDocumentsChangeHandler = (val: File[]) => {
|
||||
formik.setFieldTouched('documents', true);
|
||||
|
||||
const invalidFiles = val.filter((file) => file.size > 5 * 1024 * 1024);
|
||||
if (invalidFiles.length > 0) {
|
||||
toast.error('Ukuran dokumen maksimal 5 MB!');
|
||||
return;
|
||||
}
|
||||
|
||||
formik.setFieldValue('documents', val);
|
||||
};
|
||||
|
||||
|
||||
@@ -31,7 +31,10 @@ import { MarketingReportApi } from '@/services/api/report/marketing-report';
|
||||
import { MARKETING_TYPE_OPTIONS } from '@/config/constant';
|
||||
import { httpClient } from '@/services/http/client';
|
||||
import { BaseApiResponse } from '@/types/api/api-general';
|
||||
import { DailyMarketingReport } from '@/types/api/report/marketing';
|
||||
import {
|
||||
DailyMarketingReport,
|
||||
DailyMarketingReportResponse,
|
||||
} from '@/types/api/report/marketing';
|
||||
import { isResponseError } from '@/lib/api-helper';
|
||||
|
||||
const DailyMarketingReportContent = () => {
|
||||
@@ -191,9 +194,10 @@ const DailyMarketingReportContent = () => {
|
||||
const queryString = `?${params.toString()}`;
|
||||
|
||||
try {
|
||||
const dailyMarketingsReport = await httpClient<
|
||||
BaseApiResponse<DailyMarketingReport>
|
||||
>(`${MarketingReportApi.basePath}${queryString}`);
|
||||
const dailyMarketingsReport =
|
||||
await httpClient<DailyMarketingReportResponse>(
|
||||
`${MarketingReportApi.basePath}${queryString}`
|
||||
);
|
||||
|
||||
if (isResponseError(dailyMarketingsReport)) {
|
||||
toast.error('Gagal melakukan export penjualan harian! Coba lagi.');
|
||||
@@ -202,7 +206,10 @@ const DailyMarketingReportContent = () => {
|
||||
|
||||
const openPdf = async () => {
|
||||
const dailyMarketingReportPdfBlob = await pdf(
|
||||
<DailyMarketingReportPDF data={dailyMarketingsReport.data} />
|
||||
<DailyMarketingReportPDF
|
||||
data={dailyMarketingsReport.data}
|
||||
total={dailyMarketingsReport.total}
|
||||
/>
|
||||
).toBlob();
|
||||
|
||||
const dailyMarketingReportPdfUrl = URL.createObjectURL(
|
||||
@@ -213,7 +220,10 @@ const DailyMarketingReportContent = () => {
|
||||
|
||||
const downloadPdf = async () => {
|
||||
const blob = await pdf(
|
||||
<DailyMarketingReportPDF data={dailyMarketingsReport.data} />
|
||||
<DailyMarketingReportPDF
|
||||
data={dailyMarketingsReport.data}
|
||||
total={dailyMarketingsReport.total}
|
||||
/>
|
||||
).toBlob();
|
||||
const url = URL.createObjectURL(blob);
|
||||
|
||||
|
||||
@@ -9,11 +9,15 @@ import {
|
||||
View,
|
||||
} from '@react-pdf/renderer';
|
||||
|
||||
import { DailyMarketingReport } from '@/types/api/report/marketing';
|
||||
import {
|
||||
DailyMarketingReport,
|
||||
SalesSummary,
|
||||
} from '@/types/api/report/marketing';
|
||||
import { formatCurrency, formatDate, formatNumber } from '@/lib/helper';
|
||||
|
||||
interface DailyMarketingReportPDFProps {
|
||||
data?: DailyMarketingReport;
|
||||
total?: SalesSummary;
|
||||
}
|
||||
|
||||
const DailyMarketingReportPDFStyle = StyleSheet.create({
|
||||
@@ -267,9 +271,12 @@ const DailyMarketingReportPDFStyle = StyleSheet.create({
|
||||
},
|
||||
});
|
||||
|
||||
const DailyMarketingReportPDF = ({ data }: DailyMarketingReportPDFProps) => {
|
||||
const rows = data?.rows || [];
|
||||
const summary = data?.summary;
|
||||
const DailyMarketingReportPDF = ({
|
||||
data,
|
||||
total,
|
||||
}: DailyMarketingReportPDFProps) => {
|
||||
const rows = data || [];
|
||||
const summary = total;
|
||||
|
||||
return (
|
||||
<Document>
|
||||
@@ -409,7 +416,7 @@ const DailyMarketingReportPDF = ({ data }: DailyMarketingReportPDFProps) => {
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colDoDate}>
|
||||
<Text style={DailyMarketingReportPDFStyle.cellText}>
|
||||
{formatDate(row.do_date, 'DD/MM/YYYY')}
|
||||
{formatDate(row.realization_date, 'DD/MM/YYYY')}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colAging}>
|
||||
@@ -429,7 +436,7 @@ const DailyMarketingReportPDF = ({ data }: DailyMarketingReportPDFProps) => {
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colSales}>
|
||||
<Text style={DailyMarketingReportPDFStyle.cellText}>
|
||||
{row.sales}
|
||||
{row.sales.name}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={DailyMarketingReportPDFStyle.colProduct}>
|
||||
@@ -518,6 +525,19 @@ const DailyMarketingReportPDF = ({ data }: DailyMarketingReportPDFProps) => {
|
||||
{formatCurrency(summary?.total_sales_amount ?? 0)}
|
||||
</Text>
|
||||
</View>
|
||||
<View
|
||||
style={[
|
||||
DailyMarketingReportPDFStyle.summaryRow,
|
||||
{ borderBottomWidth: 0 },
|
||||
]}
|
||||
>
|
||||
<Text style={DailyMarketingReportPDFStyle.summaryLabel}>
|
||||
Total HPP Per KG:
|
||||
</Text>
|
||||
<Text style={DailyMarketingReportPDFStyle.summaryValue}>
|
||||
{formatCurrency(summary?.total_hpp_price_per_kg ?? 0)}
|
||||
</Text>
|
||||
</View>
|
||||
<View
|
||||
style={[
|
||||
DailyMarketingReportPDFStyle.summaryRow,
|
||||
|
||||
@@ -60,9 +60,10 @@ const DailyMarketingsTable = ({
|
||||
footer: 'Total',
|
||||
},
|
||||
{
|
||||
accessorKey: 'do_date',
|
||||
header: 'Tanggal DO',
|
||||
cell: (props) => formatDate(props.row.original.do_date, 'DD-MMM-YYYY'),
|
||||
accessorKey: 'realization_date',
|
||||
header: 'Tanggal Realisasi',
|
||||
cell: (props) =>
|
||||
formatDate(props.row.original.realization_date, 'DD-MMM-YYYY'),
|
||||
},
|
||||
{
|
||||
accessorKey: 'aging_days',
|
||||
@@ -84,6 +85,7 @@ const DailyMarketingsTable = ({
|
||||
{
|
||||
accessorKey: 'sales',
|
||||
header: 'Sales/Marketing',
|
||||
cell: (props) => props.row.original.sales.name,
|
||||
},
|
||||
{
|
||||
accessorKey: 'vehicle_number',
|
||||
@@ -106,10 +108,10 @@ const DailyMarketingsTable = ({
|
||||
cell: (props) => formatNumber(props.row.original.qty),
|
||||
footer: () => {
|
||||
const totalQty = isResponseSuccess(dailyMarketings)
|
||||
? dailyMarketings.data.summary.total_qty
|
||||
? dailyMarketings?.total?.total_qty
|
||||
: 0;
|
||||
|
||||
return formatNumber(totalQty);
|
||||
return totalQty ? formatNumber(totalQty) : '-';
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -123,10 +125,10 @@ const DailyMarketingsTable = ({
|
||||
cell: (props) => formatNumber(props.row.original.total_weight_kg),
|
||||
footer: () => {
|
||||
const totalWeightKg = isResponseSuccess(dailyMarketings)
|
||||
? dailyMarketings.data.summary.total_weight_kg
|
||||
? dailyMarketings?.total?.total_weight_kg
|
||||
: 0;
|
||||
|
||||
return formatNumber(totalWeightKg);
|
||||
return totalWeightKg ? formatNumber(totalWeightKg) : '-';
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -138,6 +140,13 @@ const DailyMarketingsTable = ({
|
||||
accessorKey: 'hpp_price_per_kg',
|
||||
header: 'HPP (Rp)',
|
||||
cell: (props) => formatCurrency(props.row.original.hpp_price_per_kg),
|
||||
footer: () => {
|
||||
const totalHppPricePerKg = isResponseSuccess(dailyMarketings)
|
||||
? dailyMarketings?.total?.total_hpp_price_per_kg
|
||||
: 0;
|
||||
|
||||
return totalHppPricePerKg ? formatCurrency(totalHppPricePerKg) : '-';
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: 'sales_amount',
|
||||
@@ -145,10 +154,10 @@ const DailyMarketingsTable = ({
|
||||
cell: (props) => formatCurrency(props.row.original.sales_amount),
|
||||
footer: () => {
|
||||
const totalSalesAmount = isResponseSuccess(dailyMarketings)
|
||||
? dailyMarketings.data.summary.total_sales_amount
|
||||
? dailyMarketings?.total?.total_sales_amount
|
||||
: 0;
|
||||
|
||||
return formatCurrency(totalSalesAmount);
|
||||
return totalSalesAmount ? formatCurrency(totalSalesAmount) : '-';
|
||||
},
|
||||
},
|
||||
];
|
||||
@@ -167,7 +176,7 @@ const DailyMarketingsTable = ({
|
||||
if (!open) {
|
||||
setOpen(
|
||||
isResponseSuccess(dailyMarketings)
|
||||
? dailyMarketings.data.rows.length > 0
|
||||
? dailyMarketings.data.length > 0
|
||||
: false
|
||||
);
|
||||
}
|
||||
@@ -215,9 +224,7 @@ const DailyMarketingsTable = ({
|
||||
|
||||
<Table<DailyMarketingRow>
|
||||
data={
|
||||
isResponseSuccess(dailyMarketings)
|
||||
? dailyMarketings?.data.rows
|
||||
: []
|
||||
isResponseSuccess(dailyMarketings) ? dailyMarketings?.data : []
|
||||
}
|
||||
columns={dailyMarketingColumns}
|
||||
pageSize={pageSize}
|
||||
@@ -242,7 +249,7 @@ const DailyMarketingsTable = ({
|
||||
containerClassName: cn({
|
||||
'w-full mb-20':
|
||||
isResponseSuccess(dailyMarketings) &&
|
||||
dailyMarketings?.data?.rows.length === 0,
|
||||
dailyMarketings?.data?.length === 0,
|
||||
}),
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -161,10 +161,7 @@ const createPDFDocument = (params: CustomerPaymentExportPDFParams) => {
|
||||
{customerReport.customer.name}
|
||||
</Text>
|
||||
<Text style={pdfStyles.supplierInfo}>
|
||||
{customerReport.customer_address || ''}
|
||||
</Text>
|
||||
<Text style={pdfStyles.supplierInfo}>
|
||||
NPWP: {customerReport.customer_npwp || '-'}
|
||||
{customerReport.customer.address || ''}
|
||||
</Text>
|
||||
{customerReport.summary && (
|
||||
<Text style={pdfStyles.supplierInfo}>
|
||||
@@ -266,7 +263,9 @@ const createPDFDocument = (params: CustomerPaymentExportPDFParams) => {
|
||||
</Text>
|
||||
</View>
|
||||
<View style={[pdfStyles.tableCellCenter, { flex: 0.8 }]}>
|
||||
<Text>{formatNumber(item.aging)} hari</Text>
|
||||
<Text>
|
||||
{item.aging_day ? formatNumber(item.aging_day) : '-'} hari
|
||||
</Text>
|
||||
</View>
|
||||
<View style={[pdfStyles.tableCell, { flex: 1 }]}>
|
||||
<Text>{item.reference || '-'}</Text>
|
||||
|
||||
@@ -30,9 +30,11 @@ export const generateCustomerPaymentExcel = (
|
||||
'Tanggal Realisasi': item.realization_date
|
||||
? formatDate(item.realization_date, 'DD MMM YYYY')
|
||||
: '',
|
||||
Aging: formatNumber(item.aging || 0),
|
||||
Aging: formatNumber(item.aging_day || 0),
|
||||
Referensi: item.reference || '',
|
||||
'Nomor Polisi': item.vehicle_plate || '',
|
||||
'Nomor Polisi': Array.isArray(item.vehicle_plate)
|
||||
? item.vehicle_plate.join(', ')
|
||||
: '',
|
||||
'Ekor/Qty': formatNumber(item.qty || 0),
|
||||
'Berat (Kg)': formatNumber(item.weight || 0),
|
||||
AVG: formatNumber(item.average_weight || 0),
|
||||
|
||||
@@ -279,10 +279,14 @@ const CustomerPaymentTab = () => {
|
||||
{
|
||||
id: 'aging',
|
||||
header: 'Aging',
|
||||
accessorKey: 'aging',
|
||||
accessorKey: 'aging_day',
|
||||
cell: (props) => {
|
||||
const value = props.row.original.aging;
|
||||
return <div className='text-center'>{formatNumber(value)} hari</div>;
|
||||
const value = props.row.original.aging_day;
|
||||
return (
|
||||
<div className='text-center'>
|
||||
{value ? formatNumber(value) : '-'} hari
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -662,7 +666,7 @@ const CustomerPaymentTab = () => {
|
||||
<Card
|
||||
key={customerReport.customer.id}
|
||||
title={customerReport.customer.name}
|
||||
subtitle={`NPWP: ${customerReport.customer_npwp || '-'} | ${customerReport.customer_address || ''}\nSaldo Piutang: ${formatCurrency(totalAccountsReceivable)}`}
|
||||
subtitle={`${customerReport.customer.address || ''}\nSaldo Piutang: ${formatCurrency(totalAccountsReceivable)}`}
|
||||
className={{ wrapper: 'w-full' }}
|
||||
variant='bordered'
|
||||
collapsible={true}
|
||||
|
||||
Reference in New Issue
Block a user