Introduction

Application use Realm Database using kotlin from MongoDB Realm Android SDKopen in new window for store data in application.

Install Realm for Android Application

on project-level select build.gradle file

└─ PROJECT
   └─ build.gradle
1
2

in build.gradle file:

buildscript {
   repositories {
      #add this line
      mavenCentral()
   }
   dependencies {
      #add this line
      classpath "io.realm:realm-gradle-plugin:10.8.0"
   }
}
1
2
3
4
5
6
7
8
9
10

on application-level select build.gradle file

└─ PROJECT
   └─ app
      └─ build.gradle
1
2
3

in build.gradle file:

plugins {
    # add 2 lines
    id 'kotlin-kapt'
    id 'realm-android'
}

android {
   # add this to use viewBinding features
   buildFeatures {
      viewBinding = true
   }
}

# add this to use sync feature of realm
realm {
    syncEnabled = true
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

Realm Object Models

Model RealmDB of this project application has 3 parts:

Directory file is:

└─ th.emerchant.terminal.edc_pos
   └─ model
1
2

Tip realm kotlin

models follow Prototype realm object concepts

Model For Store Setting Value Of Application

  • DataSettingRO
Field NameTypeDescription
enable_darkmodeBooleanuse to set light/dark mode
enable_print_testBooleanuse to enable print bitmap
enable_print_slipBooleanuse to enable print slip
ver_schema_config_dataLongversion schema of config data realm configuration
ver_schema_transaction_dataLongversion schema of transaction data realm configuration
enable_swipe_cardBooleanuse to enable function swipe card
enable_insert_cardBooleanuse to enable function insert card
enable_pass_cardBooleanuse to enable function pass card

Model For Store Config Process Data

  • ConfigTransactionRO
Field NameTypeDescription
typeStringtransaction type
processing_codeRealmList<String>list element processing code
reversalBooleanallow reversal
msgTypeStringmessage type
bitmapRealmList<DataBitmapRO>list bitmap for operation

  • DataBitmapRO
Field NameTypeDescription
typeStringoperation type (key in, magnetic, contract, contractless)
bitmapsRealmList<Int>list bitmap

  • ProcessingCodeRO
Field NameTypeDescription
nameString
dataRealmList<ProcessingCodeDataRO>list processing code

  • ProcessingCodeDataRO
Field NameTypeDescription
accStringmeaning code
codeIntprocessing code

  • ConfigTerminalRO
Field NameTypeDescription
serial_numberString
trace_invoiceInt
merchant_nameString
merchant_locationString
merchant_convinceString
app_nameString
app_versionString
app_passwordString
app_check_sumString
config_tcp_usingString
my_ipString
my_subnet_maskString
my_gatewayString
com1_enableString
com1_buad_rateString
com1_data_bitString
com1_parity_bitString
com1_stop_bitString
com1_datetimeString
com1_alarm_settingString
com1_alarm_datetimeString

  • ConfigCardRangeRO
Field NameTypeDescription
card_record_indexIntreference to ConfigCardRO
low_rangeLonglow range limit of card number
high_rangeLonghigh range limit of card number
card_number_lengthIntnumber of card number (16-19)

  • ConfigCardRO
Field NameTypeDescription
card_record_indexIntuse to reference
low_prefixStringlow prefix card number
high_prefixStringhigh prefix card number
card_labelStringcard label
min_lengthStringmin length of card number
max_lengthStringmax length of card number
check_digit_enableBoolean
check_digit_typeBoolean
card_control_record_indexIntreference to ConfigCardControlRO
host_record_indexIntreference to ConfigHostRO
emv_aidString
force_to_chipBoolean
credit_debit_typeStringcard type are credit or debit
card_scheme_typeStringcard scheme

  • ConfigCardControlRO
Field NameTypeDescription
card_control_record_indeIntuse to reference
sale_allowBooleanallow to do sale transaction
sale_passwordStringpassword of sale transaction
void_allowBooleanallow to do void transaction
void_passwordStringpassword of void transaction
refund_allowBooleanallow to do refund transaction
refund_passwordStringpassword of refund transaction
preauth_allowBooleanallow to do preauth transaction
preauth_passwordStringpassword of preauth transaction
manaul_entry_allowBooleanallow to do manaul entry transaction
manaul_entry_passwordStringpassword of manaul entry transaction
sale_complete_allowBooleanallow to do sale complete transaction
sale_complete_passwordStringpassword of sale complete transaction
offline_allowBooleanallow to do offline transaction
offline_passwordStringpassword of offline transaction
settlement_allowBooleanallow to do settlement transaction
settlement_passwordStringpassword of settlement transaction
pan_maskingStringpattern for mask number card

  • ConfigHostRO
Field NameTypeDescription
host_record_indexIntuse to reference
host_define_typeIntreference to ConfigHostDefineTypeRO
host_acquieretypeStringrecord date
host_label_nameStringrecord time
terminal_idStringtransaction amount
merchant_idStringdcc transaction amount
stanInttip transaction amount
niiStringdcc tip transaction amount
ip_addressStringoriginal transaction amount
portStringdcc transaction amount
reversal_flagBooleantransaction type (sale, void, preauth, refund, etc)
reversal_msgStringtransaction operator (key in, magnetic, contract, contractless)
last_batch_numberIntreference number from host
logo_fileStringapproval code from host
acquire_idIntresponse code from host
pre_auth_max_dayInt

  • ConfigHostDefineTypeRO
Field NameTypeDescription
host_define_typeIntuse to reference
host_define_type_nameString

  • ConfigCapkRO
Field NameTypeDescription
ridString
capk_indexString
modString
exponentString
issuerString
key_lengthInt
sha1String
expString

Model For Store Transaction History

  • TransactionHistoryRO
Field NameTypeDescription
idUUIDuniqe key, can use function UUID.randomUUID() to generate
record_numberIntrecord number of history transaction
dateStringrecord date
timeStringrecord time
datetime_from_hostBooleanmeaning datetime from host
txn_amountDoubletransaction amount
dcc_txn_amountDoubledcc transaction amount
tip_amountDoubletip transaction amount
dcc_tip_amountDoubledcc tip transaction amount
original_amountDoubleoriginal transaction amount
dcc_original_amountDoubledcc transaction amount
txn_typeStringtransaction type (sale, void, preauth, refund, etc)
txn_operatorStringtransaction operator (key in, magnetic, contract, contractless)
txn_statusStringtransaction status (online/offline)
reference_numberStringreference number from host
approval_codeStringapproval code from host
response_codeStringresponse code from host
terminal_idString
merchant_idString
stanString
invoice_numberString
batch_numberString
option_bit61String
option_bit63String
card_record_indexIntuse to get card record data
host_record_indexIntuse to get host record data
host_define_typeIntuse to get host
niiString
pos_entry_modeString
pos_condition_codeString
full_card_numberStringcard number
card_numberStringbind card number
expire_dateStringexpire date
card_holder_nameStringcard holder name
local_currency_codeString
local_currency_textString
dcc_currency_codeString
dcc_currency_textString
dcc_exchange_rateString
reff1_TextString
reff2_TextString
processing_codeString

Realm Object Structure

Object structure will extending RealmObject base class

Prototype Realm Object

Prototype object of this project:

part 1 - create class object follow basic Realm Object

open class ExampleRO(
   var id: String = "", // unique id
   var activte: Boolean = true,
   var name: String = "example",
   var age: Double = 0
) : RealmObject(){}
1
2
3
4
5
6

part 2 - add class method use to check field name for making a list

fun isList(type : String) : Boolean = when (type) {
   "" -> true
   else -> false
}
1
2
3
4

part 3 - add class method use to get field type

fun getType(type : String) : Class<*> {
   return when (type) {
      "activte" -> {
         Boolean::class.java
      }
      "age" -> {
         Double::class.java
      }
      else -> {
         String::class.java
      }
   }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

Overview

import io.realm.RealmObject

open class ExampleRO(
   var id: String = "", // unique id
   var activte: Boolean = true,
   var name: String = "example",
   var age: Double = 0
) : RealmObject(){
   fun isList(type : String) : Boolean = when (type) {
      "" -> true
      else -> false
   }
   fun getType(type : String) : Class<*> {
      return when (type) {
         "activte" -> {
            Boolean::class.java
         }
         "age" -> {
            Double::class.java
         }
         else -> {
            String::class.java
         }
      }
   }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

Prototype Realm Configuration

Prototype realm configulation of project has 3 part:

Directory file is:

└─ th.emerchant.terminal.edc_pos
   └─ RealmConfigurations.kt
1
2

Configulation for manage setting value of application

RealmModule:

@RealmModule(classes = [DataSettingRO::class])
class DataSettingModule
1
2

RealmConfiguration:

var dataSettingConfiguration: RealmConfiguration = RealmConfiguration.Builder()
    .name("setting.realm")
    .modules(DataSettingModule())
    .deleteRealmIfMigrationNeeded()
    .allowWritesOnUiThread(true)
    .build()
1
2
3
4
5
6

Configuration for mangae config process data

RealmModule:

@RealmModule(classes = [ConfigCardRO::class,ConfigCardRangeRO::class,ConfigCardControlRO::class,
    ConfigHostRO::class,ConfigHostDefineTypeRO::class,ConfigTerminalRO::class,ConfigTransactionRO::class,
    DataBitmapRO::class, ProcessingCodeRO::class,ProcessingCodeDataRO::class,ConfigCapkRO::class])
class DataConfigModule
1
2
3
4

RealmConfiguration:

var configDataRealmConfiguration = RealmConfiguration.Builder()
    .name("config.realm")
    .schemaVersion(getSchemaConfigData())
    .modules(DataConfigModule())
    .build()!!

var updateConfigDataRealmConfiguration = RealmConfiguration.Builder()
    .name("config.realm")
    .schemaVersion(getSchemaConfigData())
    .modules(DataConfigModule())
    .allowWritesOnUiThread(true)
    .build()!!
1
2
3
4
5
6
7
8
9
10
11
12

Configuration for manage transaction history

RealmModule:

@RealmModule(classes = [TransactionHistoryRO::class])
class DataTransactionModule
1
2

RealmConfiguration:

var transactionDataConfiguration = RealmConfiguration.Builder()
    .name("transaction.realm")
    .schemaVersion(getSchemaTransactionData())
    .modules(DataTransactionModule())
    .build()!!

var updateTransactionDataConfiguration = RealmConfiguration.Builder()
    .name("transaction.realm")
    .schemaVersion(getSchemaTransactionData())
    .modules(DataTransactionModule())
    .allowWritesOnUiThread(true)
    .build()!!
1
2
3
4
5
6
7
8
9
10
11
12

Tip realm kotlin

example: setup realm with customize configuration

import io.realm.Realm

Realm.init(this)

val dataSettingApp = Realm.getInstance(dataSettingConfiguration)

// close RealmDatabase when process finished
dataSettingApp.close()
1
2
3
4
5
6
7
8

Create And Update Data From JSON

Use json data create and update data in realm database

Tip kotlin

convert string to json

val jsonStringData = "{ activte:true, name:\"test\", age:1 }"

val jsonData = JSONObject(jsonStringData)
1
2
3
Create data from JSON object

Create by an object

val jsonStringData = "{ id: \"example\", activte:true, name:\"test\", age:1 }"
val jsonData = JSONObject(jsonStringData)

val realm = Realm.getInstance() // use default configuration 

val exampleData = ExampleRO(
   var id = jsonData.getString("id"),
   activte = jsonData.getBoolean("activte"),
   name = jsonData.getString("name"),
   age = jsonData.getInt("age")
)

realm.beginTransaction()
realm.delete(ExampleRO::class.java) // can use this line to reset ExampleRO file
realm.copyToRealm(exampleData)
realm.commitTransaction()

realm.close()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18


Create by many objects

val jsonStringData = "{ data: [{activte:true, name:\"test\", age:1}, {activte:false, name:\"test2\", age:0}] }"
val jsonData = JSONObject(jsonStringData)

val realm = Realm.getInstance() // use default configuration 

realm.beginTransaction()
realm.delete(ExampleRO::class.java) // can use this line to reset ExampleRO file

val listJsonData = jsonData.getJSONArray("data")
for (i in 0 until listJsonData.length()) {
   val example = listJsonData.getJSONObject(i)
   val exampleData = ExampleRO(
      id = "example$i",
      activte = example.getBoolean("activte"),
      name = example.getString("name"),
      age = example.getInt("age")
   )
   realm.copyToRealm(exampleData)
}
realm.commitTransaction()

realm.close()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Update data from JSON object

Update by an object

val jsonStringData = "{ id: \"example\", activte:true, name:\"test\", age:1 }"
val jsonData = JSONObject(jsonStringData)

val realm = Realm.getInstance() // use default configuration 

realm.executeTransaction {
   val searchExample = it.where<ExampleRO>().equalTo("id", jsonData.getString("id")).findFirst()
   if (searchExample != null) {
      searchExample.activate =
         if (jsonData.has("host_record_index")) jsonData.getInt("host_record_index")
         else searchExample.host_record_index
      searchExample.name =
         if (jsonData.has("host_label_name")) jsonData.getString("host_label_name")
         else searchExample.host_label_name
      searchExample.age =
         if (jsonData.has("host_define_type")) jsonData.getInt("host_define_type")
         else searchExample.host_define_type
   }
}

realm.close()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21


Update by many objects

val jsonStringData = 
   "{ data: [" + 
      "{id: \"example0\", activte:true, name:\"test\", age:1}, " +
      "{id: \"example1\", activte:false, name:\"test2\", age:0}" + 
   "] }"
val jsonData = JSONObject(jsonStringData)

val realm = Realm.getInstance() // use default configuration 

val listJsonData = jsonData.getJSONArray("data")
for (i in 0 until listJsonData.length()) {
   val example = listJsonData.getJSONObject(i)
   realm.executeTransaction {
      val searchExample = it.where<ExampleRO>().equalTo("id", example.getString("id")).findFirst()
      if (searchExample != null) {
         searchExample.activate =
            if (jsonData.has("host_record_index")) example.getInt("host_record_index")
            else searchExample.host_record_index
         searchExample.name =
            if (jsonData.has("host_label_name")) example.getString("host_label_name")
            else searchExample.host_label_name
         searchExample.age =
            if (jsonData.has("host_define_type")) example.getInt("host_define_type")
            else searchExample.host_define_type
      }
   }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Create or update data from JSON object

If already realm object then update by an json object, else create new realm object by json object

val jsonStringData = 
   "{ data: [" + 
      "{id: \"example0\", activte:true, name:\"test\", age:1}, " +
      "{id: \"example1\", activte:false, name:\"test2\", age:0}" + 
   "] }"
val jsonData = JSONObject(jsonStringData)

val realm = Realm.getInstance() // use default configuration 

val listJsonData = jsonData.getJSONArray("data")
for (i in 0 until listJsonData.length()) {
   val example = listJsonData.getJSONObject(i)
   realm.executeTransaction {
      val searchExample = it.where<ExampleRO>().equalTo("id", example.getString("id")).findFirst()
      if (searchExample != null) {
         searchExample.activate =
            if (jsonData.has("host_record_index")) example.getInt("host_record_index")
            else searchExample.host_record_index
         searchExample.name =
            if (jsonData.has("host_label_name")) example.getString("host_label_name")
            else searchExample.host_label_name
         searchExample.age =
            if (jsonData.has("host_define_type")) example.getInt("host_define_type")
            else searchExample.host_define_type
      }
      else{
         val exampleData = ExampleRO(
            id = "example$i",
            activte = example.getBoolean("activte"),
            name = example.getString("name"),
            age = example.getInt("age")
         )
         realm.copyToRealm(exampleData)
      }
   }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

Migrations

This feature use for developing application. Migration working when schema realm database changed

Step 1 check schema has changed by test open realm using try catch:

try {
   dataRealmConfiguration = updateConfigDataRealmConfiguration
   Realm.getInstance(updateConfigDataRealmConfiguration)
} catch (e: Exception) {
   /*
      Step 2
   */
}
1
2
3
4
5
6
7
8

Step 2 if open realm failed, then bring exception transform to event update form using GetListUpdateRO function and EvtUpdateRo data class

   val EvtsUpdateRO: ArrayList<EvtUpdateRo> = GetListUpdateRO(e.toString())
   /* Step 3 */
1
2

data class EvtUpdateRo:

data class EvtUpdateRo(val class_name: String, val field_name: String, val evt_action: String)
1

function GetListUpdateRO:

// Concept: Regular Expressions
fun GetListUpdateRO(textException: String): ArrayList<EvtUpdateRo> {
    val events = Regex("""Property.*\w+""").findAll(textException)
    val EvtsUpdateRO = ArrayList<EvtUpdateRo>()
    for (findText in events) {
        val evtSplit =
            Regex("""Property '(.*)\.(.*)' has been (.*)""").find(findText.value)?.groupValues
        EvtsUpdateRO.add(EvtUpdateRo(evtSplit!![1], evtSplit[2], evtSplit[3]))
    }
    return EvtsUpdateRO
}
1
2
3
4
5
6
7
8
9
10
11

Step 3 update version value in database for migration

   Realm.getInstance(dataSettingConfiguration).use { dataSettingRealm ->
      dataSettingRealm.executeTransaction {
         val data = dataSettingRealm.where<DataSettingRO>().findFirst()
         Log.v("TEST", "data setting: $data")
         data!!.ver_schema_config_data = getSchemaConfigData() + 1
      }
   }
   /* Step 4 */
1
2
3
4
5
6
7
8

Step 4 create RealmConfiguration has support migration for open realm

   dataRealmConfiguration = RealmConfiguration.Builder().name("config.realm")
   .schemaVersion(getSchemaConfigData()).migration(RealmMigrations(EvtsUpdateRO))
   .modules(DataConfigModule()).allowWritesOnUiThread(true).build()!!

   val realm = Realm.getInstance(dataRealmConfiguration)
1
2
3
4
5

Code Overview:

file: MainActivity.kt

try {
   dataRealmConfiguration = updateConfigDataRealmConfiguration
   Realm.getInstance(updateConfigDataRealmConfiguration)
} catch (e: Exception) {
   Log.v("TEST", "error: $e")
   val EvtsUpdateRO: ArrayList<EvtUpdateRo> = GetListUpdateRO(e.toString())
   Log.v("TEST", EvtsUpdateRO.toString())

   Realm.getInstance(dataSettingConfiguration).use { dataSettingRealm ->
         dataSettingRealm.executeTransaction {
            val data = dataSettingRealm.where<DataSettingRO>().findFirst()
            Log.v("TEST", "data setting: $data")
            data!!.ver_schema_config_data = getSchemaConfigData() + 1
         }
   }

   dataRealmConfiguration = RealmConfiguration.Builder()
         .name("config.realm")
         .schemaVersion(getSchemaConfigData())
         .migration(RealmMigrations(EvtsUpdateRO))
         .modules(DataConfigModule())
         .allowWritesOnUiThread(true)
         .build()!!

   val realm = Realm.getInstance(dataRealmConfiguration)
   Log.v(
         "TEST",
         "realm version: ${realm.version}"
   )
   realm.close()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

file: RealmUpdate.kt

data class EvtUpdateRo(val class_name: String, val field_name: String, val evt_action: String)

fun GetListUpdateRO(textException: String): ArrayList<EvtUpdateRo> {
   val events = Regex("""Property.*\w+""").findAll(textException)
   val EvtsUpdateRO = ArrayList<EvtUpdateRo>()
   for (findText in events) {
      val evtSplit =
         Regex("""Property '(.*)\.(.*)' has been (.*)""").find(findText.value)?.groupValues
      EvtsUpdateRO.add(EvtUpdateRo(evtSplit!![1], evtSplit[2], evtSplit[3]))
   }
   return EvtsUpdateRO
}
1
2
3
4
5
6
7
8
9
10
11
12

Overide RealmMigration for support application

class RealmMigrations(private val EvtsUpdateRO : ArrayList<EvtUpdateRo>) : RealmMigration {
   override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) {
      Log.v("TEST", "event update: $EvtsUpdateRO")
      var version: Long = oldVersion

      val schema = realm.schema
      Log.v("TEST", "old: $oldVersion new: $newVersion")

      for (i in 0 until EvtsUpdateRO.size){
         Log.v("TEST", "Event $i --> " +
                  "\rclass: ${EvtsUpdateRO[i].class_name} " +
                  "\rfield: ${EvtsUpdateRO[i].field_name} " +
                  "\raction: ${EvtsUpdateRO[i].evt_action}")
         when (EvtsUpdateRO[i].evt_action.split(" ")[0]) {
            "removed" -> {
               try {
                  schema.get(EvtsUpdateRO[i].class_name)!!.removeField(EvtsUpdateRO[i].field_name)
                  Log.v("TEST", "remove event success")
               }
               catch (e: Exception){
                  Log.v("TEST", "remove event fail - $e")
               }
            }
            "added" -> {
               try {
                  addFieldRO(EvtsUpdateRO[i].class_name, EvtsUpdateRO[i].field_name, schema)
                  Log.v("TEST", "add event success")
               }
               catch (e: Exception){
                  Log.v("TEST", "add event fail - $e")
               }
            }
            else -> {
               Log.v("TEST", "now not support this event")
            }
         }
      }
   }

   private fun addFieldRO(model: String, field: String, schema: RealmSchema) {
        var isList = false
        var typeField : Class<*> = String::class.java
        when (model) {
            "ConfigTerminalRO" -> {
                val ro = ConfigTerminalRO()
                isList = ro.isList(field)
                typeField = ro.getType(field)
            }
            "ConfigHostRO" -> {
                val ro = ConfigHostRO()
                isList = ro.isList(field)
                typeField = ro.getType(field)
            }
            "ConfigCardRO" -> {
                val ro = ConfigCardRO()
                isList = ro.isList(field)
                typeField = ro.getType(field)
            }
            "ConfigCardControlRO" -> {
                val ro = ConfigCardControlRO()
                isList = ro.isList(field)
                typeField = ro.getType(field)
            }
            "ConfigTransactionRO" -> {
                val ro = ConfigTransactionRO()
                isList = ro.isList(field)
                typeField = ro.getType(field)
            }
            "DataBitmapRO" -> {
                val ro = DataBitmapRO()
                isList = ro.isList(field)
                typeField = ro.getType(field)
            }
            "ProcessingCodeRO" -> {
                val ro = ProcessingCodeRO()
                isList = ro.isList(field)
                typeField = ro.getType(field)
            }
            "ProcessingCodeDataRO" -> {
                val ro = ProcessingCodeDataRO()
                isList = ro.isList(field)
                typeField = ro.getType(field)
            }
            "TransactionHistoryRO" -> {
                val ro = TransactionHistoryRO()
                isList = ro.isList(field)
                typeField = ro.getType(field)
            }
        }
        if (isList) {
            schema.get(model)!!.addRealmListField(field, typeField)
        }
        else {
            schema.get(model)!!.addField(field, typeField)
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97

Realm Support Function

Collect function working with Realm Database in file FunctionRealmDB.kt

Function For Realm Configuration

  • Function to get version schema of config data configuration
fun getSchemaConfigData() : Long {
    return if (Realm.getInstance(dataSettingConfiguration).where<DataSettingRO>().findFirst() != null){
        Realm.getInstance(dataSettingConfiguration).where<DataSettingRO>().findFirst()!!.ver_schema_config_data
    }
    else{
        0
    }
}
1
2
3
4
5
6
7
8
  • Function to get version schema of transaction data configuration
fun getSchemaTransactionData() : Long {
    return if (Realm.getInstance(dataSettingConfiguration).where<DataSettingRO>().findFirst() != null){
        Realm.getInstance(dataSettingConfiguration).where<DataSettingRO>().findFirst()!!.ver_schema_transaction_data
    }
    else{
        0
    }
}
1
2
3
4
5
6
7
8

Function For Device

  • Function to get theme(dark/light) value
fun getDarkMode() : Boolean {
    Realm.init(SyncObjectServerFacade.getApplicationContext())
    val dataSettingApp = Realm.getInstance(dataSettingConfiguration)
    val dataSetting = dataSettingApp.where<DataSettingRO>().findFirst()
    Log.v("TEST", "Get setting value: $dataSetting")
    dataSettingApp.close()
    return dataSetting?.enable_darkmode ?: false
}
1
2
3
4
5
6
7
8
  • Function to change theme(dark/light) value
fun changeDarkMode(hasEnable: Boolean) {
    Realm.init(SyncObjectServerFacade.getApplicationContext())
    val dataSettingApp = Realm.getInstance(dataSettingConfiguration)
    dataSettingApp.executeTransaction {
        val dataSettimg = dataSettingApp.where<DataSettingRO>().findFirst()
        dataSettimg?.enable_darkmode = hasEnable
    }
    dataSettingApp.close()
}
1
2
3
4
5
6
7
8
9
  • Function to get setting application value
fun getDataSetting(): DataSettingRO? {
    Realm.init(SyncObjectServerFacade.getApplicationContext())
    val realm = Realm.getInstance(dataSettingConfiguration)
    val dataSetting = realm.where<DataSettingRO>().findFirst()
    val dataSettingCopy = realm.copyFromRealm(dataSetting)
    realm.close()
    return dataSettingCopy
}
1
2
3
4
5
6
7
8
  • Function to update setting application value
fun editDataSetting(dataSetting: DataSettingRO): Boolean {
    return try {
        Realm.init(SyncObjectServerFacade.getApplicationContext())
        val realm = Realm.getInstance(dataSettingConfiguration)
        realm.beginTransaction()
        realm.delete(DataSettingRO::class.java)
        realm.copyToRealm(dataSetting)
        realm.commitTransaction()
        realm.close()
        true
    }
    catch (e:Exception){
        Log.d("TEST","Edit data setting failed")
        false
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

Function For Transaction Process

  • Function to check correct password of device before do menu entry transaction
fun checkPasswordApp(password: String): Boolean {
    Realm.init(SyncObjectServerFacade.getApplicationContext())
    val realm = Realm.getInstance(configDataRealmConfiguration)
    val dataTerminal = realm.where<ConfigTerminalRO>().equalTo("app_password",password).findFirst()
    val checkPassword = dataTerminal != null
    realm.close()
    return checkPassword
}
1
2
3
4
5
6
7
8
  • Function to get merchant data
fun getMerchantData(): JSONObject {
    Realm.init(SyncObjectServerFacade.getApplicationContext())
    val realm = Realm.getInstance(configDataRealmConfiguration)
    val dataMerchant = realm.where<ConfigTerminalRO>().findFirst()
    val dataMerchantCopy = realm.copyFromRealm(dataMerchant)
    realm.close()
    return JSONObject("{" +
            "merchant_name: \"${dataMerchantCopy?.merchant_name}\", " +
            "merchant_location: \"${dataMerchantCopy?.merchant_location}\"," +
            "merchant_convince: \"${dataMerchantCopy?.merchant_convince}\"" +
            "}")
}
1
2
3
4
5
6
7
8
9
10
11
12
  • Function to save history transaction
fun saveTransaction(data: JSONObject) : Boolean{
    try {
        Realm.init(SyncObjectServerFacade.getApplicationContext())

        val realm = Realm.getInstance(transactionDataConfiguration)
        val last_record_number =
            try { realm.where<TransactionHistoryRO>().findAll().last()!!.record_number }
            catch (e: Exception) { 1 }
        Log.v("test","record number: $last_record_number")
        val transactionHistory = TransactionHistoryRO(
            txn_type = data.getString("transaction_type"),
            txn_status = data.getString("transaction_status"),
            txn_operator = data.getString("operation"),
            full_card_number = data.getString("card_number"),
            card_number = data.getString("card_number_mask"),
            card_holder_name = data.getString("name"),
            expire_date = data.getString("card_exp"),
            record_number = last_record_number!! +1,
            date = data.getString("date"),
            time = data.getString("time"),
            datetime_from_host = data.getBoolean("datetime_from_host"),
            txn_amount = data.getString("amount").replace(",","").toDouble(),
            terminal_id = data.getString("tid"),
            merchant_id = data.getString("mid"),
            batch_number = data.getString("batch_number"),
            nii = data.getString("nii"),
            stan = data.getString("stan"),
            invoice_number = data.getString("invoice_num"),
            reference_number = data.getString("ref_num"),
            approval_code = data.getString("auth_id"),
            response_code = data.getString("res_code"),
            card_record_index = data.getInt("card_record_index"),
            host_record_index = data.getInt("host_record_index"),
            host_define_type = data.getInt("host_define_type"),
        )
        Log.v("TEST", "save transaction: $transactionHistory")
        realm.beginTransaction()
        realm.copyToRealm(transactionHistory)
        realm.commitTransaction()
        realm.close()

        val realmTerminal = Realm.getInstance(updateConfigDataRealmConfiguration)
        realmTerminal.executeTransaction {
            val config_terminal = realmTerminal.where<ConfigTerminalRO>().findFirst()
            config_terminal!!.trace_invoice++
        }
        val config_terminal = realmTerminal.where<ConfigTerminalRO>().findFirst()
        Log.v("TEST", "update invoice: ${config_terminal.toString()}")
        realmTerminal.close()

        return true
    }
    catch (e: Exception){
        Log.v("TEST", "save transaction filed: $e")
        return false
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
  • Function to update history transaction
fun updateTransaction(data: JSONObject) : Boolean{
    try {
        Realm.init(SyncObjectServerFacade.getApplicationContext())
        val realm = Realm.getInstance(updateTransactionDataConfiguration)
        realm.executeTransaction {
            val transaction = realm.where<TransactionHistoryRO>().equalTo("record_number",data.getInt("record_number")).findFirst()
            if (transaction != null) {
                transaction.txn_type = data.getString("transaction_type")
                transaction.txn_status = data.getString("transaction_status")
                transaction.date = data.getString("date")
                transaction.time = data.getString("time")
                transaction.datetime_from_host = data.getBoolean("datetime_from_host")
                transaction.txn_amount = data.getString("amount").replace(",", "").toDouble()
                transaction.original_amount =
                    data.getString("additional_amount").replace(",", "").toDouble()
                transaction.batch_number = data.getString("batch_number")
                transaction.stan = data.getString("stan")
                transaction.reference_number = data.getString("ref_num")
                transaction.approval_code = data.getString("auth_id")
                transaction.response_code = data.getString("res_code")
            }
        }
        val transaction = realm.where<TransactionHistoryRO>().equalTo("record_number",data.getInt("record_number")).findFirst()
        Log.v("TEST", "update transaction: ${transaction.toString()}")
        realm.close()

        return true
    }
    catch (e: Exception){
        Log.v("TEST", "update transaction filed: $e")
        return false
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
  • Function to update STAN value of each host
fun updateStan(hostRecordIndex: Int, stan: Int? = null) : Boolean{
    try {
        Realm.init(SyncObjectServerFacade.getApplicationContext())
        val realm = Realm.getInstance(updateConfigDataRealmConfiguration)

        realm.executeTransaction {
            val config_host = realm.where<ConfigHostRO>().equalTo("host_record_index",hostRecordIndex).findFirst()
            if (stan!=null) {
                config_host!!.stan = stan
            }else{
                if (config_host!!.stan == 999999) {
                    config_host.stan = 1
                } else {
                    config_host.stan++
                }
            }
        }
        val config_host = realm.where<ConfigHostRO>().equalTo("host_record_index",hostRecordIndex).findFirst()
        Log.v("TEST", "update stan: ${config_host.toString()}")
        realm.close()

        return true
    }
    catch (e: Exception){
        Log.v("TEST", "update stan filed: $e")
        return false
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
  • Function to save reverse message of each host
fun saveReverseMassage(hostRecordIndex: Int, reverseMassage: String?) : Boolean{
    try {
        Realm.init(SyncObjectServerFacade.getApplicationContext())
        val realm = Realm.getInstance(updateConfigDataRealmConfiguration)

        realm.executeTransaction {
            val config_host = realm.where<ConfigHostRO>().equalTo("host_record_index",hostRecordIndex).findFirst()
            if (config_host != null) config_host.reversal_msg = reverseMassage
        }
        val config_host = realm.where<ConfigHostRO>().equalTo("host_record_index",hostRecordIndex).findFirst()
        Log.v("TEST", "save reverse msg: ${config_host.toString()}")
        realm.close()

        return true
    }
    catch (e: Exception){
        Log.v("TEST", "save reverse massage filed: $e")
        return false
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  • Function to set reversee flag of each host
fun setReverseFlag(hostRecordIndex: Int, reverseFlag: Boolean) : Boolean{
    try {
        Realm.init(SyncObjectServerFacade.getApplicationContext())
        val realm = Realm.getInstance(updateConfigDataRealmConfiguration)

        realm.executeTransaction {
            val config_host = realm.where<ConfigHostRO>().equalTo("host_record_index",hostRecordIndex).findFirst()
            if (config_host != null) config_host.reversal_flag = reverseFlag
        }
        val config_host = realm.where<ConfigHostRO>().equalTo("host_record_index",hostRecordIndex).findFirst()
        Log.v("TEST", "set reverse flag: ${config_host.toString()}")
        realm.close()

        return true
    }
    catch (e: Exception){
        Log.v("TEST", "set reverse flag filed: $e")
        return false
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  • Function to select card data by card record index
fun selectCardData(cardNumber: String): (ConfigCardRO?) {
    Realm.init(SyncObjectServerFacade.getApplicationContext())
    val realm = Realm.getInstance(configDataRealmConfiguration)
    val cardRange = realm.where<ConfigCardRangeRO>()
        .lessThanOrEqualTo("low_range", cardNumber.toLong())
        .greaterThan("high_range", cardNumber.toLong())
        .equalTo("card_number_length", cardNumber.length).findFirst()
    Log.v("TEST", "range: $cardRange")
    return if (cardRange != null) {
        val cardData = realm.copyFromRealm(realm.where<ConfigCardRO>()
            .equalTo("card_record_index", cardRange?.card_record_index).findFirst())
        realm.close()
        cardData
    }
    else{
        realm.close()
        null
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  • Function to get card control data by card control record index
fun getCardControl(cardControlIndex: Int, transactionType: String): ConfigCardControlRO? {
    Realm.init(SyncObjectServerFacade.getApplicationContext())
    val realm = Realm.getInstance(configDataRealmConfiguration)
    val cardControl = realm.copyFromRealm(realm.where<ConfigCardControlRO>()
        .equalTo("card_control_record_index", cardControlIndex).findFirst())
    realm.close()
    return cardControl
}
1
2
3
4
5
6
7
8
  • Function to select host data by host record index
fun selectHost(hostIndex: Int): ConfigHostRO? {
    Realm.init(SyncObjectServerFacade.getApplicationContext())
    val realm = Realm.getInstance(configDataRealmConfiguration)
    val host = realm.where<ConfigHostRO>().equalTo("host_record_index", hostIndex).findFirst()
    val hostCopy = if (host != null) realm.copyFromRealm(host) else null
    Log.v("TEST", "select host: ${hostCopy.toString()}")
    realm.close()
    return hostCopy
}
1
2
3
4
5
6
7
8
9
  • Function to get trace invoice for do transaction
fun getTraceInvoice(): Int {
    Realm.init(SyncObjectServerFacade.getApplicationContext())
    val realm = Realm.getInstance(configDataRealmConfiguration)
    val terminal = realm.copyFromRealm(realm.where<ConfigTerminalRO>().findFirst())
    realm.close()
    Log.v("TEST", "terminal: $terminal")
    return terminal!!.trace_invoice
}
1
2
3
4
5
6
7
8
  • Function to get list of host use be host selection for echo test transaction
fun getHostList() : RealmList<ConfigHostRO> {
    Realm.init(SyncObjectServerFacade.getApplicationContext())
    val realm = Realm.getInstance(configDataRealmConfiguration)
    val hostList = realm.where<ConfigHostRO>().findAll()
    val hostListCopy = RealmList<ConfigHostRO>()
    hostListCopy.addAll(hostList)
    realm.close()
    return hostListCopy
}
1
2
3
4
5
6
7
8
9
  • Function to check reversal of host before do transaction
fun checkReversalTransaction(transactionType: String): Boolean {
    return try {
        Realm.init(SyncObjectServerFacade.getApplicationContext())
        val realm = Realm.getInstance(configDataRealmConfiguration)
        val transaction = realm.copyFromRealm(realm.where<ConfigTransactionRO>().equalTo("type", transactionType).findFirst())
        realm.close()
        transaction!!.reversal!!
    }
    catch (e:Exception) {
        false
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
  • Function to get lastest transaction
fun getLastTransaction(): TransactionHistoryRO? {
    return try {
        Realm.init(SyncObjectServerFacade.getApplicationContext())
        val realm = Realm.getInstance(transactionDataConfiguration)
        val lastTransaction = realm.copyFromRealm(realm.where<TransactionHistoryRO>().findAll().last())
        realm.close()
        lastTransaction
    }
    catch (e:Exception){
        null
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
  • Function to get today format string (YYYYMMDD)
fun getTodayStr(): String {
    val date = Date()
    return "${1900 + date.year}" +
            "${if (1 + date.month < 10) "0${1 + date.month}" else 1 + date.month}" +
            "${if (date.date < 10) "0${date.date}" else date.date}"
}
1
2
3
4
5
6
  • Function to get summary sale transaction today
@RequiresApi(Build.VERSION_CODES.O)
fun getTodaySales(): String {
    val today = getTodayStr()
    Log.v("TEST", "today: $today")
    Realm.init(SyncObjectServerFacade.getApplicationContext())
    val realm = Realm.getInstance(transactionDataConfiguration)
    val todaySale = realm.where<TransactionHistoryRO>().equalTo("txn_type","sale")
    .equalTo("date",today).sum("txn_amount")
    realm.close()
    return Utils().formatMoney(Utils().formatMoneyD2S(todaySale as Double))

}
1
2
3
4
5
6
7
8
9
10
11
12
  • Function to get transactions list of today
fun getTodayTransaction(): Array<Any> {
    val date = Date()
    val today = "${1900+date.year}" +
            "${if (1+date.month<10) "0${1+date.month}" else 1+date.month}" +
            "${if (date.date<10) "0${date.date}" else date.date}"
    Log.v("TEST", "today: $today")
    Realm.init(SyncObjectServerFacade.getApplicationContext())
    val realm = Realm.getInstance(transactionDataConfiguration)
    val todayTransaction = realm.where<TransactionHistoryRO>().equalTo("date",today)
        .sort("time", Sort.DESCENDING).findAll()
    val transactionlist = RealmList<TransactionHistoryRO>()
    transactionlist.addAll(todayTransaction)
    val transactionTotal = Utils().formatMoney(Utils().formatMoneyD2S(todayTransaction.sum("txn_amount") as Double))
    realm.close()
    return arrayOf(transactionTotal, transactionlist)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  • Function to update host data
fun updateHost(host: ConfigHostRO): Boolean {
    try {
        Realm.init(SyncObjectServerFacade.getApplicationContext())
        val realm = Realm.getInstance(updateConfigDataRealmConfiguration)

        realm.executeTransaction {
            val config_host = realm.where<ConfigHostRO>().equalTo("host_record_index",host.host_record_index).findFirst()
            if (config_host != null) {
                config_host.stan = host.stan
                config_host.last_batch_number = host.last_batch_number
                config_host.reversal_flag = host.reversal_flag
                config_host.reversal_msg = host.reversal_msg
            }
        }
        val config_host = realm.where<ConfigHostRO>().equalTo("host_record_index",host.host_record_index).findFirst()
        Log.v("TEST", "update setting host: ${config_host.toString()}")
        realm.close()

        return true
    }
    catch (e: Exception){
        Log.v("TEST", "set reverse flag filed: $e")
        return false
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
  • Function to update trace invoice value
fun updateInvoice(invoice: Int? = null): Boolean{
    try {
        Realm.init(SyncObjectServerFacade.getApplicationContext())
        val realm = Realm.getInstance(updateConfigDataRealmConfiguration)

        realm.executeTransaction {
            val config_terminal = realm.where<ConfigTerminalRO>().findFirst()
            if (invoice!=null) {
                config_terminal!!.trace_invoice = invoice
            }else{
                if (config_terminal!!.trace_invoice == 999999) {
                    config_terminal.trace_invoice = 1
                } else {
                    config_terminal.trace_invoice++
                }
            }
        }
        val config_terminal = realm.where<ConfigTerminalRO>().findFirst()
        Log.v("TEST", "update stan: ${config_terminal.toString()}")
        realm.close()

        return true
    }
    catch (e: Exception){
        Log.v("TEST", "update invoice filed: $e")
        return false
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
  • Function to get CAPK data
fun getCAPK(rid: String, capk_index: String): ConfigCapkRO? {
    Realm.init(SyncObjectServerFacade.getApplicationContext())
    val realm = Realm.getInstance(configDataRealmConfiguration)
    val configCapk = realm.where<ConfigCapkRO>().equalTo("rid", rid).equalTo("capk_index", capk_index).findFirst()
    val configCapkCopy = if (configCapk != null) realm.copyFromRealm(configCapk) else null
    realm.close()
    return configCapkCopy
}
1
2
3
4
5
6
7
8

Realm Studio

Visual tool to view file .realm (data of application) while developing. see moreopen in new window

Last Updated:
Contributors: Kittison Apaijit