Skip to content

Commit

Permalink
Merge pull request #131 from reactmore/reactmore/issue109
Browse files Browse the repository at this point in the history
Add: Import Data Siswa by CSV
  • Loading branch information
ikhsan3adi authored Aug 6, 2024
2 parents 9ddbfb8 + 79cc765 commit fb79083
Show file tree
Hide file tree
Showing 26 changed files with 1,003 additions and 9 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ Aplikasi Web Sistem Absensi Sekolah Berbasis QR Code adalah sebuah proyek yang b
- **Tambah, Ubah, Hapus(CRUD) data kelas.**
- **Lihat, Tambah, Ubah, Hapus(CRUD) data petugas.** (khusus petugas yang login sebagai **`superadmin`**).
- **Generate Laporan.** Generate laporan dalam bentuk pdf.
- **Import Banyak Siswa.** Menggunakan CSV delimiter koma (,), Contoh: [CSV](https://github.com/ikhsan3adi/absensi-sekolah-qr-code/blob/141ef728f01b14b89b43aee2c0c38680b0b60528/public/assets/file/csv_siswa_example.csv).


> [!NOTE]
>
Expand Down
16 changes: 16 additions & 0 deletions app/Common.php
Original file line number Diff line number Diff line change
Expand Up @@ -283,4 +283,20 @@ function countItems($items)
}
return 0;
}
}

//get csv value
if (!function_exists('getCSVInputValue')) {
function getCSVInputValue($array, $key, $dataType = 'string')
{
if (!empty($array)) {
if (!empty($array[$key])) {
return $array[$key];
}
}
if ($dataType == 'int') {
return 0;
}
return '';
}
}
14 changes: 13 additions & 1 deletion app/Config/Routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
$routes->post('cek', 'Scan::cekKode');
});



// Admin
$routes->group('admin', function (RouteCollection $routes) {
// Admin dashboard
Expand Down Expand Up @@ -82,6 +84,16 @@
$routes->post('siswa/edit', 'Admin\DataSiswa::updateSiswa');
// admin hapus data siswa
$routes->delete('siswa/delete/(:any)', 'Admin\DataSiswa::delete/$1');
$routes->get('siswa/bulk', 'Admin\DataSiswa::bulkPostSiswa');

// POST Data Siswa

$routes->group('siswa', ['namespace' => 'App\Controllers\Admin'], function ($routes) {
$routes->post('downloadCSVFilePost', 'DataSiswa::downloadCSVFilePost');
$routes->post('generateCSVObjectPost', 'DataSiswa::generateCSVObjectPost');
$routes->post('importCSVItemPost', 'DataSiswa::importCSVItemPost');
$routes->post('deleteSelectedSiswa', 'DataSiswa::deleteSelectedSiswa');
});


// admin lihat data guru
Expand Down Expand Up @@ -143,7 +155,7 @@
$routes->group('general-settings', ['namespace' => 'App\Controllers\Admin'], function ($routes) {
$routes->get('/', 'GeneralSettings::index');
$routes->post('update', 'GeneralSettings::generalSettingsPost');
});
});
});


Expand Down
95 changes: 95 additions & 0 deletions app/Controllers/Admin/DataSiswa.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

use App\Controllers\BaseController;
use App\Models\JurusanModel;
use App\Models\UploadModel;
use CodeIgniter\Exceptions\PageNotFoundException;

class DataSiswa extends BaseController
Expand Down Expand Up @@ -215,4 +216,98 @@ public function delete($id)
]);
return redirect()->to('/admin/siswa');
}

/**
* Delete Selected Posts
*/
public function deleteSelectedSiswa()
{
$siswaIds = inputPost('siswa_ids');
$this->siswaModel->deleteMultiSelected($siswaIds);
}

/*
*-------------------------------------------------------------------------------------------------
* IMPORT SISWA
*-------------------------------------------------------------------------------------------------
*/

