Compare commits
No commits in common. "b3a41fe0e08a69522135ae0763f227e3102694c8" and "29defb68c83578657fd80a4ed35d18ae92ceb329" have entirely different histories.
b3a41fe0e0
...
29defb68c8
@ -1,370 +0,0 @@
|
|||||||
'use client'
|
|
||||||
// React Imports
|
|
||||||
import { useState } from 'react'
|
|
||||||
|
|
||||||
// MUI Imports
|
|
||||||
import Button from '@mui/material/Button'
|
|
||||||
import Drawer from '@mui/material/Drawer'
|
|
||||||
import IconButton from '@mui/material/IconButton'
|
|
||||||
import MenuItem from '@mui/material/MenuItem'
|
|
||||||
import Typography from '@mui/material/Typography'
|
|
||||||
import Divider from '@mui/material/Divider'
|
|
||||||
import Grid from '@mui/material/Grid2'
|
|
||||||
import Box from '@mui/material/Box'
|
|
||||||
|
|
||||||
// Third-party Imports
|
|
||||||
import { useForm, Controller } from 'react-hook-form'
|
|
||||||
|
|
||||||
// Component Imports
|
|
||||||
import CustomTextField from '@core/components/mui/TextField'
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
open: boolean
|
|
||||||
handleClose: () => void
|
|
||||||
setData?: (data: any) => void
|
|
||||||
}
|
|
||||||
|
|
||||||
type UnitConversionType = {
|
|
||||||
satuan: string
|
|
||||||
quantity: number
|
|
||||||
unit: string
|
|
||||||
hargaBeli: number
|
|
||||||
hargaJual: number
|
|
||||||
isDefault: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
type FormValidateType = {
|
|
||||||
conversions: UnitConversionType[]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vars
|
|
||||||
const initialConversion: UnitConversionType = {
|
|
||||||
satuan: 'Box',
|
|
||||||
quantity: 12,
|
|
||||||
unit: 'Pcs',
|
|
||||||
hargaBeli: 3588000,
|
|
||||||
hargaJual: 5988000,
|
|
||||||
isDefault: false
|
|
||||||
}
|
|
||||||
|
|
||||||
const IngedientUnitConversionDrawer = (props: Props) => {
|
|
||||||
// Props
|
|
||||||
const { open, handleClose, setData } = props
|
|
||||||
|
|
||||||
// States
|
|
||||||
const [conversions, setConversions] = useState<UnitConversionType[]>([initialConversion])
|
|
||||||
|
|
||||||
// Hooks
|
|
||||||
const {
|
|
||||||
control,
|
|
||||||
reset: resetForm,
|
|
||||||
handleSubmit,
|
|
||||||
formState: { errors }
|
|
||||||
} = useForm<FormValidateType>({
|
|
||||||
defaultValues: {
|
|
||||||
conversions: [initialConversion]
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Functions untuk konversi unit
|
|
||||||
const handleTambahBaris = () => {
|
|
||||||
const newConversion: UnitConversionType = {
|
|
||||||
satuan: '',
|
|
||||||
quantity: 0,
|
|
||||||
unit: '',
|
|
||||||
hargaBeli: 0,
|
|
||||||
hargaJual: 0,
|
|
||||||
isDefault: false
|
|
||||||
}
|
|
||||||
setConversions([...conversions, newConversion])
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleHapusBaris = (index: number) => {
|
|
||||||
if (conversions.length > 1) {
|
|
||||||
const newConversions = conversions.filter((_, i) => i !== index)
|
|
||||||
setConversions(newConversions)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleChangeConversion = (index: number, field: keyof UnitConversionType, value: any) => {
|
|
||||||
const newConversions = [...conversions]
|
|
||||||
newConversions[index] = { ...newConversions[index], [field]: value }
|
|
||||||
setConversions(newConversions)
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleToggleDefault = (index: number) => {
|
|
||||||
const newConversions = conversions.map((conversion, i) => ({
|
|
||||||
...conversion,
|
|
||||||
isDefault: i === index
|
|
||||||
}))
|
|
||||||
setConversions(newConversions)
|
|
||||||
}
|
|
||||||
|
|
||||||
const onSubmit = (data: FormValidateType) => {
|
|
||||||
console.log('Unit conversions:', conversions)
|
|
||||||
if (setData) {
|
|
||||||
setData(conversions)
|
|
||||||
}
|
|
||||||
handleClose()
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleReset = () => {
|
|
||||||
handleClose()
|
|
||||||
setConversions([initialConversion])
|
|
||||||
resetForm({ conversions: [initialConversion] })
|
|
||||||
}
|
|
||||||
|
|
||||||
const formatNumber = (value: number) => {
|
|
||||||
return new Intl.NumberFormat('id-ID').format(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
const parseNumber = (value: string) => {
|
|
||||||
return parseInt(value.replace(/\./g, '')) || 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Drawer
|
|
||||||
open={open}
|
|
||||||
anchor='right'
|
|
||||||
variant='temporary'
|
|
||||||
onClose={handleReset}
|
|
||||||
ModalProps={{ keepMounted: true }}
|
|
||||||
sx={{
|
|
||||||
'& .MuiDrawer-paper': {
|
|
||||||
width: { xs: 350, sm: 800 },
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
height: '100%'
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{/* Sticky Header */}
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
position: 'sticky',
|
|
||||||
top: 0,
|
|
||||||
zIndex: 10,
|
|
||||||
backgroundColor: 'background.paper',
|
|
||||||
borderBottom: 1,
|
|
||||||
borderColor: 'divider'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className='flex items-center justify-between plb-5 pli-6'>
|
|
||||||
<Typography variant='h5'>Konversi Unit Bahan</Typography>
|
|
||||||
<IconButton size='small' onClick={handleReset}>
|
|
||||||
<i className='tabler-x text-2xl text-textPrimary' />
|
|
||||||
</IconButton>
|
|
||||||
</div>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* Scrollable Content */}
|
|
||||||
<Box sx={{ flex: 1, overflowY: 'auto' }}>
|
|
||||||
<form id='unit-conversion-form' onSubmit={handleSubmit(data => onSubmit(data))}>
|
|
||||||
<div className='flex flex-col gap-6 p-6'>
|
|
||||||
{/* Header Kolom */}
|
|
||||||
<Grid container spacing={2} alignItems='center' className='bg-gray-50 p-3 rounded-lg'>
|
|
||||||
<Grid size={2}>
|
|
||||||
<Typography variant='body2' fontWeight='medium'>
|
|
||||||
Satuan
|
|
||||||
</Typography>
|
|
||||||
</Grid>
|
|
||||||
<Grid size={1} className='text-center'>
|
|
||||||
<Typography variant='body2' fontWeight='medium'>
|
|
||||||
=
|
|
||||||
</Typography>
|
|
||||||
</Grid>
|
|
||||||
<Grid size={1.5}>
|
|
||||||
<Typography variant='body2' fontWeight='medium'>
|
|
||||||
Jumlah
|
|
||||||
</Typography>
|
|
||||||
</Grid>
|
|
||||||
<Grid size={1.5}>
|
|
||||||
<Typography variant='body2' fontWeight='medium'>
|
|
||||||
Unit
|
|
||||||
</Typography>
|
|
||||||
</Grid>
|
|
||||||
<Grid size={2}>
|
|
||||||
<Typography variant='body2' fontWeight='medium'>
|
|
||||||
Harga Beli
|
|
||||||
</Typography>
|
|
||||||
</Grid>
|
|
||||||
<Grid size={2}>
|
|
||||||
<Typography variant='body2' fontWeight='medium'>
|
|
||||||
Harga Jual
|
|
||||||
</Typography>
|
|
||||||
</Grid>
|
|
||||||
<Grid size={1}>
|
|
||||||
<Typography variant='body2' fontWeight='medium'>
|
|
||||||
Default
|
|
||||||
</Typography>
|
|
||||||
</Grid>
|
|
||||||
<Grid size={1}>
|
|
||||||
<Typography variant='body2' fontWeight='medium'>
|
|
||||||
Action
|
|
||||||
</Typography>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{/* Baris Konversi */}
|
|
||||||
{conversions.map((conversion, index) => (
|
|
||||||
<Grid container spacing={2} alignItems='center' key={index} className='py-2'>
|
|
||||||
<Grid size={0.5}>
|
|
||||||
<Typography variant='body2' color='text.secondary'>
|
|
||||||
{index + 1}
|
|
||||||
</Typography>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{/* Satuan */}
|
|
||||||
<Grid size={1.5}>
|
|
||||||
<CustomTextField
|
|
||||||
select
|
|
||||||
fullWidth
|
|
||||||
size='small'
|
|
||||||
value={conversion.satuan}
|
|
||||||
onChange={e => handleChangeConversion(index, 'satuan', e.target.value)}
|
|
||||||
>
|
|
||||||
<MenuItem value='Box'>Box</MenuItem>
|
|
||||||
<MenuItem value='Kg'>Kg</MenuItem>
|
|
||||||
<MenuItem value='Liter'>Liter</MenuItem>
|
|
||||||
<MenuItem value='Pack'>Pack</MenuItem>
|
|
||||||
<MenuItem value='Pcs'>Pcs</MenuItem>
|
|
||||||
</CustomTextField>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{/* Tanda sama dengan */}
|
|
||||||
<Grid size={1} className='text-center'>
|
|
||||||
<Typography variant='h6'>=</Typography>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{/* Quantity */}
|
|
||||||
<Grid size={1.5}>
|
|
||||||
<CustomTextField
|
|
||||||
fullWidth
|
|
||||||
size='small'
|
|
||||||
type='number'
|
|
||||||
value={conversion.quantity}
|
|
||||||
onChange={e => handleChangeConversion(index, 'quantity', parseInt(e.target.value) || 0)}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{/* Unit */}
|
|
||||||
<Grid size={1.5}>
|
|
||||||
<CustomTextField
|
|
||||||
select
|
|
||||||
fullWidth
|
|
||||||
size='small'
|
|
||||||
value={conversion.unit}
|
|
||||||
onChange={e => handleChangeConversion(index, 'unit', e.target.value)}
|
|
||||||
>
|
|
||||||
<MenuItem value='Pcs'>Pcs</MenuItem>
|
|
||||||
<MenuItem value='Kg'>Kg</MenuItem>
|
|
||||||
<MenuItem value='Gram'>Gram</MenuItem>
|
|
||||||
<MenuItem value='Liter'>Liter</MenuItem>
|
|
||||||
<MenuItem value='ML'>ML</MenuItem>
|
|
||||||
</CustomTextField>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{/* Harga Beli */}
|
|
||||||
<Grid size={2}>
|
|
||||||
<CustomTextField
|
|
||||||
fullWidth
|
|
||||||
size='small'
|
|
||||||
value={formatNumber(conversion.hargaBeli)}
|
|
||||||
onChange={e => handleChangeConversion(index, 'hargaBeli', parseNumber(e.target.value))}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{/* Harga Jual */}
|
|
||||||
<Grid size={2}>
|
|
||||||
<CustomTextField
|
|
||||||
fullWidth
|
|
||||||
size='small'
|
|
||||||
value={formatNumber(conversion.hargaJual)}
|
|
||||||
onChange={e => handleChangeConversion(index, 'hargaJual', parseNumber(e.target.value))}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{/* Default Star */}
|
|
||||||
<Grid size={1} className='text-center'>
|
|
||||||
<IconButton
|
|
||||||
size='small'
|
|
||||||
onClick={() => handleToggleDefault(index)}
|
|
||||||
sx={{
|
|
||||||
color: conversion.isDefault ? 'warning.main' : 'grey.400'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<i className={conversion.isDefault ? 'tabler-star-filled' : 'tabler-star'} />
|
|
||||||
</IconButton>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{/* Delete Button */}
|
|
||||||
<Grid size={1} className='text-center'>
|
|
||||||
{conversions.length > 1 && (
|
|
||||||
<IconButton
|
|
||||||
size='small'
|
|
||||||
onClick={() => handleHapusBaris(index)}
|
|
||||||
sx={{
|
|
||||||
color: 'error.main',
|
|
||||||
border: 1,
|
|
||||||
borderColor: 'error.main',
|
|
||||||
'&:hover': {
|
|
||||||
backgroundColor: 'error.light',
|
|
||||||
borderColor: 'error.main'
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<i className='tabler-trash' />
|
|
||||||
</IconButton>
|
|
||||||
)}
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
))}
|
|
||||||
|
|
||||||
{/* Tambah Baris Button */}
|
|
||||||
<div className='flex items-center justify-start'>
|
|
||||||
<Button
|
|
||||||
variant='outlined'
|
|
||||||
startIcon={<i className='tabler-plus' />}
|
|
||||||
onClick={handleTambahBaris}
|
|
||||||
sx={{
|
|
||||||
color: 'primary.main',
|
|
||||||
borderColor: 'primary.main',
|
|
||||||
'&:hover': {
|
|
||||||
backgroundColor: 'primary.light',
|
|
||||||
borderColor: 'primary.main'
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Tambah baris
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* Sticky Footer */}
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
position: 'sticky',
|
|
||||||
bottom: 0,
|
|
||||||
zIndex: 10,
|
|
||||||
backgroundColor: 'background.paper',
|
|
||||||
borderTop: 1,
|
|
||||||
borderColor: 'divider',
|
|
||||||
p: 3
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className='flex items-center gap-4'>
|
|
||||||
<Button variant='contained' type='submit' form='unit-conversion-form'>
|
|
||||||
Simpan
|
|
||||||
</Button>
|
|
||||||
<Button variant='tonal' color='error' onClick={() => handleReset()}>
|
|
||||||
Batal
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</Box>
|
|
||||||
</Drawer>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default IngedientUnitConversionDrawer
|
|
||||||
@ -1,454 +0,0 @@
|
|||||||
'use client'
|
|
||||||
// React Imports
|
|
||||||
import { useEffect, useState } from 'react'
|
|
||||||
|
|
||||||
// MUI Imports
|
|
||||||
import Button from '@mui/material/Button'
|
|
||||||
import Drawer from '@mui/material/Drawer'
|
|
||||||
import IconButton from '@mui/material/IconButton'
|
|
||||||
import MenuItem from '@mui/material/MenuItem'
|
|
||||||
import Typography from '@mui/material/Typography'
|
|
||||||
import Grid from '@mui/material/Grid2'
|
|
||||||
import Box from '@mui/material/Box'
|
|
||||||
import Radio from '@mui/material/Radio'
|
|
||||||
import RadioGroup from '@mui/material/RadioGroup'
|
|
||||||
import FormControlLabel from '@mui/material/FormControlLabel'
|
|
||||||
import FormControl from '@mui/material/FormControl'
|
|
||||||
|
|
||||||
// Third-party Imports
|
|
||||||
import { useForm, Controller } from 'react-hook-form'
|
|
||||||
|
|
||||||
// Component Imports
|
|
||||||
import CustomTextField from '@core/components/mui/TextField'
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
open: boolean
|
|
||||||
handleClose: () => void
|
|
||||||
setData?: (data: any) => void
|
|
||||||
}
|
|
||||||
|
|
||||||
type StockAdjustmentType = {
|
|
||||||
tipeStok: 'perhitungan' | 'stokMasukKeluar'
|
|
||||||
gudang: string
|
|
||||||
tanggal: string
|
|
||||||
akun: string
|
|
||||||
nomor: string
|
|
||||||
referensi: string
|
|
||||||
tag: string
|
|
||||||
qtyTercatat: number
|
|
||||||
satuan: string
|
|
||||||
qtyAktual: number
|
|
||||||
selisih: number
|
|
||||||
hargaRataRata: number
|
|
||||||
}
|
|
||||||
|
|
||||||
type FormValidateType = StockAdjustmentType
|
|
||||||
|
|
||||||
// Vars
|
|
||||||
const initialData: StockAdjustmentType = {
|
|
||||||
tipeStok: 'perhitungan',
|
|
||||||
gudang: '',
|
|
||||||
tanggal: '11/09/2025',
|
|
||||||
akun: '8-80100 Penyesuaian Persediaan',
|
|
||||||
nomor: 'SA/00007',
|
|
||||||
referensi: '',
|
|
||||||
tag: '',
|
|
||||||
qtyTercatat: 0,
|
|
||||||
satuan: 'Pcs',
|
|
||||||
qtyAktual: 0,
|
|
||||||
selisih: 0,
|
|
||||||
hargaRataRata: 0
|
|
||||||
}
|
|
||||||
|
|
||||||
const IngredientDetailStockAdjustmentDrawer = (props: Props) => {
|
|
||||||
// Props
|
|
||||||
const { open, handleClose, setData } = props
|
|
||||||
|
|
||||||
// States
|
|
||||||
const [formData, setFormData] = useState<StockAdjustmentType>(initialData)
|
|
||||||
|
|
||||||
// Hooks
|
|
||||||
const {
|
|
||||||
control,
|
|
||||||
reset: resetForm,
|
|
||||||
handleSubmit,
|
|
||||||
watch,
|
|
||||||
setValue,
|
|
||||||
formState: { errors }
|
|
||||||
} = useForm<FormValidateType>({
|
|
||||||
defaultValues: initialData
|
|
||||||
})
|
|
||||||
|
|
||||||
// Watch values untuk kalkulasi otomatis
|
|
||||||
const qtyTercatat = watch('qtyTercatat')
|
|
||||||
const qtyAktual = watch('qtyAktual')
|
|
||||||
|
|
||||||
// Kalkulasi selisih otomatis
|
|
||||||
useEffect(() => {
|
|
||||||
const selisih = qtyAktual - qtyTercatat
|
|
||||||
setValue('selisih', selisih)
|
|
||||||
}, [qtyTercatat, qtyAktual, setValue])
|
|
||||||
|
|
||||||
const onSubmit = (data: FormValidateType) => {
|
|
||||||
console.log('Stock adjustment data:', data)
|
|
||||||
if (setData) {
|
|
||||||
setData(data)
|
|
||||||
}
|
|
||||||
handleClose()
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleReset = () => {
|
|
||||||
handleClose()
|
|
||||||
resetForm(initialData)
|
|
||||||
setFormData(initialData)
|
|
||||||
}
|
|
||||||
|
|
||||||
const formatNumber = (value: number) => {
|
|
||||||
return new Intl.NumberFormat('id-ID').format(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
const parseNumber = (value: string) => {
|
|
||||||
return parseInt(value.replace(/\./g, '')) || 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Drawer
|
|
||||||
open={open}
|
|
||||||
anchor='right'
|
|
||||||
variant='temporary'
|
|
||||||
onClose={handleReset}
|
|
||||||
ModalProps={{ keepMounted: true }}
|
|
||||||
sx={{
|
|
||||||
'& .MuiDrawer-paper': {
|
|
||||||
width: { xs: 400, sm: 600 },
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
height: '100%'
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{/* Sticky Header */}
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
position: 'sticky',
|
|
||||||
top: 0,
|
|
||||||
zIndex: 10,
|
|
||||||
backgroundColor: 'background.paper',
|
|
||||||
borderBottom: 1,
|
|
||||||
borderColor: 'divider'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className='flex items-center justify-between plb-5 pli-6'>
|
|
||||||
<Typography variant='h5'>Penyesuaian Stok</Typography>
|
|
||||||
<IconButton size='small' onClick={handleReset}>
|
|
||||||
<i className='tabler-x text-2xl text-textPrimary' />
|
|
||||||
</IconButton>
|
|
||||||
</div>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* Scrollable Content */}
|
|
||||||
<Box sx={{ flex: 1, overflowY: 'auto' }}>
|
|
||||||
<form id='stock-adjustment-form' onSubmit={handleSubmit(data => onSubmit(data))}>
|
|
||||||
<div className='flex flex-col gap-6 p-6'>
|
|
||||||
{/* Tipe Penyesuaian Stok */}
|
|
||||||
<div>
|
|
||||||
<Typography variant='body2' className='mb-3' sx={{ color: 'error.main' }}>
|
|
||||||
* Tipe penyesuaian stok
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name='tipeStok'
|
|
||||||
control={control}
|
|
||||||
rules={{ required: true }}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormControl component='fieldset'>
|
|
||||||
<RadioGroup {...field} row sx={{ gap: 4 }}>
|
|
||||||
<FormControlLabel
|
|
||||||
value='perhitungan'
|
|
||||||
control={<Radio />}
|
|
||||||
label={
|
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
|
||||||
<Typography>Perhitungan Stok</Typography>
|
|
||||||
<IconButton size='small' sx={{ color: 'text.secondary' }}>
|
|
||||||
<i className='tabler-help-circle' style={{ fontSize: '16px' }} />
|
|
||||||
</IconButton>
|
|
||||||
</Box>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<FormControlLabel
|
|
||||||
value='stokMasukKeluar'
|
|
||||||
control={<Radio />}
|
|
||||||
label={
|
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
|
||||||
<Typography>Stok Masuk / Keluar</Typography>
|
|
||||||
<IconButton size='small' sx={{ color: 'text.secondary' }}>
|
|
||||||
<i className='tabler-help-circle' style={{ fontSize: '16px' }} />
|
|
||||||
</IconButton>
|
|
||||||
</Box>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</RadioGroup>
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Gudang dan Tanggal */}
|
|
||||||
<Grid container spacing={4}>
|
|
||||||
<Grid size={6}>
|
|
||||||
<Typography variant='body2' className='mb-2' sx={{ color: 'error.main' }}>
|
|
||||||
* Gudang
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name='gudang'
|
|
||||||
control={control}
|
|
||||||
rules={{ required: true }}
|
|
||||||
render={({ field }) => (
|
|
||||||
<CustomTextField
|
|
||||||
{...field}
|
|
||||||
select
|
|
||||||
fullWidth
|
|
||||||
placeholder='Pilih gudang'
|
|
||||||
{...(errors.gudang && { error: true, helperText: 'Field ini wajib diisi.' })}
|
|
||||||
>
|
|
||||||
<MenuItem value=''>Pilih gudang</MenuItem>
|
|
||||||
<MenuItem value='Gudang Utama'>Gudang Utama</MenuItem>
|
|
||||||
<MenuItem value='Gudang Cabang'>Gudang Cabang</MenuItem>
|
|
||||||
<MenuItem value='Gudang Produksi'>Gudang Produksi</MenuItem>
|
|
||||||
</CustomTextField>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
<Grid size={6}>
|
|
||||||
<Typography variant='body2' className='mb-2' sx={{ color: 'error.main' }}>
|
|
||||||
* Tanggal
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name='tanggal'
|
|
||||||
control={control}
|
|
||||||
rules={{ required: true }}
|
|
||||||
render={({ field }) => (
|
|
||||||
<CustomTextField
|
|
||||||
{...field}
|
|
||||||
fullWidth
|
|
||||||
type='date'
|
|
||||||
{...(errors.tanggal && { error: true, helperText: 'Field ini wajib diisi.' })}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{/* Akun dan Nomor */}
|
|
||||||
<Grid container spacing={4}>
|
|
||||||
<Grid size={6}>
|
|
||||||
<Typography variant='body2' className='mb-2' sx={{ color: 'error.main' }}>
|
|
||||||
* Akun
|
|
||||||
<IconButton size='small' sx={{ color: 'text.secondary', ml: 1 }}>
|
|
||||||
<i className='tabler-help-circle' style={{ fontSize: '16px' }} />
|
|
||||||
</IconButton>
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name='akun'
|
|
||||||
control={control}
|
|
||||||
rules={{ required: true }}
|
|
||||||
render={({ field }) => (
|
|
||||||
<CustomTextField
|
|
||||||
{...field}
|
|
||||||
select
|
|
||||||
fullWidth
|
|
||||||
{...(errors.akun && { error: true, helperText: 'Field ini wajib diisi.' })}
|
|
||||||
>
|
|
||||||
<MenuItem value='8-80100 Penyesuaian Persediaan'>8-80100 Penyesuaian Persediaan</MenuItem>
|
|
||||||
<MenuItem value='8-80200 Penyesuaian Stok Rusak'>8-80200 Penyesuaian Stok Rusak</MenuItem>
|
|
||||||
<MenuItem value='8-80300 Penyesuaian Stok Hilang'>8-80300 Penyesuaian Stok Hilang</MenuItem>
|
|
||||||
</CustomTextField>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
<Grid size={6}>
|
|
||||||
<Typography variant='body2' className='mb-2'>
|
|
||||||
Nomor
|
|
||||||
<IconButton size='small' sx={{ color: 'text.secondary', ml: 1 }}>
|
|
||||||
<i className='tabler-help-circle' style={{ fontSize: '16px' }} />
|
|
||||||
</IconButton>
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name='nomor'
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => <CustomTextField {...field} fullWidth placeholder='SA/00007' />}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{/* Referensi dan Tag */}
|
|
||||||
<Grid container spacing={4}>
|
|
||||||
<Grid size={6}>
|
|
||||||
<Typography variant='body2' className='mb-2'>
|
|
||||||
Referensi
|
|
||||||
<IconButton size='small' sx={{ color: 'text.secondary', ml: 1 }}>
|
|
||||||
<i className='tabler-help-circle' style={{ fontSize: '16px' }} />
|
|
||||||
</IconButton>
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name='referensi'
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => <CustomTextField {...field} fullWidth placeholder='Referensi' />}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
<Grid size={6}>
|
|
||||||
<Typography variant='body2' className='mb-2'>
|
|
||||||
Tag
|
|
||||||
<IconButton size='small' sx={{ color: 'text.secondary', ml: 1 }}>
|
|
||||||
<i className='tabler-help-circle' style={{ fontSize: '16px' }} />
|
|
||||||
</IconButton>
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name='tag'
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<CustomTextField {...field} select fullWidth placeholder='Pilih Tag'>
|
|
||||||
<MenuItem value=''>Pilih Tag</MenuItem>
|
|
||||||
<MenuItem value='Urgent'>Urgent</MenuItem>
|
|
||||||
<MenuItem value='Regular'>Regular</MenuItem>
|
|
||||||
<MenuItem value='Maintenance'>Maintenance</MenuItem>
|
|
||||||
</CustomTextField>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{/* Stock Details Section */}
|
|
||||||
<Box sx={{ mt: 4 }}>
|
|
||||||
<Grid container spacing={2} alignItems='end'>
|
|
||||||
{/* Qty Tercatat */}
|
|
||||||
<Grid size={2}>
|
|
||||||
<Typography variant='body2' className='mb-2 font-medium'>
|
|
||||||
Qty Tercatat
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name='qtyTercatat'
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<CustomTextField
|
|
||||||
{...field}
|
|
||||||
fullWidth
|
|
||||||
type='number'
|
|
||||||
onChange={e => field.onChange(parseInt(e.target.value) || 0)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{/* Satuan */}
|
|
||||||
<Grid size={2}>
|
|
||||||
<Typography variant='body2' className='mb-2 font-medium'>
|
|
||||||
Satuan
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name='satuan'
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<CustomTextField {...field} select fullWidth>
|
|
||||||
<MenuItem value='Pcs'>Pcs</MenuItem>
|
|
||||||
<MenuItem value='Kg'>Kg</MenuItem>
|
|
||||||
<MenuItem value='Liter'>Liter</MenuItem>
|
|
||||||
<MenuItem value='Box'>Box</MenuItem>
|
|
||||||
</CustomTextField>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{/* Qty Aktual */}
|
|
||||||
<Grid size={2}>
|
|
||||||
<Typography variant='body2' className='mb-2 font-medium'>
|
|
||||||
Qty Aktual
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name='qtyAktual'
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<CustomTextField
|
|
||||||
{...field}
|
|
||||||
fullWidth
|
|
||||||
type='number'
|
|
||||||
onChange={e => field.onChange(parseInt(e.target.value) || 0)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{/* Selisih */}
|
|
||||||
<Grid size={2}>
|
|
||||||
<Typography variant='body2' className='mb-2 font-medium'>
|
|
||||||
Selisih
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name='selisih'
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<CustomTextField
|
|
||||||
{...field}
|
|
||||||
fullWidth
|
|
||||||
type='number'
|
|
||||||
disabled
|
|
||||||
sx={{
|
|
||||||
'& .MuiInputBase-input.Mui-disabled': {
|
|
||||||
WebkitTextFillColor: 'text.primary',
|
|
||||||
backgroundColor: 'grey.100'
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{/* Harga Rata-rata */}
|
|
||||||
<Grid size={4}>
|
|
||||||
<Typography variant='body2' className='mb-2 font-medium'>
|
|
||||||
Harga Rata-rata
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name='hargaRataRata'
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<CustomTextField
|
|
||||||
{...field}
|
|
||||||
fullWidth
|
|
||||||
value={formatNumber(field.value)}
|
|
||||||
onChange={e => field.onChange(parseNumber(e.target.value))}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</Box>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* Sticky Footer */}
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
position: 'sticky',
|
|
||||||
bottom: 0,
|
|
||||||
zIndex: 10,
|
|
||||||
backgroundColor: 'background.paper',
|
|
||||||
borderTop: 1,
|
|
||||||
borderColor: 'divider',
|
|
||||||
p: 3
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className='flex items-center gap-4'>
|
|
||||||
<Button variant='contained' type='submit' form='stock-adjustment-form'>
|
|
||||||
Simpan
|
|
||||||
</Button>
|
|
||||||
<Button variant='tonal' color='error' onClick={() => handleReset()}>
|
|
||||||
Batal
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</Box>
|
|
||||||
</Drawer>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default IngredientDetailStockAdjustmentDrawer
|
|
||||||
@ -1,30 +1,8 @@
|
|||||||
'use client'
|
import React from 'react'
|
||||||
import React, { useState } from 'react'
|
|
||||||
import { Card, CardContent, CardHeader, Typography, Button, Box, Stack } from '@mui/material'
|
import { Card, CardContent, CardHeader, Typography, Button, Box, Stack } from '@mui/material'
|
||||||
import IngedientUnitConversionDrawer from './IngedientUnitConversionDrawer' // Sesuaikan dengan path file Anda
|
|
||||||
|
|
||||||
const IngredientDetailUnit = () => {
|
const IngredientDetailUnit = () => {
|
||||||
// State untuk mengontrol drawer
|
|
||||||
const [openConversionDrawer, setOpenConversionDrawer] = useState(false)
|
|
||||||
|
|
||||||
// Function untuk membuka drawer
|
|
||||||
const handleOpenConversionDrawer = () => {
|
|
||||||
setOpenConversionDrawer(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function untuk menutup drawer
|
|
||||||
const handleCloseConversionDrawer = () => {
|
|
||||||
setOpenConversionDrawer(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function untuk handle data dari drawer (opsional)
|
|
||||||
const handleSetConversionData = (data: any) => {
|
|
||||||
console.log('Conversion data received:', data)
|
|
||||||
// Anda bisa menambahkan logic untuk mengupdate state atau API call di sini
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
|
||||||
<Card sx={{ maxWidth: 400 }}>
|
<Card sx={{ maxWidth: 400 }}>
|
||||||
<CardHeader title='Satuan' />
|
<CardHeader title='Satuan' />
|
||||||
<CardContent>
|
<CardContent>
|
||||||
@ -43,7 +21,6 @@ const IngredientDetailUnit = () => {
|
|||||||
variant='contained'
|
variant='contained'
|
||||||
fullWidth
|
fullWidth
|
||||||
startIcon={<span style={{ fontSize: '18px' }}>+</span>}
|
startIcon={<span style={{ fontSize: '18px' }}>+</span>}
|
||||||
onClick={handleOpenConversionDrawer}
|
|
||||||
sx={{
|
sx={{
|
||||||
py: 1.5,
|
py: 1.5,
|
||||||
borderRadius: 2,
|
borderRadius: 2,
|
||||||
@ -55,14 +32,6 @@ const IngredientDetailUnit = () => {
|
|||||||
</Button>
|
</Button>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
{/* Ingredient Unit Conversion Drawer */}
|
|
||||||
<IngedientUnitConversionDrawer
|
|
||||||
open={openConversionDrawer}
|
|
||||||
handleClose={handleCloseConversionDrawer}
|
|
||||||
setData={handleSetConversionData}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,67 +1,17 @@
|
|||||||
'use client'
|
|
||||||
|
|
||||||
import { useState } from 'react'
|
|
||||||
import Grid from '@mui/material/Grid2'
|
import Grid from '@mui/material/Grid2'
|
||||||
import IngredientDetailInfo from './IngredientDetailInfo'
|
import IngredientDetailInfo from './IngredientDetailInfo'
|
||||||
import IngredientDetailUnit from './IngredientDetailUnit'
|
import IngredientDetailUnit from './IngredientDetailUnit'
|
||||||
import IngredientDetailStockAdjustmentDrawer from './IngredientDetailStockAdjustmentDrawer' // Sesuaikan dengan path file Anda
|
|
||||||
import { Button } from '@mui/material'
|
|
||||||
|
|
||||||
const IngredientDetail = () => {
|
const IngredientDetail = () => {
|
||||||
// State untuk mengontrol stock adjustment drawer
|
|
||||||
const [openStockAdjustmentDrawer, setOpenStockAdjustmentDrawer] = useState(false)
|
|
||||||
|
|
||||||
// Function untuk membuka stock adjustment drawer
|
|
||||||
const handleOpenStockAdjustmentDrawer = () => {
|
|
||||||
setOpenStockAdjustmentDrawer(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function untuk menutup stock adjustment drawer
|
|
||||||
const handleCloseStockAdjustmentDrawer = () => {
|
|
||||||
setOpenStockAdjustmentDrawer(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function untuk handle data dari stock adjustment drawer
|
|
||||||
const handleSetStockAdjustmentData = (data: any) => {
|
|
||||||
console.log('Stock adjustment data received:', data)
|
|
||||||
// Anda bisa menambahkan logic untuk mengupdate state atau API call di sini
|
|
||||||
// Misalnya: update stock data, refresh ingredient data, dll.
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
|
||||||
<Grid container spacing={6}>
|
<Grid container spacing={6}>
|
||||||
<Grid size={{ xs: 12, lg: 8, md: 7 }}>
|
<Grid size={{ xs: 12, lg: 8, md: 7 }}>
|
||||||
<IngredientDetailInfo />
|
<IngredientDetailInfo />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid size={{ xs: 12, lg: 4, md: 5 }}>
|
<Grid size={{ xs: 12, lg: 4, md: 5 }}>
|
||||||
<Button
|
|
||||||
variant='contained'
|
|
||||||
fullWidth
|
|
||||||
startIcon={<span style={{ fontSize: '18px' }}>+</span>}
|
|
||||||
onClick={handleOpenStockAdjustmentDrawer}
|
|
||||||
className='mb-4'
|
|
||||||
sx={{
|
|
||||||
py: 1.5,
|
|
||||||
borderRadius: 2,
|
|
||||||
textTransform: 'none',
|
|
||||||
fontSize: '16px',
|
|
||||||
mb: 3 // Menambahkan margin bottom untuk spacing
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Penyesuaian Stok
|
|
||||||
</Button>
|
|
||||||
<IngredientDetailUnit />
|
<IngredientDetailUnit />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
{/* Stock Adjustment Drawer */}
|
|
||||||
<IngredientDetailStockAdjustmentDrawer
|
|
||||||
open={openStockAdjustmentDrawer}
|
|
||||||
handleClose={handleCloseStockAdjustmentDrawer}
|
|
||||||
setData={handleSetStockAdjustmentData}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user