mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-24 23:35:45 +00:00
refactor(FE-361,363,364): Use per-supplier report arrays for export
This commit is contained in:
@@ -15,7 +15,10 @@ import { LogisticApi } from '@/services/api/report/logistic-stock';
|
|||||||
import Table from '@/components/Table';
|
import Table from '@/components/Table';
|
||||||
import { ColumnDef } from '@tanstack/react-table';
|
import { ColumnDef } from '@tanstack/react-table';
|
||||||
import { formatCurrency, formatDate, formatNumber } from '@/lib/helper';
|
import { formatCurrency, formatDate, formatNumber } from '@/lib/helper';
|
||||||
import { LogisticPurchasePerSupplierReport } from '@/types/api/report/logistic-stock';
|
import {
|
||||||
|
LogisticPurchasePerSupplierReport,
|
||||||
|
LogisticPurchasePerSupplierSummary,
|
||||||
|
} from '@/types/api/report/logistic-stock';
|
||||||
import { isResponseSuccess } from '@/lib/api-helper';
|
import { isResponseSuccess } from '@/lib/api-helper';
|
||||||
import { useTableFilter } from '@/services/hooks/useTableFilter';
|
import { useTableFilter } from '@/services/hooks/useTableFilter';
|
||||||
import Pagination from '@/components/Pagination';
|
import Pagination from '@/components/Pagination';
|
||||||
@@ -26,22 +29,6 @@ import Menu from '@/components/menu/Menu';
|
|||||||
import { generatePurchasesPerSupplierPDF } from '@/components/pages/report/logistic-stock/export/PurchasesPerSupplierExport';
|
import { generatePurchasesPerSupplierPDF } from '@/components/pages/report/logistic-stock/export/PurchasesPerSupplierExport';
|
||||||
import toast from 'react-hot-toast';
|
import toast from 'react-hot-toast';
|
||||||
import * as XLSX from 'xlsx';
|
import * as XLSX from 'xlsx';
|
||||||
import { Supplier } from '@/types/api/master-data/supplier';
|
|
||||||
|
|
||||||
interface Totals {
|
|
||||||
total_qty: number;
|
|
||||||
total_price: number;
|
|
||||||
total_purchase_amount: number;
|
|
||||||
total_transport: number;
|
|
||||||
total_value_transport: number;
|
|
||||||
total_jumlah: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface GroupedSupplierData {
|
|
||||||
id: number;
|
|
||||||
supplier: Supplier;
|
|
||||||
items: LogisticPurchasePerSupplierReport['rows'];
|
|
||||||
}
|
|
||||||
|
|
||||||
const PurchasesPerSupplierTab = () => {
|
const PurchasesPerSupplierTab = () => {
|
||||||
// ===== STATE MANAGEMENT =====
|
// ===== STATE MANAGEMENT =====
|
||||||
@@ -279,11 +266,11 @@ const PurchasesPerSupplierTab = () => {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
const data: LogisticPurchasePerSupplierReport['rows'] = useMemo(
|
const data: LogisticPurchasePerSupplierReport[] = useMemo(
|
||||||
() =>
|
() =>
|
||||||
isResponseSuccess(purchasePerSupplier)
|
isResponseSuccess(purchasePerSupplier)
|
||||||
? (purchasePerSupplier?.data
|
? (purchasePerSupplier?.data as unknown as LogisticPurchasePerSupplierReport[]) ||
|
||||||
?.rows as LogisticPurchasePerSupplierReport['rows']) || []
|
[]
|
||||||
: [],
|
: [],
|
||||||
[purchasePerSupplier]
|
[purchasePerSupplier]
|
||||||
);
|
);
|
||||||
@@ -294,58 +281,61 @@ const PurchasesPerSupplierTab = () => {
|
|||||||
: null;
|
: null;
|
||||||
|
|
||||||
// ===== EXPORT DATA FETCHER =====
|
// ===== EXPORT DATA FETCHER =====
|
||||||
const logisticPurchasePerSupplierExport =
|
const logisticPurchasePerSupplierExport = useCallback(async (): Promise<
|
||||||
useCallback(async (): Promise<LogisticPurchasePerSupplierReport | null> => {
|
LogisticPurchasePerSupplierReport[] | null
|
||||||
const params = {
|
> => {
|
||||||
area_id:
|
const params = {
|
||||||
tableFilterState.area_id.length > 0
|
area_id:
|
||||||
? tableFilterState.area_id.join(',')
|
tableFilterState.area_id.length > 0
|
||||||
: undefined,
|
? tableFilterState.area_id.join(',')
|
||||||
supplier_id:
|
: undefined,
|
||||||
tableFilterState.supplier_id.length > 0
|
supplier_id:
|
||||||
? tableFilterState.supplier_id.join(',')
|
tableFilterState.supplier_id.length > 0
|
||||||
: undefined,
|
? tableFilterState.supplier_id.join(',')
|
||||||
product_id:
|
: undefined,
|
||||||
tableFilterState.product_id.length > 0
|
product_id:
|
||||||
? tableFilterState.product_id.join(',')
|
tableFilterState.product_id.length > 0
|
||||||
: undefined,
|
? tableFilterState.product_id.join(',')
|
||||||
product_category_id:
|
: undefined,
|
||||||
tableFilterState.product_category_id.length > 0
|
product_category_id:
|
||||||
? tableFilterState.product_category_id.join(',')
|
tableFilterState.product_category_id.length > 0
|
||||||
: undefined,
|
? tableFilterState.product_category_id.join(',')
|
||||||
received_date:
|
: undefined,
|
||||||
tableFilterState.filter_by === 'received_date'
|
received_date:
|
||||||
? tableFilterState.start_date || undefined
|
tableFilterState.filter_by === 'received_date'
|
||||||
: undefined,
|
? tableFilterState.start_date || undefined
|
||||||
po_date:
|
: undefined,
|
||||||
tableFilterState.filter_by === 'po_date'
|
po_date:
|
||||||
? tableFilterState.start_date || undefined
|
tableFilterState.filter_by === 'po_date'
|
||||||
: undefined,
|
? tableFilterState.start_date || undefined
|
||||||
start_date: tableFilterState.start_date || undefined,
|
: undefined,
|
||||||
end_date: tableFilterState.end_date || undefined,
|
start_date: tableFilterState.start_date || undefined,
|
||||||
sort_by: tableFilterState.sort_by || undefined,
|
end_date: tableFilterState.end_date || undefined,
|
||||||
filter_by: tableFilterState.filter_by || undefined,
|
sort_by: tableFilterState.sort_by || undefined,
|
||||||
limit: 10000,
|
filter_by: tableFilterState.filter_by || undefined,
|
||||||
page: 1,
|
limit: 10000,
|
||||||
};
|
page: 1,
|
||||||
|
};
|
||||||
|
|
||||||
const response = await LogisticApi.getLogisticPurchasePerSupplierReport(
|
const response = await LogisticApi.getLogisticPurchasePerSupplierReport(
|
||||||
params.area_id,
|
params.area_id,
|
||||||
params.supplier_id,
|
params.supplier_id,
|
||||||
params.product_id,
|
params.product_id,
|
||||||
params.product_category_id,
|
params.product_category_id,
|
||||||
params.received_date,
|
params.received_date,
|
||||||
params.po_date,
|
params.po_date,
|
||||||
params.start_date,
|
params.start_date,
|
||||||
params.end_date,
|
params.end_date,
|
||||||
params.sort_by,
|
params.sort_by,
|
||||||
params.filter_by,
|
params.filter_by,
|
||||||
params.page,
|
params.page,
|
||||||
params.limit
|
params.limit
|
||||||
);
|
);
|
||||||
|
|
||||||
return isResponseSuccess(response) ? response.data : null;
|
return isResponseSuccess(response)
|
||||||
}, [tableFilterState]);
|
? (response.data as unknown as LogisticPurchasePerSupplierReport[])
|
||||||
|
: null;
|
||||||
|
}, [tableFilterState]);
|
||||||
|
|
||||||
// ===== EXPORT HANDLERS =====
|
// ===== EXPORT HANDLERS =====
|
||||||
const handleExportExcel = useCallback(async () => {
|
const handleExportExcel = useCallback(async () => {
|
||||||
@@ -355,73 +345,43 @@ const PurchasesPerSupplierTab = () => {
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
!allDataForExport ||
|
!allDataForExport ||
|
||||||
!allDataForExport?.rows ||
|
!Array.isArray(allDataForExport) ||
|
||||||
allDataForExport.rows.length === 0
|
allDataForExport.length === 0
|
||||||
) {
|
) {
|
||||||
toast.error('Tidak ada data untuk diekspor.');
|
toast.error('Tidak ada data untuk diekspor.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const allExportData =
|
|
||||||
allDataForExport.rows as LogisticPurchasePerSupplierReport['rows'];
|
|
||||||
const groupedBySupplier: { [key: string]: typeof allExportData } = {};
|
|
||||||
|
|
||||||
allExportData.forEach((item) => {
|
|
||||||
const supplierName = item.supplier?.name || 'Unknown Supplier';
|
|
||||||
if (!groupedBySupplier[supplierName]) {
|
|
||||||
groupedBySupplier[supplierName] = [];
|
|
||||||
}
|
|
||||||
groupedBySupplier[supplierName].push(item);
|
|
||||||
});
|
|
||||||
|
|
||||||
const workbook = XLSX.utils.book_new();
|
const workbook = XLSX.utils.book_new();
|
||||||
|
|
||||||
Object.entries(groupedBySupplier).forEach(
|
allDataForExport.forEach((supplierReport) => {
|
||||||
([supplierName, supplierData]) => {
|
const supplierData = supplierReport.rows;
|
||||||
const totals = supplierData.reduce(
|
const supplierName =
|
||||||
(acc, item) => ({
|
supplierReport.supplier?.name || 'Unknown Supplier';
|
||||||
total_qty: acc.total_qty + (item.qty || 0),
|
|
||||||
total_price: acc.total_price + (item.unit_price || 0),
|
|
||||||
total_purchase_amount:
|
|
||||||
acc.total_purchase_amount + (item.purchase_value || 0),
|
|
||||||
total_transport:
|
|
||||||
acc.total_transport + (item.transport_unit_price || 0),
|
|
||||||
total_value_transport:
|
|
||||||
acc.total_value_transport + (item.transport_value || 0),
|
|
||||||
total_jumlah: acc.total_jumlah + (item.total_amount || 0),
|
|
||||||
}),
|
|
||||||
{
|
|
||||||
total_qty: 0,
|
|
||||||
total_price: 0,
|
|
||||||
total_purchase_amount: 0,
|
|
||||||
total_transport: 0,
|
|
||||||
total_value_transport: 0,
|
|
||||||
total_jumlah: 0,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const excelData: { [key: string]: string | number }[] =
|
const excelData: { [key: string]: string | number }[] =
|
||||||
supplierData.map((item, index) => ({
|
supplierData.map((item, index) => ({
|
||||||
No: index + 1,
|
No: index + 1,
|
||||||
'Tanggal Terima': item.receive_date
|
'Tanggal Terima': item.receive_date
|
||||||
? formatDate(item.receive_date, 'DD MMM YYYY')
|
? formatDate(item.receive_date, 'DD MMM YYYY')
|
||||||
: '',
|
: '',
|
||||||
'Tanggal PO': item.po_date
|
'Tanggal PO': item.po_date
|
||||||
? formatDate(item.po_date, 'DD MMM YYYY')
|
? formatDate(item.po_date, 'DD MMM YYYY')
|
||||||
: '',
|
: '',
|
||||||
'No. Referensi': item.po_number || '',
|
'No. Referensi': item.po_number || '',
|
||||||
'Nama Produk': item.product?.name || '',
|
'Nama Produk': item.product?.name || '',
|
||||||
Tujuan: item.warehouse?.name || '',
|
Tujuan: item.warehouse?.name || '',
|
||||||
QTY: item.qty || 0,
|
QTY: item.qty || 0,
|
||||||
'Harga Beli (Rp)': item.unit_price || 0,
|
'Harga Beli (Rp)': item.unit_price || 0,
|
||||||
'Value Harga Beli (Rp)': item.purchase_value || 0,
|
'Value Harga Beli (Rp)': item.purchase_value || 0,
|
||||||
'Transport (Rp)': item.transport_unit_price || 0,
|
'Transport (Rp)': item.transport_unit_price || 0,
|
||||||
'Value Transport (Rp)': item.transport_value || 0,
|
'Value Transport (Rp)': item.transport_value || 0,
|
||||||
'Jumlah (Rp)': item.total_amount || 0,
|
'Jumlah (Rp)': item.total_amount || 0,
|
||||||
Ekspedisi: item.expedition || '',
|
Ekspedisi: item.expedition || '',
|
||||||
'Surat Jalan': item.delivery_number || '',
|
'Surat Jalan': item.delivery_number || '',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
if (supplierReport.summary) {
|
||||||
excelData.push({
|
excelData.push({
|
||||||
No: 'Total',
|
No: 'Total',
|
||||||
'Tanggal Terima': '',
|
'Tanggal Terima': '',
|
||||||
@@ -429,43 +389,45 @@ const PurchasesPerSupplierTab = () => {
|
|||||||
'No. Referensi': '',
|
'No. Referensi': '',
|
||||||
'Nama Produk': '',
|
'Nama Produk': '',
|
||||||
Tujuan: '',
|
Tujuan: '',
|
||||||
QTY: totals.total_qty,
|
QTY: supplierReport.summary.total_qty || 0,
|
||||||
'Harga Beli (Rp)': totals.total_price,
|
'Harga Beli (Rp)': '',
|
||||||
'Value Harga Beli (Rp)': totals.total_purchase_amount,
|
'Value Harga Beli (Rp)':
|
||||||
'Transport (Rp)': totals.total_transport,
|
supplierReport.summary.total_purchase_value || 0,
|
||||||
'Value Transport (Rp)': totals.total_value_transport,
|
'Transport (Rp)': '',
|
||||||
'Jumlah (Rp)': totals.total_jumlah,
|
'Value Transport (Rp)':
|
||||||
|
supplierReport.summary.total_transport_value || 0,
|
||||||
|
'Jumlah (Rp)': supplierReport.summary.total_amount || 0,
|
||||||
Ekspedisi: '',
|
Ekspedisi: '',
|
||||||
'Surat Jalan': '',
|
'Surat Jalan': '',
|
||||||
});
|
});
|
||||||
|
|
||||||
const worksheet = XLSX.utils.json_to_sheet(excelData);
|
|
||||||
|
|
||||||
const colWidths = [
|
|
||||||
{ wch: 5 }, // No
|
|
||||||
{ wch: 15 }, // Tanggal Terima
|
|
||||||
{ wch: 15 }, // Tanggal PO
|
|
||||||
{ wch: 15 }, // No. Referensi
|
|
||||||
{ wch: 30 }, // Nama Produk
|
|
||||||
{ wch: 20 }, // Tujuan
|
|
||||||
{ wch: 10 }, // QTY
|
|
||||||
{ wch: 18 }, // Harga Beli
|
|
||||||
{ wch: 20 }, // Value Harga Beli
|
|
||||||
{ wch: 15 }, // Transport
|
|
||||||
{ wch: 20 }, // Value Transport
|
|
||||||
{ wch: 18 }, // Jumlah
|
|
||||||
{ wch: 15 }, // Ekspedisi
|
|
||||||
{ wch: 15 }, // Surat Jalan
|
|
||||||
];
|
|
||||||
worksheet['!cols'] = colWidths;
|
|
||||||
|
|
||||||
const sheetName =
|
|
||||||
supplierName.length > 31
|
|
||||||
? supplierName.substring(0, 31)
|
|
||||||
: supplierName;
|
|
||||||
XLSX.utils.book_append_sheet(workbook, worksheet, sheetName);
|
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
const worksheet = XLSX.utils.json_to_sheet(excelData);
|
||||||
|
|
||||||
|
const colWidths = [
|
||||||
|
{ wch: 5 }, // No
|
||||||
|
{ wch: 15 }, // Tanggal Terima
|
||||||
|
{ wch: 15 }, // Tanggal PO
|
||||||
|
{ wch: 15 }, // No. Referensi
|
||||||
|
{ wch: 30 }, // Nama Produk
|
||||||
|
{ wch: 20 }, // Tujuan
|
||||||
|
{ wch: 10 }, // QTY
|
||||||
|
{ wch: 18 }, // Harga Beli
|
||||||
|
{ wch: 20 }, // Value Harga Beli
|
||||||
|
{ wch: 15 }, // Transport
|
||||||
|
{ wch: 20 }, // Value Transport
|
||||||
|
{ wch: 18 }, // Jumlah
|
||||||
|
{ wch: 15 }, // Ekspedisi
|
||||||
|
{ wch: 15 }, // Surat Jalan
|
||||||
|
];
|
||||||
|
worksheet['!cols'] = colWidths;
|
||||||
|
|
||||||
|
const sheetName =
|
||||||
|
supplierName.length > 31
|
||||||
|
? supplierName.substring(0, 31)
|
||||||
|
: supplierName;
|
||||||
|
XLSX.utils.book_append_sheet(workbook, worksheet, sheetName);
|
||||||
|
});
|
||||||
|
|
||||||
const filename = `laporan-pembelian-per-supplier-dicetak-pada-${formatDate(new Date(), 'YYYY-MM-DD-HHmm')}.xlsx`;
|
const filename = `laporan-pembelian-per-supplier-dicetak-pada-${formatDate(new Date(), 'YYYY-MM-DD-HHmm')}.xlsx`;
|
||||||
|
|
||||||
@@ -490,12 +452,17 @@ const PurchasesPerSupplierTab = () => {
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
!allDataForExport ||
|
!allDataForExport ||
|
||||||
!allDataForExport?.rows ||
|
!Array.isArray(allDataForExport) ||
|
||||||
allDataForExport.rows.length === 0
|
allDataForExport.length === 0
|
||||||
) {
|
) {
|
||||||
toast.error('Tidak ada data untuk diekspor.');
|
toast.error('Tidak ada data untuk diekspor.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const allRows = allDataForExport.flatMap(
|
||||||
|
(supplierReport) => supplierReport.rows
|
||||||
|
);
|
||||||
|
|
||||||
const areaName =
|
const areaName =
|
||||||
tableFilterState.area_id.length > 0
|
tableFilterState.area_id.length > 0
|
||||||
? tableFilterState.area_id
|
? tableFilterState.area_id
|
||||||
@@ -551,10 +518,7 @@ const PurchasesPerSupplierTab = () => {
|
|||||||
end_date: tableFilterState.end_date || '',
|
end_date: tableFilterState.end_date || '',
|
||||||
};
|
};
|
||||||
|
|
||||||
await generatePurchasesPerSupplierPDF(
|
await generatePurchasesPerSupplierPDF(allRows, exportParams);
|
||||||
allDataForExport.rows,
|
|
||||||
exportParams
|
|
||||||
);
|
|
||||||
toast.success('PDF berhasil dibuat dan diunduh.');
|
toast.success('PDF berhasil dibuat dan diunduh.');
|
||||||
} catch {
|
} catch {
|
||||||
toast.error('Gagal membuat PDF. Silakan coba lagi.');
|
toast.error('Gagal membuat PDF. Silakan coba lagi.');
|
||||||
@@ -591,28 +555,8 @@ const PurchasesPerSupplierTab = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// ===== TABLE COLUMNS DEFINITION =====
|
|
||||||
const groupedData = useMemo(() => {
|
|
||||||
const groups: { [key: number]: GroupedSupplierData } = {};
|
|
||||||
|
|
||||||
data.forEach((item) => {
|
|
||||||
const supplierId = item.supplier?.id;
|
|
||||||
if (supplierId && !groups[supplierId]) {
|
|
||||||
groups[supplierId] = {
|
|
||||||
id: supplierId,
|
|
||||||
supplier: item.supplier,
|
|
||||||
items: [],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (groups[supplierId]) {
|
|
||||||
groups[supplierId].items.push(item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return Object.values(groups);
|
|
||||||
}, [data]);
|
|
||||||
const getTableColumns = (
|
const getTableColumns = (
|
||||||
totals: Totals
|
summary: LogisticPurchasePerSupplierSummary
|
||||||
): ColumnDef<LogisticPurchasePerSupplierReport['rows'][0]>[] => {
|
): ColumnDef<LogisticPurchasePerSupplierReport['rows'][0]>[] => {
|
||||||
const tableColumns: ColumnDef<
|
const tableColumns: ColumnDef<
|
||||||
LogisticPurchasePerSupplierReport['rows'][0]
|
LogisticPurchasePerSupplierReport['rows'][0]
|
||||||
@@ -679,7 +623,7 @@ const PurchasesPerSupplierTab = () => {
|
|||||||
},
|
},
|
||||||
footer: () => (
|
footer: () => (
|
||||||
<div className='text-right font-semibold text-gray-900'>
|
<div className='text-right font-semibold text-gray-900'>
|
||||||
{formatNumber(totals.total_qty)}
|
{formatNumber(summary.total_qty) || '-'}
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@@ -693,7 +637,7 @@ const PurchasesPerSupplierTab = () => {
|
|||||||
},
|
},
|
||||||
footer: () => (
|
footer: () => (
|
||||||
<div className='text-right font-semibold text-gray-900'>
|
<div className='text-right font-semibold text-gray-900'>
|
||||||
{formatCurrency(totals.total_price)}
|
{formatCurrency(summary.total_unit_price) || '-'}
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@@ -707,7 +651,7 @@ const PurchasesPerSupplierTab = () => {
|
|||||||
},
|
},
|
||||||
footer: () => (
|
footer: () => (
|
||||||
<div className='text-right font-semibold text-gray-900'>
|
<div className='text-right font-semibold text-gray-900'>
|
||||||
{formatCurrency(totals.total_purchase_amount)}
|
{formatCurrency(summary.total_purchase_value) || '-'}
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@@ -721,7 +665,7 @@ const PurchasesPerSupplierTab = () => {
|
|||||||
},
|
},
|
||||||
footer: () => (
|
footer: () => (
|
||||||
<div className='text-right font-semibold text-gray-900'>
|
<div className='text-right font-semibold text-gray-900'>
|
||||||
{formatCurrency(totals.total_transport)}
|
{formatCurrency(summary.total_transport_unit_price) || '-'}
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@@ -735,7 +679,7 @@ const PurchasesPerSupplierTab = () => {
|
|||||||
},
|
},
|
||||||
footer: () => (
|
footer: () => (
|
||||||
<div className='text-right font-semibold text-gray-900'>
|
<div className='text-right font-semibold text-gray-900'>
|
||||||
{formatCurrency(totals.total_value_transport)}
|
{formatCurrency(summary.total_transport_value) || '-'}
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@@ -749,7 +693,7 @@ const PurchasesPerSupplierTab = () => {
|
|||||||
},
|
},
|
||||||
footer: () => (
|
footer: () => (
|
||||||
<div className='text-right font-semibold text-gray-900'>
|
<div className='text-right font-semibold text-gray-900'>
|
||||||
{formatCurrency(totals.total_jumlah)}
|
{formatCurrency(summary.total_amount) || '-'}
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@@ -920,54 +864,33 @@ const PurchasesPerSupplierTab = () => {
|
|||||||
Tidak ada data yang dapat ditampilkan...
|
Tidak ada data yang dapat ditampilkan...
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
groupedData.map((supplier) => {
|
data.map((supplierReport) => {
|
||||||
const total_qty = supplier.items.reduce(
|
const summary = supplierReport.summary || {
|
||||||
(sum, item) => sum + (item.qty || 0),
|
total_qty: 0,
|
||||||
0
|
total_unit_price: 0,
|
||||||
);
|
total_purchase_value: 0,
|
||||||
const total_price = supplier.items.reduce(
|
total_transport_unit_price: 0,
|
||||||
(sum, item) => sum + (item.purchase_value || 0),
|
total_transport_value: 0,
|
||||||
0
|
total_amount: 0,
|
||||||
);
|
|
||||||
const total_transport = supplier.items.reduce(
|
|
||||||
(sum, item) => sum + (item.transport_value || 0),
|
|
||||||
0
|
|
||||||
);
|
|
||||||
const total_value_transport = supplier.items.reduce(
|
|
||||||
(sum, item) => sum + (item.transport_value || 0),
|
|
||||||
0
|
|
||||||
);
|
|
||||||
const total_jumlah = supplier.items.reduce(
|
|
||||||
(sum, item) => sum + (item.total_amount || 0),
|
|
||||||
0
|
|
||||||
);
|
|
||||||
|
|
||||||
const totals = {
|
|
||||||
total_qty,
|
|
||||||
total_price,
|
|
||||||
total_purchase_amount: total_price,
|
|
||||||
total_transport,
|
|
||||||
total_value_transport,
|
|
||||||
total_jumlah,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const totalPurchase = totals.total_jumlah;
|
const totalPurchase = summary.total_amount;
|
||||||
const tableColumns = getTableColumns(totals);
|
const tableColumns = getTableColumns(summary);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
key={supplier.id}
|
key={supplierReport.supplier.id}
|
||||||
title={supplier.supplier.name}
|
title={supplierReport.supplier.name}
|
||||||
subtitle={`Total Pembelian: ${formatCurrency(totalPurchase)}`}
|
subtitle={`Total Pembelian: ${formatCurrency(totalPurchase)}`}
|
||||||
className={{ wrapper: 'w-full' }}
|
className={{ wrapper: 'w-full' }}
|
||||||
variant='bordered'
|
variant='bordered'
|
||||||
collapsible={true}
|
collapsible={true}
|
||||||
>
|
>
|
||||||
<Table
|
<Table
|
||||||
data={supplier.items}
|
data={supplierReport.rows}
|
||||||
columns={tableColumns}
|
columns={tableColumns}
|
||||||
pageSize={10}
|
pageSize={10}
|
||||||
renderFooter={supplier.items.length > 0}
|
renderFooter={supplierReport.rows.length > 0}
|
||||||
className={{
|
className={{
|
||||||
containerClassName: 'w-full',
|
containerClassName: 'w-full',
|
||||||
tableWrapperClassName: 'overflow-x-auto mt-4',
|
tableWrapperClassName: 'overflow-x-auto mt-4',
|
||||||
|
|||||||
+2
@@ -21,7 +21,9 @@ export type LogisticPurchasePerSupplierReportRow = {
|
|||||||
|
|
||||||
export type LogisticPurchasePerSupplierSummary = {
|
export type LogisticPurchasePerSupplierSummary = {
|
||||||
total_qty: number;
|
total_qty: number;
|
||||||
|
total_unit_price: number;
|
||||||
total_purchase_value: number;
|
total_purchase_value: number;
|
||||||
|
total_transport_unit_price: number;
|
||||||
total_transport_value: number;
|
total_transport_value: number;
|
||||||
total_amount: number;
|
total_amount: number;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user