/**
* Bulk Post Upload
*/
public function bulkPostSiswa()
{
$data['title'] = 'Import Siswa';
$data['ctx'] = 'siswa';
$data['kelas'] = $this->kelasModel->getDataKelas();

return view('/admin/data/import-siswa', $data);
}

/**
* Generate CSV Object Post
*/
public function generateCSVObjectPost()
{
$uploadModel = new UploadModel();
//delete old txt files
$files = glob(FCPATH . 'uploads/tmp/*.txt');
if (!empty($files)) {
foreach ($files as $item) {
@unlink($item);
}
}
$file = $uploadModel->uploadCSVFile('file');
if (!empty($file) && !empty($file['path'])) {
$obj = $this->siswaModel->generateCSVObject($file['path']);
if (!empty($obj)) {
$data = [
'result' => 1,
'numberOfItems' => $obj->numberOfItems,
'txtFileName' => $obj->txtFileName,
];
echo json_encode($data);
exit();
}
}
echo json_encode(['result' => 0]);
}

/**
* Import CSV Item Post
*/
public function importCSVItemPost()
{
$txtFileName = inputPost('txtFileName');
$index = inputPost('index');
$siswa = $this->siswaModel->importCSVItem($txtFileName, $index);
if (!empty($siswa)) {
$data = [
'result' => 1,
'siswa' => $siswa,
'index' => $index
];
echo json_encode($data);
} else {
$data = [
'result' => 0,
'index' => $index
];
echo json_encode($data);
}
}

/**
* Download CSV File Post
*/
public function downloadCSVFilePost()
{
$submit = inputPost('submit');
$response = \Config\Services::response();
if ($submit == 'csv_siswa_template') {
return $response->download(FCPATH . 'assets/file/csv_siswa_template.csv', null);
} elseif ($submit == 'csv_guru_template') {
return $response->download(FCPATH . 'assets/file/csv_guru_template.csv', null);
}
}
}
7 changes: 3 additions & 4 deletions app/Controllers/Admin/QRGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ public function downloadQrSiswa($idSiswa = null)
]);
return redirect()->back();
}

try {
$kelas = $this->getKelasJurusanSlug($siswa['id_kelas']) ?? 'tmp';
$this->qrCodeFilePath .= "qr-siswa/$kelas/";
Expand Down Expand Up @@ -330,11 +331,9 @@ protected function kelas(string $unique_code)

protected function getKelasJurusanSlug(string $idKelas)
{
$kelas = (new KelasModel)
->join('tb_jurusan', 'tb_kelas.id_jurusan = tb_jurusan.id', 'left')
->find($idKelas);
$kelas = (new KelasModel)->getKelas($idKelas);;
if ($kelas) {
return url_title($kelas['kelas'] . ' ' . $kelas['jurusan'], lowercase: true);
return url_title($kelas->kelas . ' ' . $kelas->jurusan, lowercase: true);
} else {
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion app/Models/KelasModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public function getDataKelas()

public function getKelas($id)
{
return $this->builder->where('id_kelas', cleanNumber($id))->get()->getRow();
return $this->builder->join('tb_jurusan', 'tb_kelas.id_jurusan = tb_jurusan.id')->where('id_kelas', cleanNumber($id))->get()->getRow();
}

public function getCategoryTree($categoryId, $categories)
Expand Down
92 changes: 91 additions & 1 deletion app/Models/SiswaModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public function createSiswa($nis, $nama, $idKelas, $jenisKelamin, $noHp)
'id_kelas' => $idKelas,
'jenis_kelamin' => $jenisKelamin,
'no_hp' => $noHp,
'unique_code' => sha1($nama . md5($nis . $noHp . $nama)) . substr(sha1($nis . rand(0, 100)), 0, 24)
'unique_code' => generateToken()
]);
}

Expand Down Expand Up @@ -118,4 +118,94 @@ public function getSiswaCountByKelas($kelasId)

return $this->whereIn('tb_siswa.id_kelas', $kelasIds, false)->countAllResults();
}

