pos-dashboard-v2/src/views/apps/report/profit-loss/ReportProfitLossContent.tsx

263 lines
8.9 KiB
TypeScript
Raw Normal View History

2025-09-11 18:20:40 +07:00
'use client'
import DateRangePicker from '@/components/RangeDatePicker'
import { ReportItem, ReportItemFooter, ReportItemHeader, ReportItemSubheader } from '@/components/report/ReportItem'
2025-09-25 15:45:49 +07:00
import { ExcelExportProfitLossService } from '@/services/export/excel/ExcelExportProfitLossService'
2025-09-25 19:35:22 +07:00
import { PDFExportProfitLossService } from '@/services/export/pdf/PDFExportProfitLossService'
2025-09-25 14:59:08 +07:00
import { ProfitLossReport } from '@/types/services/analytic'
2025-09-25 19:35:22 +07:00
import { Button, Card, CardContent, Box, Menu, MenuItem, ListItemIcon, ListItemText } from '@mui/material'
import { useState } from 'react'
2025-09-11 18:20:40 +07:00
2025-09-25 14:59:08 +07:00
interface ReportProfitLossContentProps {
profitData: ProfitLossReport | undefined
startDate: Date | null
endDate: Date | null
onStartDateChange: (date: Date | null) => void
onEndDateChange: (date: Date | null) => void
}
// Utility function to format date for display
const formatDisplayDate = (dateString: string) => {
const date = new Date(dateString)
return date.toLocaleDateString('id-ID', {
day: '2-digit',
month: '2-digit',
year: 'numeric'
})
}
const ReportProfitLossContent = ({
profitData,
startDate,
endDate,
onStartDateChange,
onEndDateChange
}: ReportProfitLossContentProps) => {
2025-09-25 19:35:22 +07:00
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null)
const open = Boolean(anchorEl)
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
setAnchorEl(event.currentTarget)
}
const handleClose = () => {
setAnchorEl(null)
}
const handleExportExcel = async () => {
2025-09-25 15:45:49 +07:00
if (!profitData) return
2025-09-25 19:35:22 +07:00
handleClose()
2025-09-25 15:45:49 +07:00
try {
const result = await ExcelExportProfitLossService.exportProfitLossToExcel(profitData)
if (result.success) {
2025-09-25 19:35:22 +07:00
console.log('Excel export successful:', result.filename)
} else {
console.error('Excel export failed:', result.error)
alert('Export Excel gagal. Silakan coba lagi.')
}
} catch (error) {
console.error('Excel export error:', error)
alert('Terjadi kesalahan saat export Excel.')
}
}
const handleExportPDF = async () => {
if (!profitData) return
handleClose()
try {
const result = await PDFExportProfitLossService.exportProfitLossToPDF(profitData)
if (result.success) {
console.log('PDF export successful:', result.filename)
2025-09-25 15:45:49 +07:00
// Optional: Show success notification
} else {
2025-09-25 19:35:22 +07:00
console.error('PDF export failed:', result.error)
alert('Export PDF gagal. Silakan coba lagi.')
2025-09-25 15:45:49 +07:00
}
} catch (error) {
2025-09-25 19:35:22 +07:00
console.error('PDF export error:', error)
alert('Terjadi kesalahan saat export PDF.')
2025-09-25 15:45:49 +07:00
}
2025-09-25 14:59:08 +07:00
}
2025-09-11 18:20:40 +07:00
return (
<Card>
<div className='p-6 border-be'>
<div className='flex items-center justify-end gap-2'>
<Button
color='secondary'
variant='tonal'
2025-09-25 19:35:22 +07:00
startIcon={<i className='tabler-download' />}
endIcon={<i className='tabler-chevron-down' />}
2025-09-11 18:20:40 +07:00
className='max-sm:is-full'
2025-09-25 19:35:22 +07:00
onClick={handleClick}
2025-09-25 14:59:08 +07:00
disabled={!profitData}
2025-09-25 19:35:22 +07:00
aria-controls={open ? 'export-menu' : undefined}
aria-haspopup='true'
aria-expanded={open ? 'true' : undefined}
2025-09-11 18:20:40 +07:00
>
2025-09-25 19:35:22 +07:00
Export
2025-09-11 18:20:40 +07:00
</Button>
2025-09-25 19:35:22 +07:00
<Menu
id='export-menu'
anchorEl={anchorEl}
open={open}
onClose={handleClose}
MenuListProps={{
'aria-labelledby': 'export-button'
}}
transformOrigin={{ horizontal: 'right', vertical: 'top' }}
anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}
>
<MenuItem onClick={handleExportExcel}>
<ListItemIcon>
<i className='tabler-file-type-xls text-green-600' />
</ListItemIcon>
<ListItemText>Export to Excel</ListItemText>
</MenuItem>
<MenuItem onClick={handleExportPDF}>
<ListItemIcon>
<i className='tabler-file-type-pdf text-red-600' />
</ListItemIcon>
<ListItemText>Export to PDF</ListItemText>
</MenuItem>
</Menu>
2025-09-11 18:20:40 +07:00
<DateRangePicker
startDate={startDate}
endDate={endDate}
2025-09-25 14:59:08 +07:00
onStartDateChange={onStartDateChange}
onEndDateChange={onEndDateChange}
2025-09-11 18:20:40 +07:00
/>
</div>
</div>
<CardContent>
2025-09-25 14:59:08 +07:00
{profitData ? (
<>
{/* Summary Section */}
<ReportItemHeader
title='Pendapatan'
date={`${profitData.date_from.split('T')[0]} - ${profitData.date_to.split('T')[0]}`}
/>
<ReportItemSubheader title='Penjualan' />
<ReportItem
accountCode=''
accountName='Revenue'
amount={profitData.summary.total_revenue}
onClick={() => {}}
/>
<ReportItemFooter title='Total Pendapatan' amount={profitData.summary.total_revenue} />
<ReportItemSubheader title='' />
<ReportItemHeader
title='Beban Pokok Penjualan'
date={`${profitData.date_from.split('T')[0]} - ${profitData.date_to.split('T')[0]}`}
/>
<ReportItem
accountCode=''
accountName='Cost of Goods Sold'
amount={profitData.summary.total_cost}
onClick={() => {}}
/>
<ReportItemFooter title='Total Beban Pokok Penjualan' amount={profitData.summary.total_cost} />
<ReportItemSubheader title='' />
<ReportItemHeader title='Laba Kotor' amount={profitData.summary.gross_profit} />
<ReportItemSubheader title='' />
{/* Daily Data Breakdown Section */}
{profitData.data && profitData.data.length > 0 && (
<>
<ReportItemHeader
title='Rincian Data Harian'
date={`${profitData.date_from.split('T')[0]} - ${profitData.date_to.split('T')[0]}`}
/>
<ReportItemSubheader title='Breakdown per Hari' />
{profitData.data.map((dailyData, index) => (
<div key={index} className='mb-4'>
<ReportItemSubheader title={`Data ${formatDisplayDate(dailyData.date)}`} />
<ReportItem
accountCode=''
accountName='Revenue Harian'
amount={dailyData.revenue}
onClick={() => {}}
/>
<ReportItem accountCode='' accountName='Cost Harian' amount={dailyData.cost} onClick={() => {}} />
<ReportItem
accountCode=''
accountName='Gross Profit Harian'
amount={dailyData.gross_profit}
onClick={() => {}}
/>
<ReportItem accountCode='' accountName='Tax Harian' amount={dailyData.tax} onClick={() => {}} />
<ReportItem
accountCode=''
accountName='Discount Harian'
amount={dailyData.discount}
onClick={() => {}}
/>
<ReportItem
accountCode=''
accountName='Orders Harian'
amount={dailyData.orders}
onClick={() => {}}
/>
<ReportItemFooter
title={`Net Profit ${formatDisplayDate(dailyData.date)}`}
amount={dailyData.net_profit}
/>
</div>
))}
<ReportItemSubheader title='' />
</>
)}
{/* Operational Costs Section */}
<ReportItemHeader
title='Biaya Operasional'
date={`${profitData.date_from.split('T')[0]} - ${profitData.date_to.split('T')[0]}`}
/>
<ReportItemSubheader title='Biaya Operasional' />
<ReportItem accountCode='' accountName='Tax' amount={profitData.summary.total_tax} onClick={() => {}} />
<ReportItem
accountCode=''
accountName='Discount'
amount={profitData.summary.total_discount}
onClick={() => {}}
/>
<ReportItemFooter
title='Total Biaya Operasional'
amount={profitData.summary.total_tax + profitData.summary.total_discount}
/>
<ReportItemSubheader title='' />
<ReportItemHeader title='Laba Bersih' amount={profitData.summary.net_profit} />
</>
) : (
<Box display='flex' justifyContent='center' alignItems='center' minHeight={200}>
<span>No data available</span>
</Box>
)}
2025-09-11 18:20:40 +07:00
</CardContent>
</Card>
)
}
export default ReportProfitLossContent