1 Commits

Author SHA1 Message Date
Sas Andy
3edb6d1051 coba init 2024-02-06 17:05:02 +07:00
15 changed files with 13 additions and 7690 deletions

View File

@@ -1,9 +1,9 @@
privatekey: ./certificate/private.pem
dbuser: absensiUserDev
dbuser: absensiUser
dbpass: absensi102938
dbhost: devone.aplikasi.web.id
dbport: 3306
dbname: absensi_dev
dbname: absensi
# lokasi file
clockInFolder: ./selfie_attachment/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,9 @@
# MODEL COMPANY
type Company{
companyID:ID!;
companyName:String!;
}
extend type Query {
searchCompanyByName(name: String!): [Company!]!
}

View File

@@ -1,68 +0,0 @@
// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
package model
type LogoutResponse struct {
Status *string `json:"status,omitempty"`
Message *string `json:"message,omitempty"`
}
type Mutation struct {
}
type Query struct {
}
type RekapKehadiranHomeScreen struct {
Status *string `json:"status,omitempty"`
Message *string `json:"message,omitempty"`
Kehadiran *string `json:"kehadiran,omitempty"`
TidakHadir *string `json:"tidak_hadir,omitempty"`
Lembur *string `json:"lembur,omitempty"`
}
type Staff struct {
StaffID string `json:"staff_id"`
Nip string `json:"nip"`
Name string `json:"name"`
Email string `json:"email"`
PhoneNumber *string `json:"phone_number,omitempty"`
CompanyID string `json:"company_id"`
CompanyName *string `json:"company_name,omitempty"`
IsActive *string `json:"is_active,omitempty"`
IsLogin *string `json:"is_login,omitempty"`
Token *string `json:"token,omitempty"`
Expired *string `json:"expired,omitempty"`
IDGoogleSignIn string `json:"id_google_sign_in"`
DisplayNameGoogleSignIn *string `json:"display_name_google_sign_in,omitempty"`
CreatedAt *string `json:"created_at,omitempty"`
LastUpdatedAt *string `json:"last_updated_at,omitempty"`
}
type TokenResponse struct {
Token *string `json:"token,omitempty"`
Message *string `json:"message,omitempty"`
}
type TransAbsensiCheckDistanceResponse struct {
Status *string `json:"status,omitempty"`
Message *string `json:"message,omitempty"`
Selfie *string `json:"selfie,omitempty"`
MaxDistance *string `json:"max_distance,omitempty"`
CurrentDistance *string `json:"current_distance,omitempty"`
Unit *string `json:"unit,omitempty"`
}
type TransAbsensiCheckTimeAttendanceResponse struct {
Status *string `json:"status,omitempty"`
Message *string `json:"message,omitempty"`
JamClockIn *string `json:"jam_clock_in,omitempty"`
JamClockOut *string `json:"jam_clock_out,omitempty"`
IsAbsenClockIn *string `json:"is_absen_clock_in,omitempty"`
IsAbsenClockOut *string `json:"is_absen_clock_out,omitempty"`
}
type TransAbsensiResponse struct {
Status *string `json:"status,omitempty"`
Message *string `json:"message,omitempty"`
}

View File

@@ -1,7 +1,6 @@
package transabsensi
import (
"database/sql"
"encoding/base64"
"errors"
"fmt"
@@ -143,197 +142,6 @@ func (transabsensi *TransAbsensiCheckDistanceResponse) CheckDistance(M_StaffID s
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
@@ -344,12 +152,6 @@ func (transabsensi *TransAbsensiResponse) ClockInAbsensi(T_TransactionM_StaffID
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
@@ -406,8 +208,6 @@ func (transabsensi *TransAbsensiResponse) ClockInAbsensi(T_TransactionM_StaffID
// selfie true
if isSelfie == "TRUE" {
// check current distance
// pecah string
strToArrayFoto := strings.Split(T_TransactionSelfiePhoto, ",")
@@ -504,7 +304,7 @@ func (transabsensi *TransAbsensiResponse) ClockInAbsensi(T_TransactionM_StaffID
NOW()
)`
result, err := db.Handle.Exec(qInsertClockIn,
_, err = db.Handle.Exec(qInsertClockIn,
"1",
T_TransactionM_StaffID,
T_TransactionM_CompanyID,
@@ -517,116 +317,8 @@ func (transabsensi *TransAbsensiResponse) ClockInAbsensi(T_TransactionM_StaffID
"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"
}
@@ -641,197 +333,6 @@ func (transabsensi *TransAbsensiResponse) ClockInAbsensi(T_TransactionM_StaffID
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
@@ -842,12 +343,6 @@ func (transabsensi *TransAbsensiResponse) ClockOutAbsensi(T_TransactionM_StaffID
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
@@ -1000,7 +495,7 @@ func (transabsensi *TransAbsensiResponse) ClockOutAbsensi(T_TransactionM_StaffID
NOW()
)`
result, err := db.Handle.Exec(qInsertClockIn,
_, err = db.Handle.Exec(qInsertClockIn,
"2",
T_TransactionM_StaffID,
T_TransactionM_CompanyID,
@@ -1013,116 +508,8 @@ func (transabsensi *TransAbsensiResponse) ClockOutAbsensi(T_TransactionM_StaffID
"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"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 232 KiB