//generate CSV object
public function generateCSVObject($filePath)
{
$array = array();
$fields = array();
$txtName = uniqid() . '.txt';
$i = 0;
$handle = fopen($filePath, 'r');
if ($handle) {
while (($row = fgetcsv($handle)) !== false) {
if (empty($fields)) {
$fields = $row;
continue;
}
foreach ($row as $k => $value) {
$array[$i][$fields[$k]] = $value;
}
$i++;
}
if (!feof($handle)) {
return false;
}
fclose($handle);
if (!empty($array)) {
$txtFile = fopen(FCPATH . 'uploads/tmp/' . $txtName, 'w');
fwrite($txtFile, serialize($array));
fclose($txtFile);
$obj = new \stdClass();
$obj->numberOfItems = countItems($array);
$obj->txtFileName = $txtName;
@unlink($filePath);
return $obj;
}
}
return false;
}

//import csv item
public function importCSVItem($txtFileName, $index)
{
$filePath = FCPATH . 'uploads/tmp/' . $txtFileName;
$file = fopen($filePath, 'r');
$content = fread($file, filesize($filePath));
$array = @unserialize($content);
if (!empty($array)) {
$i = 1;
foreach ($array as $item) {
if ($i == $index) {
$data = array();
$data['nis'] = getCSVInputValue($item, 'nis', 'int');
$data['nama_siswa'] = getCSVInputValue($item, 'nama_siswa');
$data['id_kelas'] = getCSVInputValue($item, 'id_kelas', 'int');
$data['jenis_kelamin'] = getCSVInputValue($item, 'jenis_kelamin');
$data['no_hp'] = getCSVInputValue($item, 'no_hp');
$data['unique_code'] = generateToken();

$this->insert($data);
return $data;
}
$i++;
}
}
}

public function getSiswa($id)
{
return $this->where('id_siswa', cleanNumber($id))->get()->getRow();
}

//delete post
public function deleteSiswa($id)
{
$siswa = $this->getSiswa($id);
if (!empty($siswa)) {
//delete siswa
return $this->where('id_siswa', $siswa->id_siswa)->delete();
}
return false;
}

//delete multi post
public function deleteMultiSelected($siswaIds)
{
if (!empty($siswaIds)) {
foreach ($siswaIds as $id) {
$this->deleteSiswa($id);
}
}
}
}
6 changes: 6 additions & 0 deletions app/Models/UploadModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ public function uploadLogo($inputName)
return $this->upload($inputName, "uploads/logo/", "logo_", ['jpg', 'jpeg', 'png', 'gif', 'svg']);
}

//upload CSV file
public function uploadCSVFile($inputName)
{
return $this->upload($inputName, 'uploads/tmp/', 'temp_', ['csv']);
}

//check allowed file types
public function checkAllowedFileTypes($fileName, $allowedTypes)
{
Expand Down
11 changes: 11 additions & 0 deletions app/Views/admin/data/data-siswa.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
<a class="btn btn-primary ml-3 pl-3 py-3" href="<?= base_url('admin/siswa/create'); ?>">
<i class="material-icons mr-2">add</i> Tambah data siswa
</a>
<a class="btn btn-primary ml-3 pl-3 py-3" href="<?= base_url('admin/siswa/bulk'); ?>">
<i class="material-icons mr-2">add</i> Import CSV
</a>
<button class="btn btn-danger ml-3 pl-3 py-3 btn-table-delete" onclick="deleteSelectedSiswa('Data yang sudah dihapus tidak bisa kembalikan');"><i class="material-icons mr-2">delete_forever</i>Bulk Delete</button>
<div class="card">
<div class="card-header card-header-tabs card-header-primary">
<div class="nav-tabs-navigation">
Expand Down Expand Up @@ -115,5 +119,12 @@ function getDataSiswa(_kelas = null, _jurusan = null) {
}
});
}

document.addEventListener('DOMContentLoaded', function() {
$("#checkAll").click(function(e) {
console.log(e);
$('input:checkbox').not(this).prop('checked', this.checked);
});
});
</script>
<?= $this->endSection() ?>
Loading

0 comments on commit fb79083

Please sign in to comment.