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
2
in build.gradle file:
buildscript {
repositories {
#add this line
mavenCentral()
}
dependencies {
#add this line
classpath "io.realm:realm-gradle-plugin:10.8.0"
}
}
2
3
4
5
6
7
8
9
10
on application-level select build.gradle file
└─ PROJECT
└─ app
└─ build.gradle
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
}
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:
- Model for store setting value of application
- Model for store config process data
- Model for store transaction history
Directory file is:
└─ th.emerchant.terminal.edc_pos
└─ model
2
Tip realm kotlin
models follow Prototype realm object concepts
Model For Store Setting Value Of Application
- DataSettingRO
| Field Name | Type | Description |
|---|---|---|
| enable_darkmode | Boolean | use to set light/dark mode |
| enable_print_test | Boolean | use to enable print bitmap |
| enable_print_slip | Boolean | use to enable print slip |
| ver_schema_config_data | Long | version schema of config data realm configuration |
| ver_schema_transaction_data | Long | version schema of transaction data realm configuration |
| enable_swipe_card | Boolean | use to enable function swipe card |
| enable_insert_card | Boolean | use to enable function insert card |
| enable_pass_card | Boolean | use to enable function pass card |
Model For Store Config Process Data
- ConfigTransactionRO
| Field Name | Type | Description |
|---|---|---|
| type | String | transaction type |
| processing_code | RealmList<String> | list element processing code |
| reversal | Boolean | allow reversal |
| msgType | String | message type |
| bitmap | RealmList<DataBitmapRO> | list bitmap for operation |
- DataBitmapRO
| Field Name | Type | Description |
|---|---|---|
| type | String | operation type (key in, magnetic, contract, contractless) |
| bitmaps | RealmList<Int> | list bitmap |
- ProcessingCodeRO
| Field Name | Type | Description |
|---|---|---|
| name | String | |
| data | RealmList<ProcessingCodeDataRO> | list processing code |
- ProcessingCodeDataRO
| Field Name | Type | Description |
|---|---|---|
| acc | String | meaning code |
| code | Int | processing code |
- ConfigTerminalRO
| Field Name | Type | Description |
|---|---|---|
| serial_number | String | |
| trace_invoice | Int | |
| merchant_name | String | |
| merchant_location | String | |
| merchant_convince | String | |
| app_name | String | |
| app_version | String | |
| app_password | String | |
| app_check_sum | String | |
| config_tcp_using | String | |
| my_ip | String | |
| my_subnet_mask | String | |
| my_gateway | String | |
| com1_enable | String | |
| com1_buad_rate | String | |
| com1_data_bit | String | |
| com1_parity_bit | String | |
| com1_stop_bit | String | |
| com1_datetime | String | |
| com1_alarm_setting | String | |
| com1_alarm_datetime | String |
- ConfigCardRangeRO
| Field Name | Type | Description |
|---|---|---|
| card_record_index | Int | reference to ConfigCardRO |
| low_range | Long | low range limit of card number |
| high_range | Long | high range limit of card number |
| card_number_length | Int | number of card number (16-19) |
- ConfigCardRO
| Field Name | Type | Description |
|---|---|---|
| card_record_index | Int | use to reference |
| low_prefix | String | low prefix card number |
| high_prefix | String | high prefix card number |
| card_label | String | card label |
| min_length | String | min length of card number |
| max_length | String | max length of card number |
| check_digit_enable | Boolean | |
| check_digit_type | Boolean | |
| card_control_record_index | Int | reference to ConfigCardControlRO |
| host_record_index | Int | reference to ConfigHostRO |
| emv_aid | String | |
| force_to_chip | Boolean | |
| credit_debit_type | String | card type are credit or debit |
| card_scheme_type | String | card scheme |
- ConfigCardControlRO
| Field Name | Type | Description |
|---|---|---|
| card_control_record_inde | Int | use to reference |
| sale_allow | Boolean | allow to do sale transaction |
| sale_password | String | password of sale transaction |
| void_allow | Boolean | allow to do void transaction |
| void_password | String | password of void transaction |
| refund_allow | Boolean | allow to do refund transaction |
| refund_password | String | password of refund transaction |
| preauth_allow | Boolean | allow to do preauth transaction |
| preauth_password | String | password of preauth transaction |
| manaul_entry_allow | Boolean | allow to do manaul entry transaction |
| manaul_entry_password | String | password of manaul entry transaction |
| sale_complete_allow | Boolean | allow to do sale complete transaction |
| sale_complete_password | String | password of sale complete transaction |
| offline_allow | Boolean | allow to do offline transaction |
| offline_password | String | password of offline transaction |
| settlement_allow | Boolean | allow to do settlement transaction |
| settlement_password | String | password of settlement transaction |
| pan_masking | String | pattern for mask number card |
- ConfigHostRO
| Field Name | Type | Description |
|---|---|---|
| host_record_index | Int | use to reference |
| host_define_type | Int | reference to ConfigHostDefineTypeRO |
| host_acquieretype | String | record date |
| host_label_name | String | record time |
| terminal_id | String | transaction amount |
| merchant_id | String | dcc transaction amount |
| stan | Int | tip transaction amount |
| nii | String | dcc tip transaction amount |
| ip_address | String | original transaction amount |
| port | String | dcc transaction amount |
| reversal_flag | Boolean | transaction type (sale, void, preauth, refund, etc) |
| reversal_msg | String | transaction operator (key in, magnetic, contract, contractless) |
| last_batch_number | Int | reference number from host |
| logo_file | String | approval code from host |
| acquire_id | Int | response code from host |
| pre_auth_max_day | Int |
- ConfigHostDefineTypeRO
| Field Name | Type | Description |
|---|---|---|
| host_define_type | Int | use to reference |
| host_define_type_name | String |
- ConfigCapkRO
| Field Name | Type | Description |
|---|---|---|
| rid | String | |
| capk_index | String | |
| mod | String | |
| exponent | String | |
| issuer | String | |
| key_length | Int | |
| sha1 | String | |
| exp | String |
Model For Store Transaction History
- TransactionHistoryRO
| Field Name | Type | Description |
|---|---|---|
| id | UUID | uniqe key, can use function UUID.randomUUID() to generate |
| record_number | Int | record number of history transaction |
| date | String | record date |
| time | String | record time |
| datetime_from_host | Boolean | meaning datetime from host |
| txn_amount | Double | transaction amount |
| dcc_txn_amount | Double | dcc transaction amount |
| tip_amount | Double | tip transaction amount |
| dcc_tip_amount | Double | dcc tip transaction amount |
| original_amount | Double | original transaction amount |
| dcc_original_amount | Double | dcc transaction amount |
| txn_type | String | transaction type (sale, void, preauth, refund, etc) |
| txn_operator | String | transaction operator (key in, magnetic, contract, contractless) |
| txn_status | String | transaction status (online/offline) |
| reference_number | String | reference number from host |
| approval_code | String | approval code from host |
| response_code | String | response code from host |
| terminal_id | String | |
| merchant_id | String | |
| stan | String | |
| invoice_number | String | |
| batch_number | String | |
| option_bit61 | String | |
| option_bit63 | String | |
| card_record_index | Int | use to get card record data |
| host_record_index | Int | use to get host record data |
| host_define_type | Int | use to get host |
| nii | String | |
| pos_entry_mode | String | |
| pos_condition_code | String | |
| full_card_number | String | card number |
| card_number | String | bind card number |
| expire_date | String | expire date |
| card_holder_name | String | card holder name |
| local_currency_code | String | |
| local_currency_text | String | |
| dcc_currency_code | String | |
| dcc_currency_text | String | |
| dcc_exchange_rate | String | |
| reff1_Text | String | |
| reff2_Text | String | |
| processing_code | String |
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(){}
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
}
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
}
}
}
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
}
}
}
}
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:
- Configuration for manage setting value of application
- Configuration for mangae config process data
- Configuration for manage transaction history
Directory file is:
└─ th.emerchant.terminal.edc_pos
└─ RealmConfigurations.kt
2
Configulation for manage setting value of application
RealmModule:
@RealmModule(classes = [DataSettingRO::class])
class DataSettingModule
2
RealmConfiguration:
var dataSettingConfiguration: RealmConfiguration = RealmConfiguration.Builder()
.name("setting.realm")
.modules(DataSettingModule())
.deleteRealmIfMigrationNeeded()
.allowWritesOnUiThread(true)
.build()
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
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()!!
2
3
4
5
6
7
8
9
10
11
12
Configuration for manage transaction history
RealmModule:
@RealmModule(classes = [TransactionHistoryRO::class])
class DataTransactionModule
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()!!
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()
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)
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()
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()
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()
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
}
}
}
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)
}
}
}
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
*/
}
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 */
2
data class EvtUpdateRo:
data class EvtUpdateRo(val class_name: String, val field_name: String, val evt_action: String)
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
}
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 */
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)
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()
}
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
}
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)
}
}
}
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
}
}
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
}
}
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
}
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()
}
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
}
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
}
}
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
}
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}\"" +
"}")
}
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
}
}
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
}
}
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
}
}
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
}
}
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
}
}
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
}
}
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
}
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
}
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
}
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
}
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
}
}
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
}
}
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}"
}
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))
}
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)
}
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
}
}
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
}
}
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
}
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