update report add standard hpp, realisasi hpp, dan status

This commit is contained in:
Efril
2026-02-26 14:02:04 +07:00
parent 3c13aa897c
commit a3dd214a99
4 changed files with 377 additions and 197 deletions
@@ -15,6 +15,23 @@ import ReportGeneratorComponent from '@/views/dashboards/daily-report/report-gen
import ReportHeader from '@/views/dashboards/daily-report/report-header'
import React, { useEffect, useRef, useState } from 'react'
// Dummy HPP values — ganti dengan data real nantinya
const DUMMY_STD_HPP = 30 // 30%
const DUMMY_REAL_HPP = 28 // 28%
const getHppStatus = (stdHpp: number, realHpp: number): 'Sehat' | 'Tidak Sehat' =>
realHpp <= stdHpp ? 'Sehat' : 'Tidak Sehat'
const StatusBadge = ({ status }: { status: 'Sehat' | 'Tidak Sehat' }) => (
<span
className={`inline-block px-3 py-1 rounded-full text-base font-bold ${
status === 'Sehat' ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800'
}`}
>
{status}
</span>
)
const DailyPOSReport = () => {
const reportRef = useRef<HTMLDivElement | null>(null)
@@ -108,11 +125,7 @@ const DailyPOSReport = () => {
}
const getReportTitle = () => {
if (filterType === 'single') {
return 'Laporan Transaksi'
} else {
return `Laporan Transaksi`
}
return 'Laporan Transaksi'
}
const handleGeneratePDF = async () => {
@@ -342,7 +355,7 @@ const DailyPOSReport = () => {
</div>
</div>
{/* Category Summary */}
{/* Category Summary — +3 kolom baru */}
<div className='px-8 pb-8'>
<h3 className='text-3xl font-bold mb-8' style={{ color: '#36175e' }}>
Ringkasan Kategori
@@ -355,18 +368,31 @@ const DailyPOSReport = () => {
<th className='text-left text-xl p-4 font-semibold'>Nama</th>
<th className='text-center text-xl p-4 font-semibold'>Qty</th>
<th className='text-right text-xl p-4 font-semibold'>Pendapatan</th>
<th className='text-center text-xl p-4 font-semibold'>% Std HPP</th>
<th className='text-center text-xl p-4 font-semibold'>% Real HPP</th>
<th className='text-center text-xl p-4 font-semibold'>Status</th>
</tr>
</thead>
<tbody>
{category?.data?.map((c, index) => (
<tr key={index} className={index % 2 === 0 ? 'bg-white' : 'bg-gray-50'}>
<td className='p-4 text-xl font-medium text-gray-800'>{c.category_name}</td>
<td className='p-4 text-xl text-center text-gray-700'>{c.total_quantity}</td>
<td className='p-4 text-xl text-right font-semibold' style={{ color: '#36175e' }}>
{formatCurrency(c.total_revenue)}
</td>
</tr>
)) || []}
{category?.data?.map((c, index) => {
const stdHpp = DUMMY_STD_HPP
const realHpp = DUMMY_REAL_HPP
const status = getHppStatus(stdHpp, realHpp)
return (
<tr key={index} className={index % 2 === 0 ? 'bg-white' : 'bg-gray-50'}>
<td className='p-4 text-xl font-medium text-gray-800'>{c.category_name}</td>
<td className='p-4 text-xl text-center text-gray-700'>{c.total_quantity}</td>
<td className='p-4 text-xl text-right font-semibold' style={{ color: '#36175e' }}>
{formatCurrency(c.total_revenue)}
</td>
<td className='p-4 text-xl text-center text-gray-700'>{stdHpp}%</td>
<td className='p-4 text-xl text-center text-gray-700'>{realHpp}%</td>
<td className='p-4 text-center'>
<StatusBadge status={status} />
</td>
</tr>
)
}) || []}
</tbody>
<tfoot>
<tr className='text-gray-800 border-t-2 border-gray-300'>
@@ -375,13 +401,16 @@ const DailyPOSReport = () => {
<td className='p-4 text-xl text-right font-bold'>
{formatCurrency(categorySummary?.totalRevenue ?? 0)}
</td>
<td className='p-4'></td>
<td className='p-4'></td>
<td className='p-4'></td>
</tr>
</tfoot>
</table>
</div>
</div>
{/* Product Summary - Dipisah per kategori dengan tabel terpisah */}
{/* Product Summary — +3 kolom baru */}
<div className='px-8 pb-8'>
<h3 className='text-3xl font-bold mb-8' style={{ color: '#36175e' }}>
Ringkasan Item Per Kategori
@@ -398,7 +427,6 @@ const DailyPOSReport = () => {
})
.map((categoryName, catIndex) => {
const categoryProducts = groupedProducts[categoryName].sort((a, b) => {
// Sort by product_sku ASC
const skuA = a.product_sku || ''
const skuB = b.product_sku || ''
return skuA.localeCompare(skuB)
@@ -421,31 +449,57 @@ const DailyPOSReport = () => {
style={{ borderCollapse: 'collapse', tableLayout: 'fixed', width: '100%' }}
>
<colgroup>
<col style={{ width: '50%' }} />
<col style={{ width: '20%' }} />
<col style={{ width: '30%' }} />
<col style={{ width: '28%' }} />
<col style={{ width: '10%' }} />
<col style={{ width: '22%' }} />
<col style={{ width: '13%' }} />
<col style={{ width: '13%' }} />
<col style={{ width: '14%' }} />
</colgroup>
<thead>
<tr className='text-gray-800 border-b-2 border-gray-300 bg-gray-100'>
<th className='text-left text-xl p-5 font-semibold border-r border-gray-300'>Produk</th>
<th className='text-center text-xl p-5 font-semibold border-r border-gray-300'>Qty</th>
<th className='text-right text-xl p-5 font-semibold'>Pendapatan</th>
<th className='text-right text-xl p-5 font-semibold border-r border-gray-300'>
Pendapatan
</th>
<th className='text-center text-xl p-5 font-semibold border-r border-gray-300'>
% Std HPP
</th>
<th className='text-center text-xl p-5 font-semibold border-r border-gray-300'>
% Real HPP
</th>
<th className='text-center text-xl p-5 font-semibold'>Status</th>
</tr>
</thead>
<tbody>
{categoryProducts.map((item, index) => (
<tr key={index} className={index % 2 === 0 ? 'bg-white' : 'bg-gray-50'}>
<td className='p-5 text-xl font-medium text-gray-800 border-r border-gray-200'>
{item.product_name}
</td>
<td className='p-5 text-xl text-center text-gray-700 border-r border-gray-200'>
{item.quantity_sold}
</td>
<td className='p-5 text-xl text-right font-semibold text-gray-800'>
{formatCurrency(item.revenue)}
</td>
</tr>
))}
{categoryProducts.map((item, index) => {
const stdHpp = DUMMY_STD_HPP
const realHpp = DUMMY_REAL_HPP
const status = getHppStatus(stdHpp, realHpp)
return (
<tr key={index} className={index % 2 === 0 ? 'bg-white' : 'bg-gray-50'}>
<td className='p-5 text-xl font-medium text-gray-800 border-r border-gray-200'>
{item.product_name}
</td>
<td className='p-5 text-xl text-center text-gray-700 border-r border-gray-200'>
{item.quantity_sold}
</td>
<td className='p-5 text-xl text-right font-semibold text-gray-800 border-r border-gray-200'>
{formatCurrency(item.revenue)}
</td>
<td className='p-5 text-xl text-center text-gray-700 border-r border-gray-200'>
{stdHpp}%
</td>
<td className='p-5 text-xl text-center text-gray-700 border-r border-gray-200'>
{realHpp}%
</td>
<td className='p-5 text-center'>
<StatusBadge status={status} />
</td>
</tr>
)
})}
</tbody>
<tfoot>
<tr className='bg-gray-200 border-t-2 border-gray-400'>
@@ -455,9 +509,12 @@ const DailyPOSReport = () => {
<td className='p-5 text-xl text-center font-bold text-gray-800 border-r border-gray-400'>
{categoryTotalQty}
</td>
<td className='p-5 text-xl text-right font-bold text-gray-800'>
<td className='p-5 text-xl text-right font-bold text-gray-800 border-r border-gray-400'>
{formatCurrency(categoryTotalRevenue)}
</td>
<td className='p-5 border-r border-gray-400'></td>
<td className='p-5 border-r border-gray-400'></td>
<td className='p-5'></td>
</tr>
</tfoot>
</table>
@@ -468,24 +525,35 @@ const DailyPOSReport = () => {
{/* Grand Total */}
<div className='bg-purple-50 rounded-lg border-2 border-purple-300 mt-6'>
<table className='w-full' style={{ borderCollapse: 'collapse' }}>
<table className='w-full' style={{ borderCollapse: 'collapse', tableLayout: 'fixed' }}>
<colgroup>
<col style={{ width: '28%' }} />
<col style={{ width: '10%' }} />
<col style={{ width: '22%' }} />
<col style={{ width: '13%' }} />
<col style={{ width: '13%' }} />
<col style={{ width: '14%' }} />
</colgroup>
<tfoot>
<tr className='text-gray-800'>
<td
className='p-5 text-2xl font-bold border-r-2 border-purple-300'
style={{ width: '50%', color: '#36175e' }}
>
<td className='p-5 text-2xl font-bold border-r-2 border-purple-300' style={{ color: '#36175e' }}>
TOTAL KESELURUHAN
</td>
<td
className='p-5 text-2xl text-center font-bold border-r-2 border-purple-300'
style={{ width: '20%', color: '#36175e' }}
style={{ color: '#36175e' }}
>
{productSummary.totalQuantitySold ?? 0}
</td>
<td className='p-5 text-2xl text-right font-bold' style={{ width: '30%', color: '#36175e' }}>
<td
className='p-5 text-2xl text-right font-bold border-r-2 border-purple-300'
style={{ color: '#36175e' }}
>
{formatCurrency(productSummary.totalRevenue ?? 0)}
</td>
<td className='p-5 border-r-2 border-purple-300'></td>
<td className='p-5 border-r-2 border-purple-300'></td>
<td className='p-5'></td>
</tr>
</tfoot>
</table>