Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add: Import Data Siswa by CSV #131

Merged
merged 7 commits into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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