Files
bij/app/Services/Mobile/MobileJsonService.php
2026-04-21 05:59:39 +07:00

787 lines
25 KiB
PHP

<?php
namespace App\Services\Mobile;
use CodeIgniter\Database\BaseConnection;
use Config\Database;
use Exception;
/**
* Port logika bisnis dari CI3 `application/controllers/Json.php`.
* Respons struktur disamakan dengan legacy untuk kompatibilitas aplikasi mobile.
*
* TODO (fase berikutnya): pecah per agregat (PresensiService, CutiService), tambahkan transaksi,
* perbaiki keamanan (MD5 → password_hash, token → JWT) setelah cutover klien.
*/
class MobileJsonService
{
protected BaseConnection $db;
/** @var array<int, string> */
private array $hariIndo = [
1 => 'Senin',
2 => 'Selasa',
3 => 'Rabu',
4 => 'Kamis',
5 => 'Jumat',
6 => 'Sabtu',
7 => 'Minggu',
];
public function __construct(?BaseConnection $db = null)
{
$this->db = $db ?? Database::connect();
}
public function loginWToken(string $token): array
{
$data = [
'status' => 0,
'pesan' => '',
];
$pegawai = $this->db->table('pegawai')->where('token', $token)->get()->getRow();
if ($pegawai) {
unset($pegawai->username, $pegawai->password, $pegawai->token);
$this->db->table('pegawai')->where('id_pegawai', $pegawai->id_pegawai)->update([
'last_login' => date('Y-m-d H:i:s'),
]);
$data['status'] = 1;
}
return $data;
}
public function login(string $user, string $pass): array
{
$data = [
'status' => 0,
'pesan' => 'Username atau Password tidak sesuai',
];
$pegawai = $this->db->table('pegawai')
->where('username', $user)
->where('password', md5($pass))
->get()
->getRow();
if ($pegawai) {
unset($pegawai->username, $pegawai->password, $pegawai->token);
$token = md5((string) $pegawai->id_pegawai) . $this->generateRandomString(15);
$this->db->table('pegawai')->where('id_pegawai', $pegawai->id_pegawai)->update([
'token' => $token,
'last_login' => date('Y-m-d H:i:s'),
]);
$data['status'] = 1;
$data['pesan'] = 'Selamat datang';
$data['token'] = $token;
}
return $data;
}
/**
* Terbitkan token API mobile untuk pegawai (id_pegawai), seperti setelah login sukses.
* Dipakai saat login admin lewat tabel admin_users (proxy token ke pegawai tertentu).
*/
public function issueTokenForPegawaiId(int $id): ?string
{
$pegawai = $this->db->table('pegawai')->where('id_pegawai', $id)->get()->getRow();
if ($pegawai === null) {
return null;
}
$token = md5((string) $pegawai->id_pegawai) . $this->generateRandomString(15);
$this->db->table('pegawai')->where('id_pegawai', $id)->update([
'token' => $token,
'last_login' => date('Y-m-d H:i:s'),
]);
return $token;
}
public function profil(string $token): array
{
$data = [
'status' => 0,
'pesan' => '',
];
$pegawai = $this->db->table('pegawai')
->select('*, COALESCE(tanggal_lahir, \'0000-00-00\') as tanggal_lahir', false)
->where('token', $token)
->limit(1)
->get()
->getRow();
if (! $pegawai) {
return $data;
}
unset($pegawai->username, $pegawai->password, $pegawai->token);
$pegawai->kantor = $this->db->table('kantor')->where('id_kantor', $pegawai->kantor)->limit(1)->get()->getRow();
$pegawai->jabatan = $this->db->table('jabatan')->where('id_jabatan', $pegawai->jabatan)->limit(1)->get()->getRow();
$pegawai->unit_kerja = $this->db->table('unit_kerja')->where('id_unit_kerja', $pegawai->unit_kerja)->limit(1)->get()->getRow();
$pegawai->lembur = $this->db->table('lembur')->where('pegawai', $pegawai->id_pegawai)->where('tanggal_lembur', date('Y-m-d'))->limit(1)->get()->getRow();
$dilapangan = $this->db->table('dilapangan')->where('pegawai', $pegawai->id_pegawai)->limit(1)->get()->getRow();
$pegawai->dilapangan = $dilapangan ? true : false;
$hari = (int) date('N');
$pre_in = $hari . '_in';
$pre_out = $hari . '_out';
$jadwal_ar = [
'hari' => $this->hariIndo[$hari],
'masuk' => '',
'pulang' => '',
'istirahat' => '',
'toleransi_masuk' => '0',
'toleransi_pulang' => '0',
'libur' => true,
];
$libur_perusahaan = $this->db->table('libur')->where('tanggal_libur', date('Y-m-d'))->limit(1)->get()->getRow();
if ($libur_perusahaan) {
$jadwal_ar['ket_libur'] = 'Libur: ' . $libur_perusahaan->keterangan_libur;
} else {
$cuti = $this->db->table('cuti')
->where('pegawai', $pegawai->id_pegawai)
->where('tanggal_cuti', date('Y-m-d'))
->where('status_cuti', 'Approve')
->limit(1)
->get()
->getRow();
if ($cuti) {
$jadwal_ar['ket_libur'] = 'Cuti: ' . $cuti->alasan_cuti;
} else {
$jadwal = $this->db->table('jadwal')->where('id_jadwal', $pegawai->jadwal)->limit(1)->get()->getRow();
if ($jadwal) {
$jadwal_ar['masuk'] = $jadwal->{$pre_in};
$jadwal_ar['pulang'] = $jadwal->{$pre_out};
$jadwal_ar['istirahat'] = '12:00';
$jadwal_ar['toleransi_masuk'] = $jadwal->toleransi_terlambat;
$jadwal_ar['toleransi_pulang'] = $jadwal->toleransi_pulang_cepat;
$jadwal_ar['libur'] = false;
$jadwal_ar['ket_libur'] = '';
} else {
$jadwal_ar['ket_libur'] = 'Tidak ada jadwal. Hubungi Petugas';
}
}
}
$pegawai->jadwal = $jadwal_ar;
$data['status'] = 1;
$data['pegawai'] = $pegawai;
return $data;
}
public function saveCuti(string $token, string $nama_photo, string $img, string $tanggal, string $alasan, string $tipe): array
{
$data = [
'status' => 0,
'pesan' => '',
];
$pegawai = $this->db->table('pegawai')->where('token', $token)->limit(1)->get()->getRow();
if (! $pegawai) {
return $data;
}
$dir = $this->ensureUploadDir('dokcuti');
$image = base64_decode($img);
$image_name = uniqid((string) mt_rand(), true);
$filename = $image_name . '-' . $nama_photo;
if ($image === false || $image === '' || file_put_contents($dir . DIRECTORY_SEPARATOR . $filename, $image) === false) {
$data['pesan'] = 'Photo Dokumen GAGAL upload';
return $data;
}
$this->db->table('cuti')->insert([
'pegawai' => $pegawai->id_pegawai,
'tanggal_cuti' => $tanggal,
'tipe_cuti' => $tipe,
'alasan_cuti' => $alasan,
'status_cuti' => 'Waiting',
'alasan_tolak' => '',
]);
$id = (int) $this->db->insertID();
$this->db->table('cuti_dokumen')->insert([
'cuti' => $id,
'dokumen' => $filename,
]);
$data['status'] = 1;
$data['pesan'] = 'Photo Dokumen berhasil di upload';
return $data;
}
/**
* @param int|string|null $id
*/
public function batalkanCuti(string $token, $id): array
{
$data = [
'status' => 0,
'pesan' => '',
];
$pegawai = $this->db->table('pegawai')->where('token', $token)->limit(1)->get()->getRow();
if (! $pegawai) {
return $data;
}
$this->db->table('cuti')->where('pegawai', $pegawai->id_pegawai)->where('id_cuti', $id)->update([
'status_cuti' => 'Cancelled',
]);
$data['status'] = 1;
$data['pesan'] = "Ajuan di batalkan {$id} - {$pegawai->id_pegawai}";
return $data;
}
public function saveAktifitas(string $token, string $nama_photo, string $img, string $tanggal, string $deksripsi): array
{
$data = [
'status' => 0,
'pesan' => '',
];
$pegawai = $this->db->table('pegawai')->where('token', $token)->limit(1)->get()->getRow();
if (! $pegawai) {
return $data;
}
$dir = $this->ensureUploadDir('aktifitas');
$image = base64_decode($img);
$image_name = uniqid((string) mt_rand(), true);
$filename = $image_name . '-' . $nama_photo;
if ($image === false || $image === '' || file_put_contents($dir . DIRECTORY_SEPARATOR . $filename, $image) === false) {
$data['pesan'] = 'Photo Kegiatan GAGAL upload';
return $data;
}
$this->db->table('aktifitas_harian')->insert([
'pegawai' => $pegawai->id_pegawai,
'image' => $filename,
'deskripsi' => $deksripsi,
'waktu_aktifitas' => $tanggal,
]);
$data['status'] = 1;
$data['pesan'] = 'Photo Kegiatan berhasil di upload';
return $data;
}
public function saveMasuk(string $token, string $nama_photo, string $img, string $lat, string $lng, string $jarak): array
{
$data = [
'status' => 0,
'pesan' => 'Tidak ada jadwal kerja',
];
$pegawai = $this->db->table('pegawai')->where('token', $token)->limit(1)->get()->getRow();
if (! $pegawai) {
return $data;
}
$jadwal = $this->db->table('jadwal')->where('id_jadwal', $pegawai->jadwal)->limit(1)->get()->getRow();
if (! $jadwal) {
return $data;
}
$dir = $this->ensureUploadDir('absen' . DIRECTORY_SEPARATOR . 'masuk');
$image = base64_decode($img);
$image_name = uniqid((string) mt_rand(), true);
$filename = $image_name . '-' . $nama_photo;
if ($image === false || $image === '' || file_put_contents($dir . DIRECTORY_SEPARATOR . $filename, $image) === false) {
$data['pesan'] = 'Photo Kehadiran GAGAL upload';
return $data;
}
$hari = (int) date('N');
$pre_in = $hari . '_in';
$masuk_jadwal = date('Y-m-d') . ' ' . $jadwal->{$pre_in};
$jam_masuk = strtotime($masuk_jadwal);
$jam_toleransi = strtotime($masuk_jadwal) + ((int) $jadwal->toleransi_terlambat * 60);
$jam_sekarang = time();
if ($jam_sekarang < $jam_masuk) {
$ket_masuk = 'Sesuai jadwal';
} elseif ($jam_sekarang >= $jam_masuk && $jam_sekarang <= $jam_toleransi) {
$ket_masuk = 'Terlambat';
} else {
$ket_masuk = 'Sangat terlambat';
}
$this->db->table('presensi')->where('tanggal', date('Y-m-d'))->where('pegawai', $pegawai->id_pegawai)->update([
'jam_masuk' => date('Y-m-d H:i:s'),
'ket_masuk' => $ket_masuk,
'photo_masuk' => $filename,
'lat_masuk' => $lat,
'lng_masuk' => $lng,
'jarak_masuk' => $jarak,
]);
$data['status'] = 1;
$data['pesan'] = 'Photo Kehadiran berhasil di upload';
return $data;
}
public function savePulang(string $token, string $nama_photo, string $img, string $lat, string $lng, string $jarak): array
{
$data = [
'status' => 0,
'pesan' => 'Tidak ada jadwal kerja',
];
$pegawai = $this->db->table('pegawai')->where('token', $token)->limit(1)->get()->getRow();
if (! $pegawai) {
return $data;
}
$jadwal = $this->db->table('jadwal')->where('id_jadwal', $pegawai->jadwal)->limit(1)->get()->getRow();
if (! $jadwal) {
return $data;
}
$dir = $this->ensureUploadDir('absen' . DIRECTORY_SEPARATOR . 'pulang');
$image = base64_decode($img);
$image_name = uniqid((string) mt_rand(), true);
$filename = $image_name . '-' . $nama_photo;
if ($image === false || $image === '' || file_put_contents($dir . DIRECTORY_SEPARATOR . $filename, $image) === false) {
$data['pesan'] = 'Photo Kehadiran GAGAL upload';
return $data;
}
$wibNow = new \DateTimeImmutable('now', new \DateTimeZone('Asia/Jakarta'));
$hari = (int) $wibNow->format('N');
$pre_out = $hari . '_out';
$jadwal_pulang = $wibNow->format('Y-m-d') . ' ' . $jadwal->{$pre_out};
$jam_pulang = strtotime($jadwal_pulang);
$jam_toleransi = strtotime($jadwal_pulang) - ((int) $jadwal->toleransi_terlambat * 60);
$jam_sekarang = $wibNow->getTimestamp();
if ($jam_sekarang < $jam_toleransi) {
$data['pesan'] = 'Belum waktunya Pulang, waktu pulang anda adalah pukul ' . $jadwal->{$pre_out} . '. Jika anda memerlukan untuk pulang cepat, silahkan hubungi Operator';
return $data;
}
if ($jam_sekarang >= $jam_toleransi && $jam_sekarang <= $jam_pulang) {
$ket_pulang = 'Pulang Cepat';
} else {
$ket_pulang = 'Sesuai jadwal';
}
$this->db->table('presensi')->where('tanggal', $wibNow->format('Y-m-d'))->where('pegawai', $pegawai->id_pegawai)->update([
'jam_pulang' => $wibNow->format('Y-m-d H:i:s'),
'ket_pulang' => $ket_pulang,
'photo_pulang' => $filename,
'lat_pulang' => $lat,
'lng_pulang' => $lng,
'jarak_pulang' => $jarak,
]);
$data['status'] = 1;
$data['pesan'] = 'Photo Kehadiran berhasil di upload';
return $data;
}
public function saveIstirahat(string $token, string $mulai, string $selesai): array
{
$data = [
'status' => 0,
'pesan' => 'Tidak ada jadwal kerja',
];
$pegawai = $this->db->table('pegawai')->where('token', $token)->limit(1)->get()->getRow();
if (! $pegawai) {
return $data;
}
$jadwal = $this->db->table('jadwal')->where('id_jadwal', $pegawai->jadwal)->limit(1)->get()->getRow();
if (! $jadwal) {
return $data;
}
$ist = null;
if ($mulai !== '') {
$ist = [
'mulai_istirahat' => $mulai,
'beres_istirahat' => $mulai,
];
}
if ($selesai !== '') {
$ist = [
'beres_istirahat' => $selesai,
'is_istirahat' => 1,
];
}
if ($ist === null) {
return $data;
}
$this->db->table('presensi')->where('tanggal', date('Y-m-d'))->where('pegawai', $pegawai->id_pegawai)->update($ist);
$data['status'] = 1;
$data['pesan'] = 'berhasil disimpan';
return $data;
}
public function presensiToday(string $token): array
{
$data = [
'status' => 0,
'pesan' => '',
];
$pegawai = $this->db->table('pegawai')->select('id_pegawai, jadwal')->where('token', $token)->limit(1)->get()->getRow();
if (! $pegawai) {
return $data;
}
$presensi = $this->db->table('presensi')->where('tanggal', date('Y-m-d'))->where('pegawai', $pegawai->id_pegawai)->limit(1)->get()->getRow();
if (! $presensi) {
$jadwal = $this->db->table('jadwal')->where('id_jadwal', $pegawai->jadwal)->get()->getRow();
$ins = [
'pegawai' => $pegawai->id_pegawai,
'tanggal' => date('Y-m-d'),
'jadwal' => serialize($jadwal),
'jam_masuk' => null,
'ket_masuk' => '',
'photo_masuk' => '',
'jam_pulang' => null,
'ket_pulang' => '',
'photo_pulang' => '',
'mulai_istirahat' => null,
'beres_istirahat' => null,
'is_istirahat' => '0',
'lat_masuk' => '0',
'lng_masuk' => '0',
'lat_pulang' => '0',
'lng_pulang' => '0',
'jarak_masuk' => '0',
'jarak_pulang' => '0',
];
$this->db->table('presensi')->insert($ins);
$id = (int) $this->db->insertID();
$ins['id_presensi'] = $id . '.';
$presensi = (object) $ins;
}
$data['status'] = 1;
$data['data'] = $presensi;
return $data;
}
public function presensi(string $token): array
{
$data = [
'status' => 0,
'pesan' => '',
];
$pegawai = $this->db->table('pegawai')->select('id_pegawai, jadwal')->where('token', $token)->limit(1)->get()->getRow();
if (! $pegawai) {
return $data;
}
$presensi = $this->db->table('presensi')->where('pegawai', $pegawai->id_pegawai)->orderBy('tanggal', 'DESC')->limit(20)->get()->getResult();
if ($presensi) {
$data['status'] = 1;
$data['data'] = $presensi;
}
return $data;
}
public function daftarToday(string $token): array
{
$data = [
'status' => 0,
'pesan' => '',
];
$pegawai = $this->db->table('pegawai')->select('id_pegawai, jadwal')->where('token', $token)->limit(1)->get()->getRow();
if (! $pegawai) {
return $data;
}
$today = date('Y-m-d');
$presensi = $this->db->table('pegawai')
->join('jabatan', 'id_jabatan=jabatan', 'left')
->join('presensi', 'id_pegawai=pegawai AND tanggal = ' . $this->db->escape($today), 'left', false)
->where('id_pegawai !=', $pegawai->id_pegawai)
->where('id_presensi IS NOT NULL', null, false)
->orderBy('jam_masuk', 'DESC')
->orderBy('nama_lengkap')
->get()
->getResult();
if ($presensi) {
$data['status'] = 1;
$data['data'] = $presensi;
}
return $data;
}
public function berita(string $token, $dari, $jumlah): array
{
if ($dari === '' || $dari === null) {
$dari = 0;
}
if ($jumlah === '' || $jumlah === null) {
$jumlah = 10;
}
$dari = (int) $dari;
$jumlah = (int) $jumlah;
$data = [
'status' => 0,
'pesan' => '',
];
$pegawai = $this->db->table('pegawai')->select('id_pegawai')->where('token', $token)->limit(1)->get()->getRow();
if (! $pegawai) {
return $data;
}
$berita = $this->db->table('berita')->orderBy('tanggal', 'DESC')->limit($jumlah, $dari)->get()->getResult();
$data['status'] = 1;
$data['data'] = $berita;
return $data;
}
public function cuti(string $token, $dari, $jumlah): array
{
if ($dari === '' || $dari === null) {
$dari = 0;
}
if ($jumlah === '' || $jumlah === null) {
$jumlah = 25;
}
$dari = (int) $dari;
$jumlah = (int) $jumlah;
$data = [
'status' => 0,
'pesan' => '',
];
$pegawai = $this->db->table('pegawai')->select('id_pegawai')->where('token', $token)->limit(1)->get()->getRow();
if (! $pegawai) {
return $data;
}
$cuti = $this->db->table('cuti')->where('pegawai', $pegawai->id_pegawai)->orderBy('tanggal_cuti', 'DESC')->limit($jumlah, $dari)->get()->getResult();
if ($cuti) {
foreach ($cuti as $v) {
$v->dokumen = $this->db->table('cuti_dokumen')->select('dokumen')->where('cuti', $v->id_cuti)->get()->getResult();
}
}
$data['status'] = 1;
$data['data'] = $cuti;
return $data;
}
public function lembur(string $token, $dari, $jumlah): array
{
if ($dari === '' || $dari === null) {
$dari = 0;
}
if ($jumlah === '' || $jumlah === null) {
$jumlah = 25;
}
$dari = (int) $dari;
$jumlah = (int) $jumlah;
$data = [
'status' => 0,
'pesan' => '',
];
$pegawai = $this->db->table('pegawai')->select('id_pegawai')->where('token', $token)->limit(1)->get()->getRow();
if (! $pegawai) {
return $data;
}
$rows = $this->db->table('lembur')->where('pegawai', $pegawai->id_pegawai)->orderBy('tanggal_lembur', 'DESC')->limit($jumlah, $dari)->get()->getResult();
$data['status'] = 1;
$data['data'] = $rows;
return $data;
}
public function libur(string $token): array
{
$data = [
'status' => 0,
'pesan' => '',
];
$pegawai = $this->db->table('pegawai')->select('id_pegawai')->where('token', $token)->limit(1)->get()->getRow();
if (! $pegawai) {
return $data;
}
$rows = $this->db->table('libur')->orderBy('tanggal_libur', 'DESC')->get()->getResult();
$data['status'] = 1;
$data['data'] = $rows;
return $data;
}
public function aktifitas(string $token, $dari, $jumlah): array
{
if ($dari === '' || $dari === null) {
$dari = 0;
}
if ($jumlah === '' || $jumlah === null) {
$jumlah = 25;
}
$dari = (int) $dari;
$jumlah = (int) $jumlah;
$data = [
'status' => 0,
'pesan' => '',
];
$pegawai = $this->db->table('pegawai')->select('id_pegawai')->where('token', $token)->limit(1)->get()->getRow();
if (! $pegawai) {
return $data;
}
$rows = $this->db->table('aktifitas_harian')->where('pegawai', $pegawai->id_pegawai)->orderBy('waktu_aktifitas', 'DESC')->limit($jumlah, $dari)->get()->getResult();
$data['status'] = 1;
$data['data'] = $rows;
return $data;
}
public function savePp(string $token, string $nama_photo, string $img): array
{
$data = [
'status' => 0,
'pesan' => 'Tidak ada jadwal kerja',
];
$pegawai = $this->db->table('pegawai')->where('token', $token)->limit(1)->get()->getRow();
if (! $pegawai) {
return $data;
}
$dir = $this->ensureUploadDir('pengguna');
$image = base64_decode($img);
$image_name = uniqid((string) mt_rand(), true);
$filename = $image_name . '-' . $nama_photo;
if ($image === false || $image === '' || file_put_contents($dir . DIRECTORY_SEPARATOR . $filename, $image) === false) {
$data['pesan'] = 'Photo Kehadiran GAGAL upload';
return $data;
}
if ($pegawai->photo !== '' && $pegawai->photo !== null) {
try {
$photoPath = $dir . DIRECTORY_SEPARATOR . $pegawai->photo;
if (is_file($photoPath)) {
unlink($photoPath);
}
} catch (Exception $e) {
}
}
$this->db->table('pegawai')->where('id_pegawai', $pegawai->id_pegawai)->update([
'photo' => $filename,
]);
$data['status'] = 1;
$data['pesan'] = 'Photo Profil berhasil di upload';
return $data;
}
public function savePassword(string $token, string $passlama, string $passbaru): array
{
$data = [
'status' => 0,
'pesan' => '-',
];
$pegawai = $this->db->table('pegawai')->where('token', $token)->limit(1)->get()->getRow();
if (! $pegawai) {
return $data;
}
if (md5($passlama) == $pegawai->password) {
$this->db->table('pegawai')->where('id_pegawai', $pegawai->id_pegawai)->update([
'password' => md5($passbaru),
]);
$data['status'] = 1;
$data['pesan'] = 'Password berhasil di ubah';
} else {
$data['pesan'] = 'Password lama tidak sesuai, silahkan coba lagi';
}
return $data;
}
private function generateRandomString(int $length = 10): string
{
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$randomString = '';
for ($i = 0; $i < $length; $i++) {
// Sengaja memakai rand() seperti CI3 agar pola token kompatibel.
$randomString .= $characters[rand(0, strlen($characters) - 1)];
}
return $randomString;
}
private function ensureUploadDir(string $relativeUnderUploads): string
{
$base = FCPATH . 'assets' . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $relativeUnderUploads);
if (! is_dir($base)) {
mkdir($base, 0755, true);
}
return $base;
}
}