step 7 : clock in selfie or not

This commit is contained in:
sindhu
2024-01-23 11:40:59 +07:00
parent e9e4d5bf05
commit d3fe3234eb
8 changed files with 239 additions and 41 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 KiB

View File

@@ -48,7 +48,7 @@ type DirectiveRoot struct {
type ComplexityRoot struct { type ComplexityRoot struct {
Mutation struct { Mutation struct {
LoginAttendance func(childComplexity int, email string, idGoogleSignIn string) int LoginAttendance func(childComplexity int, email string, idGoogleSignIn string) int
MutationClockInAttendance func(childComplexity int, tTransactionMAbsensiTypeID string, tTransactionMStaffID string, tTransactionMCompanyID string, tTransactionCurrentLatitude string, tTransactionCurrentLongitude string, tTransactionDistance string, tTransactionSelfiePhoto *string, tTransactionNote *string) int MutationClockInAttendance func(childComplexity int, tTransactionMStaffID string, tTransactionMCompanyID string, tTransactionCurrentLatitude string, tTransactionCurrentLongitude string, tTransactionCurrentDistance string, tTransactionSelfiePhoto *string, token string, isSelfie string) int
} }
Query struct { Query struct {
@@ -98,7 +98,7 @@ type ComplexityRoot struct {
type MutationResolver interface { type MutationResolver interface {
LoginAttendance(ctx context.Context, email string, idGoogleSignIn string) (*model.Staff, error) LoginAttendance(ctx context.Context, email string, idGoogleSignIn string) (*model.Staff, error)
MutationClockInAttendance(ctx context.Context, tTransactionMAbsensiTypeID string, tTransactionMStaffID string, tTransactionMCompanyID string, tTransactionCurrentLatitude string, tTransactionCurrentLongitude string, tTransactionDistance string, tTransactionSelfiePhoto *string, tTransactionNote *string) (*model.TransAbsensiResponse, error) MutationClockInAttendance(ctx context.Context, tTransactionMStaffID string, tTransactionMCompanyID string, tTransactionCurrentLatitude string, tTransactionCurrentLongitude string, tTransactionCurrentDistance string, tTransactionSelfiePhoto *string, token string, isSelfie string) (*model.TransAbsensiResponse, error)
} }
type QueryResolver interface { type QueryResolver interface {
SearchStaffByEmail(ctx context.Context, email string) (*model.Staff, error) SearchStaffByEmail(ctx context.Context, email string) (*model.Staff, error)
@@ -148,7 +148,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return 0, false return 0, false
} }
return e.complexity.Mutation.MutationClockInAttendance(childComplexity, args["T_TransactionM_AbsensiTypeID"].(string), args["T_TransactionM_StaffID"].(string), args["T_TransactionM_CompanyID"].(string), args["T_TransactionCurrentLatitude"].(string), args["T_TransactionCurrentLongitude"].(string), args["T_TransactionDistance"].(string), args["T_TransactionSelfiePhoto"].(*string), args["T_TransactionNote"].(*string)), true return e.complexity.Mutation.MutationClockInAttendance(childComplexity, args["T_TransactionM_StaffID"].(string), args["T_TransactionM_CompanyID"].(string), args["T_TransactionCurrentLatitude"].(string), args["T_TransactionCurrentLongitude"].(string), args["T_TransactionCurrentDistance"].(string), args["T_TransactionSelfiePhoto"].(*string), args["token"].(string), args["isSelfie"].(string)), true
case "Query.queryCheckDistance": case "Query.queryCheckDistance":
if e.complexity.Query.QueryCheckDistance == nil { if e.complexity.Query.QueryCheckDistance == nil {
@@ -539,7 +539,7 @@ extend type Query {
# mutation # mutation
extend type Mutation { extend type Mutation {
# untuk clock in absensi (absensi masuk) # untuk clock in absensi (absensi masuk)
mutationClockInAttendance(T_TransactionM_AbsensiTypeID:String!, T_TransactionM_StaffID:String!, T_TransactionM_CompanyID:String!, T_TransactionCurrentLatitude:String!, T_TransactionCurrentLongitude:String!, T_TransactionDistance:String!, T_TransactionSelfiePhoto:String, T_TransactionNote:String):TransAbsensiResponse! mutationClockInAttendance(T_TransactionM_StaffID:String!, T_TransactionM_CompanyID:String!, T_TransactionCurrentLatitude:String!, T_TransactionCurrentLongitude:String!, T_TransactionCurrentDistance:String!, T_TransactionSelfiePhoto:String, token:String!, isSelfie:String!):TransAbsensiResponse!
} `, BuiltIn: false}, } `, BuiltIn: false},
} }
var parsedSchema = gqlparser.MustLoadSchema(sources...) var parsedSchema = gqlparser.MustLoadSchema(sources...)
@@ -576,77 +576,77 @@ func (ec *executionContext) field_Mutation_mutationClockInAttendance_args(ctx co
var err error var err error
args := map[string]interface{}{} args := map[string]interface{}{}
var arg0 string var arg0 string
if tmp, ok := rawArgs["T_TransactionM_AbsensiTypeID"]; ok { if tmp, ok := rawArgs["T_TransactionM_StaffID"]; ok {
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("T_TransactionM_AbsensiTypeID")) ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("T_TransactionM_StaffID"))
arg0, err = ec.unmarshalNString2string(ctx, tmp) arg0, err = ec.unmarshalNString2string(ctx, tmp)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
args["T_TransactionM_AbsensiTypeID"] = arg0 args["T_TransactionM_StaffID"] = arg0
var arg1 string var arg1 string
if tmp, ok := rawArgs["T_TransactionM_StaffID"]; ok { if tmp, ok := rawArgs["T_TransactionM_CompanyID"]; ok {
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("T_TransactionM_StaffID")) ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("T_TransactionM_CompanyID"))
arg1, err = ec.unmarshalNString2string(ctx, tmp) arg1, err = ec.unmarshalNString2string(ctx, tmp)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
args["T_TransactionM_StaffID"] = arg1 args["T_TransactionM_CompanyID"] = arg1
var arg2 string var arg2 string
if tmp, ok := rawArgs["T_TransactionM_CompanyID"]; ok { if tmp, ok := rawArgs["T_TransactionCurrentLatitude"]; ok {
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("T_TransactionM_CompanyID")) ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("T_TransactionCurrentLatitude"))
arg2, err = ec.unmarshalNString2string(ctx, tmp) arg2, err = ec.unmarshalNString2string(ctx, tmp)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
args["T_TransactionM_CompanyID"] = arg2 args["T_TransactionCurrentLatitude"] = arg2
var arg3 string var arg3 string
if tmp, ok := rawArgs["T_TransactionCurrentLatitude"]; ok { if tmp, ok := rawArgs["T_TransactionCurrentLongitude"]; ok {
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("T_TransactionCurrentLatitude")) ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("T_TransactionCurrentLongitude"))
arg3, err = ec.unmarshalNString2string(ctx, tmp) arg3, err = ec.unmarshalNString2string(ctx, tmp)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
args["T_TransactionCurrentLatitude"] = arg3 args["T_TransactionCurrentLongitude"] = arg3
var arg4 string var arg4 string
if tmp, ok := rawArgs["T_TransactionCurrentLongitude"]; ok { if tmp, ok := rawArgs["T_TransactionCurrentDistance"]; ok {
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("T_TransactionCurrentLongitude")) ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("T_TransactionCurrentDistance"))
arg4, err = ec.unmarshalNString2string(ctx, tmp) arg4, err = ec.unmarshalNString2string(ctx, tmp)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
args["T_TransactionCurrentLongitude"] = arg4 args["T_TransactionCurrentDistance"] = arg4
var arg5 string var arg5 *string
if tmp, ok := rawArgs["T_TransactionDistance"]; ok {
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("T_TransactionDistance"))
arg5, err = ec.unmarshalNString2string(ctx, tmp)
if err != nil {
return nil, err
}
}
args["T_TransactionDistance"] = arg5
var arg6 *string
if tmp, ok := rawArgs["T_TransactionSelfiePhoto"]; ok { if tmp, ok := rawArgs["T_TransactionSelfiePhoto"]; ok {
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("T_TransactionSelfiePhoto")) ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("T_TransactionSelfiePhoto"))
arg6, err = ec.unmarshalOString2ᚖstring(ctx, tmp) arg5, err = ec.unmarshalOString2ᚖstring(ctx, tmp)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
args["T_TransactionSelfiePhoto"] = arg6 args["T_TransactionSelfiePhoto"] = arg5
var arg7 *string var arg6 string
if tmp, ok := rawArgs["T_TransactionNote"]; ok { if tmp, ok := rawArgs["token"]; ok {
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("T_TransactionNote")) ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("token"))
arg7, err = ec.unmarshalOString2string(ctx, tmp) arg6, err = ec.unmarshalNString2string(ctx, tmp)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
args["T_TransactionNote"] = arg7 args["token"] = arg6
var arg7 string
if tmp, ok := rawArgs["isSelfie"]; ok {
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("isSelfie"))
arg7, err = ec.unmarshalNString2string(ctx, tmp)
if err != nil {
return nil, err
}
}
args["isSelfie"] = arg7
return args, nil return args, nil
} }
@@ -909,7 +909,7 @@ func (ec *executionContext) _Mutation_mutationClockInAttendance(ctx context.Cont
}() }()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children ctx = rctx // use context from middleware stack in children
return ec.resolvers.Mutation().MutationClockInAttendance(rctx, fc.Args["T_TransactionM_AbsensiTypeID"].(string), fc.Args["T_TransactionM_StaffID"].(string), fc.Args["T_TransactionM_CompanyID"].(string), fc.Args["T_TransactionCurrentLatitude"].(string), fc.Args["T_TransactionCurrentLongitude"].(string), fc.Args["T_TransactionDistance"].(string), fc.Args["T_TransactionSelfiePhoto"].(*string), fc.Args["T_TransactionNote"].(*string)) return ec.resolvers.Mutation().MutationClockInAttendance(rctx, fc.Args["T_TransactionM_StaffID"].(string), fc.Args["T_TransactionM_CompanyID"].(string), fc.Args["T_TransactionCurrentLatitude"].(string), fc.Args["T_TransactionCurrentLongitude"].(string), fc.Args["T_TransactionCurrentDistance"].(string), fc.Args["T_TransactionSelfiePhoto"].(*string), fc.Args["token"].(string), fc.Args["isSelfie"].(string))
}) })
if err != nil { if err != nil {
ec.Error(ctx, err) ec.Error(ctx, err)

View File

@@ -23,5 +23,5 @@ extend type Query {
# mutation # mutation
extend type Mutation { extend type Mutation {
# untuk clock in absensi (absensi masuk) # untuk clock in absensi (absensi masuk)
mutationClockInAttendance(T_TransactionM_AbsensiTypeID:String!, T_TransactionM_StaffID:String!, T_TransactionM_CompanyID:String!, T_TransactionCurrentLatitude:String!, T_TransactionCurrentLongitude:String!, T_TransactionDistance:String!, T_TransactionSelfiePhoto:String, T_TransactionNote:String):TransAbsensiResponse! mutationClockInAttendance(T_TransactionM_StaffID:String!, T_TransactionM_CompanyID:String!, T_TransactionCurrentLatitude:String!, T_TransactionCurrentLongitude:String!, T_TransactionCurrentDistance:String!, T_TransactionSelfiePhoto:String, token:String!, isSelfie:String!):TransAbsensiResponse!
} }

View File

@@ -6,15 +6,16 @@ package resolver
import ( import (
"context" "context"
"fmt"
"com.sismedika.com.absensi/graph/model" "com.sismedika.com.absensi/graph/model"
transabsensiinternal "com.sismedika.com.absensi/internal/transabsensi" transabsensiinternal "com.sismedika.com.absensi/internal/transabsensi"
) )
// MutationClockInAttendance is the resolver for the mutationClockInAttendance field. // MutationClockInAttendance is the resolver for the mutationClockInAttendance field.
func (r *mutationResolver) MutationClockInAttendance(ctx context.Context, tTransactionMAbsensiTypeID string, tTransactionMStaffID string, tTransactionMCompanyID string, tTransactionCurrentLatitude string, tTransactionCurrentLongitude string, tTransactionDistance string, tTransactionSelfiePhoto *string, tTransactionNote *string) (*model.TransAbsensiResponse, error) { func (r *mutationResolver) MutationClockInAttendance(ctx context.Context, tTransactionMStaffID string, tTransactionMCompanyID string, tTransactionCurrentLatitude string, tTransactionCurrentLongitude string, tTransactionCurrentDistance string, tTransactionSelfiePhoto *string, token string, isSelfie string) (*model.TransAbsensiResponse, error) {
panic(fmt.Errorf("not implemented: MutationClockInAttendance - mutationClockInAttendance")) // panic(fmt.Errorf("not implemented: MutationClockInAttendance - mutationClockInAttendance"))
var transabsensiinternal transabsensiinternal.TransAbsensiResponse
return transabsensiinternal.ClockInAbsensi(tTransactionMStaffID, tTransactionMCompanyID, tTransactionCurrentLatitude, tTransactionCurrentLongitude, tTransactionCurrentDistance, *tTransactionSelfiePhoto, token, isSelfie)
} }
// QueryCheckDistance is the resolver for the queryCheckDistance field. // QueryCheckDistance is the resolver for the queryCheckDistance field.

View File

@@ -1,16 +1,26 @@
package transabsensi package transabsensi
import ( import (
"encoding/base64"
"errors"
"fmt"
"log" "log"
"os"
"strconv" "strconv"
"strings"
"time"
"com.sismedika.com.absensi/graph/model" "com.sismedika.com.absensi/graph/model"
"com.sismedika.com.absensi/pkg/config"
db "com.sismedika.com.absensi/pkg/database" db "com.sismedika.com.absensi/pkg/database"
) )
// diambil dari graph/model/struct nya TransAbsensiResponse // diambil dari graph/model/struct nya TransAbsensiResponse
type TransAbsensiCheckDistanceResponse model.TransAbsensiCheckDistanceResponse type TransAbsensiCheckDistanceResponse model.TransAbsensiCheckDistanceResponse
type TransAbsensiResponse model.TransAbsensiResponse
// 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) { func (transabsensi *TransAbsensiCheckDistanceResponse) CheckDistance(M_StaffID string, M_CompanyID string, CurrentLatitude string, CurrentLongitude string) (*model.TransAbsensiCheckDistanceResponse, error) {
// inisialisasi // inisialisasi
var err error var err error
@@ -127,3 +137,190 @@ func (transabsensi *TransAbsensiCheckDistanceResponse) CheckDistance(M_StaffID s
// hasil return nya // hasil return nya
return &ret, err 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
// check user token
qCheckTokenStaff := `SELECT
M_StaffToken,
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 = ""
}
// 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)
// if err != nil {
// log.Printf("here %v", err)
// return &ret, err
// }
// }
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 = 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_TransactionSelfiePhoto,
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,
&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
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 KiB