diff --git a/.gitignore b/.gitignore index 62136cd..ec539bb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,9 @@ .DS_Store +application/config/config.php +application/config/database.php +.htaccess + application/cache/* !application/cache/index.html diff --git a/.htaccess b/.htaccess deleted file mode 100644 index 7257c88..0000000 --- a/.htaccess +++ /dev/null @@ -1,9 +0,0 @@ - - RewriteEngine On - RewriteBase /accounting_dev - - # Redirect requests to index.php - RewriteCond %{REQUEST_FILENAME} !-f - RewriteCond %{REQUEST_FILENAME} !-d - RewriteRule ^(.*)$ index.php?/$1 [L] - diff --git a/application/.htaccess b/application/.htaccess deleted file mode 100644 index 6c63ed4..0000000 --- a/application/.htaccess +++ /dev/null @@ -1,6 +0,0 @@ - - Require all denied - - - Deny from all - \ No newline at end of file diff --git a/application/config/config.php b/application/config/config.php deleted file mode 100644 index 87143cb..0000000 --- a/application/config/config.php +++ /dev/null @@ -1,533 +0,0 @@ -]+$/i -| -| DO NOT CHANGE THIS UNLESS YOU FULLY UNDERSTAND THE REPERCUSSIONS!! -| -*/ -$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-'; - -/* -|-------------------------------------------------------------------------- -| Enable Query Strings -|-------------------------------------------------------------------------- -| -| By default CodeIgniter uses search-engine friendly segment based URLs: -| example.com/who/what/where/ -| -| You can optionally enable standard query string based URLs: -| example.com?who=me&what=something&where=here -| -| Options are: TRUE or FALSE (boolean) -| -| The other items let you set the query string 'words' that will -| invoke your controllers and its functions: -| example.com/index.php?c=controller&m=function -| -| Please note that some of the helpers won't work as expected when -| this feature is enabled, since CodeIgniter is designed primarily to -| use segment based URLs. -| -*/ -$config['enable_query_strings'] = FALSE; -$config['controller_trigger'] = 'c'; -$config['function_trigger'] = 'm'; -$config['directory_trigger'] = 'd'; - -/* -|-------------------------------------------------------------------------- -| Allow $_GET array -|-------------------------------------------------------------------------- -| -| By default CodeIgniter enables access to the $_GET array. If for some -| reason you would like to disable it, set 'allow_get_array' to FALSE. -| -| WARNING: This feature is DEPRECATED and currently available only -| for backwards compatibility purposes! -| -*/ -$config['allow_get_array'] = TRUE; - -/* -|-------------------------------------------------------------------------- -| Error Logging Threshold -|-------------------------------------------------------------------------- -| -| You can enable error logging by setting a threshold over zero. The -| threshold determines what gets logged. Threshold options are: -| -| 0 = Disables logging, Error logging TURNED OFF -| 1 = Error Messages (including PHP errors) -| 2 = Debug Messages -| 3 = Informational Messages -| 4 = All Messages -| -| You can also pass an array with threshold levels to show individual error types -| -| array(2) = Debug Messages, without Error Messages -| -| For a live site you'll usually only enable Errors (1) to be logged otherwise -| your log files will fill up very fast. -| -*/ -$config['log_threshold'] = 4; - -/* -|-------------------------------------------------------------------------- -| Error Logging Directory Path -|-------------------------------------------------------------------------- -| -| Leave this BLANK unless you would like to set something other than the default -| application/logs/ directory. Use a full server path with trailing slash. -| -*/ -$config['log_path'] = ''; - -/* -|-------------------------------------------------------------------------- -| Log File Extension -|-------------------------------------------------------------------------- -| -| The default filename extension for log files. The default 'php' allows for -| protecting the log files via basic scripting, when they are to be stored -| under a publicly accessible directory. -| -| Note: Leaving it blank will default to 'php'. -| -*/ -$config['log_file_extension'] = ''; - -/* -|-------------------------------------------------------------------------- -| Log File Permissions -|-------------------------------------------------------------------------- -| -| The file system permissions to be applied on newly created log files. -| -| IMPORTANT: This MUST be an integer (no quotes) and you MUST use octal -| integer notation (i.e. 0700, 0644, etc.) -*/ -$config['log_file_permissions'] = 0644; - -/* -|-------------------------------------------------------------------------- -| Date Format for Logs -|-------------------------------------------------------------------------- -| -| Each item that is logged has an associated date. You can use PHP date -| codes to set your own date formatting -| -*/ -$config['log_date_format'] = 'Y-m-d H:i:s'; - -/* -|-------------------------------------------------------------------------- -| Error Views Directory Path -|-------------------------------------------------------------------------- -| -| Leave this BLANK unless you would like to set something other than the default -| application/views/errors/ directory. Use a full server path with trailing slash. -| -*/ -$config['error_views_path'] = ''; - -/* -|-------------------------------------------------------------------------- -| Cache Directory Path -|-------------------------------------------------------------------------- -| -| Leave this BLANK unless you would like to set something other than the default -| application/cache/ directory. Use a full server path with trailing slash. -| -*/ -$config['cache_path'] = ''; - -/* -|-------------------------------------------------------------------------- -| Cache Include Query String -|-------------------------------------------------------------------------- -| -| Whether to take the URL query string into consideration when generating -| output cache files. Valid options are: -| -| FALSE = Disabled -| TRUE = Enabled, take all query parameters into account. -| Please be aware that this may result in numerous cache -| files generated for the same page over and over again. -| array('q') = Enabled, but only take into account the specified list -| of query parameters. -| -*/ -$config['cache_query_string'] = FALSE; - -/* -|-------------------------------------------------------------------------- -| Encryption Key -|-------------------------------------------------------------------------- -| -| If you use the Encryption class, you must set an encryption key. -| See the user guide for more info. -| -| https://codeigniter.com/userguide3/libraries/encryption.html -| -*/ -$config['encryption_key'] = ''; - -/* -|-------------------------------------------------------------------------- -| Session Variables -|-------------------------------------------------------------------------- -| -| 'sess_driver' -| -| The storage driver to use: files, database, redis, memcached -| -| 'sess_cookie_name' -| -| The session cookie name, must contain only [0-9a-z_-] characters -| -| 'sess_samesite' -| -| Session cookie SameSite attribute: Lax (default), Strict or None -| -| 'sess_expiration' -| -| The number of SECONDS you want the session to last. -| Setting to 0 (zero) means expire when the browser is closed. -| -| 'sess_save_path' -| -| The location to save sessions to, driver dependent. -| -| For the 'files' driver, it's a path to a writable directory. -| WARNING: Only absolute paths are supported! -| -| For the 'database' driver, it's a table name. -| Please read up the manual for the format with other session drivers. -| -| IMPORTANT: You are REQUIRED to set a valid save path! -| -| 'sess_match_ip' -| -| Whether to match the user's IP address when reading the session data. -| -| WARNING: If you're using the database driver, don't forget to update -| your session table's PRIMARY KEY when changing this setting. -| -| 'sess_time_to_update' -| -| How many seconds between CI regenerating the session ID. -| -| 'sess_regenerate_destroy' -| -| Whether to destroy session data associated with the old session ID -| when auto-regenerating the session ID. When set to FALSE, the data -| will be later deleted by the garbage collector. -| -| Other session cookie settings are shared with the rest of the application, -| except for 'cookie_prefix' and 'cookie_httponly', which are ignored here. -| -*/ -$config['sess_driver'] = 'files'; -$config['sess_cookie_name'] = 'ci_session'; -$config['sess_samesite'] = 'Lax'; -$config['sess_expiration'] = 7200; -$config['sess_save_path'] = sys_get_temp_dir(); -$config['sess_match_ip'] = FALSE; -$config['sess_time_to_update'] = 300; -$config['sess_regenerate_destroy'] = FALSE; - -/* -|-------------------------------------------------------------------------- -| Cookie Related Variables -|-------------------------------------------------------------------------- -| -| 'cookie_prefix' = Set a cookie name prefix if you need to avoid collisions -| 'cookie_domain' = Set to .your-domain.com for site-wide cookies -| 'cookie_path' = Typically will be a forward slash -| 'cookie_secure' = Cookie will only be set if a secure HTTPS connection exists. -| 'cookie_httponly' = Cookie will only be accessible via HTTP(S) (no javascript) -| 'cookie_samesite' = Cookie's samesite attribute (Lax, Strict or None) -| -| Note: These settings (with the exception of 'cookie_prefix' and -| 'cookie_httponly') will also affect sessions. -| -*/ -$config['cookie_prefix'] = ''; -$config['cookie_domain'] = ''; -$config['cookie_path'] = '/'; -$config['cookie_secure'] = FALSE; -$config['cookie_httponly'] = FALSE; -$config['cookie_samesite'] = 'Lax'; - -/* -|-------------------------------------------------------------------------- -| Standardize newlines -|-------------------------------------------------------------------------- -| -| Determines whether to standardize newline characters in input data, -| meaning to replace \r\n, \r, \n occurrences with the PHP_EOL value. -| -| WARNING: This feature is DEPRECATED and currently available only -| for backwards compatibility purposes! -| -*/ -$config['standardize_newlines'] = FALSE; - -/* -|-------------------------------------------------------------------------- -| Global XSS Filtering -|-------------------------------------------------------------------------- -| -| Determines whether the XSS filter is always active when GET, POST or -| COOKIE data is encountered -| -| WARNING: This feature is DEPRECATED and currently available only -| for backwards compatibility purposes! -| -*/ -$config['global_xss_filtering'] = FALSE; - -/* -|-------------------------------------------------------------------------- -| Cross Site Request Forgery -|-------------------------------------------------------------------------- -| Enables a CSRF cookie token to be set. When set to TRUE, token will be -| checked on a submitted form. If you are accepting user data, it is strongly -| recommended CSRF protection be enabled. -| -| 'csrf_token_name' = The token name -| 'csrf_cookie_name' = The cookie name -| 'csrf_expire' = The number in seconds the token should expire. -| 'csrf_regenerate' = Regenerate token on every submission -| 'csrf_exclude_uris' = Array of URIs which ignore CSRF checks -*/ -$config['csrf_protection'] = FALSE; -$config['csrf_token_name'] = 'csrf_test_name'; -$config['csrf_cookie_name'] = 'csrf_cookie_name'; -$config['csrf_expire'] = 7200; -$config['csrf_regenerate'] = TRUE; -$config['csrf_exclude_uris'] = array(); - -/* -|-------------------------------------------------------------------------- -| Output Compression -|-------------------------------------------------------------------------- -| -| Enables Gzip output compression for faster page loads. When enabled, -| the output class will test whether your server supports Gzip. -| Even if it does, however, not all browsers support compression -| so enable only if you are reasonably sure your visitors can handle it. -| -| Only used if zlib.output_compression is turned off in your php.ini. -| Please do not use it together with httpd-level output compression. -| -| VERY IMPORTANT: If you are getting a blank page when compression is enabled it -| means you are prematurely outputting something to your browser. It could -| even be a line of whitespace at the end of one of your scripts. For -| compression to work, nothing can be sent before the output buffer is called -| by the output class. Do not 'echo' any values with compression enabled. -| -*/ -$config['compress_output'] = FALSE; - -/* -|-------------------------------------------------------------------------- -| Master Time Reference -|-------------------------------------------------------------------------- -| -| Options are 'local' or any PHP supported timezone. This preference tells -| the system whether to use your server's local time as the master 'now' -| reference, or convert it to the configured one timezone. See the 'date -| helper' page of the user guide for information regarding date handling. -| -*/ -$config['time_reference'] = 'local'; - -/* -|-------------------------------------------------------------------------- -| Rewrite PHP Short Tags -|-------------------------------------------------------------------------- -| -| If your PHP installation does not have short tag support enabled CI -| can rewrite the tags on-the-fly, enabling you to utilize that syntax -| in your view files. Options are TRUE or FALSE (boolean) -| -| Note: You need to have eval() enabled for this to work. -| -*/ -$config['rewrite_short_tags'] = FALSE; - -/* -|-------------------------------------------------------------------------- -| Reverse Proxy IPs -|-------------------------------------------------------------------------- -| -| If your server is behind a reverse proxy, you must whitelist the proxy -| IP addresses from which CodeIgniter should trust headers such as -| HTTP_X_FORWARDED_FOR and HTTP_CLIENT_IP in order to properly identify -| the visitor's IP address. -| -| You can use both an array or a comma-separated list of proxy addresses, -| as well as specifying whole subnets. Here are a few examples: -| -| Comma-separated: '10.0.1.200,192.168.5.0/24' -| Array: array('10.0.1.200', '192.168.5.0/24') -*/ -$config['proxy_ips'] = ''; diff --git a/application/config/database.php b/application/config/database.php deleted file mode 100644 index 3c75eaa..0000000 --- a/application/config/database.php +++ /dev/null @@ -1,98 +0,0 @@ -db->last_query() and profiling of DB queries. -| When you run a query, with this setting set to TRUE (default), -| CodeIgniter will store the SQL statement for debugging purposes. -| However, this may cause high memory usage, especially if you run -| a lot of SQL queries ... disable this to avoid that problem. -| -| The $active_group variable lets you choose which connection group to -| make active. By default there is only one group (the 'default' group). -| -| The $query_builder variables lets you determine whether or not to load -| the query builder class. -*/ -$active_group = 'default'; -$query_builder = TRUE; - -$db['default'] = array( - 'dsn' => '', - 'hostname' => '103.242.106.56', // tanpa port - 'port' => 3310, // port PostgreSQL - 'username' => 'accointing_dev', - 'password' => 'accointing_dev', - 'database' => 'accointing_dev', - 'dbdriver' => 'mysqli', // WAJIB: driver PostgreSQL - 'dbprefix' => '', - 'pconnect' => FALSE, - 'db_debug' => (ENVIRONMENT !== 'production'), - 'cache_on' => FALSE, - 'cachedir' => '', - 'char_set' => 'utf8', - 'dbcollat' => 'utf8_general_ci', // PostgreSQL abaikan ini, tapi biarkan saja - 'swap_pre' => '', - 'encrypt' => FALSE, - 'compress' => FALSE, - 'stricton' => FALSE, - 'failover' => array(), - 'save_queries' => TRUE -); - diff --git a/application/controllers/Cronjob.php b/application/controllers/Cronjob.php index d162d68..3d1ba37 100644 --- a/application/controllers/Cronjob.php +++ b/application/controllers/Cronjob.php @@ -137,4 +137,220 @@ class Cronjob extends CI_Controller { 'period' => $period ]); } + + // ===================================================== + // CRONJOB UNTUK LIHAT KEHADIRAN SELAMA 1 BULAN + // ===================================================== + + // | Kriteria | Pengurangan | + // | ---------------------- | ------------------: | + // | Alpha | -20 poin / hari | + // | Terlambat | -2 poin / kejadian | + // | Izin (permit) | -1 poin / hari | + // | Akumulasi telat | -1 poin / 60 menit | + // | Akumulasi pulang cepat | -1 poin / 120 menit | + + public function generateMonthlyAttendance() + { + $month = date('Y-m-01'); + + $startDate = date('Y-m-01', strtotime($month)); + $endDate = date('Y-m-t', strtotime($month)); + + $employees = $this->db + ->where('is_active', 1) + ->get('k_employees') + ->result(); + + $processed = 0; + + $this->db->trans_begin(); + + try { + + foreach ($employees as $employee) { + + // Total Hari Kerja + $schedule = $this->db->query(" + SELECT + COUNT(*) AS total_hari_kerja + FROM k_employee_shift_schedules + WHERE employee_id = ? + AND status IN ('published','done') + AND schedule_date BETWEEN ? AND ? + ", array( + $employee->id, + $startDate, + $endDate + ))->row(); + + $total_hari_kerja = (int) $schedule->total_hari_kerja; + + // Rekap Absensi + $attendance = $this->db->query(" + SELECT + + COALESCE(SUM(attendance_status='present'),0) AS total_present, + COALESCE(SUM(attendance_status='late'),0) AS total_late, + COALESCE(SUM(attendance_status='alpha'),0) AS total_alpha, + COALESCE(SUM(attendance_status='sick'),0) AS total_sick, + COALESCE(SUM(attendance_status='permit'),0) AS total_permit, + COALESCE(SUM(attendance_status='annual'),0) AS total_annual, + + COALESCE(SUM(late_minutes),0) AS total_late_minutes, + COALESCE(SUM(early_leave_minutes),0) AS total_early_leave_minutes, + + COALESCE(SUM(work_hours),0) AS total_work_hours, + COALESCE(SUM(overtime_hours),0) AS total_overtime_hours + + FROM k_attendances + WHERE employee_id = ? + AND attendance_date BETWEEN ? AND ? + ", array( + $employee->id, + $startDate, + $endDate + ))->row(); + + $total_present = (int) $attendance->total_present; + $total_late = (int) $attendance->total_late; + $total_alpha = (int) $attendance->total_alpha; + $total_sick = (int) $attendance->total_sick; + $total_permit = (int) $attendance->total_permit; + $total_annual = (int) $attendance->total_annual; + + // Kehadiran + $total_hadir = $total_present + $total_late; + + $attendance_percentage = 0; + + if ($total_hari_kerja > 0) { + $attendance_percentage = round( + ($total_hadir / $total_hari_kerja) * 100, + 2 + ); + } + + // SCOR + $score = 100; + + // Alpha + $score -= ($total_alpha * 20); + + // Telat + $score -= ($total_late * 2); + + // Izin + $score -= ($total_permit * 1); + + // Total menit telat + $score -= floor( + ((int) $attendance->total_late_minutes) / 60 + ); + + // Total menit pulang cepat + $score -= floor( + ((int) $attendance->total_early_leave_minutes) / 120 + ); + + if ($score < 0) { + $score = 0; + } + + // LOGIKA STATUS + if ($score >= 90) { + $status = 'baik sekali'; + } elseif ($score >= 75) { + $status = 'baik'; + } elseif ($score >= 60) { + $status = 'kurang baik'; + } else { + $status = 'buruk'; + } + + // INSERT OR UPDATE TO k_attendance_monthly + $sql = " + INSERT INTO k_attendance_monthly ( + employee_id, month, + total_present, total_late, total_alpha, total_sick, total_permit, total_annual, + total_late_minutes, total_early_leave_minutes, + total_work_hours, total_overtime_hours, + total_hari_kerja, total_hadir, attendance_percentage, + score, status + ) + VALUES ( + ?, ?, + ?, ?, ?, ?, ?, ?, + ?, ?, + ?, ?, + ?, ?, ?, + ?, ? + ) + ON DUPLICATE KEY UPDATE + total_present = VALUES(total_present), + total_late = VALUES(total_late), + total_alpha = VALUES(total_alpha), + total_sick = VALUES(total_sick), + total_permit = VALUES(total_permit), + total_annual = VALUES(total_annual), + total_late_minutes = VALUES(total_late_minutes), + total_early_leave_minutes = VALUES(total_early_leave_minutes), + total_work_hours = VALUES(total_work_hours), + total_overtime_hours = VALUES(total_overtime_hours), + total_hari_kerja = VALUES(total_hari_kerja), + total_hadir = VALUES(total_hadir), + attendance_percentage = VALUES(attendance_percentage), + score = VALUES(score), + status = VALUES(status), + updated_at = CURRENT_TIMESTAMP + "; + + $this->db->query($sql, array( + $employee->id, + $month, + $total_present, + $total_late, + $total_alpha, + $total_sick, + $total_permit, + $total_annual, + (int)$attendance->total_late_minutes, + (int)$attendance->total_early_leave_minutes, + (float)$attendance->total_work_hours, + (float)$attendance->total_overtime_hours, + $total_hari_kerja, + $total_hadir, + $attendance_percentage, + $score, + $status + )); + + $processed++; + } + + if ($this->db->trans_status() === FALSE) { + throw new Exception('Transaction failed'); + } + + $this->db->trans_commit(); + + echo json_encode(array( + 'status' => true, + 'month' => $month, + 'processed' => $processed, + 'message' => 'Monthly attendance generated successfully' + )); + + } catch (Exception $e) { + + $this->db->trans_rollback(); + + echo json_encode(array( + 'status' => false, + 'month' => $month, + 'message' => $e->getMessage() + )); + } + } + } \ No newline at end of file