# Employee Attendance Contract

{% code title="kehadiran.cpp" %}

```cpp
#include <string>
#include <eosio/eosio.hpp>
#include <eosio/time.hpp>
#include <eosio/system.hpp>
#include <eosio/print.hpp>

using namespace eosio;
using namespace std;
 
using eosio::check;
using eosio::const_mem_fun;
using eosio::current_time_point;
using eosio::datastream;
using eosio::indexed_by;
using eosio::name;
using eosio::time_point_sec;
using eosio::print;
using std::function;
using std::string;


#define SCACCKEHADIRAN "belajarsc222"

class [[eosio::contract("kehadiran")]] kehadiran : public eosio::contract
{
public:
    kehadiran(name receiver, name code, datastream<const char *> ds) : contract(receiver, code, ds) 
     , peg_instance(receiver, receiver.value), dh_instance(receiver, receiver.value)
    {}
    

    [[eosio::action]] void tambahpeg(name idpeg, name accpeg, string namapeg, string deppeg, string pospeg){
        //hanya account vexakuncoba1 yang bisa action : tambah data pegawai baru
        require_auth(name(SCACCKEHADIRAN));

        auto i = peg_instance.find(idpeg.value);
        auto j = peg_instance.get_index<name("byaccpeg")>();
        auto itr = j.lower_bound(idpeg.value);
        
        //cek : id_pegawai harus belum ada di pegawai_table
        check(i == peg_instance.end(), "id pegawai sudah terpakai oleh karyawan lain, masukkan id karyawan yg baru.");
        check(itr == j.end(), "username pegawai sudah digunakan oleh pegawai lain, masukkan ulang username baru.");

        //insert row baru ke dalam pegawai_table
       peg_instance.emplace(get_self(), [&](auto &i)
                      {              
            
        	i.id_pegawai = idpeg;
        	i.username = accpeg; 
		    i.nama_pegawai = namapeg;
            i.departemen = deppeg;
            i.posisi = pospeg;
        });
    }
 
    [[eosio::action]] void hapuspeg(name &idpeg){
        require_auth(name(SCACCKEHADIRAN));

        auto i = peg_instance.find(idpeg.value);

        check(i != peg_instance.end(), "id pegawai yg akan dihapus tidak ditemukan." );
        peg_instance.erase(i);        
    }


    [[eosio::action]] void isi(name &idpeg, int8_t stat, int8_t ket){
        auto i = peg_instance.find(idpeg.value); //cari id pegawai terdaftar apa engga

        check(i != peg_instance.end(), "idpegawai salah");

        require_auth(name(i->username)); //butuh auth username tsb 

        auto k = dh_instance.get_index<name("byidpeg")>(); 
        auto itrk = k.find(idpeg.value);

        int itrg;

        for(auto itr = k.crbegin(); itrg < itr->id_daftar_hadir; itr++) {
            int a = itr->status;
            int b = itr->keterangan;
            print_f(" % % % % ", itr->id_daftar_hadir, itr->id_pegawai, a, b);
            if(itr->id_pegawai == idpeg){
                itrg = itr->id_daftar_hadir;
                print_f(" % ", itrg);

                if(itrk == k.end() || a == 1 || a == -1 ){
                    dh_instance.emplace(get_self(), [&](auto &i){
                i.id_daftar_hadir = dh_instance.available_primary_key();
                i.id_pegawai = idpeg;
                i.status = stat;
                i.waktu_masuk = current_time_point();
                i.keterangan = ket;
                });
                }
                else if(itr->status == 0){

            auto f = itr->id_daftar_hadir;
            auto g = dh_instance.find(f);

            dh_instance.modify(g, get_self(), [&](auto &i){
                i.status = 1;
                i.waktu_pulang = current_time_point();
            });
            }
                
            }
        } 
    }

    [[eosio::action]] void hapusdh(int8_t nomor){
        require_auth(name(SCACCKEHADIRAN));

        auto i = dh_instance.find(nomor);

        check(i != dh_instance.end(), "nomor daftar hadir yg akan dihapus tidak ditemukan." );
        dh_instance.erase(i);        
    }

private:
enum status_hadir : int8_t
    {
        selesai = 1,
        sedang_bekerja = 0,
        absen = -1
    };

enum status_keterangan : int8_t
    {
        attended = 1,
        sick_leave = 2 ,
        personal_leave = 3,
        no_call_no_shows = 4 
    };

struct [[eosio::table]] pegawai_table{
    name id_pegawai;
    name username;
    string nama_pegawai;
    string departemen;
    string posisi;
    
    uint64_t primary_key() const { return id_pegawai.value;}
    uint64_t by_secondary() const { return username.value; }
    
};

typedef eosio::multi_index<"pegawai"_n, pegawai_table, eosio::indexed_by<"byaccpeg"_n, eosio::const_mem_fun<pegawai_table, uint64_t, &pegawai_table::by_secondary>>> pegawai_index;

pegawai_index peg_instance;

struct [[eosio::table]] dh_table{ //dh = daftar_hadir
    uint64_t id_daftar_hadir;
    name id_pegawai;
    int8_t status;
    int8_t keterangan;
    time_point_sec waktu_masuk;
    time_point_sec waktu_pulang;

    uint64_t primary_key() const { return id_daftar_hadir;}
    uint64_t by_secondary() const { return id_pegawai.value; }
};

typedef eosio::multi_index<"daftarhadir"_n, dh_table, eosio::indexed_by<"byidpeg"_n, eosio::const_mem_fun<dh_table, uint64_t, &dh_table::by_secondary>>> dh_index;

dh_index dh_instance;

using isi_action = action_wrapper<"isi"_n, &kehadiran::isi>;
};


```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.vexanium.com/reference/smart-contract/c++-smart-contract/employee-attendance-contract.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
