done next login
parent
4029cd099f
commit
724212f714
@ -0,0 +1,129 @@
|
|||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import { toast } from 'react-toastify'
|
||||||
|
import { Modal } from '@/Components/Modal'
|
||||||
|
import { useForm } from '@inertiajs/inertia-react'
|
||||||
|
import Button from '@/Components/Button'
|
||||||
|
import Input from '@/Components/Input'
|
||||||
|
import { getAll } from '@/Services/Karyawan'
|
||||||
|
import { create } from '@/Services/Absensi'
|
||||||
|
|
||||||
|
export default function FormModal({ modalState, periode }) {
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
const { data, setData, reset } = useForm({
|
||||||
|
users: []
|
||||||
|
})
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getAll()
|
||||||
|
.then(items => setData({
|
||||||
|
users: items.filter(item => item.data.jabatan.id != "1").map(item => {
|
||||||
|
return {
|
||||||
|
id: item.id,
|
||||||
|
name: item.data.name,
|
||||||
|
nik: item.data.nik,
|
||||||
|
jenisKelamin: item.data.jenisKelamin,
|
||||||
|
jabatan: item.data.jabatan.nama,
|
||||||
|
jabatan_id: item.data.jabatan.id,
|
||||||
|
hadir: 0,
|
||||||
|
sakit: 0,
|
||||||
|
alfa: 0,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
},[modalState])
|
||||||
|
|
||||||
|
const onHandleChange = (item, event) => {
|
||||||
|
setData({
|
||||||
|
users: data.users.map(user => {
|
||||||
|
if (user.id == item.id) {
|
||||||
|
user[event.target.name] = event.target.value
|
||||||
|
}
|
||||||
|
return user
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const submit = (e) => {
|
||||||
|
e.preventDefault()
|
||||||
|
setLoading(true)
|
||||||
|
create({
|
||||||
|
...data,
|
||||||
|
periode: periode,
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
reset()
|
||||||
|
modalState.toggle()
|
||||||
|
toast.success("berhasil menambahkan absensi")
|
||||||
|
})
|
||||||
|
.finally(() => setLoading(false))
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal isOpen={modalState.isOpen} toggleModal={modalState.toggle} size="2xl">
|
||||||
|
<div className="text-lg font-bold">Absensi Karyawan</div>
|
||||||
|
<div className="text-md">Periode : {periode}</div>
|
||||||
|
<div className="overflow-x-auto relative pt-5">
|
||||||
|
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
||||||
|
<thead className="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
|
||||||
|
<tr>
|
||||||
|
<th scope="col" className="py-3 px-6">
|
||||||
|
NIK
|
||||||
|
</th>
|
||||||
|
<th scope="col" className="py-3 px-6">
|
||||||
|
Nama
|
||||||
|
</th>
|
||||||
|
<th scope="col" className="py-3 px-6">
|
||||||
|
Jenis Kelamin
|
||||||
|
</th>
|
||||||
|
<th scope="col" className="py-3 px-6">
|
||||||
|
Jabatan
|
||||||
|
</th>
|
||||||
|
<th scope="col" className="py-3 px-6">Hadir</th>
|
||||||
|
<th scope="col" className="py-3 px-6">Sakit</th>
|
||||||
|
<th scope="col" className="py-3 px-6">Alfa</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{data.users.map(item => (
|
||||||
|
<tr key={item.id} className="bg-white border-b dark:bg-gray-800 dark:border-gray-700">
|
||||||
|
<th scope="row" className="py-4 px-6 font-medium text-gray-900 whitespace-nowrap dark:text-white">
|
||||||
|
{item.nik}
|
||||||
|
</th>
|
||||||
|
<td className="py-4 px-6">
|
||||||
|
{item.name}
|
||||||
|
</td>
|
||||||
|
<td className="py-4 px-6">
|
||||||
|
{item.jenisKelamin}
|
||||||
|
</td>
|
||||||
|
<td className="py-4 px-6">
|
||||||
|
{item.jabatan}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<Input
|
||||||
|
name="hadir"
|
||||||
|
value={item.hadir}
|
||||||
|
handleChange={(e) => onHandleChange(item, e)}/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<Input
|
||||||
|
name="sakit"
|
||||||
|
value={item.sakit}
|
||||||
|
handleChange={(e) => onHandleChange(item, e)}/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<Input
|
||||||
|
name="alfa"
|
||||||
|
value={item.alfa}
|
||||||
|
handleChange={(e) => onHandleChange(item, e)}/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<Button className={'mt-4'} onClick={submit} disabled={loading} processing={loading}>
|
||||||
|
Save
|
||||||
|
</Button>
|
||||||
|
</Modal>
|
||||||
|
)
|
||||||
|
}
|
@ -0,0 +1,265 @@
|
|||||||
|
import React, { useRef, useState } from 'react';
|
||||||
|
import Authenticated from '@/Layouts/Authenticated';
|
||||||
|
import { Head, useForm } from '@inertiajs/inertia-react';
|
||||||
|
import { useModalState } from '@/Hooks'
|
||||||
|
import Button from '@/Components/Button';
|
||||||
|
import FormModal from './FormModal';
|
||||||
|
import { getDataGaji } from '@/Services/DataGaji';
|
||||||
|
import { useReactToPrint } from 'react-to-print';
|
||||||
|
import { formatIDR } from '@/Utils';
|
||||||
|
|
||||||
|
const ComponentToPrint = React.forwardRef(({ items, month, year }, ref) => {
|
||||||
|
const date = new Date()
|
||||||
|
return (
|
||||||
|
<div ref={ref} className="p-5 print-only">
|
||||||
|
<div className='w-full text-center p-2'>
|
||||||
|
<p className='font-bold text-3xl'>Koro Koro Family Karaoke</p>
|
||||||
|
<p className='text-xl'>Periode Gaji Bulan {month} Tahun {year}</p>
|
||||||
|
</div>
|
||||||
|
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400 mt-5 block whitespace-nowrap">
|
||||||
|
<thead className="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
|
||||||
|
<tr>
|
||||||
|
<th scope="col" className="py-3 px-6">
|
||||||
|
NIK
|
||||||
|
</th>
|
||||||
|
<th scope="col" className="py-3 px-6">
|
||||||
|
Nama
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
Jabatan
|
||||||
|
</th>
|
||||||
|
<th scope="col" className='px-2'>
|
||||||
|
Gaji Pokok
|
||||||
|
</th>
|
||||||
|
<th scope="col" className='px-2'>
|
||||||
|
Tunjangan
|
||||||
|
</th>
|
||||||
|
<th scope="col" className='px-2'>
|
||||||
|
Fee Penjualan
|
||||||
|
</th>
|
||||||
|
<th scope="col" className='px-2'>
|
||||||
|
Uang Transport
|
||||||
|
</th>
|
||||||
|
<th scope="col" className='px-2'>
|
||||||
|
Uang Makan
|
||||||
|
</th>
|
||||||
|
<th scope="col" className='px-2'>
|
||||||
|
Bonus
|
||||||
|
</th>
|
||||||
|
<th scope="col" className='px-2'>
|
||||||
|
Potongan
|
||||||
|
</th>
|
||||||
|
<th scope="col" className='px-2'>
|
||||||
|
Total
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{items.map(item => (
|
||||||
|
<tr key={item.id} className="bg-white border-b dark:bg-gray-800 dark:border-gray-700">
|
||||||
|
<th scope="row" className="py-4 px-6 font-medium text-gray-900 whitespace-nowrap dark:text-white">
|
||||||
|
{item.nik}
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
{item.name}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{item.jabatan}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
Rp. {formatIDR(item.gajiPokok)}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
Rp. {formatIDR(item.tunjangan)}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
Rp. {formatIDR(item.feePenjualan)}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
Rp. {formatIDR(item.transport)}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
Rp. {formatIDR(item.uangMakan)}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
Rp. {formatIDR(item.bonus)}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
Rp. {formatIDR(item.potongan)}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
Rp. {formatIDR(item.total)}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div className='flex justify-end mt-5 mr-5'>
|
||||||
|
<div className='flex flex-col'>
|
||||||
|
<p>Pekanbaru, {date.getDate()}-{date.getMonth()}-{date.getFullYear()}</p>
|
||||||
|
<p>Finance</p>
|
||||||
|
<div className='border-black border-2 mt-20'/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
export default function Gaji(props) {
|
||||||
|
const formModal = useModalState(false)
|
||||||
|
|
||||||
|
const componentRef = useRef();
|
||||||
|
const handlePrint = useReactToPrint({
|
||||||
|
content: () => componentRef.current,
|
||||||
|
});
|
||||||
|
|
||||||
|
const month = (new Date()).getMonth()
|
||||||
|
const year = (new Date()).getFullYear()
|
||||||
|
const months = [1,2,3,4,5,6,7,8,9,10,11,12]
|
||||||
|
const years = [+year-2, +year-1, year, +year+1, +year+2]
|
||||||
|
|
||||||
|
const {data, setData} = useForm({
|
||||||
|
month: month,
|
||||||
|
year: year
|
||||||
|
})
|
||||||
|
|
||||||
|
const onHandleChange = (event) => {
|
||||||
|
setData(
|
||||||
|
event.target.name,
|
||||||
|
event.target.type === 'checkbox'
|
||||||
|
? event.target.checked
|
||||||
|
: event.target.value
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const [items, setItems] = useState([])
|
||||||
|
const onClickShow = () => {
|
||||||
|
getDataGaji(`${data.month}_${data.year}`, setItems)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Authenticated
|
||||||
|
auth={props.auth}
|
||||||
|
errors={props.errors}
|
||||||
|
>
|
||||||
|
<Head title="Data Gaji" />
|
||||||
|
|
||||||
|
<div className="py-0">
|
||||||
|
<div className="max-w-3xl xl:max-w-7xl w-full sm:px-6">
|
||||||
|
<div className="bg-white overflow-hidden shadow-sm sm:rounded-lg">
|
||||||
|
<div className="p-6 bg-white border-b border-gray-200">
|
||||||
|
<div className='mb-5 text-3xl font-semibold'>
|
||||||
|
Data Gaji
|
||||||
|
</div>
|
||||||
|
<div className='flex flex-col md:flex-row space-y-1 md:space-y-0 justify-between'>
|
||||||
|
<div className='flex space-x-1 items-center'>
|
||||||
|
<p>Periode Data :</p>
|
||||||
|
<select className='select' value={data.month} name="month" onChange={onHandleChange}>
|
||||||
|
<option value="">Bulan</option>
|
||||||
|
{months.map(month => (
|
||||||
|
<option key={month}>{month}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
<select className='select' value={data.year} name="year" onChange={onHandleChange}>
|
||||||
|
<option>Tahun</option>
|
||||||
|
{years.map(year => (
|
||||||
|
<option key={year}>{year}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className='flex space-x-1'>
|
||||||
|
<Button onClick={onClickShow}>Tampilkan Data</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ComponentToPrint ref={componentRef} items={items} month={data.month} year={data.year}/>
|
||||||
|
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400 mt-5 block overflow-x-auto whitespace-nowrap">
|
||||||
|
<thead className="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
|
||||||
|
<tr>
|
||||||
|
<th scope="col" className="py-3 px-6">
|
||||||
|
NIK
|
||||||
|
</th>
|
||||||
|
<th scope="col" className="py-3 px-6">
|
||||||
|
Nama
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
Jabatan
|
||||||
|
</th>
|
||||||
|
<th scope="col" className='px-2'>
|
||||||
|
Gaji Pokok
|
||||||
|
</th>
|
||||||
|
<th scope="col" className='px-2'>
|
||||||
|
Tunjangan
|
||||||
|
</th>
|
||||||
|
<th scope="col" className='px-2'>
|
||||||
|
Fee Penjualan
|
||||||
|
</th>
|
||||||
|
<th scope="col" className='px-2'>
|
||||||
|
Uang Transport
|
||||||
|
</th>
|
||||||
|
<th scope="col" className='px-2'>
|
||||||
|
Uang Makan
|
||||||
|
</th>
|
||||||
|
<th scope="col" className='px-2'>
|
||||||
|
Bonus
|
||||||
|
</th>
|
||||||
|
<th scope="col" className='px-2'>
|
||||||
|
Potongan
|
||||||
|
</th>
|
||||||
|
<th scope="col" className='px-2'>
|
||||||
|
Total
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{items.map(item => (
|
||||||
|
<tr key={item.id} className="bg-white border-b dark:bg-gray-800 dark:border-gray-700">
|
||||||
|
<th scope="row" className="py-4 px-6 font-medium text-gray-900 whitespace-nowrap dark:text-white">
|
||||||
|
{item.nik}
|
||||||
|
</th>
|
||||||
|
<td className="py-4 px-6">
|
||||||
|
{item.name}
|
||||||
|
</td>
|
||||||
|
<td className="py-4 px-6">
|
||||||
|
{item.jabatan}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
Rp. {formatIDR(item.gajiPokok)}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
Rp. {formatIDR(item.tunjangan)}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
Rp. {formatIDR(item.feePenjualan)}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
Rp. {formatIDR(item.transport)}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
Rp. {formatIDR(item.uangMakan)}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
Rp. {formatIDR(item.bonus)}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
Rp. {formatIDR(item.potongan)}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
Rp. {formatIDR(item.total)}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{items.length > 0 && (
|
||||||
|
<div className='flex justify-end'>
|
||||||
|
<Button onClick={handlePrint} className="mt-2">Cetak</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<FormModal modalState={formModal} periode={`${data.month}_${data.year}`}/>
|
||||||
|
</Authenticated>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,195 @@
|
|||||||
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
|
import Authenticated from '@/Layouts/Authenticated';
|
||||||
|
import { Head, useForm } from '@inertiajs/inertia-react';
|
||||||
|
import { useModalState } from '@/Hooks'
|
||||||
|
import Button from '@/Components/Button';
|
||||||
|
import FormModal from './FormModal';
|
||||||
|
import { getDataGaji } from '@/Services/DataGaji';
|
||||||
|
import { useReactToPrint } from 'react-to-print';
|
||||||
|
import { formatIDR } from '@/Utils';
|
||||||
|
|
||||||
|
const ComponentToPrint = React.forwardRef(({ user, month, year }, ref) => {
|
||||||
|
const date = new Date()
|
||||||
|
return (
|
||||||
|
<div ref={ref} className="p-5 print-only">
|
||||||
|
<div className='w-full text-center p-2 flex flex-col justify-center items-center'>
|
||||||
|
<p className='font-bold text-3xl'>Koro Koro Family Karaoke</p>
|
||||||
|
<p className='text-xl border-b-2 w-2/3'>Slip Gaji Pegawai</p>
|
||||||
|
</div>
|
||||||
|
<table className='ml-10'>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>Nama Karyawan </td>
|
||||||
|
<td>: {user?.name}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>NIK </td>
|
||||||
|
<td>: {user?.nik}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Jabatan </td>
|
||||||
|
<td>: {user?.jabatan}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Bulan </td>
|
||||||
|
<td>: {month}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Tahun</td>
|
||||||
|
<td>: {year}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<table className="w-full text-sm text-left text-gray-800 dark:text-gray-400 mt-5" border={1}>
|
||||||
|
<tbody>
|
||||||
|
<tr className="bg-white border dark:bg-gray-800 dark:border-gray-700">
|
||||||
|
<td className="border px-2 py-2 font-bold">No</td>
|
||||||
|
<td className="border px-2 py-2 font-bold">Keterangan</td>
|
||||||
|
<td className="border px-2 py-2 font-bold">Jumlah</td>
|
||||||
|
</tr>
|
||||||
|
<tr className="bg-white border dark:bg-gray-800 dark:border-gray-700">
|
||||||
|
<td className="border px-2 py-2">1</td>
|
||||||
|
<td className="border px-2 py-2">Gaji Pokok</td>
|
||||||
|
<td className="border px-2 py-2">Rp. {formatIDR(user?.gajiPokok)}</td>
|
||||||
|
</tr>
|
||||||
|
<tr className="bg-white border dark:bg-gray-800 dark:border-gray-700">
|
||||||
|
<td className="border px-2 py-2">2</td>
|
||||||
|
<td className="border px-2 py-2">Tunjangan Jabatan</td>
|
||||||
|
<td className="border px-2 py-2">Rp. {formatIDR(user?.tunjangan)}</td>
|
||||||
|
</tr>
|
||||||
|
<tr className="bg-white border dark:bg-gray-800 dark:border-gray-700">
|
||||||
|
<td className="border px-2 py-2">3</td>
|
||||||
|
<td className="border px-2 py-2">Fee Penjualan</td>
|
||||||
|
<td className="border px-2 py-2">Rp. {formatIDR(user?.feePenjualan)}</td>
|
||||||
|
</tr>
|
||||||
|
<tr className="bg-white border dark:bg-gray-800 dark:border-gray-700">
|
||||||
|
<td className="border px-2 py-2">4</td>
|
||||||
|
<td className="border px-2 py-2">Tunjangan Transaportasi</td>
|
||||||
|
<td className="border px-2 py-2">Rp. {formatIDR(user?.transport)}</td>
|
||||||
|
</tr>
|
||||||
|
<tr className="bg-white border dark:bg-gray-800 dark:border-gray-700">
|
||||||
|
<td className="border px-2 py-2">5</td>
|
||||||
|
<td className="border px-2 py-2">Uang Makan</td>
|
||||||
|
<td className="border px-2 py-2">Rp. {formatIDR(user?.uangMakan)}</td>
|
||||||
|
</tr>
|
||||||
|
<tr className="bg-white border dark:bg-gray-800 dark:border-gray-700">
|
||||||
|
<td className="border px-2 py-2">6</td>
|
||||||
|
<td className="border px-2 py-2">Bonus</td>
|
||||||
|
<td className="border px-2 py-2">Rp. {formatIDR(user?.bonus)}</td>
|
||||||
|
</tr>
|
||||||
|
<tr className="bg-white border dark:bg-gray-800 dark:border-gray-700">
|
||||||
|
<td className="border px-2 py-2">7</td>
|
||||||
|
<td className="border px-2 py-2">Potongan</td>
|
||||||
|
<td className="border px-2 py-2">Rp. {formatIDR(user?.potongan)}</td>
|
||||||
|
</tr>
|
||||||
|
<tr className="bg-white border dark:bg-gray-800 dark:border-gray-700">
|
||||||
|
<td colSpan={2} className="text-right font-bold">Total Gaji</td>
|
||||||
|
<td className="border px-2 py-2">Rp. {formatIDR(user?.total)}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div className='flex justify-between mt-5 mr-5'>
|
||||||
|
<div className='flex flex-col ml-10'>
|
||||||
|
<p>Pegawai</p>
|
||||||
|
<div className='mt-20'>{user?.name}</div>
|
||||||
|
</div>
|
||||||
|
<div className='flex flex-col'>
|
||||||
|
<p>Pekanbaru, {date.getDate()}-{date.getMonth()}-{date.getFullYear()}</p>
|
||||||
|
<p>Finance</p>
|
||||||
|
<div className='border-black border-2 mt-20'/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
export default function Gaji(props) {
|
||||||
|
const formModal = useModalState(false)
|
||||||
|
|
||||||
|
const componentRef = useRef();
|
||||||
|
const handlePrint = useReactToPrint({
|
||||||
|
content: () => componentRef.current,
|
||||||
|
});
|
||||||
|
|
||||||
|
const month = (new Date()).getMonth()
|
||||||
|
const year = (new Date()).getFullYear()
|
||||||
|
const months = [1,2,3,4,5,6,7,8,9,10,11,12]
|
||||||
|
const years = [+year-2, +year-1, year, +year+1, +year+2]
|
||||||
|
|
||||||
|
const {data, setData} = useForm({
|
||||||
|
month: month,
|
||||||
|
year: year,
|
||||||
|
userId: '',
|
||||||
|
})
|
||||||
|
console.log(data.userId)
|
||||||
|
const onHandleChange = (event) => {
|
||||||
|
setData(
|
||||||
|
event.target.name,
|
||||||
|
event.target.type === 'checkbox'
|
||||||
|
? event.target.checked
|
||||||
|
: event.target.value
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const [items, setItems] = useState([])
|
||||||
|
const user = items.find(item => item.id == data.userId)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getDataGaji(`${data.month}_${data.year}`, setItems)
|
||||||
|
}, [data])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Authenticated
|
||||||
|
auth={props.auth}
|
||||||
|
errors={props.errors}
|
||||||
|
>
|
||||||
|
<Head title="Slip Gaji" />
|
||||||
|
|
||||||
|
<div className="py-0">
|
||||||
|
<div className="max-w-3xl xl:max-w-7xl w-full sm:px-6">
|
||||||
|
<div className="bg-white overflow-hidden shadow-sm sm:rounded-lg">
|
||||||
|
<div className="p-6 bg-white border-b border-gray-200">
|
||||||
|
<div className='mb-5 text-3xl font-semibold'>
|
||||||
|
Slip Gaji
|
||||||
|
</div>
|
||||||
|
<div className='flex flex-col space-y-2 justify-center'>
|
||||||
|
<div className='flex flex-row items-center space-x-2'>
|
||||||
|
<label>Bulan</label>
|
||||||
|
<select className='select' value={data.month} name="month" onChange={onHandleChange}>
|
||||||
|
<option value="">Bulan</option>
|
||||||
|
{months.map(month => (
|
||||||
|
<option key={month}>{month}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className='flex flex-row items-center space-x-2'>
|
||||||
|
<label>Tahun</label>
|
||||||
|
<select className='select' value={data.year} name="year" onChange={onHandleChange}>
|
||||||
|
<option>Tahun</option>
|
||||||
|
{years.map(year => (
|
||||||
|
<option key={year}>{year}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className='flex flex-row items-center space-x-2'>
|
||||||
|
<label>Karyawan</label>
|
||||||
|
<select className='select' value={data.userId} name="userId" onChange={onHandleChange}>
|
||||||
|
<option value="">Karyawan</option>
|
||||||
|
{items.map(em => (
|
||||||
|
<option key={em.id} value={em.id}>{em.name}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Button onClick={handlePrint}>Cetak</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ComponentToPrint ref={componentRef} user={user} month={data.month} year={data.year}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<FormModal modalState={formModal} periode={`${data.month}_${data.year}`}/>
|
||||||
|
</Authenticated>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
import { getByPeriode } from './Absensi'
|
||||||
|
import { getAll as getJabatan } from './Jabatan'
|
||||||
|
import { getAll as getPotongan } from './SettingPotonganGaji'
|
||||||
|
import { toast } from "react-toastify";
|
||||||
|
|
||||||
|
async function getDataGaji(periode, setLists) {
|
||||||
|
let potongan = []
|
||||||
|
getJabatan()
|
||||||
|
.then(jabatans => {
|
||||||
|
getByPeriode(periode).then(items => {
|
||||||
|
if(items[0] == undefined) {
|
||||||
|
setLists([])
|
||||||
|
toast.error("data tidak tersedia")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
getPotongan()
|
||||||
|
.then(p => p.map(item => {
|
||||||
|
potongan.push(item)
|
||||||
|
}))
|
||||||
|
.finally(() => {
|
||||||
|
let alfa = potongan.find(pot => pot.data.jenis == 'alfa')
|
||||||
|
let sakit = potongan.find(pot => pot.data.jenis == 'sakit')
|
||||||
|
|
||||||
|
let employees = items[0].data.users.map(employee => {
|
||||||
|
let jab = jabatans.find(item => item.id == employee.jabatan_id)
|
||||||
|
|
||||||
|
let potong = 0
|
||||||
|
if(alfa != undefined) {
|
||||||
|
potong += +alfa.data.potongan * +employee.alfa
|
||||||
|
}
|
||||||
|
if(sakit != undefined) {
|
||||||
|
potong += +sakit.data.potongan * +employee.sakit
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...employee,
|
||||||
|
gajiPokok: jab.data.gajiPokok,
|
||||||
|
tunjangan: jab.data.tunjangan,
|
||||||
|
feePenjualan: jab.data.feePenjualan,
|
||||||
|
transport: jab.data.transport,
|
||||||
|
uangMakan: jab.data.uangMakan,
|
||||||
|
bonus: jab.data.bonus,
|
||||||
|
potongan: potong,
|
||||||
|
total: +jab.data.total - +potong
|
||||||
|
}
|
||||||
|
})
|
||||||
|
setLists(employees)
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
getDataGaji
|
||||||
|
}
|
@ -1,33 +0,0 @@
|
|||||||
import { useState } from "react";
|
|
||||||
import db from "@/firebase";
|
|
||||||
import { collection, getDocs, doc, addDoc, deleteDoc, updateDoc, query, where } from "firebase/firestore";
|
|
||||||
import { getAll as getKaryawan } from './Karyawan'
|
|
||||||
import { getAll as getJabatan } from './Jabatan'
|
|
||||||
|
|
||||||
async function getDataGaji() {
|
|
||||||
const [lists, setLists] = useState([])
|
|
||||||
const [jabatans, setJabatan] = useState([])
|
|
||||||
Promise.all([
|
|
||||||
() => getJabatan().then(items => setJabatan(items)),
|
|
||||||
() => getKaryawan().then(items => {
|
|
||||||
const employees = items.map(employee => {
|
|
||||||
const jab = jabatans.find(item => item.id == employee.data.jabatan.id)
|
|
||||||
// TODO: fetch potongan
|
|
||||||
return {
|
|
||||||
...employee,
|
|
||||||
gajiPokok: jab.gajiPokok,
|
|
||||||
tunjangan: jab.tunjangan,
|
|
||||||
feePenjualan: jab.feePenjualan,
|
|
||||||
transport: jab.transport,
|
|
||||||
uangMakan: jab.uangMakan,
|
|
||||||
bonus: jab.bonus,
|
|
||||||
total: jab.total
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
setLists(employees)
|
|
||||||
}),
|
|
||||||
])
|
|
||||||
|
|
||||||
return lists
|
|
||||||
}
|
|
Loading…
Reference in New Issue