1694 lines
44 KiB
Go
1694 lines
44 KiB
Go
package transabsensi
|
|
|
|
import (
|
|
"database/sql"
|
|
"encoding/base64"
|
|
"errors"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"com.sismedika.com.absensi/graph/model"
|
|
"com.sismedika.com.absensi/pkg/config"
|
|
db "com.sismedika.com.absensi/pkg/database"
|
|
)
|
|
|
|
// diambil dari graph/model/struct nya TransAbsensiResponse
|
|
type TransAbsensiCheckDistanceResponse model.TransAbsensiCheckDistanceResponse
|
|
|
|
type TransAbsensiResponse model.TransAbsensiResponse
|
|
|
|
type TransAbsensiCheckTimeAttendanceResponse model.TransAbsensiCheckTimeAttendanceResponse
|
|
|
|
type RekapKehadiranHomeScreen model.RekapKehadiranHomeScreen
|
|
|
|
// fungsi untuk Check Distance antara kantor dengan current user location
|
|
func (transabsensi *TransAbsensiCheckDistanceResponse) CheckDistance(M_StaffID string, M_CompanyID string, CurrentLatitude string, CurrentLongitude string) (*model.TransAbsensiCheckDistanceResponse, error) {
|
|
// inisialisasi
|
|
var err error
|
|
var ret model.TransAbsensiCheckDistanceResponse
|
|
var rMaxDistance int
|
|
var rCurrentDistance float64
|
|
var rMCompanyLongitude string
|
|
var rMCompanyLatitude string
|
|
var statusCheck string
|
|
|
|
q := `SELECT
|
|
M_CompanyLatitude,
|
|
M_CompanyLongitude,
|
|
M_CompanyMaxDistance
|
|
FROM m_company
|
|
WHERE M_CompanyIsActive = 'Y'
|
|
AND M_CompanyID = ?`
|
|
|
|
row := db.Handle.QueryRow(
|
|
q,
|
|
M_CompanyID)
|
|
db.LogSQL(q)
|
|
err = row.Scan(
|
|
&rMCompanyLatitude,
|
|
&rMCompanyLongitude,
|
|
&rMaxDistance,
|
|
)
|
|
|
|
if err != nil {
|
|
log.Printf("Error m_company select max distance: %v", err)
|
|
log.Printf("Executing query: %s\n", q)
|
|
return nil, err
|
|
}
|
|
|
|
// get distance
|
|
qCurrentDistance := `SELECT distance_v2(?, ?, ?, ?)`
|
|
|
|
rowxCurrentDistance := db.Handle.QueryRow(
|
|
qCurrentDistance,
|
|
CurrentLatitude,
|
|
CurrentLongitude,
|
|
rMCompanyLatitude,
|
|
rMCompanyLongitude,
|
|
)
|
|
db.LogSQL(qCurrentDistance)
|
|
err = rowxCurrentDistance.Scan(
|
|
&rCurrentDistance,
|
|
)
|
|
|
|
if err != nil {
|
|
log.Printf("Error m_staff select: %v", err)
|
|
log.Printf("Executing query: %s\n", qCurrentDistance)
|
|
return nil, err
|
|
}
|
|
|
|
// check distance
|
|
qCheckDistance := `SELECT IF(distance_v2(?, ?, ?, ?) < ?, 'range', 'not range') AS distance_status`
|
|
|
|
rowx := db.Handle.QueryRow(
|
|
qCheckDistance,
|
|
CurrentLatitude,
|
|
CurrentLongitude,
|
|
rMCompanyLatitude,
|
|
rMCompanyLongitude,
|
|
rMaxDistance,
|
|
)
|
|
db.LogSQL(qCheckDistance)
|
|
err = rowx.Scan(
|
|
&statusCheck,
|
|
)
|
|
|
|
if err != nil {
|
|
log.Printf("Error m_staff select: %v", err)
|
|
log.Printf("Executing query: %s\n", qCheckDistance)
|
|
return nil, err
|
|
}
|
|
|
|
if statusCheck == "range" {
|
|
// buat di set isi nya kosong dulu
|
|
ret.Status = new(string)
|
|
ret.Message = new(string)
|
|
ret.Selfie = new(string)
|
|
ret.CurrentDistance = new(string)
|
|
ret.MaxDistance = new(string)
|
|
ret.Unit = new(string)
|
|
|
|
// di set kan langsung dengan * atau pointer
|
|
*ret.Status = "OK"
|
|
*ret.Selfie = "FALSE"
|
|
*ret.Unit = "m"
|
|
*ret.CurrentDistance = strconv.FormatFloat(rCurrentDistance, 'f', -1, 64)
|
|
*ret.MaxDistance = strconv.Itoa(rMaxDistance)
|
|
*ret.Message = "Masih dalam jarak absensi"
|
|
}
|
|
|
|
if statusCheck != "range" {
|
|
// buat di set isi nya kosong dulu
|
|
ret.Status = new(string)
|
|
ret.Message = new(string)
|
|
ret.Selfie = new(string)
|
|
ret.CurrentDistance = new(string)
|
|
ret.MaxDistance = new(string)
|
|
ret.Unit = new(string)
|
|
|
|
// di set kan langsung dengan * atau pointer
|
|
*ret.Status = "OK"
|
|
*ret.Selfie = "TRUE"
|
|
*ret.Unit = "m"
|
|
*ret.CurrentDistance = strconv.FormatFloat(rCurrentDistance, 'f', -1, 64)
|
|
*ret.MaxDistance = strconv.Itoa(rMaxDistance)
|
|
*ret.Message = "Max Distance : " + strconv.Itoa(rMaxDistance) + " meter. Current Distance: " + strconv.FormatFloat(rCurrentDistance, 'f', -1, 64) + ". Jauh dari area absensi, perlu foto selfie"
|
|
}
|
|
|
|
// hasil return nya
|
|
return &ret, err
|
|
}
|
|
|
|
// clock in v1
|
|
func (transabsensi *TransAbsensiResponse) ClockInAbsensiV1(T_TransactionM_StaffID string, T_TransactionM_CompanyID string, T_TransactionCurrentLatitude string, T_TransactionCurrentLongitude string, T_TransactionCurrentDistance string, T_TransactionSelfiePhoto string, token string, isSelfie string) (*model.TransAbsensiResponse, error) {
|
|
// inisialisasi
|
|
var err error
|
|
var ret model.TransAbsensiResponse
|
|
var varGetToken string
|
|
var varGetM_StaffNIP string
|
|
var varProsesFotoSelfie string
|
|
var jamClockIn string
|
|
var varFileName string
|
|
|
|
// check user token
|
|
qCheckTokenStaff := `SELECT
|
|
M_StaffToken,
|
|
LOWER(M_StaffNIP) AS M_StaffNIP
|
|
FROM m_staff
|
|
WHERE M_StaffIsActive = 'Y'
|
|
AND M_StaffToken = ?
|
|
`
|
|
|
|
rowCheckTokenStaff := db.Handle.QueryRow(
|
|
qCheckTokenStaff,
|
|
token,
|
|
)
|
|
db.LogSQL(qCheckTokenStaff)
|
|
err = rowCheckTokenStaff.Scan(
|
|
&varGetToken,
|
|
&varGetM_StaffNIP,
|
|
)
|
|
|
|
if err != nil {
|
|
log.Printf("Error m_staff select token: %v", err)
|
|
log.Printf("Executing query: %s\n", qCheckTokenStaff)
|
|
return nil, err
|
|
}
|
|
|
|
// check varGetToken jk M_StaffToken kosong
|
|
if varGetToken == "" {
|
|
log.Printf("Error Token Kosong, Silahkan Login Dulu: %v", err)
|
|
log.Printf("Executing query: %s\n", qCheckTokenStaff)
|
|
return nil, err
|
|
}
|
|
|
|
ret.Status = new(string)
|
|
ret.Message = new(string)
|
|
|
|
// lanjut proses absen
|
|
if varGetToken != "" {
|
|
|
|
// tanpa selfie T_TransactionSelfiePhoto di set kosong
|
|
if isSelfie != "TRUE" {
|
|
T_TransactionSelfiePhoto = ""
|
|
varProsesFotoSelfie = ""
|
|
|
|
// setting jam absen
|
|
currentTime := time.Now()
|
|
jam := currentTime.Hour()
|
|
menit := currentTime.Minute()
|
|
detik := currentTime.Second()
|
|
|
|
jamClockIn = fmt.Sprintf("%02d:%02d:%02d", jam, menit, detik)
|
|
}
|
|
|
|
// selfie true
|
|
if isSelfie == "TRUE" {
|
|
|
|
// pecah string
|
|
strToArrayFoto := strings.Split(T_TransactionSelfiePhoto, ",")
|
|
|
|
// check apakah sudah sesuai apa belum
|
|
if len(strToArrayFoto) == 0 {
|
|
log.Printf("Eror Tidak Sesuai Format %v", err)
|
|
return &ret, err
|
|
}
|
|
|
|
// jika sesuai ambil strToArrayFoto ke 1 atau index ke 1
|
|
if len(strToArrayFoto) > 0 {
|
|
base64DataFoto := strToArrayFoto[1]
|
|
T_TransactionSelfiePhoto = base64DataFoto
|
|
}
|
|
|
|
currentTime := time.Now()
|
|
|
|
// setting jam absen
|
|
jam := currentTime.Hour()
|
|
menit := currentTime.Minute()
|
|
detik := currentTime.Second()
|
|
|
|
jamClockIn = fmt.Sprintf("%02d:%02d:%02d", jam, menit, detik)
|
|
|
|
formattedTime := currentTime.Format("2006-01-02_15_04_05")
|
|
// buat nama file
|
|
varProsesFotoSelfie = "clockin_" + varGetM_StaffNIP + "_" + formattedTime
|
|
strPhoto := varProsesFotoSelfie + ".jpg"
|
|
|
|
// folder upload file nya selfie_attachment akan otomatis sesuai bulan dan tahun
|
|
folderName := currentTime.Format("200601")
|
|
folder := "selfie_attachment/" + folderName + "/"
|
|
photoPath := config.Data.Get("document") + folder
|
|
|
|
log.Printf("documentPath: %s", photoPath)
|
|
|
|
// create folder selfie_attachment jika belum ada
|
|
if _, err := os.Stat(photoPath); errors.Is(err, os.ErrNotExist) {
|
|
err = os.MkdirAll(photoPath, os.ModePerm.Perm())
|
|
if err != nil {
|
|
log.Printf("here %v", err)
|
|
return &ret, err
|
|
}
|
|
}
|
|
|
|
photoPath = photoPath + strPhoto
|
|
|
|
// proses decode
|
|
decodedByte, err := base64.StdEncoding.DecodeString(T_TransactionSelfiePhoto)
|
|
|
|
if err != nil {
|
|
log.Printf("here %v", err)
|
|
return &ret, err
|
|
}
|
|
|
|
fs, err := os.Create(photoPath)
|
|
if err != nil {
|
|
log.Printf("here %v", err)
|
|
return &ret, err
|
|
}
|
|
defer fs.Close()
|
|
fs.Write(decodedByte)
|
|
fs.Sync()
|
|
|
|
varProsesFotoSelfie = "selfie_attachment/" + folderName + "/" + strPhoto
|
|
varFileName = strPhoto
|
|
}
|
|
|
|
qInsertClockIn := `INSERT INTO t_transaction (
|
|
T_TransactionM_AbsensiTypeID,
|
|
T_TransactionM_StaffID,
|
|
T_TransactionM_CompanyID,
|
|
T_TransactionClockAbsensi,
|
|
T_TransactionDate,
|
|
T_TransactionCurrentLatitude,
|
|
T_TransactionCurrentLongitude,
|
|
T_TransactionCurrentDistance,
|
|
T_TransactionFileName,
|
|
T_TransactionSelfiePhotoPath,
|
|
T_TransactionIsActive,
|
|
T_TransactionCreated
|
|
) VALUES (
|
|
?,
|
|
?,
|
|
?,
|
|
?,
|
|
NOW(),
|
|
?,
|
|
?,
|
|
?,
|
|
?,
|
|
?,
|
|
?,
|
|
NOW()
|
|
)`
|
|
|
|
_, err = db.Handle.Exec(qInsertClockIn,
|
|
"1",
|
|
T_TransactionM_StaffID,
|
|
T_TransactionM_CompanyID,
|
|
&jamClockIn,
|
|
T_TransactionCurrentLatitude,
|
|
T_TransactionCurrentLongitude,
|
|
T_TransactionCurrentDistance,
|
|
&varFileName,
|
|
&varProsesFotoSelfie,
|
|
"Y",
|
|
)
|
|
|
|
// set status jika tidak error
|
|
if err == nil {
|
|
*ret.Status = "OK"
|
|
*ret.Message = "Proses Absensi Masuk Berhasil"
|
|
}
|
|
|
|
// set status jika error
|
|
if err != nil {
|
|
*ret.Status = "ERR"
|
|
*ret.Message = "ERROR : " + err.Error()
|
|
}
|
|
}
|
|
|
|
return &ret, err
|
|
}
|
|
|
|
// fungsi untuk absen masuk clock in
|
|
func (transabsensi *TransAbsensiResponse) ClockInAbsensi(T_TransactionM_StaffID string, T_TransactionM_CompanyID string, T_TransactionCurrentLatitude string, T_TransactionCurrentLongitude string, T_TransactionCurrentDistance string, T_TransactionSelfiePhoto string, token string, isSelfie string) (*model.TransAbsensiResponse, error) {
|
|
// inisialisasi
|
|
var err error
|
|
var ret model.TransAbsensiResponse
|
|
var varGetToken string
|
|
var varGetM_StaffNIP string
|
|
var varProsesFotoSelfie string
|
|
var jamClockIn string
|
|
var varFileName string
|
|
var rMaxDistance int
|
|
var rMCompanyLongitude string
|
|
var rMCompanyLatitude string
|
|
var statusCheckDistance string
|
|
var statusDayOfWeek string
|
|
var statusLibur string = ""
|
|
|
|
// check user token
|
|
qCheckTokenStaff := `SELECT
|
|
M_StaffToken,
|
|
LOWER(M_StaffNIP) AS M_StaffNIP
|
|
FROM m_staff
|
|
WHERE M_StaffIsActive = 'Y'
|
|
AND M_StaffToken = ?
|
|
`
|
|
|
|
rowCheckTokenStaff := db.Handle.QueryRow(
|
|
qCheckTokenStaff,
|
|
token,
|
|
)
|
|
db.LogSQL(qCheckTokenStaff)
|
|
err = rowCheckTokenStaff.Scan(
|
|
&varGetToken,
|
|
&varGetM_StaffNIP,
|
|
)
|
|
|
|
if err != nil {
|
|
log.Printf("Error m_staff select token: %v", err)
|
|
log.Printf("Executing query: %s\n", qCheckTokenStaff)
|
|
return nil, err
|
|
}
|
|
|
|
// check varGetToken jk M_StaffToken kosong
|
|
if varGetToken == "" {
|
|
log.Printf("Error Token Kosong, Silahkan Login Dulu: %v", err)
|
|
log.Printf("Executing query: %s\n", qCheckTokenStaff)
|
|
return nil, err
|
|
}
|
|
|
|
ret.Status = new(string)
|
|
ret.Message = new(string)
|
|
|
|
// lanjut proses absen
|
|
if varGetToken != "" {
|
|
|
|
// tanpa selfie T_TransactionSelfiePhoto di set kosong
|
|
if isSelfie != "TRUE" {
|
|
T_TransactionSelfiePhoto = ""
|
|
varProsesFotoSelfie = ""
|
|
|
|
// setting jam absen
|
|
currentTime := time.Now()
|
|
jam := currentTime.Hour()
|
|
menit := currentTime.Minute()
|
|
detik := currentTime.Second()
|
|
|
|
jamClockIn = fmt.Sprintf("%02d:%02d:%02d", jam, menit, detik)
|
|
}
|
|
|
|
// selfie true
|
|
if isSelfie == "TRUE" {
|
|
|
|
// check current distance
|
|
|
|
// pecah string
|
|
strToArrayFoto := strings.Split(T_TransactionSelfiePhoto, ",")
|
|
|
|
// check apakah sudah sesuai apa belum
|
|
if len(strToArrayFoto) == 0 {
|
|
log.Printf("Eror Tidak Sesuai Format %v", err)
|
|
return &ret, err
|
|
}
|
|
|
|
// jika sesuai ambil strToArrayFoto ke 1 atau index ke 1
|
|
if len(strToArrayFoto) > 0 {
|
|
base64DataFoto := strToArrayFoto[1]
|
|
T_TransactionSelfiePhoto = base64DataFoto
|
|
}
|
|
|
|
currentTime := time.Now()
|
|
|
|
// setting jam absen
|
|
jam := currentTime.Hour()
|
|
menit := currentTime.Minute()
|
|
detik := currentTime.Second()
|
|
|
|
jamClockIn = fmt.Sprintf("%02d:%02d:%02d", jam, menit, detik)
|
|
|
|
formattedTime := currentTime.Format("2006-01-02_15_04_05")
|
|
// buat nama file
|
|
varProsesFotoSelfie = "clockin_" + varGetM_StaffNIP + "_" + formattedTime
|
|
strPhoto := varProsesFotoSelfie + ".jpg"
|
|
|
|
// folder upload file nya selfie_attachment akan otomatis sesuai bulan dan tahun
|
|
folderName := currentTime.Format("200601")
|
|
folder := "selfie_attachment/" + folderName + "/"
|
|
photoPath := config.Data.Get("document") + folder
|
|
|
|
log.Printf("documentPath: %s", photoPath)
|
|
|
|
// create folder selfie_attachment jika belum ada
|
|
if _, err := os.Stat(photoPath); errors.Is(err, os.ErrNotExist) {
|
|
err = os.MkdirAll(photoPath, os.ModePerm.Perm())
|
|
if err != nil {
|
|
log.Printf("here %v", err)
|
|
return &ret, err
|
|
}
|
|
}
|
|
|
|
photoPath = photoPath + strPhoto
|
|
|
|
// proses decode
|
|
decodedByte, err := base64.StdEncoding.DecodeString(T_TransactionSelfiePhoto)
|
|
|
|
if err != nil {
|
|
log.Printf("here %v", err)
|
|
return &ret, err
|
|
}
|
|
|
|
fs, err := os.Create(photoPath)
|
|
if err != nil {
|
|
log.Printf("here %v", err)
|
|
return &ret, err
|
|
}
|
|
defer fs.Close()
|
|
fs.Write(decodedByte)
|
|
fs.Sync()
|
|
|
|
varProsesFotoSelfie = "selfie_attachment/" + folderName + "/" + strPhoto
|
|
varFileName = strPhoto
|
|
}
|
|
|
|
qInsertClockIn := `INSERT INTO t_transaction (
|
|
T_TransactionM_AbsensiTypeID,
|
|
T_TransactionM_StaffID,
|
|
T_TransactionM_CompanyID,
|
|
T_TransactionClockAbsensi,
|
|
T_TransactionDate,
|
|
T_TransactionCurrentLatitude,
|
|
T_TransactionCurrentLongitude,
|
|
T_TransactionCurrentDistance,
|
|
T_TransactionFileName,
|
|
T_TransactionSelfiePhotoPath,
|
|
T_TransactionIsActive,
|
|
T_TransactionCreated
|
|
) VALUES (
|
|
?,
|
|
?,
|
|
?,
|
|
?,
|
|
NOW(),
|
|
?,
|
|
?,
|
|
?,
|
|
?,
|
|
?,
|
|
?,
|
|
NOW()
|
|
)`
|
|
|
|
result, err := db.Handle.Exec(qInsertClockIn,
|
|
"1",
|
|
T_TransactionM_StaffID,
|
|
T_TransactionM_CompanyID,
|
|
&jamClockIn,
|
|
T_TransactionCurrentLatitude,
|
|
T_TransactionCurrentLongitude,
|
|
T_TransactionCurrentDistance,
|
|
&varFileName,
|
|
&varProsesFotoSelfie,
|
|
"Y",
|
|
)
|
|
|
|
// dapatkan id terakhir ketika sudah ditambahkan
|
|
lastInsertID, err := result.LastInsertId()
|
|
|
|
// set status jika tidak error
|
|
if err == nil {
|
|
// jika distance not in range T_TransactionNeedConfirmation update to Y
|
|
q := `SELECT
|
|
M_CompanyLatitude,
|
|
M_CompanyLongitude,
|
|
M_CompanyMaxDistance
|
|
FROM m_company
|
|
WHERE M_CompanyIsActive = 'Y'
|
|
AND M_CompanyID = ?`
|
|
|
|
row := db.Handle.QueryRow(
|
|
q,
|
|
T_TransactionM_CompanyID)
|
|
db.LogSQL(q)
|
|
err = row.Scan(
|
|
&rMCompanyLatitude,
|
|
&rMCompanyLongitude,
|
|
&rMaxDistance,
|
|
)
|
|
|
|
if err != nil {
|
|
log.Printf("Error m_company select max distance: %v", err)
|
|
log.Printf("Executing query: %s\n", q)
|
|
return nil, err
|
|
}
|
|
|
|
// check distance
|
|
qCheckDistance := `SELECT IF(distance_v2(?, ?, ?, ?) < ?, 'range', 'not range') AS distance_status`
|
|
|
|
rowx := db.Handle.QueryRow(
|
|
qCheckDistance,
|
|
T_TransactionCurrentLatitude,
|
|
T_TransactionCurrentLongitude,
|
|
rMCompanyLatitude,
|
|
rMCompanyLongitude,
|
|
rMaxDistance,
|
|
)
|
|
db.LogSQL(qCheckDistance)
|
|
err = rowx.Scan(
|
|
&statusCheckDistance,
|
|
)
|
|
if err != nil {
|
|
log.Printf("Executing query: %s\n", qCheckDistance)
|
|
return nil, err
|
|
}
|
|
|
|
// check libur di table m_libur
|
|
qCheckLibur := `SELECT IF(COUNT(*) > 0, 'libur', 'tidak libur') as statusLibur
|
|
FROM m_libur
|
|
WHERE M_LiburIsActive = 'Y'
|
|
AND M_LiburDate = DATE_FORMAT(CURDATE(), '%Y-%m-%d')`
|
|
|
|
rowx = db.Handle.QueryRow(
|
|
qCheckLibur,
|
|
)
|
|
|
|
db.LogSQL(qCheckLibur)
|
|
err = rowx.Scan(
|
|
&statusLibur,
|
|
)
|
|
if err != nil {
|
|
if err == sql.ErrNoRows {
|
|
statusLibur = "tidak libur"
|
|
} else {
|
|
log.Printf("Executing query check status libur: %s\n", qCheckLibur)
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
// check hari absen (hari ini) == hari sabtu atau minggu.
|
|
// hari sabtu dalam mysql day of week == hari ke 6
|
|
// hari minggu dalam mysql day of week == hari ke 1
|
|
|
|
qCheckDayOfWeek := `SELECT DAYOFWEEK(CURDATE()) As statusDayOfWeek`
|
|
db.LogSQL(qCheckDayOfWeek)
|
|
rowx = db.Handle.QueryRow(
|
|
qCheckDayOfWeek,
|
|
)
|
|
err = rowx.Scan(
|
|
&statusDayOfWeek,
|
|
)
|
|
if err != nil {
|
|
if err == sql.ErrNoRows {
|
|
statusDayOfWeek = ""
|
|
} else {
|
|
log.Printf("Executing query check status day of week: %s\n", qCheckDayOfWeek)
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
// jika tidak berada di lokasi kantor maka update T_TransactionNeedConfirmation = Y
|
|
if statusCheckDistance != "range" || statusLibur == "libur" || (statusDayOfWeek == "1" || statusDayOfWeek == "7") {
|
|
qUpdate := `UPDATE t_transaction
|
|
SET T_TransactionNeedConfirmation = 'Y'
|
|
WHERE T_TransactionID = ?`
|
|
|
|
_, err := db.Handle.Exec(qUpdate,
|
|
lastInsertID,
|
|
)
|
|
|
|
if err != nil {
|
|
log.Printf("Executing query update T_TransactionNeedConfirmation : %s\n", qUpdate)
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
*ret.Status = "OK"
|
|
*ret.Message = "Proses Absensi Masuk Berhasil"
|
|
}
|
|
|
|
// set status jika error
|
|
if err != nil {
|
|
*ret.Status = "ERR"
|
|
*ret.Message = "ERROR : " + err.Error()
|
|
}
|
|
}
|
|
|
|
return &ret, err
|
|
}
|
|
|
|
// clock out v1
|
|
func (transabsensi *TransAbsensiResponse) ClockOutAbsensiV1(T_TransactionM_StaffID string, T_TransactionM_CompanyID string, T_TransactionCurrentLatitude string, T_TransactionCurrentLongitude string, T_TransactionCurrentDistance string, T_TransactionSelfiePhoto string, token string, isSelfie string) (*model.TransAbsensiResponse, error) {
|
|
// inisialisasi
|
|
var err error
|
|
var ret model.TransAbsensiResponse
|
|
var varGetToken string
|
|
var varGetM_StaffNIP string
|
|
var varProsesFotoSelfie string
|
|
var jamClockOut string
|
|
var varFileName string
|
|
|
|
// check user token
|
|
qCheckTokenStaff := `SELECT
|
|
M_StaffToken,
|
|
LOWER(M_StaffNIP) AS M_StaffNIP
|
|
FROM m_staff
|
|
WHERE M_StaffIsActive = 'Y'
|
|
AND M_StaffToken = ?
|
|
`
|
|
|
|
rowCheckTokenStaff := db.Handle.QueryRow(
|
|
qCheckTokenStaff,
|
|
token,
|
|
)
|
|
db.LogSQL(qCheckTokenStaff)
|
|
err = rowCheckTokenStaff.Scan(
|
|
&varGetToken,
|
|
&varGetM_StaffNIP,
|
|
)
|
|
|
|
if err != nil {
|
|
log.Printf("Error m_staff select token: %v", err)
|
|
log.Printf("Executing query: %s\n", qCheckTokenStaff)
|
|
return nil, err
|
|
}
|
|
|
|
// check varGetToken jk M_StaffToken kosong
|
|
if varGetToken == "" {
|
|
log.Printf("Error Token Kosong, Silahkan Login Dulu: %v", err)
|
|
log.Printf("Executing query: %s\n", qCheckTokenStaff)
|
|
return nil, err
|
|
}
|
|
|
|
ret.Status = new(string)
|
|
ret.Message = new(string)
|
|
|
|
// lanjut proses absen
|
|
if varGetToken != "" {
|
|
|
|
// tanpa selfie T_TransactionSelfiePhoto di set kosong
|
|
if isSelfie != "TRUE" {
|
|
T_TransactionSelfiePhoto = ""
|
|
varProsesFotoSelfie = ""
|
|
|
|
// setting jam absen
|
|
currentTime := time.Now()
|
|
jam := currentTime.Hour()
|
|
menit := currentTime.Minute()
|
|
detik := currentTime.Second()
|
|
|
|
jamClockOut = fmt.Sprintf("%02d:%02d:%02d", jam, menit, detik)
|
|
}
|
|
|
|
// selfie true
|
|
if isSelfie == "TRUE" {
|
|
|
|
// pecah string
|
|
strToArrayFoto := strings.Split(T_TransactionSelfiePhoto, ",")
|
|
|
|
// check apakah sudah sesuai apa belum
|
|
if len(strToArrayFoto) == 0 {
|
|
log.Printf("Eror Tidak Sesuai Format %v", err)
|
|
return &ret, err
|
|
}
|
|
|
|
// jika sesuai ambil strToArrayFoto ke 1 atau index ke 1
|
|
if len(strToArrayFoto) > 0 {
|
|
base64DataFoto := strToArrayFoto[1]
|
|
T_TransactionSelfiePhoto = base64DataFoto
|
|
}
|
|
|
|
currentTime := time.Now()
|
|
|
|
// setting jam absen
|
|
jam := currentTime.Hour()
|
|
menit := currentTime.Minute()
|
|
detik := currentTime.Second()
|
|
|
|
jamClockOut = fmt.Sprintf("%02d:%02d:%02d", jam, menit, detik)
|
|
|
|
formattedTime := currentTime.Format("2006-01-02_15_04_05")
|
|
// buat nama file
|
|
varProsesFotoSelfie = "clockout_" + varGetM_StaffNIP + "_" + formattedTime
|
|
strPhoto := varProsesFotoSelfie + ".jpg"
|
|
|
|
// folder upload file nya selfie_attachment akan otomatis sesuai bulan dan tahun
|
|
folderName := currentTime.Format("200601")
|
|
folder := "selfie_attachment/" + folderName + "/"
|
|
photoPath := config.Data.Get("document") + folder
|
|
|
|
log.Printf("documentPath: %s", photoPath)
|
|
|
|
// create folder selfie_attachment jika belum ada
|
|
if _, err := os.Stat(photoPath); errors.Is(err, os.ErrNotExist) {
|
|
err = os.MkdirAll(photoPath, os.ModePerm.Perm())
|
|
if err != nil {
|
|
log.Printf("here %v", err)
|
|
return &ret, err
|
|
}
|
|
}
|
|
|
|
photoPath = photoPath + strPhoto
|
|
|
|
// proses decode
|
|
decodedByte, err := base64.StdEncoding.DecodeString(T_TransactionSelfiePhoto)
|
|
|
|
if err != nil {
|
|
log.Printf("here %v", err)
|
|
return &ret, err
|
|
}
|
|
|
|
fs, err := os.Create(photoPath)
|
|
if err != nil {
|
|
log.Printf("here %v", err)
|
|
return &ret, err
|
|
}
|
|
defer fs.Close()
|
|
fs.Write(decodedByte)
|
|
fs.Sync()
|
|
|
|
varProsesFotoSelfie = "selfie_attachment/" + folderName + "/" + strPhoto
|
|
varFileName = strPhoto
|
|
}
|
|
|
|
qInsertClockIn := `INSERT INTO t_transaction (
|
|
T_TransactionM_AbsensiTypeID,
|
|
T_TransactionM_StaffID,
|
|
T_TransactionM_CompanyID,
|
|
T_TransactionClockAbsensi,
|
|
T_TransactionDate,
|
|
T_TransactionCurrentLatitude,
|
|
T_TransactionCurrentLongitude,
|
|
T_TransactionCurrentDistance,
|
|
T_TransactionFileName,
|
|
T_TransactionSelfiePhotoPath,
|
|
T_TransactionIsActive,
|
|
T_TransactionCreated
|
|
) VALUES (
|
|
?,
|
|
?,
|
|
?,
|
|
?,
|
|
NOW(),
|
|
?,
|
|
?,
|
|
?,
|
|
?,
|
|
?,
|
|
?,
|
|
NOW()
|
|
)`
|
|
|
|
_, err = db.Handle.Exec(qInsertClockIn,
|
|
"2",
|
|
T_TransactionM_StaffID,
|
|
T_TransactionM_CompanyID,
|
|
&jamClockOut,
|
|
T_TransactionCurrentLatitude,
|
|
T_TransactionCurrentLongitude,
|
|
T_TransactionCurrentDistance,
|
|
&varFileName,
|
|
&varProsesFotoSelfie,
|
|
"Y",
|
|
)
|
|
|
|
// set status jika tidak error
|
|
if err == nil {
|
|
*ret.Status = "OK"
|
|
*ret.Message = "Proses Absensi Pulang Berhasil"
|
|
}
|
|
|
|
// set status jika error
|
|
if err != nil {
|
|
*ret.Status = "ERR"
|
|
*ret.Message = "ERROR : " + err.Error()
|
|
}
|
|
}
|
|
|
|
return &ret, err
|
|
}
|
|
|
|
// fungsi untuk absen keluar clock out
|
|
func (transabsensi *TransAbsensiResponse) ClockOutAbsensi(T_TransactionM_StaffID string, T_TransactionM_CompanyID string, T_TransactionCurrentLatitude string, T_TransactionCurrentLongitude string, T_TransactionCurrentDistance string, T_TransactionSelfiePhoto string, token string, isSelfie string) (*model.TransAbsensiResponse, error) {
|
|
// inisialisasi
|
|
var err error
|
|
var ret model.TransAbsensiResponse
|
|
var varGetToken string
|
|
var varGetM_StaffNIP string
|
|
var varProsesFotoSelfie string
|
|
var jamClockOut string
|
|
var varFileName string
|
|
var rMaxDistance int
|
|
var rMCompanyLongitude string
|
|
var rMCompanyLatitude string
|
|
var statusCheckDistance string
|
|
var statusDayOfWeek string
|
|
var statusLibur string = ""
|
|
|
|
// check user token
|
|
qCheckTokenStaff := `SELECT
|
|
M_StaffToken,
|
|
LOWER(M_StaffNIP) AS M_StaffNIP
|
|
FROM m_staff
|
|
WHERE M_StaffIsActive = 'Y'
|
|
AND M_StaffToken = ?
|
|
`
|
|
|
|
rowCheckTokenStaff := db.Handle.QueryRow(
|
|
qCheckTokenStaff,
|
|
token,
|
|
)
|
|
db.LogSQL(qCheckTokenStaff)
|
|
err = rowCheckTokenStaff.Scan(
|
|
&varGetToken,
|
|
&varGetM_StaffNIP,
|
|
)
|
|
|
|
if err != nil {
|
|
log.Printf("Error m_staff select token: %v", err)
|
|
log.Printf("Executing query: %s\n", qCheckTokenStaff)
|
|
return nil, err
|
|
}
|
|
|
|
// check varGetToken jk M_StaffToken kosong
|
|
if varGetToken == "" {
|
|
log.Printf("Error Token Kosong, Silahkan Login Dulu: %v", err)
|
|
log.Printf("Executing query: %s\n", qCheckTokenStaff)
|
|
return nil, err
|
|
}
|
|
|
|
ret.Status = new(string)
|
|
ret.Message = new(string)
|
|
|
|
// lanjut proses absen
|
|
if varGetToken != "" {
|
|
|
|
// tanpa selfie T_TransactionSelfiePhoto di set kosong
|
|
if isSelfie != "TRUE" {
|
|
T_TransactionSelfiePhoto = ""
|
|
varProsesFotoSelfie = ""
|
|
|
|
// setting jam absen
|
|
currentTime := time.Now()
|
|
jam := currentTime.Hour()
|
|
menit := currentTime.Minute()
|
|
detik := currentTime.Second()
|
|
|
|
jamClockOut = fmt.Sprintf("%02d:%02d:%02d", jam, menit, detik)
|
|
}
|
|
|
|
// selfie true
|
|
if isSelfie == "TRUE" {
|
|
|
|
// pecah string
|
|
strToArrayFoto := strings.Split(T_TransactionSelfiePhoto, ",")
|
|
|
|
// check apakah sudah sesuai apa belum
|
|
if len(strToArrayFoto) == 0 {
|
|
log.Printf("Eror Tidak Sesuai Format %v", err)
|
|
return &ret, err
|
|
}
|
|
|
|
// jika sesuai ambil strToArrayFoto ke 1 atau index ke 1
|
|
if len(strToArrayFoto) > 0 {
|
|
base64DataFoto := strToArrayFoto[1]
|
|
T_TransactionSelfiePhoto = base64DataFoto
|
|
}
|
|
|
|
currentTime := time.Now()
|
|
|
|
// setting jam absen
|
|
jam := currentTime.Hour()
|
|
menit := currentTime.Minute()
|
|
detik := currentTime.Second()
|
|
|
|
jamClockOut = fmt.Sprintf("%02d:%02d:%02d", jam, menit, detik)
|
|
|
|
formattedTime := currentTime.Format("2006-01-02_15_04_05")
|
|
// buat nama file
|
|
varProsesFotoSelfie = "clockout_" + varGetM_StaffNIP + "_" + formattedTime
|
|
strPhoto := varProsesFotoSelfie + ".jpg"
|
|
|
|
// folder upload file nya selfie_attachment akan otomatis sesuai bulan dan tahun
|
|
folderName := currentTime.Format("200601")
|
|
folder := "selfie_attachment/" + folderName + "/"
|
|
photoPath := config.Data.Get("document") + folder
|
|
|
|
log.Printf("documentPath: %s", photoPath)
|
|
|
|
// create folder selfie_attachment jika belum ada
|
|
if _, err := os.Stat(photoPath); errors.Is(err, os.ErrNotExist) {
|
|
err = os.MkdirAll(photoPath, os.ModePerm.Perm())
|
|
if err != nil {
|
|
log.Printf("here %v", err)
|
|
return &ret, err
|
|
}
|
|
}
|
|
|
|
photoPath = photoPath + strPhoto
|
|
|
|
// proses decode
|
|
decodedByte, err := base64.StdEncoding.DecodeString(T_TransactionSelfiePhoto)
|
|
|
|
if err != nil {
|
|
log.Printf("here %v", err)
|
|
return &ret, err
|
|
}
|
|
|
|
fs, err := os.Create(photoPath)
|
|
if err != nil {
|
|
log.Printf("here %v", err)
|
|
return &ret, err
|
|
}
|
|
defer fs.Close()
|
|
fs.Write(decodedByte)
|
|
fs.Sync()
|
|
|
|
varProsesFotoSelfie = "selfie_attachment/" + folderName + "/" + strPhoto
|
|
varFileName = strPhoto
|
|
}
|
|
|
|
qInsertClockIn := `INSERT INTO t_transaction (
|
|
T_TransactionM_AbsensiTypeID,
|
|
T_TransactionM_StaffID,
|
|
T_TransactionM_CompanyID,
|
|
T_TransactionClockAbsensi,
|
|
T_TransactionDate,
|
|
T_TransactionCurrentLatitude,
|
|
T_TransactionCurrentLongitude,
|
|
T_TransactionCurrentDistance,
|
|
T_TransactionFileName,
|
|
T_TransactionSelfiePhotoPath,
|
|
T_TransactionIsActive,
|
|
T_TransactionCreated
|
|
) VALUES (
|
|
?,
|
|
?,
|
|
?,
|
|
?,
|
|
NOW(),
|
|
?,
|
|
?,
|
|
?,
|
|
?,
|
|
?,
|
|
?,
|
|
NOW()
|
|
)`
|
|
|
|
result, err := db.Handle.Exec(qInsertClockIn,
|
|
"2",
|
|
T_TransactionM_StaffID,
|
|
T_TransactionM_CompanyID,
|
|
&jamClockOut,
|
|
T_TransactionCurrentLatitude,
|
|
T_TransactionCurrentLongitude,
|
|
T_TransactionCurrentDistance,
|
|
&varFileName,
|
|
&varProsesFotoSelfie,
|
|
"Y",
|
|
)
|
|
|
|
// dapatkan id terakhir ketika sudah ditambahkan
|
|
lastInsertID, err := result.LastInsertId()
|
|
|
|
// set status jika tidak error
|
|
if err == nil {
|
|
// jika distance not in range T_TransactionNeedConfirmation update to Y
|
|
q := `SELECT
|
|
M_CompanyLatitude,
|
|
M_CompanyLongitude,
|
|
M_CompanyMaxDistance
|
|
FROM m_company
|
|
WHERE M_CompanyIsActive = 'Y'
|
|
AND M_CompanyID = ?`
|
|
|
|
row := db.Handle.QueryRow(
|
|
q,
|
|
T_TransactionM_CompanyID)
|
|
db.LogSQL(q)
|
|
err = row.Scan(
|
|
&rMCompanyLatitude,
|
|
&rMCompanyLongitude,
|
|
&rMaxDistance,
|
|
)
|
|
|
|
if err != nil {
|
|
log.Printf("Error m_company select max distance: %v", err)
|
|
log.Printf("Executing query: %s\n", q)
|
|
return nil, err
|
|
}
|
|
|
|
// check distance
|
|
qCheckDistance := `SELECT IF(distance_v2(?, ?, ?, ?) < ?, 'range', 'not range') AS distance_status`
|
|
|
|
rowx := db.Handle.QueryRow(
|
|
qCheckDistance,
|
|
T_TransactionCurrentLatitude,
|
|
T_TransactionCurrentLongitude,
|
|
rMCompanyLatitude,
|
|
rMCompanyLongitude,
|
|
rMaxDistance,
|
|
)
|
|
db.LogSQL(qCheckDistance)
|
|
err = rowx.Scan(
|
|
&statusCheckDistance,
|
|
)
|
|
if err != nil {
|
|
log.Printf("Executing query: %s\n", qCheckDistance)
|
|
return nil, err
|
|
}
|
|
|
|
// check libur di table m_libur
|
|
qCheckLibur := `SELECT 'libur' as statusLibur
|
|
FROM m_libur
|
|
WHERE M_LiburIsActive = 'Y'
|
|
AND M_LiburDate = DATE_FORMAT(CURDATE(), "%Y-%m-%d")`
|
|
|
|
rowx = db.Handle.QueryRow(
|
|
qCheckLibur,
|
|
)
|
|
|
|
db.LogSQL(qCheckLibur)
|
|
err = rowx.Scan(
|
|
&statusLibur,
|
|
)
|
|
if err != nil {
|
|
if err == sql.ErrNoRows {
|
|
statusLibur = "tidak libur"
|
|
} else {
|
|
log.Printf("Executing query check status libur: %s\n", qCheckLibur)
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
// check hari absen (hari ini) == hari sabtu atau minggu.
|
|
// hari sabtu dalam mysql day of week == hari ke 6
|
|
// hari minggu dalam mysql day of week == hari ke 1
|
|
|
|
qCheckDayOfWeek := `SELECT DAYOFWEEK(CURDATE()) As statusDayOfWeek`
|
|
rowx = db.Handle.QueryRow(
|
|
qCheckDayOfWeek,
|
|
)
|
|
db.LogSQL(qCheckDayOfWeek)
|
|
err = rowx.Scan(
|
|
&statusDayOfWeek,
|
|
)
|
|
if err != nil {
|
|
if err == sql.ErrNoRows {
|
|
statusDayOfWeek = ""
|
|
} else {
|
|
log.Printf("Executing query check status day of week: %s\n", qCheckDayOfWeek)
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
// jika tidak berada di lokasi kantor maka update T_TransactionNeedConfirmation = Y
|
|
if statusCheckDistance != "range" || statusLibur == "libur" || (statusDayOfWeek == "1" || statusDayOfWeek == "7") {
|
|
qUpdate := `UPDATE t_transaction
|
|
SET T_TransactionNeedConfirmation = 'Y'
|
|
WHERE T_TransactionID = ?`
|
|
|
|
_, err := db.Handle.Exec(qUpdate,
|
|
lastInsertID,
|
|
)
|
|
|
|
if err != nil {
|
|
log.Printf("Executing query update T_TransactionNeedConfirmation : %s\n", qUpdate)
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
*ret.Status = "OK"
|
|
*ret.Message = "Proses Absensi Pulang Berhasil"
|
|
}
|
|
|
|
// set status jika error
|
|
if err != nil {
|
|
*ret.Status = "ERR"
|
|
*ret.Message = "ERROR : " + err.Error()
|
|
}
|
|
}
|
|
|
|
return &ret, err
|
|
}
|
|
|
|
// fungsi untuk get jam absen dan pulang
|
|
func (transabsensi *TransAbsensiCheckTimeAttendanceResponse) CheckTimeAttendance(M_StaffID string, M_CompanyID string, token string) (*model.TransAbsensiCheckTimeAttendanceResponse, error) {
|
|
|
|
// inisialisasi
|
|
var err error
|
|
var ret model.TransAbsensiCheckTimeAttendanceResponse
|
|
|
|
var var_jam_clock_in string
|
|
var var_jam_clock_out string
|
|
var var_is_absen_clock_in string = "FALSE"
|
|
var var_is_absen_clock_out string = "FALSE"
|
|
|
|
var varGetToken string
|
|
var resultsArrayAttendance []struct {
|
|
T_TransactionM_AbsensiTypeID string
|
|
T_TransactionClockAbsensi string
|
|
}
|
|
|
|
ret.Status = new(string)
|
|
ret.Message = new(string)
|
|
ret.JamClockIn = new(string)
|
|
ret.JamClockOut = new(string)
|
|
ret.IsAbsenClockIn = new(string)
|
|
ret.IsAbsenClockOut = new(string)
|
|
|
|
qCheckTokenStaff := `SELECT
|
|
M_StaffToken
|
|
FROM m_staff
|
|
WHERE M_StaffIsActive = 'Y'
|
|
AND M_StaffToken = ?
|
|
`
|
|
|
|
rowCheckTokenStaff := db.Handle.QueryRow(
|
|
qCheckTokenStaff,
|
|
token,
|
|
)
|
|
|
|
db.LogSQL(qCheckTokenStaff)
|
|
err = rowCheckTokenStaff.Scan(
|
|
&varGetToken,
|
|
)
|
|
|
|
if err != nil {
|
|
log.Printf("Error m_staff select token: %v", err)
|
|
log.Printf("Executing query: %s\n", qCheckTokenStaff)
|
|
return nil, err
|
|
}
|
|
|
|
// check varGetToken jk M_StaffToken kosong
|
|
if varGetToken == "" {
|
|
log.Printf("Error Token Kosong, Silahkan Login Dulu: %v", err)
|
|
log.Printf("Executing query: %s\n", qCheckTokenStaff)
|
|
return nil, err
|
|
}
|
|
|
|
// proses check attendance
|
|
if varGetToken != "" {
|
|
q := `SELECT T_TransactionM_AbsensiTypeID,
|
|
DATE_FORMAT(T_TransactionClockAbsensi,'%H:%i') as T_TransactionClockAbsensi
|
|
FROM t_transaction
|
|
WHERE T_TransactionIsActive = 'Y'
|
|
AND T_TransactionM_AbsensiTypeID IN (1, 2)
|
|
AND T_TransactionM_StaffID = ?
|
|
AND T_TransactionM_CompanyID = ?
|
|
AND T_TransactionDate BETWEEN DATE_FORMAT(NOW(), "%Y-%m-%d 01:00:00")
|
|
AND DATE_FORMAT(NOW(), "%Y-%m-%d 23:00:00")
|
|
ORDER BY T_TransactionM_AbsensiTypeID ASC`
|
|
|
|
db.LogSQL(q, M_StaffID,
|
|
M_CompanyID)
|
|
|
|
rows, err := db.Handle.Query(
|
|
q,
|
|
M_StaffID,
|
|
M_CompanyID)
|
|
|
|
if err != nil {
|
|
log.Printf("Error m_company select jam_clock_in dan jam_clock_out: %v", err)
|
|
log.Printf("Executing query: %s\n", q)
|
|
return nil, err
|
|
}
|
|
|
|
defer rows.Close()
|
|
|
|
for rows.Next() {
|
|
var resultTmp struct {
|
|
T_TransactionM_AbsensiTypeID string
|
|
T_TransactionClockAbsensi string
|
|
}
|
|
|
|
if err := rows.Scan(
|
|
&resultTmp.T_TransactionM_AbsensiTypeID,
|
|
&resultTmp.T_TransactionClockAbsensi,
|
|
); err != nil {
|
|
log.Printf("Error scanning row: %v", err)
|
|
return nil, err
|
|
}
|
|
|
|
// array push
|
|
resultsArrayAttendance = append(resultsArrayAttendance, resultTmp)
|
|
}
|
|
|
|
if err := rows.Err(); err != nil {
|
|
log.Printf("Error after iterating rows attendance : %v", err)
|
|
return nil, err
|
|
}
|
|
|
|
// check length resultsArrayAttendance
|
|
if len(resultsArrayAttendance) == 0 {
|
|
log.Printf("Error Data Tidak Ada: %v", err)
|
|
*ret.Status = "OK"
|
|
*ret.Message = "Belum Ada Absen"
|
|
*ret.JamClockIn = ""
|
|
*ret.JamClockOut = ""
|
|
*ret.IsAbsenClockIn = "FALSE"
|
|
*ret.IsAbsenClockOut = "FALSE"
|
|
}
|
|
|
|
if len(resultsArrayAttendance) > 0 {
|
|
for _, result := range resultsArrayAttendance {
|
|
// clock in (absen masuk)
|
|
if result.T_TransactionM_AbsensiTypeID == "1" {
|
|
var_jam_clock_in = result.T_TransactionClockAbsensi
|
|
|
|
if var_is_absen_clock_in != "" {
|
|
var_is_absen_clock_in = "TRUE"
|
|
}
|
|
}
|
|
|
|
// clock out (absen pulang)
|
|
if result.T_TransactionM_AbsensiTypeID == "2" {
|
|
var_jam_clock_out = result.T_TransactionClockAbsensi
|
|
|
|
if var_is_absen_clock_out != "" {
|
|
var_is_absen_clock_out = "TRUE"
|
|
}
|
|
}
|
|
}
|
|
|
|
*ret.Status = "OK"
|
|
*ret.Message = "Sudah Ada Absen"
|
|
*ret.JamClockIn = var_jam_clock_in
|
|
*ret.JamClockOut = var_jam_clock_out
|
|
*ret.IsAbsenClockIn = var_is_absen_clock_in
|
|
*ret.IsAbsenClockOut = var_is_absen_clock_out
|
|
}
|
|
}
|
|
|
|
return &ret, err
|
|
}
|
|
|
|
// fungsi untuk rekap kehadiran home screen
|
|
func (transabsensi *RekapKehadiranHomeScreen) RekapKehadiranHomeScreenV1(M_StaffID string, M_CompanyID string, token string) (*model.RekapKehadiranHomeScreen, error) {
|
|
|
|
// inisialisasi
|
|
var err error
|
|
var ret model.RekapKehadiranHomeScreen
|
|
|
|
var jumlah_saturday int = 0
|
|
var jumlah_sunday int = 0
|
|
var jumlah_hari_sampai_hari_ini int = 0
|
|
|
|
var jumlah_hari_sampai_hari_ini_point_a int = 0
|
|
var jumlah_hari_libur_sampai_hari_ini_point_b int = 0
|
|
var jumlah_absen_sampai_hari_ini_point_c int = 0
|
|
var total_ketidakhadiran int = 0
|
|
var total_lembur_sampai_hari_ini int = 0
|
|
|
|
// clear memory address
|
|
ret.Kehadiran = new(string)
|
|
ret.Lembur = new(string)
|
|
ret.TidakHadir = new(string)
|
|
ret.Status = new(string)
|
|
ret.Message = new(string)
|
|
|
|
// set value
|
|
*ret.TidakHadir = "0"
|
|
*ret.Kehadiran = "0"
|
|
*ret.Lembur = "0"
|
|
|
|
// query rekap lembur
|
|
qLembur := `SELECT COUNT(T_TransactionLemburID) as total_lembur_sampai_hari_ini
|
|
FROM t_transaction_lembur
|
|
WHERE
|
|
T_TransactionLemburIsActive = 'Y'
|
|
AND T_TransactionLemburM_StaffID = ?
|
|
AND T_TransactionLemburM_CompanyID = ?
|
|
AND T_TransactionLemburM_AbsensiTypeID = 5
|
|
AND MONTH(T_TransactionTglLembur) = MONTH(CURDATE())`
|
|
|
|
rowQLembur := db.Handle.QueryRow(
|
|
qLembur,
|
|
M_StaffID,
|
|
M_CompanyID,
|
|
)
|
|
|
|
if err != nil {
|
|
log.Printf("Error select count lembur: %v", err)
|
|
log.Printf("Executing query: %s\n", qLembur)
|
|
return nil, err
|
|
}
|
|
|
|
db.LogSQL(qLembur)
|
|
err = rowQLembur.Scan(
|
|
&total_lembur_sampai_hari_ini,
|
|
)
|
|
|
|
// query point A : jumlah hari sampai hari ini ( dalam bulan ini ) selain sabtu dan minggu
|
|
qCountSaturday := `WITH RECURSIVE offdays as(
|
|
SELECT
|
|
LAST_DAY(CURDATE()-INTERVAL 1 MONTH) + INTERVAL 1 DAY AS Date,
|
|
DAYNAME(LAST_DAY(CURDATE()-INTERVAL 1 MONTH) + INTERVAL 1 DAY) AS DayName
|
|
UNION ALL
|
|
SELECT Date + INTERVAL 1 DAY, DAYNAME(Date + INTERVAL 1 DAY)
|
|
FROM offdays WHERE DATE < LAST_DAY(CURDATE())
|
|
) SELECT count(*) as countSaturday FROM offdays where DAYNAME(DATE) = 'Saturday'`
|
|
|
|
rowQCountSaturday := db.Handle.QueryRow(
|
|
qCountSaturday,
|
|
)
|
|
|
|
if err != nil {
|
|
log.Printf("Error select count jumlah saturday : %v", err)
|
|
log.Printf("Executing query: %s\n", qCountSaturday)
|
|
return nil, err
|
|
}
|
|
|
|
db.LogSQL(qCountSaturday)
|
|
err = rowQCountSaturday.Scan(
|
|
&jumlah_saturday,
|
|
)
|
|
|
|
qCountSunday := `WITH RECURSIVE offdays as(
|
|
SELECT
|
|
LAST_DAY(CURDATE()-INTERVAL 1 MONTH) + INTERVAL 1 DAY AS Date,
|
|
DAYNAME(LAST_DAY(CURDATE()-INTERVAL 1 MONTH) + INTERVAL 1 DAY) AS DayName
|
|
UNION ALL
|
|
SELECT Date + INTERVAL 1 DAY, DAYNAME(Date + INTERVAL 1 DAY)
|
|
FROM offdays WHERE DATE < LAST_DAY(CURDATE())
|
|
) SELECT count(*) as countSaturday FROM offdays where DAYNAME(DATE) = 'Sunday'`
|
|
|
|
rowQCountSunday := db.Handle.QueryRow(
|
|
qCountSunday,
|
|
)
|
|
|
|
if err != nil {
|
|
log.Printf("Error select count jumlah saturday : %v", err)
|
|
log.Printf("Executing query: %s\n", qCountSunday)
|
|
return nil, err
|
|
}
|
|
|
|
db.LogSQL(qCountSunday)
|
|
err = rowQCountSunday.Scan(
|
|
&jumlah_sunday,
|
|
)
|
|
|
|
qJumlahHariSampaiHariIni := `select timestampdiff(day,
|
|
concat(year(now()),'-',month(now()),'-01'),
|
|
date_add( concat(year(now()),'-',month(now()),'-01'), interval 1 month)) as jumlah_hari_sampai_hari_ini`
|
|
|
|
rowqJumlahHariSampaiHariIni := db.Handle.QueryRow(
|
|
qJumlahHariSampaiHariIni,
|
|
)
|
|
|
|
if err != nil {
|
|
log.Printf("Error select count jumlah_hari_sampai_hari_ini: %v", err)
|
|
log.Printf("Executing query: %s\n", qJumlahHariSampaiHariIni)
|
|
return nil, err
|
|
}
|
|
|
|
db.LogSQL(qJumlahHariSampaiHariIni)
|
|
err = rowqJumlahHariSampaiHariIni.Scan(
|
|
&jumlah_hari_sampai_hari_ini,
|
|
)
|
|
|
|
// hitung point A
|
|
jumlah_hari_sampai_hari_ini_point_a = jumlah_hari_sampai_hari_ini - jumlah_sunday - jumlah_saturday
|
|
|
|
// query point B : jumlah hari libur selain sabtu dan minggu sampai hari ini
|
|
qPointB := `SELECT COUNT(M_LiburID) as jumlah_hari_libur_sampai_hari_ini_point_b
|
|
FROM m_libur
|
|
WHERE
|
|
M_LiburIsActive = 'Y'
|
|
AND M_LiburDate <= CURDATE()
|
|
AND DAYOFWEEK(CURDATE()) BETWEEN 2 AND 6
|
|
AND MONTH(M_LiburDate) = MONTH(CURDATE())`
|
|
|
|
rowQPointB := db.Handle.QueryRow(
|
|
qPointB,
|
|
)
|
|
|
|
if err != nil {
|
|
log.Printf("Error select count jumlah_hari_libur_sampai_hari_ini_point_b: %v", err)
|
|
log.Printf("Executing query: %s\n", qPointB)
|
|
return nil, err
|
|
}
|
|
|
|
db.LogSQL(qPointB)
|
|
err = rowQPointB.Scan(
|
|
&jumlah_hari_libur_sampai_hari_ini_point_b,
|
|
)
|
|
|
|
// query point C : jumlah absen sampai hari ini ( bisa di lihat dari clock in )
|
|
qPointC := `SELECT COUNT(T_TransactionID) as jumlah_absen_sampai_hari_ini_point_c
|
|
FROM t_transaction
|
|
WHERE
|
|
T_TransactionIsActive = 'Y'
|
|
AND T_TransactionM_StaffID = ?
|
|
AND T_TransactionM_CompanyID = ?
|
|
AND (
|
|
T_TransactionDate >= DATE_FORMAT(CURDATE(), '%Y-%m-01')
|
|
OR T_TransactionDate = CURDATE()
|
|
)
|
|
AND (
|
|
T_TransactionM_AbsensiTypeID = 1
|
|
AND (T_TransactionClockAbsensi != '00:00:00' OR T_TransactionClockAbsensi IS NOT NULL)
|
|
)`
|
|
|
|
rowQPointC := db.Handle.QueryRow(
|
|
qPointC,
|
|
M_StaffID,
|
|
M_CompanyID,
|
|
)
|
|
|
|
if err != nil {
|
|
log.Printf("Error select count jumlah_absen_sampai_hari_ini_point_c: %v", err)
|
|
log.Printf("Executing query: %s\n", qPointC)
|
|
return nil, err
|
|
}
|
|
|
|
db.LogSQL(qPointC)
|
|
err = rowQPointC.Scan(
|
|
&jumlah_absen_sampai_hari_ini_point_c,
|
|
)
|
|
|
|
total_ketidakhadiran = jumlah_hari_sampai_hari_ini_point_a - jumlah_hari_libur_sampai_hari_ini_point_b - jumlah_absen_sampai_hari_ini_point_c
|
|
|
|
log.Printf("Executing jumlah_saturday: %s\n", strconv.Itoa(jumlah_saturday))
|
|
log.Printf("Executing jumlah_sunday: %s\n", strconv.Itoa(jumlah_sunday))
|
|
log.Printf("Executing jumlah_hari_sampai_hari_ini: %s\n", strconv.Itoa(jumlah_hari_sampai_hari_ini))
|
|
|
|
log.Printf("Executing jumlah_hari_sampai_hari_ini_point_a: %s\n", strconv.Itoa(jumlah_hari_sampai_hari_ini_point_a))
|
|
log.Printf("Executing jumlah_hari_libur_sampai_hari_ini_point_b: %s\n", strconv.Itoa(jumlah_hari_libur_sampai_hari_ini_point_b))
|
|
log.Printf("Executing jumlah_absen_sampai_hari_ini_point_c: %s\n", strconv.Itoa(jumlah_absen_sampai_hari_ini_point_c))
|
|
|
|
if total_ketidakhadiran != 0 {
|
|
*ret.TidakHadir = strconv.Itoa(total_ketidakhadiran)
|
|
}
|
|
|
|
if jumlah_absen_sampai_hari_ini_point_c != 0 {
|
|
*ret.Kehadiran = strconv.Itoa(jumlah_absen_sampai_hari_ini_point_c)
|
|
}
|
|
|
|
if total_lembur_sampai_hari_ini != 0 {
|
|
*ret.Lembur = strconv.Itoa(total_lembur_sampai_hari_ini)
|
|
}
|
|
|
|
*ret.Status = "OK"
|
|
*ret.Message = "Rekap Kehadiran Muncul"
|
|
|
|
return &ret, err
|
|
}
|
|
|
|
func (transabsensi *RekapKehadiranHomeScreen) RekapKehadiranHomeScreen(M_StaffID string, M_CompanyID string, token string) (*model.RekapKehadiranHomeScreen, error) {
|
|
|
|
// inisialisasi
|
|
var err error
|
|
var ret model.RekapKehadiranHomeScreen
|
|
|
|
var jumlah_saturday int = 0
|
|
var jumlah_sunday int = 0
|
|
var jumlah_hari_sampai_hari_ini int = 0
|
|
|
|
var jumlah_hari_sampai_hari_ini_point_a int = 0
|
|
// var jumlah_hari_libur_sampai_hari_ini_point_b int = 0
|
|
var jumlah_absen_sampai_hari_ini_point_c int = 0
|
|
var total_ketidakhadiran int = 0
|
|
var total_lembur_sampai_hari_ini int = 0
|
|
|
|
// clear memory address
|
|
ret.Kehadiran = new(string)
|
|
ret.Lembur = new(string)
|
|
ret.TidakHadir = new(string)
|
|
ret.Status = new(string)
|
|
ret.Message = new(string)
|
|
|
|
// set value
|
|
*ret.TidakHadir = "0"
|
|
*ret.Kehadiran = "0"
|
|
*ret.Lembur = "0"
|
|
|
|
// query rekap lembur
|
|
qLembur := `SELECT COUNT(T_TransactionLemburID) as total_lembur_sampai_hari_ini
|
|
FROM t_transaction_lembur
|
|
WHERE
|
|
T_TransactionLemburIsActive = 'Y'
|
|
AND T_TransactionLemburM_StaffID = ?
|
|
AND T_TransactionLemburM_CompanyID = ?
|
|
AND T_TransactionLemburM_AbsensiTypeID = 5
|
|
AND MONTH(T_TransactionTglLembur) = MONTH(CURDATE())`
|
|
|
|
rowQLembur := db.Handle.QueryRow(
|
|
qLembur,
|
|
M_StaffID,
|
|
M_CompanyID,
|
|
)
|
|
|
|
if err != nil {
|
|
log.Printf("Error select count lembur: %v", err)
|
|
log.Printf("Executing query: %s\n", qLembur)
|
|
return nil, err
|
|
}
|
|
|
|
db.LogSQL(qLembur)
|
|
err = rowQLembur.Scan(
|
|
&total_lembur_sampai_hari_ini,
|
|
)
|
|
|
|
// query point A : jumlah hari sampai hari ini ( dalam bulan ini ) selain sabtu dan minggu
|
|
qCountSaturday := `WITH RECURSIVE offdays as(
|
|
SELECT
|
|
LAST_DAY(DATE_FORMAT(CURDATE(), '%Y-%m-01') - INTERVAL 1 MONTH) + INTERVAL 1 DAY AS Date,
|
|
DAYNAME(LAST_DAY(DATE_FORMAT(CURDATE(), '%Y-%m-01') - INTERVAL 1 MONTH) + INTERVAL 1 DAY) AS DayName
|
|
UNION ALL
|
|
SELECT Date + INTERVAL 1 DAY, DAYNAME(Date + INTERVAL 1 DAY)
|
|
FROM offdays WHERE DATE < LAST_DAY(CURDATE())
|
|
)
|
|
SELECT count(*) as countSaturday
|
|
FROM offdays where DAYNAME(DATE) = 'Saturday'
|
|
AND Date BETWEEN DATE_FORMAT(CURDATE(), '%Y-%m-01') AND CURDATE()`
|
|
|
|
rowQCountSaturday := db.Handle.QueryRow(
|
|
qCountSaturday,
|
|
)
|
|
|
|
if err != nil {
|
|
log.Printf("Error select count jumlah saturday : %v", err)
|
|
log.Printf("Executing query: %s\n", qCountSaturday)
|
|
return nil, err
|
|
}
|
|
|
|
db.LogSQL(qCountSaturday)
|
|
err = rowQCountSaturday.Scan(
|
|
&jumlah_saturday,
|
|
)
|
|
|
|
qCountSunday := `WITH RECURSIVE offdays AS (
|
|
SELECT
|
|
LAST_DAY(DATE_FORMAT(CURDATE(), '%Y-%m-01') - INTERVAL 1 MONTH) + INTERVAL 1 DAY AS Date,
|
|
DAYNAME(LAST_DAY(DATE_FORMAT(CURDATE(), '%Y-%m-01') - INTERVAL 1 MONTH) + INTERVAL 1 DAY) AS DayName
|
|
UNION ALL
|
|
SELECT Date + INTERVAL 1 DAY, DAYNAME(Date + INTERVAL 1 DAY)
|
|
FROM offdays
|
|
WHERE DATE < LAST_DAY(CURDATE())
|
|
)
|
|
SELECT COUNT(*) AS countSunday
|
|
FROM offdays
|
|
WHERE DAYNAME(Date) = 'Sunday' AND Date BETWEEN DATE_FORMAT(CURDATE(), '%Y-%m-01') AND CURDATE()`
|
|
|
|
rowQCountSunday := db.Handle.QueryRow(
|
|
qCountSunday,
|
|
)
|
|
|
|
if err != nil {
|
|
log.Printf("Error select count jumlah saturday : %v", err)
|
|
log.Printf("Executing query: %s\n", qCountSunday)
|
|
return nil, err
|
|
}
|
|
|
|
db.LogSQL(qCountSunday)
|
|
err = rowQCountSunday.Scan(
|
|
&jumlah_sunday,
|
|
)
|
|
|
|
qJumlahHariSampaiHariIni := `SELECT DATEDIFF(CURDATE(), DATE_FORMAT(CURDATE(), '%Y-%m-01') ) + 1 AS total_hari`
|
|
|
|
rowqJumlahHariSampaiHariIni := db.Handle.QueryRow(
|
|
qJumlahHariSampaiHariIni,
|
|
)
|
|
|
|
if err != nil {
|
|
log.Printf("Error select count jumlah_hari_sampai_hari_ini: %v", err)
|
|
log.Printf("Executing query: %s\n", qJumlahHariSampaiHariIni)
|
|
return nil, err
|
|
}
|
|
|
|
db.LogSQL(qJumlahHariSampaiHariIni)
|
|
err = rowqJumlahHariSampaiHariIni.Scan(
|
|
&jumlah_hari_sampai_hari_ini,
|
|
)
|
|
|
|
// hitung point A
|
|
jumlah_hari_sampai_hari_ini_point_a = jumlah_hari_sampai_hari_ini - jumlah_sunday - jumlah_saturday
|
|
|
|
// query point C : jumlah absen sampai hari ini ( bisa di lihat dari clock in )
|
|
qPointC := `SELECT COUNT(T_TransactionID) as jumlah_absen_sampai_hari_ini_point_c
|
|
FROM t_transaction
|
|
WHERE
|
|
T_TransactionIsActive = 'Y'
|
|
AND T_TransactionM_StaffID = ?
|
|
AND T_TransactionM_CompanyID = ?
|
|
AND (
|
|
T_TransactionDate >= DATE_FORMAT(CURDATE(), '%Y-%m-01')
|
|
OR T_TransactionDate = CURDATE()
|
|
)
|
|
AND (
|
|
T_TransactionM_AbsensiTypeID = 1
|
|
AND (T_TransactionClockAbsensi != '00:00:00' OR T_TransactionClockAbsensi IS NOT NULL)
|
|
)`
|
|
|
|
rowQPointC := db.Handle.QueryRow(
|
|
qPointC,
|
|
M_StaffID,
|
|
M_CompanyID,
|
|
)
|
|
|
|
if err != nil {
|
|
log.Printf("Error select count jumlah_absen_sampai_hari_ini_point_c: %v", err)
|
|
log.Printf("Executing query: %s\n", qPointC)
|
|
return nil, err
|
|
}
|
|
|
|
db.LogSQL(qPointC)
|
|
err = rowQPointC.Scan(
|
|
&jumlah_absen_sampai_hari_ini_point_c,
|
|
)
|
|
|
|
total_ketidakhadiran = jumlah_hari_sampai_hari_ini_point_a - jumlah_absen_sampai_hari_ini_point_c
|
|
|
|
log.Printf("Executing jumlah_saturday: %s\n", strconv.Itoa(jumlah_saturday))
|
|
log.Printf("Executing jumlah_sunday: %s\n", strconv.Itoa(jumlah_sunday))
|
|
log.Printf("Executing jumlah_hari_sampai_hari_ini: %s\n", strconv.Itoa(jumlah_hari_sampai_hari_ini))
|
|
|
|
log.Printf("Executing jumlah_hari_sampai_hari_ini_point_a: %s\n", strconv.Itoa(jumlah_hari_sampai_hari_ini_point_a))
|
|
// log.Printf("Executing jumlah_hari_libur_sampai_hari_ini_point_b: %s\n", strconv.Itoa(jumlah_hari_libur_sampai_hari_ini_point_b))
|
|
log.Printf("Executing jumlah_absen_sampai_hari_ini_point_c: %s\n", strconv.Itoa(jumlah_absen_sampai_hari_ini_point_c))
|
|
|
|
if total_ketidakhadiran != 0 {
|
|
*ret.TidakHadir = strconv.Itoa(total_ketidakhadiran)
|
|
}
|
|
|
|
if jumlah_absen_sampai_hari_ini_point_c != 0 {
|
|
*ret.Kehadiran = strconv.Itoa(jumlah_absen_sampai_hari_ini_point_c)
|
|
}
|
|
|
|
if total_lembur_sampai_hari_ini != 0 {
|
|
*ret.Lembur = strconv.Itoa(total_lembur_sampai_hari_ini)
|
|
}
|
|
|
|
*ret.Status = "OK"
|
|
*ret.Message = "Rekap Kehadiran Muncul"
|
|
|
|
return &ret, err
|
|
}
|