Reconciliation and Cash Bank Detail Transaction

This commit is contained in:
efrilm 2025-09-11 21:47:52 +07:00
parent 1a9015563f
commit 5723d49090
7 changed files with 647 additions and 1 deletions

View File

@ -0,0 +1,18 @@
import CashBankDetailTransactionContent from '@/views/apps/cash-bank/detail/transaction/CashBankDetailTransactionContent'
import CashBankDetailTransactionHeader from '@/views/apps/cash-bank/detail/transaction/CashBankDetailTransactionHeader'
import Grid from '@mui/material/Grid2'
const TransactionPage = () => {
return (
<Grid container spacing={6}>
<Grid size={{ xs: 12 }}>
<CashBankDetailTransactionHeader title='Giro 1-10003' transaction='Terima Pembayaran Tagihan' />
</Grid>
<Grid size={{ xs: 12 }}>
<CashBankDetailTransactionContent />
</Grid>
</Grid>
)
}
export default TransactionPage

View File

@ -338,7 +338,7 @@ const CashBankDetailTable = () => {
color='primary'
className='p-0 min-w-0 font-medium normal-case justify-start'
component={Link}
href={getLocalizedUrl(`/apps/cashbank/${row.original.id}/detail`, locale as Locale)}
href={getLocalizedUrl(`/apps/cash-bank/1-10003/detail/transaction/${row.original.id}`, locale as Locale)}
sx={{
textTransform: 'none',
fontWeight: 500,

View File

@ -0,0 +1,27 @@
'use client'
import Grid from '@mui/material/Grid2'
import CashBankDetailTransactionInformation from './CashBankDetailTransactionInformation'
import CashBankDetailTransactionLog from './CashBankDetailTransactionLog'
import CashBankDetailTransactionReconciliationDrawer from './CashBankDetailTransactionReconsiled'
import { useState } from 'react'
const CashBankDetailTransactionContent = () => {
return (
<>
<Grid container spacing={6}>
<Grid size={{ xs: 12 }}>
<CashBankDetailTransactionInformation />
</Grid>
{/* <Grid size={{ xs: 12 }}>
<ExpenseDetailSendPayment />
</Grid> */}
<Grid size={{ xs: 12 }}>
<CashBankDetailTransactionLog />
</Grid>
</Grid>
</>
)
}
export default CashBankDetailTransactionContent

View File

@ -0,0 +1,23 @@
import { Typography } from '@mui/material'
interface Props {
title: string
transaction: string
}
const CashBankDetailTransactionHeader = ({ title, transaction }: Props) => {
return (
<div className='flex flex-wrap sm:items-center justify-between max-sm:flex-col gap-6'>
<div>
<Typography variant='h4' className='mbe-1'>
{title}
</Typography>
<Typography variant='h6' className='mbe-1'>
Transaksi: {transaction}
</Typography>
</div>
</div>
)
}
export default CashBankDetailTransactionHeader

View File

@ -0,0 +1,177 @@
'use client'
import React, { useState } from 'react'
import { Card, CardHeader, CardContent, Typography, Box, Button, IconButton } from '@mui/material'
import Grid from '@mui/material/Grid2'
import CashBankDetailTransactionReconciliationDrawer from './CashBankDetailTransactionReconsiled'
interface PaymentData {
dari: string
nomor: string
tglTransaksi: string
referensi: string
status: string
}
interface TransactionItem {
deskripsi: string
total: number
}
const CashBankDetailTransactionInformation: React.FC = () => {
const [open, setOpen] = useState(false)
const paymentData: PaymentData = {
dari: 'POS Customer',
nomor: 'IP/00030',
tglTransaksi: '10/09/2025',
referensi: 'Pembayaran INV/01/59A/4CY/00003',
status: 'Unreconciled'
}
const transactionItems: TransactionItem[] = [
{
deskripsi: 'Terima pembayaran tagihan INV/01/59A/4CY/00003',
total: 220890
}
]
const totalAmount: number = transactionItems.reduce((sum, item) => sum + item.total, 0)
const formatCurrency = (amount: number): string => {
return new Intl.NumberFormat('id-ID').format(amount)
}
return (
<>
<Card sx={{ width: '100%' }}>
<CardHeader
title={
<Box display='flex' justifyContent='space-between' alignItems='center'>
<Typography variant='h5' color='error' sx={{ fontWeight: 'bold' }}>
Unreconciled
</Typography>
<Box>
<Button variant='outlined' size='small' sx={{ mr: 1 }} onClick={() => setOpen(true)}>
Rekonsiliasi
</Button>
<Button startIcon={<i className='tabler-share' />} variant='outlined' size='small' sx={{ mr: 1 }}>
Bagikan
</Button>
<Button startIcon={<i className='tabler-printer' />} variant='outlined' size='small' sx={{ mr: 1 }}>
Print
</Button>
</Box>
</Box>
}
/>
<CardContent>
{/* Payment Information */}
<Grid container spacing={3} sx={{ mb: 4 }}>
<Grid size={{ xs: 12, md: 6 }}>
<Box sx={{ mb: 2 }}>
<Typography variant='subtitle2' color='text.secondary'>
Dari
</Typography>
<Typography variant='body1' color='primary' sx={{ fontWeight: 'medium', cursor: 'pointer' }}>
{paymentData.dari}
</Typography>
</Box>
<Box sx={{ mb: 2 }}>
<Typography variant='subtitle2' color='text.secondary'>
Tanggal Transaksi
</Typography>
<Typography variant='body1'>{paymentData.tglTransaksi}</Typography>
</Box>
</Grid>
<Grid size={{ xs: 12, md: 6 }}>
<Box sx={{ mb: 2 }}>
<Typography variant='subtitle2' color='text.secondary'>
Nomor
</Typography>
<Typography variant='body1'>{paymentData.nomor}</Typography>
</Box>
<Box>
<Typography variant='subtitle2' color='text.secondary'>
Referensi
</Typography>
<Typography variant='body1'>{paymentData.referensi}</Typography>
</Box>
</Grid>
</Grid>
{/* Transaction Items Header */}
<Box
sx={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
py: 2,
borderBottom: '2px solid #e0e0e0',
mb: 2
}}
>
<Typography variant='h6' sx={{ fontWeight: 'bold' }}>
Deskripsi
</Typography>
<Typography variant='h6' sx={{ fontWeight: 'bold' }}>
Total
</Typography>
</Box>
{/* Transaction Items */}
<Box sx={{ mb: 4 }}>
{transactionItems.map((item, index) => (
<Box
key={index}
sx={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
py: 2,
borderBottom: index === transactionItems.length - 1 ? 'none' : '1px solid #f0f0f0'
}}
>
<Box sx={{ flex: 1 }}>
<Typography variant='body1' color='primary' sx={{ cursor: 'pointer' }}>
{item.deskripsi}
</Typography>
</Box>
<Box sx={{ textAlign: 'right', ml: 3 }}>
<Typography variant='body1' sx={{ fontWeight: 'medium' }}>
{formatCurrency(item.total)}
</Typography>
</Box>
</Box>
))}
</Box>
{/* Total Section */}
<Box sx={{ mt: 4, pt: 3, borderTop: '2px solid #e0e0e0' }}>
<Box
sx={{
display: 'flex',
justifyContent: 'flex-end',
alignItems: 'center'
}}
>
<Typography variant='h5' sx={{ fontWeight: 'bold', mr: 4 }}>
Total
</Typography>
<Typography variant='h5' sx={{ fontWeight: 'bold' }}>
{formatCurrency(totalAmount)}
</Typography>
</Box>
</Box>
</CardContent>
</Card>
<CashBankDetailTransactionReconciliationDrawer open={open} handleClose={() => setOpen(!open)} />
</>
)
}
export default CashBankDetailTransactionInformation

View File

@ -0,0 +1,59 @@
'use client'
import React from 'react'
import { Card, CardContent, CardHeader, Typography, Box, Link } from '@mui/material'
interface LogEntry {
id: string
action: string
timestamp: string
user: string
}
const CashBankDetailTransactionLog: React.FC = () => {
const logEntries: LogEntry[] = [
{
id: '1',
action: 'Terakhir diubah oleh',
timestamp: '08 Sep 2025 18:26',
user: 'pada'
}
]
return (
<Card>
<CardHeader
title={
<Typography variant='h6' sx={{ fontWeight: 'bold' }}>
Pantau log perubahan data
</Typography>
}
sx={{ pb: 1 }}
/>
<CardContent sx={{ mt: 5 }}>
{logEntries.map(entry => (
<Box key={entry.id} sx={{ mb: 2 }}>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
<i className='tabler-edit' style={{ fontSize: '16px', color: '#1976d2' }} />
<Link
href='#'
underline='hover'
color='primary'
sx={{
textDecoration: 'none',
'&:hover': {
textDecoration: 'underline'
}
}}
>
{entry.action} {entry.user} {entry.timestamp}
</Link>
</Box>
</Box>
))}
</CardContent>
</Card>
)
}
export default CashBankDetailTransactionLog

View File

@ -0,0 +1,342 @@
import React, { useState } from 'react'
import {
Drawer,
Typography,
Box,
IconButton,
Button,
TextField,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Checkbox,
Paper,
MenuItem,
Select,
FormControl
} from '@mui/material'
import Grid from '@mui/material/Grid2'
interface Props {
open: boolean
handleClose: () => void
}
const CashBankDetailTransactionReconciliationDrawer: React.FC<Props> = ({ open, handleClose }) => {
const [tanggalDari, setTanggalDari] = useState('10/09/2025')
const [tanggalSampai, setTanggalSampai] = useState('10/09/2025')
const [totalDari, setTotalDari] = useState('220.890')
const [totalSampai, setTotalSampai] = useState('220.890')
const [cari, setCari] = useState('')
const transactionData = {
detil: '10/09/2025',
kirim: 'Terima pembayaran tagihan: POS Customer INV/01/59A/4CY/00003',
terima: '220.890'
}
return (
<Drawer
open={open}
anchor='right'
variant='temporary'
onClose={handleClose}
ModalProps={{ keepMounted: true }}
sx={{
'& .MuiDrawer-paper': {
width: { xs: '90%', sm: '80%', md: '80%', lg: '80%' },
display: 'flex',
flexDirection: 'column',
height: '100%'
}
}}
>
{/* Header */}
<Box
sx={{
position: 'sticky',
top: 0,
zIndex: 10,
backgroundColor: 'background.paper',
borderBottom: 1,
borderColor: 'divider',
p: 3
}}
>
<div className='flex items-center justify-between'>
<Typography variant='h5' sx={{ fontWeight: 'bold' }}>
Rekonsiliasi
</Typography>
<IconButton size='small' onClick={handleClose}>
<i className='tabler-x text-2xl' />
</IconButton>
</div>
</Box>
{/* Content */}
<Box sx={{ flex: 1, overflowY: 'auto', p: 3 }}>
<Grid container spacing={2}>
<Grid size={6}>
{/* Mutasi Bank Section */}
<Box sx={{ mb: 4 }}>
<Typography variant='h6' sx={{ fontWeight: 'bold', mb: 1 }}>
Mutasi Bank
</Typography>
<Typography variant='body2' color='text.secondary' sx={{ mb: 3 }}>
Cari mutasi bank yang sesuai dengan transaksi di Kledo
</Typography>
{/* Filter Section */}
<Grid container spacing={3} sx={{ mb: 3 }}>
{/* Tanggal */}
<Grid size={12}>
<Typography variant='body2' sx={{ mb: 1, fontWeight: 'medium' }}>
Tanggal
</Typography>
<div className='flex items-center gap-3'>
<TextField
size='small'
value={tanggalDari}
onChange={e => setTanggalDari(e.target.value)}
sx={{ width: '150px' }}
/>
<Typography variant='body2'>s/d</Typography>
<TextField
size='small'
value={tanggalSampai}
onChange={e => setTanggalSampai(e.target.value)}
sx={{ width: '150px' }}
/>
</div>
</Grid>
{/* Total */}
<Grid size={12}>
<Typography variant='body2' sx={{ mb: 1, fontWeight: 'medium' }}>
Total
</Typography>
<div className='flex items-center gap-3'>
<TextField
size='small'
value={totalDari}
onChange={e => setTotalDari(e.target.value)}
sx={{ width: '150px' }}
/>
<Typography variant='body2'>s/d</Typography>
<TextField
size='small'
value={totalSampai}
onChange={e => setTotalSampai(e.target.value)}
sx={{ width: '150px' }}
/>
</div>
</Grid>
{/* Cari */}
<Grid size={12}>
<Typography variant='body2' sx={{ mb: 1, fontWeight: 'medium' }}>
Cari
</Typography>
<div className='flex items-center gap-3'>
<TextField
size='small'
placeholder='Cari'
value={cari}
onChange={e => setCari(e.target.value)}
sx={{ width: '300px' }}
/>
<Button variant='contained' size='small'>
Go
</Button>
</div>
</Grid>
</Grid>
{/* Table */}
<TableContainer component={Paper} sx={{ mb: 3 }}>
<Table size='small'>
<TableHead>
<TableRow sx={{ backgroundColor: 'grey.50' }}>
<TableCell padding='checkbox'>
<Checkbox />
</TableCell>
<TableCell>Detil</TableCell>
<TableCell>Kirim</TableCell>
<TableCell>Terima</TableCell>
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell colSpan={4} sx={{ textAlign: 'center', py: 4 }}>
<div className='flex flex-col items-center gap-2'>
<i className='tabler-folder-open text-gray-400 text-4xl' />
<Typography variant='body2' color='text.secondary'>
Tidak ada data
</Typography>
</div>
</TableCell>
</TableRow>
</TableBody>
</Table>
</TableContainer>
{/* Information Text */}
<Typography variant='body2' color='text.secondary' sx={{ mb: 2 }}>
Transaksi yang sudah dipilih, tambah transaksi baru sesuai kebutuhan.
</Typography>
{/* Table */}
<TableContainer component={Paper} sx={{ mb: 3 }}>
<Table size='small'>
<TableHead>
<TableRow sx={{ backgroundColor: 'grey.50' }}>
<TableCell padding='checkbox'>
<Checkbox />
</TableCell>
<TableCell>Detil</TableCell>
<TableCell>Kirim</TableCell>
<TableCell>Terima</TableCell>
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell colSpan={4} sx={{ textAlign: 'center', py: 4 }}>
<div className='flex flex-col items-center gap-2'>
<i className='tabler-folder-open text-gray-400 text-4xl' />
<Typography variant='body2' color='text.secondary'>
Tidak ada data
</Typography>
</div>
</TableCell>
</TableRow>
</TableBody>
</Table>
</TableContainer>
</Box>
{/* Summary Section */}
<Box sx={{ mb: 4 }}>
<Typography variant='body2' sx={{ mb: 3, fontWeight: 'medium' }}>
Total transaksi di Kledo harus sama dengan total mutasi
</Typography>
<Grid container spacing={3} sx={{ mb: 3 }}>
<Grid size={6}>
<Typography variant='body2' color='text.secondary'>
Total transaksi di Kledo
</Typography>
</Grid>
<Grid size={6}>
<Typography variant='body2' sx={{ textAlign: 'right' }}>
220.890
</Typography>
</Grid>
</Grid>
<Grid container spacing={3} sx={{ mb: 3 }}>
<Grid size={6}>
<Typography variant='body2' color='text.secondary'>
Total mutasi
</Typography>
</Grid>
<Grid size={6}>
<Typography variant='body2' sx={{ textAlign: 'right' }}>
0
</Typography>
</Grid>
</Grid>
<Grid container spacing={3}>
<Grid size={6}>
<Typography variant='body2' sx={{ fontWeight: 'bold' }}>
Selisih
</Typography>
</Grid>
<Grid size={6}>
<Typography variant='body2' sx={{ textAlign: 'right', fontWeight: 'bold' }}>
220.890
</Typography>
</Grid>
</Grid>
</Box>
</Grid>
<Grid size={6}>
{/* Transaction Summary */}
<Box
sx={{
backgroundColor: 'grey.50',
p: 3,
borderRadius: 1,
border: '1px solid',
borderColor: 'grey.200'
}}
>
<Grid container spacing={3}>
<Grid size={4}>
<Typography variant='body2' sx={{ fontWeight: 'bold', mb: 1 }}>
Detil
</Typography>
<Typography variant='body2'>{transactionData.detil}</Typography>
</Grid>
<Grid size={4}>
<Typography variant='body2' sx={{ fontWeight: 'bold', mb: 1 }}>
Kirim
</Typography>
<Typography variant='body2' color='primary' sx={{ cursor: 'pointer' }}>
{transactionData.kirim}
</Typography>
</Grid>
<Grid size={4}>
<Typography variant='body2' sx={{ fontWeight: 'bold', mb: 1 }}>
Terima
</Typography>
<Typography variant='body2' color='primary' sx={{ fontWeight: 'bold' }}>
{transactionData.terima}
</Typography>
</Grid>
</Grid>
<Box sx={{ mt: 3, pt: 2, borderTop: '1px solid', borderColor: 'grey.300' }}>
<Box sx={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center' }}>
<Typography variant='h6' sx={{ fontWeight: 'bold', mr: 2 }}>
Total
</Typography>
<Typography variant='h6' sx={{ fontWeight: 'bold' }}>
220.890
</Typography>
</Box>
</Box>
</Box>
</Grid>
</Grid>
</Box>
{/* Footer Buttons */}
<Box
sx={{
position: 'sticky',
bottom: 0,
zIndex: 10,
backgroundColor: 'background.paper',
borderTop: 1,
borderColor: 'divider',
p: 3
}}
>
<div className='flex items-center justify-end gap-3'>
<Button variant='outlined' color='error' onClick={handleClose}>
Batal
</Button>
<Button variant='outlined' disabled>
Rekonsiliasi
</Button>
</div>
</Box>
</Drawer>
)
}
export default CashBankDetailTransactionReconciliationDrawer