mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-25 15:55:48 +00:00
refactor(FE): Refactor export logic for PurchasesPerSupplier report
This commit is contained in:
@@ -0,0 +1,101 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import ExcelJS from 'exceljs';
|
||||||
|
import { formatDate, formatCurrency, formatNumber } from '@/lib/helper';
|
||||||
|
import { LogisticPurchasePerSupplierReport } from '@/types/api/report/logistic-stock';
|
||||||
|
|
||||||
|
interface PurchasesPerSupplierExportExcelParams {
|
||||||
|
data: LogisticPurchasePerSupplierReport[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const generatePurchasesPerSupplierExcel = async (
|
||||||
|
params: PurchasesPerSupplierExportExcelParams
|
||||||
|
): Promise<void> => {
|
||||||
|
if (!params.data || params.data.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const workbook = new ExcelJS.Workbook();
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{ header: 'No', key: 'no', width: 5 },
|
||||||
|
{ header: 'Tanggal Terima', key: 'receiveDate', width: 15 },
|
||||||
|
{ header: 'Tanggal PO', key: 'poDate', width: 15 },
|
||||||
|
{ header: 'No. Referensi', key: 'poNumber', width: 15 },
|
||||||
|
{ header: 'Nama Produk', key: 'productName', width: 30 },
|
||||||
|
{ header: 'Tujuan', key: 'warehouse', width: 20 },
|
||||||
|
{ header: 'QTY', key: 'qty', width: 10 },
|
||||||
|
{ header: 'Harga Beli (Rp)', key: 'unitPrice', width: 18 },
|
||||||
|
{ header: 'Value Harga Beli (Rp)', key: 'purchaseValue', width: 20 },
|
||||||
|
{ header: 'Transport (Rp)', key: 'transportUnitPrice', width: 15 },
|
||||||
|
{ header: 'Value Transport (Rp)', key: 'transportValue', width: 20 },
|
||||||
|
{ header: 'Jumlah (Rp)', key: 'totalAmount', width: 18 },
|
||||||
|
{ header: 'Ekspedisi', key: 'expedition', width: 15 },
|
||||||
|
{ header: 'Surat Jalan', key: 'deliveryNumber', width: 15 },
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const supplierReport of params.data) {
|
||||||
|
const supplierData = supplierReport.rows;
|
||||||
|
const supplierName = supplierReport.supplier?.name || 'Unknown Supplier';
|
||||||
|
|
||||||
|
const worksheet = workbook.addWorksheet(supplierName.substring(0, 31));
|
||||||
|
worksheet.columns = columns;
|
||||||
|
|
||||||
|
supplierData.forEach((item, index) => {
|
||||||
|
worksheet.addRow({
|
||||||
|
no: index + 1,
|
||||||
|
receiveDate: item.receive_date
|
||||||
|
? formatDate(item.receive_date, 'DD MMM YYYY')
|
||||||
|
: '',
|
||||||
|
poDate: item.po_date ? formatDate(item.po_date, 'DD MMM YYYY') : '',
|
||||||
|
poNumber: item.po_number || '',
|
||||||
|
productName: item.product?.name || '',
|
||||||
|
warehouse: item.warehouse?.name || '',
|
||||||
|
qty: formatNumber(item.qty || 0),
|
||||||
|
unitPrice: formatCurrency(item.unit_price || 0),
|
||||||
|
purchaseValue: formatCurrency(item.purchase_value || 0),
|
||||||
|
transportUnitPrice: formatCurrency(item.transport_unit_price || 0),
|
||||||
|
transportValue: formatCurrency(item.transport_value || 0),
|
||||||
|
totalAmount: formatCurrency(item.total_amount || 0),
|
||||||
|
expedition: item.expedition || '',
|
||||||
|
deliveryNumber: item.delivery_number || '',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (supplierReport.summary) {
|
||||||
|
worksheet.addRow({
|
||||||
|
no: 'Total',
|
||||||
|
receiveDate: '',
|
||||||
|
poDate: '',
|
||||||
|
poNumber: '',
|
||||||
|
productName: '',
|
||||||
|
warehouse: '',
|
||||||
|
qty: formatNumber(supplierReport.summary.total_qty || 0),
|
||||||
|
unitPrice: '',
|
||||||
|
purchaseValue: formatCurrency(
|
||||||
|
supplierReport.summary.total_purchase_value || 0
|
||||||
|
),
|
||||||
|
transportUnitPrice: '',
|
||||||
|
transportValue: formatCurrency(
|
||||||
|
supplierReport.summary.total_transport_value || 0
|
||||||
|
),
|
||||||
|
totalAmount: formatCurrency(supplierReport.summary.total_amount || 0),
|
||||||
|
expedition: '',
|
||||||
|
deliveryNumber: '',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const filename = `laporan-pembelian-per-supplier-dicetak-pada-${formatDate(new Date(), 'YYYY-MM-DD-HHmm')}.xlsx`;
|
||||||
|
|
||||||
|
const buffer = await workbook.xlsx.writeBuffer();
|
||||||
|
const blob = new Blob([buffer], {
|
||||||
|
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||||
|
});
|
||||||
|
const url = window.URL.createObjectURL(blob);
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = url;
|
||||||
|
link.download = filename;
|
||||||
|
link.click();
|
||||||
|
window.URL.revokeObjectURL(url);
|
||||||
|
};
|
||||||
@@ -26,9 +26,9 @@ import Button from '@/components/Button';
|
|||||||
import Dropdown from '@/components/Dropdown';
|
import Dropdown from '@/components/Dropdown';
|
||||||
import MenuItem from '@/components/menu/MenuItem';
|
import MenuItem from '@/components/menu/MenuItem';
|
||||||
import Menu from '@/components/menu/Menu';
|
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/PurchasesPerSupplierExportPDF';
|
||||||
|
import { generatePurchasesPerSupplierExcel } from '@/components/pages/report/logistic-stock/export/PurchasesPerSupplierExportXLSX';
|
||||||
import toast from 'react-hot-toast';
|
import toast from 'react-hot-toast';
|
||||||
import * as XLSX from 'xlsx';
|
|
||||||
import { Icon } from '@iconify/react';
|
import { Icon } from '@iconify/react';
|
||||||
|
|
||||||
const PurchasesPerSupplierTab = () => {
|
const PurchasesPerSupplierTab = () => {
|
||||||
@@ -355,98 +355,14 @@ const PurchasesPerSupplierTab = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const workbook = XLSX.utils.book_new();
|
await generatePurchasesPerSupplierExcel({ data: allDataForExport });
|
||||||
|
|
||||||
allDataForExport.forEach((supplierReport) => {
|
|
||||||
const supplierData = supplierReport.rows;
|
|
||||||
const supplierName =
|
|
||||||
supplierReport.supplier?.name || 'Unknown Supplier';
|
|
||||||
|
|
||||||
const excelData: { [key: string]: string | number }[] =
|
|
||||||
supplierData.map((item, index) => ({
|
|
||||||
No: index + 1,
|
|
||||||
'Tanggal Terima': item.receive_date
|
|
||||||
? formatDate(item.receive_date, 'DD MMM YYYY')
|
|
||||||
: '',
|
|
||||||
'Tanggal PO': item.po_date
|
|
||||||
? formatDate(item.po_date, 'DD MMM YYYY')
|
|
||||||
: '',
|
|
||||||
'No. Referensi': item.po_number || '',
|
|
||||||
'Nama Produk': item.product?.name || '',
|
|
||||||
Tujuan: item.warehouse?.name || '',
|
|
||||||
QTY: item.qty || 0,
|
|
||||||
'Harga Beli (Rp)': item.unit_price || 0,
|
|
||||||
'Value Harga Beli (Rp)': item.purchase_value || 0,
|
|
||||||
'Transport (Rp)': item.transport_unit_price || 0,
|
|
||||||
'Value Transport (Rp)': item.transport_value || 0,
|
|
||||||
'Jumlah (Rp)': item.total_amount || 0,
|
|
||||||
Ekspedisi: item.expedition || '',
|
|
||||||
'Surat Jalan': item.delivery_number || '',
|
|
||||||
}));
|
|
||||||
|
|
||||||
if (supplierReport.summary) {
|
|
||||||
excelData.push({
|
|
||||||
No: 'Total',
|
|
||||||
'Tanggal Terima': '',
|
|
||||||
'Tanggal PO': '',
|
|
||||||
'No. Referensi': '',
|
|
||||||
'Nama Produk': '',
|
|
||||||
Tujuan: '',
|
|
||||||
QTY: supplierReport.summary.total_qty || 0,
|
|
||||||
'Harga Beli (Rp)': '',
|
|
||||||
'Value Harga Beli (Rp)':
|
|
||||||
supplierReport.summary.total_purchase_value || 0,
|
|
||||||
'Transport (Rp)': '',
|
|
||||||
'Value Transport (Rp)':
|
|
||||||
supplierReport.summary.total_transport_value || 0,
|
|
||||||
'Jumlah (Rp)': supplierReport.summary.total_amount || 0,
|
|
||||||
Ekspedisi: '',
|
|
||||||
'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 filename = `laporan-pembelian-per-supplier-dicetak-pada-${formatDate(new Date(), 'YYYY-MM-DD-HHmm')}.xlsx`;
|
|
||||||
|
|
||||||
XLSX.writeFile(workbook, filename);
|
|
||||||
toast.success('Excel berhasil dibuat dan diunduh.');
|
toast.success('Excel berhasil dibuat dan diunduh.');
|
||||||
} catch {
|
} catch {
|
||||||
toast.error('Gagal membuat Excel. Silakan coba lagi.');
|
toast.error('Gagal membuat Excel. Silakan coba lagi.');
|
||||||
} finally {
|
} finally {
|
||||||
setIsExcelExportLoading(false);
|
setIsExcelExportLoading(false);
|
||||||
}
|
}
|
||||||
}, [
|
}, [logisticPurchasePerSupplierExport]);
|
||||||
logisticPurchasePerSupplierExport,
|
|
||||||
tableFilterState,
|
|
||||||
areaOptions,
|
|
||||||
supplierOptions,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const handleExportPdf = useCallback(async () => {
|
const handleExportPdf = useCallback(async () => {
|
||||||
setIsPdfExportLoading(true);
|
setIsPdfExportLoading(true);
|
||||||
|
|||||||
Reference in New Issue
Block a user