Helpful Function

Function of Utils class in direct file utils/Utils.kt

How to call out function from Utils class

// example
Utils().cardMasking("5500 1234 9876 4556", "NNNN NNNN NNXX XXXX")
1
2

  • Function masking card number

** Input value (full card number and pan mask) must be equal

fun cardMasking(fullCard: String, panMask: String): String {
    var cardMask = ""
    var index = 0
    for (char in panMask) {
        when (char) {
            'N' -> {
                cardMask += fullCard[index]
                index++
            }
            'X' -> {
                cardMask += "X"
                index++
            }
            else -> {
                cardMask += " "
            }
        }
    }
    return cardMask
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

  • Function Format Date String

Use to format date string form 20220212 to feb 02 ,2022 for slip form

fun convertToDate(number: String): String {
    try {
        val date = number.substring(6, 8)
        val month = number.substring(4, 6)
        val year = number.substring(0, 4)

        val getMonthToString = Month.listOfMonth.single { it.numberOfMonth == month.toInt() }
        return "${getMonthToString.name.uppercase()} $date ,$year"

    } catch (e: Exception) {
        throw Exception(e.message)
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

  • Function Format Time String

Use to format time string form 115924 to 11:59:24 for slip form

fun convertToTime(number: String): String {
    try {
        val hour = number.substring(0,2)
        val minute = number.substring(2,4)
        val second = number.substring(4,6)

        return "$hour:$minute:$second"
    } catch (e: Exception) {
        throw Exception(e.message)
    }
}
1
2
3
4
5
6
7
8
9
10
11

  • Function Reprint Lastest function

Use for reprint lastest transaction on user menu page

fun reprintLastTransaction(context: Context) {
    val lastTransaction = getLastTransaction()

    if (lastTransaction != null) {
        val lastTransactionJson = transactionToJson(lastTransaction.txn_type!!,lastTransaction)
        Printer().printSlip(
            lastTransactionJson,
            context,
            "merchant"
        )
        Log.v("TEST", "Last transaction json: $lastTransactionJson")
    }
    else{
        Log.v("TEST", "Have not last transaction")
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

  • Function Format Amount Of Money

For use to format amount of money string form 125000 to 1250.00 for display on application

fun formatMoney(raw_amount: String) : String{
    return when {
        raw_amount.isEmpty() -> {
            "0.00"
        }
        raw_amount.length == 1 -> {
            "0.0$raw_amount"
        }
        raw_amount.length == 2 -> {
            "0.$raw_amount"
        }
        else -> {
            "${ "%,d".format(raw_amount.dropLast(2).toLong()) }.${ raw_amount.drop(raw_amount.length-2) }"
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

For use to format amount of money double 1250.0 to string 125000 for transaction record form

fun formatMoneyD2S(amount: Double): String{
    val split_amount = amount.toString().split(".")
    var amountDisplay = split_amount[0] + split_amount[1]
    if (split_amount[1].length == 1) amountDisplay += "0"
    return amountDisplay
}
1
2
3
4
5
6

Transaction Function

Function for process transaction in direct file utils/TransactionProcess.kt


  • Function Transform Transaction Data

Use to transform transaction data form TransactionHistoryRO object to JSON object for convenient to process transaction

fun transactionToJson(
    transactionType: String?, 
    transaction: TransactionHistoryRO
): JSONObject{
    val host = transaction.host_record_index?.let { selectHost(it) }
    val cardData = transaction.card_record_index?.let { getCardData(it) }
    val jsonData = JSONObject()

    if (host != null && cardData != null) {
        val amountDisplay = Utils().formatMoney(Utils().formatMoneyD2S(transaction.txn_amount!!))
        jsonData.put("time", transaction.time)
        jsonData.put("date", transaction.date)
        jsonData.put("record_number", transaction.record_number)
        jsonData.put("card_record_index", transaction.card_record_index)
        jsonData.put("name", transaction.card_holder_name)
        jsonData.put("card_label", cardData.card_scheme_type)
        jsonData.put("card_number", transaction.full_card_number)
        jsonData.put("card_exp", transaction.expire_date)
        jsonData.put("amount", amountDisplay)
        jsonData.put("additional_amount", amountDisplay)
        jsonData.put("transaction_type", transactionType)
        jsonData.put("operation", transaction.txn_operator)
        jsonData.put("tid", transaction.terminal_id)
        jsonData.put("mid", transaction.merchant_id)
        jsonData.put("nii", transaction.nii)
        jsonData.put("stan", host.stan)
        jsonData.put("ip_address1", host.ip_address1)
        jsonData.put("port1", host.port1)
        jsonData.put("host_record_index", host.host_record_index)
        jsonData.put("host_define_type", host.host_define_type)
        jsonData.put("host_label", host.host_label_name)
        jsonData.put("batch_number", transaction.batch_number!!.toInt())
        jsonData.put("invoice", transaction.invoice_number!!.toInt())
        jsonData.put("ref_number", transaction.reference_number)
        jsonData.put("approve_code", transaction.approval_code)
        jsonData.put("response_code", transaction.response_code)
    }

    return jsonData
}
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

  • Function Get ISO8583 Message

Use to get ISO8583 message each transaction consists of:
- Recieve JSON data for build ISO8583 message
- Get ISO8583 message by using ISO8583Message class
- Return ISO8583 message for send to host

fun buildISO(data: JSONObject) : JSONObject {
    try {
        Realm.init(SyncObjectServerFacade.getApplicationContext())
        val realm = Realm.getInstance(configDataRealmConfiguration)
        val message = ISO8583Message(
            realm = realm,
            transactionType = if (data.has("transaction_type")) data.getString("transaction_type") else null,
            operation = if (data.has("operation")) data.getString("operation") else null,
            cardNumber = if (data.has("card_number")) data.getString("card_number") else null,
            amount = if (data.has("amount")) data.getString("amount").replace(",", "") else null,
            cardEXP = if (data.has("card_exp")) data.getString("card_exp") else null,
            track1 = if (data.has("track1")) data.getString("track1") else null,
            track2 = if (data.has("track2")) data.getString("track2") else null,
            tid = if (data.has("tid")) data.getString("tid") else null,
            mid = if (data.has("mid")) data.getString("mid") else null,
            nii = if (data.has("nii")) data.getString("nii") else null,
            stan = if (data.has("stan")) data.getInt("stan") else null,
            invoice = if (data.has("invoice")) data.getInt("invoice") else null,
            refNumber = if (data.has("ref_number")) data.getString("ref_number") else null,
            approveCode = if (data.has("approve_code")) data.getString("approve_code") else null,
            responseCode = if (data.has("response_code")) data.getString("response_code") else null,
            additionalAmount = if (data.has("additional_amount")) data.getString("additional_amount") else null,
            originalAmount = if (data.has("original_amount")) data.getString("original_amount") else null,
            date = if (data.has("date")) data.getString("date").substring(data.getString("date").length - 4) else null,
            time = if (data.has("time")) data.getString("time") else null,
        )
        data.put("iso8583_payload", message.iso8583Payload())
        data.put("iso8583_reversal_payload", message.iso8583ReversalPayload())

        realm.close()

        return data
    } catch (e: Exception) {
        throw Exception("Build ISO8583 Function Error : "+e.message)
    }
}
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

  • Function Test Host

Use to process each transaction consists of:
- Prepare data for build ISO8583 message
- Build ISO8583 message
- Send to host
- Display result

suspend fun testHost(
    ip: String,
    port: Int,
    openLoadingMessage: MutableState<String>,
    openErrDialogMessage: MutableState<String>
): Boolean = withContext(Dispatchers.Default) {

    val utils = Utils()
    val beeper: UBeeper = DeviceHelper.me().beeper
    try {
        val jsonData = JSONObject()
        jsonData.put("transaction_type", "test_host")
        jsonData.put("nii", "0120")
        jsonData.put("tid", "11111111")
        jsonData.put("mid", "111111111111111")
        jsonData.put("operation", "test_host")
        val dataISO8583 = buildISO(jsonData)

        val resqData =
            Printer().stringToArrayHexString(dataISO8583.getString("iso8583_payload"))
        Printer().printBitmap(resqData, "Request", ("$ip:$port"))

        val socket = SocketCommunication(address = ip, port = port, timeout = 3000)
        val checkStatus =
            withContext(Dispatchers.Default) { socket.run() }

        if (checkStatus) {
            openLoadingMessage.value = "Connected"
            val writeMessage =
                withContext(Dispatchers.Default) {
                    socket.write(
                        dataISO8583.getString("iso8583_payload")
                    )
                }
            openLoadingMessage.value = "Sending message..."
            if (writeMessage) {
                openLoadingMessage.value = "Send message is success"
                val readStream = withContext(Dispatchers.Default) { socket.read() }
                openLoadingMessage.value = "Receving message..."
                if (readStream.size > 0) {
                    val jsonResp = utils.extractISO8583TOJSON(readStream)
                    Log.d("TEST", "Socket Resp: $readStream")
                    Log.d("Test", "extract respone: ${jsonResp.toString()}")
                    openLoadingMessage.value = "Receved message"
                    beeper.startBeep(100)
                    delay(500)
                    Printer().printBitmap(
                        readStream,
                        "Response",
                        ("$ip:$port")
                    )
                    true
                } else {
                    openErrDialogMessage.value = "Connection Timeout"
                    beeper.startBeep(500)
                    false
                }
            } else {
                openErrDialogMessage.value = "Write message Failed"
                beeper.startBeep(500)
                false
            }
        } else {
            openErrDialogMessage.value = "Connection Failed"
            beeper.startBeep(500)
            false
        }

    } catch (e: Exception) {
        openErrDialogMessage.value = e.toString()
        beeper.startBeep(500)
        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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

  • Function Transaction Of Card Entry

Use to process each transaction consists of:
- Prepare data for process
- Verify data
- Check transaction type (offline/online)
- Check connection
- Check reverse
- Build ISO8583 message
- Send to host
- Check response
- Update history transaction in database

suspend fun cardEntryProcess(
    jsonData: JSONObject,
    errMessage: MutableState<String>,
    context: Context,
    popupPrintSlipCustomer: MutableState<Boolean>,
    loading: MutableState<Boolean>,
    textLoading: MutableState<String>,
    popUpBalanceInquiry: MutableState<Boolean>,
    balanceInquiryAmount: MutableState<String>,
    balanceInquiryTitle: MutableState<String>,
    popUpContinue: MutableState<Boolean>,
    nextRoute: MutableState<String>,
): Boolean {
    val utils = Utils()
    val iso8583Message = ISO8583()

    val printer: UPrinter = DeviceHelper.me().printer
    val beeper: UBeeper = DeviceHelper.me().beeper
    val led: ULed = DeviceHelper.me().getLed(RFDeviceName.INNER)
    val host =
        withContext(Dispatchers.Default) { selectHost(jsonData.getInt("host_record_index")) }

    if (host != null) {
        jsonData.put("tid", host.terminal_id)
        jsonData.put("mid", host.merchant_id)
        jsonData.put("nii", host.nii)
        jsonData.put("stan", host.stan)
        jsonData.put("ip_address1", host.ip_address1)
        jsonData.put("port1", host.port1)
        jsonData.put("host_define_type", host.host_define_type)
        jsonData.put("host_label", host.host_label_name)
        jsonData.put("batch_number", host.last_batch_number)
        jsonData.put("invoice", getTraceInvoice())

        if (jsonData.getString("transaction_type") == "offline_sale") {
            nextRoute.value = Route.EnterApproveCode.route
            return true
        } else {
            textLoading.value = "Connecting..."
            if (printer.status == PrinterError.SUCCESS) {
                try {
                    val socket = SocketCommunication(host.ip_address1!!, host.port1!!, 10000)
                    val checkStatus = withContext(Dispatchers.Default) { socket.run() }

                    if (checkStatus) {
                        textLoading.value = "Connected"
                        val hasReverse =
                            if (host.reversal_flag!!) {
                                val dataReverse = 
                                    withContext(Dispatchers.Default) {sendReverse(host, errMessage)}
                                    
                                if (dataReverse.has("res_code")) {
                                    val (isApprove, meaning) = iso8583Message.checkBit39Payload(
                                        dataReverse.getString("res_code")
                                    )
                                    isApprove as Boolean
                                } else {
                                    true
                                }
                            }
                            else false

                        if (!hasReverse) {
                            setReverseFlag(host.host_record_index, false)
                            saveReverseMassage(host.host_record_index, null)

                            val dataISO8583 = buildISO(jsonData)
                            val hexData =
                                Printer().stringToArrayHexString(dataISO8583.getString("iso8583_payload"))

                            Printer().printBitmap(
                                hexData, "Request", "${host.ip_address1!!}:${host.port1!!}"
                            )

                            val reverseMsg =
                                if (dataISO8583.has("iso8583_reversal_payload"))
                                    dataISO8583.getString("iso8583_reversal_payload")
                                else null

                            withContext(Dispatchers.Default) { 
                                saveReverseMassage(host.host_record_index,reverseMsg) 
                            }
                            textLoading.value = "Sending.."

                            val writeMessage = socket.write(dataISO8583.getString("iso8583_payload"))
                            if (writeMessage) {
                                textLoading.value = "Sended"
                                val readStream = withContext(Dispatchers.Default) { socket.read() }
                                if (readStream.size > 0) {
                                    textLoading.value = "Recive Response"
                                    val jsonResp = utils.extractISO8583TOJSON(readStream)

                                    Printer().printBitmap(
                                        readStream, "Response", "${host.ip_address1!!}:${host.port1!!}"
                                    )

                                    if (if (jsonResp.has("res_code")) {
                                            val (isApprove, meaning) = iso8583Message.checkBit39Payload(
                                                jsonResp.getString("res_code")
                                            )

                                            textLoading.value = "Status is: $meaning"
                                            val transactionIsApprove = isApprove as Boolean
                                            if (transactionIsApprove) {
                                                beeper.startBeep(100)
                                                delay(1_500)
                                            } else {
                                                led.turnOn(Light.RED)
                                                delay(2_500)
                                            }
                                            led.turnOff(Light.RED)
                                            transactionIsApprove
                                        }
                                        else { false }
                                    ) {
                                        if (jsonData.getString("transaction_type") != "balance_inquiry") {
                                            textLoading.value = "Printing..."
                                            jsonData.put("datetime_from_host", true)
                                            jsonData.put(
                                                "date",
                                                (1900 + Date().year).toString() + jsonResp.getString(
                                                    "date"
                                                )
                                            )
                                            jsonData.put("time", jsonResp.getString("time"))
                                            jsonData.put("transaction_status", "online")
                                            jsonData.put("response_code", jsonResp.getString("res_code"))
                                            jsonData.put("approve_code", jsonResp.getString("auth_id"))
                                            jsonData.put("ref_number", jsonResp.getString("ref_num"))
                                            jsonData.put(
                                                "invoice",
                                                if (jsonResp.has("invoice"))
                                                    jsonResp.getString("invoice").toInt().toString()
                                                else jsonData.getString("invoice")
                                            )
                                            jsonData.put(
                                                "card_number_mask",
                                                Utils().cardMasking(
                                                    jsonData.getString("card_number"),
                                                    jsonData.getString("pan_masking")
                                                )
                                            )
                                            saveTransaction(jsonData)
                                            Printer().printSlip(jsonData, context, "merchant")
                                            loading.value = false
                                            textLoading.value = ""
                                            popupPrintSlipCustomer.value = true
                                            popUpContinue.value = true
                                        }
                                        else {
                                            if (jsonResp.getString("amount_transaction").isNotEmpty()) {
                                                popUpContinue.value = true
                                                popUpBalanceInquiry.value = true
                                                balanceInquiryTitle.value = "Balance Inquiry"
                                                balanceInquiryAmount.value = 
                                                    utils.formatMoney(
                                                        jsonResp.getString("amount_transaction")
                                                    )
                                            }

                                            Printer().printBitmap(
                                                readStream,
                                                "Respone",
                                                "${host.ip_address1!!}:${host.port1!!}"
                                            )
                                        }
                                        withContext(Dispatchers.Default) { 
                                            updateStan(host.host_record_index) 
                                        }
                                        saveReverseMassage(host.host_record_index, null)
                                        return true
                                    } else {
                                        withContext(Dispatchers.Default) { 
                                            updateStan(host.host_record_index) 
                                        }
                                        saveReverseMassage(host.host_record_index, null)
                                        errMessage.value = "Transtion not approve"
                                        beeper.startBeep(500)
                                        return false
                                    }
                                }
                                else {
                                    val dataReverse = sendReverse(host, errMessage)
                                    if (dataReverse.has("res_code")) {
                                        val (isApprove, meaning) = iso8583Message.checkBit39Payload(
                                            dataReverse.getString("res_code")
                                        )
                                        return if (isApprove as Boolean) {
                                            updateStan(host.host_record_index)
                                            saveReverseMassage(host.host_record_index, null)
                                            true
                                        } else {
                                            setReverseFlag(host.host_record_index, true)
                                            errMessage.value =
                                                "Send pending reverse not approve because $meaning"
                                            beeper.startBeep(500)
                                            false
                                        }
                                    } else {
                                        setReverseFlag(host.host_record_index, true)
                                        errMessage.value = "Send pending reverse Failed"
                                        beeper.startBeep(500)
                                        return false
                                    }
                                }
                            } else {
                                errMessage.value = "Write message Failed"
                                beeper.startBeep(500)
                                return false
                            }
                        } else {
                            errMessage.value = "Send reverse Failed"
                            beeper.startBeep(500)
                            return false
                        }
                    } else {
                        errMessage.value = "Connection Failed"
                        beeper.startBeep(500)
                        return false
                    }

                } catch (e: Exception) {
                    errMessage.value = e.toString()
                    beeper.startBeep(500)
                    return false
                }
            } else {
                errMessage.value = "Printer Error"
                beeper.startBeep(500)
                return false
            }
        }
    } else {
        errMessage.value = "Host or card data not found"
        beeper.startBeep(500)
        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
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238

  • Function Offline Transaction

Use to record transaction for offline transaction process

fun saveOfflineTransaction(
    jsonData: JSONObject,
    context: Context,
    errMessage: MutableState<String>,
    loading: MutableState<Boolean>,
    textLoading: MutableState<String>,
    popupPrintSlipCustomer: MutableState<Boolean>,
    popUpContinue: MutableState<Boolean>,
): Boolean {
    return try {
        textLoading.value = "Printing..."
        val date = Date()
        jsonData.put("datetime_from_host", false)
        jsonData.put(
            "date",
            "${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}"
        )
        jsonData.put(
            "time",
            "${if (date.hours < 10) "0${date.hours}" else date.hours}" +
                    "${if (date.minutes < 10) "0${date.minutes}" else date.minutes}" +
                    "${if (date.seconds < 10) "0${date.seconds}" else date.seconds}"
        )
        jsonData.put("transaction_status", "offline")
        if (!jsonData.has("approve_code")) jsonData.put("approve_code", "")
        if (!jsonData.has("ref_number")) jsonData.put("ref_number", "")
        if (!jsonData.has("stan")) jsonData.put("stan", "")
        if (!jsonData.has("invoice")) jsonData.put("invoice", getTraceInvoice())
        if (!jsonData.has("card_number_mask"))
            jsonData.put(
                "card_number_mask",
                Utils().cardMasking(jsonData.getString("card_number"),
                    jsonData.getString("pan_masking"))
            )
        jsonData.put("response_code", "00")
        saveTransaction(jsonData)
        Printer().printSlip(
            jsonData,
            context,
            "merchant"
        )
        true
    } catch (e: Exception) {
        errMessage.value = "Offline sale failed - $e"
        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

  • Function Online Transaction Of Menu Entry

Use to process each transaction consists of:
- Prepare data for process
- Verify data
- Check connection
- Check reverse
- Build ISO8583 message
- Send to host
- Check response
- Update history transaction in database

suspend fun sendOnlineTransaction(
    jsonData: JSONObject,
    context: Context,
    errMessage: MutableState<String>,
    loading: MutableState<Boolean>,
    textLoading: MutableState<String>,
    popupPrintSlipCustomer: MutableState<Boolean>,
    popUpContinue: MutableState<Boolean>,
)
: JSONObject {
    textLoading.value = "Preparing Data..."
    val utils = Utils()
    val iso8583Message = ISO8583()

    val printer: UPrinter = DeviceHelper.me().printer
    val beeper: UBeeper = DeviceHelper.me().beeper
    val led: ULed = DeviceHelper.me().getLed(RFDeviceName.INNER)
    val host = selectHost(jsonData.getInt("host_record_index"))

    if (jsonData != JSONObject() && host != null) {
        textLoading.value = "Connecting..."
        if (printer.status == PrinterError.SUCCESS) {
            try {
                val socket = SocketCommunication(
                    host.ip_address1!!,
                    host.port1!!,
                    10000
                )
                val checkStatus = withContext(Dispatchers.Default) { socket.run() }
                if (checkStatus) {
                    textLoading.value = "Connected"
                    var hasReverse = false
                    if (host.reversal_flag!!) {
                        val dataReverse =
                            withContext(Dispatchers.Default) { sendReverse(host, errMessage) }
                        hasReverse = if (dataReverse.has("res_code")) {
                            val (isApprove, meaning) = iso8583Message.checkBit39Payload(
                                dataReverse.getString("res_code")
                            )
                            isApprove as Boolean
                        } else {
                            true
                        }
                    }

                    if (!hasReverse) {
                        setReverseFlag(host.host_record_index, false)
                        saveReverseMassage(host.host_record_index, null)

                        val dataISO8583 = buildISO(jsonData)
                        val hexData =
                            Printer().stringToArrayHexString(dataISO8583.getString("iso8583_payload"))
                        Printer().printBitmap(
                            hexData, "Request", "${host.ip_address1!!}:${host.port1!!}"
                        )

                        saveReverseMassage(
                            host.host_record_index,
                            if (dataISO8583.has("iso8583_reversal_payload"))
                                dataISO8583.getString("iso8583_reversal_payload")
                            else null
                        )
                        textLoading.value = "Sending.."

                        val writeMessage = socket.write(
                            dataISO8583.getString("iso8583_payload")
                        )
                        if (writeMessage) {
                            textLoading.value = "Sended"
                            val readStream = withContext(Dispatchers.Default) {socket.read() }
                            if (readStream.size > 0) {
                                textLoading.value = "Recive Response"
                                val jsonResp = utils.extractISO8583TOJSON(readStream)

                                Printer().printBitmap(
                                    readStream,
                                    "Response",
                                    "${host.ip_address1!!}:${host.port1!!}"
                                )

                                if (if (jsonResp.has("res_code")) {
                                        val (isApprove, meaning) = iso8583Message.checkBit39Payload(
                                            jsonResp.getString("res_code")
                                        )
                                        textLoading.value = "Status is: $meaning"
                                        val transactionIsApprove = isApprove as Boolean
                                        if (transactionIsApprove) {
                                            beeper.startBeep(100)
                                            delay(1_500)
                                        } else {
                                            led.turnOn(Light.RED);
                                            delay(2_500)
                                        }
                                        led.turnOff(Light.RED);
                                        transactionIsApprove
                                    } else {
                                        false
                                    }
                                ) {
                                    textLoading.value = "Printing..."
                                    jsonData.put("datetime_from_host", true)
                                    jsonData.put(
                                        "date",
                                        (1900 + Date().year).toString() + jsonResp.getString(
                                            "date"
                                        )
                                    )
                                    jsonData.put("time", jsonResp.getString("time"))
                                    jsonData.put("transaction_status", "online")
                                    jsonData.put("response_code", jsonResp.getString("res_code"))
                                    jsonData.put("approve_code",
                                        if (jsonResp.has("auth_id")) jsonResp.getString("auth_id")
                                        else jsonData.getString("approve_code")
                                    )
                                    jsonData.put("ref_number", jsonResp.getString("ref_num"))
                                    jsonData.put("invoice",
                                        if (jsonResp.has("invoice")) jsonResp.getString("invoice")
                                        else jsonData.getString("invoice")
                                    )
                                    jsonData.put("card_number_mask", jsonData.getString("card_number"))
                                    withContext(Dispatchers.Default) { updateTransaction(jsonData) }

                                    Printer().printSlip(jsonData, context, "merchant")

                                    loading.value = false
                                    textLoading.value = ""

                                    popupPrintSlipCustomer.value = true
                                    popUpContinue.value = true

                                    Printer().printBitmap(
                                        readStream,
                                        "Respone",
                                        "${host.ip_address1!!}:${host.port1!!}"
                                    )
                                    updateStan(host.host_record_index)
                                    saveReverseMassage(host.host_record_index, null)
                                    return jsonData
                                } else {
                                    updateStan(host.host_record_index)
                                    saveReverseMassage(host.host_record_index, null)
                                    errMessage.value = "Transtion not approve"
                                    beeper.startBeep(500)
                                    return JSONObject()
                                }
                            }
                            else {
                                if (checkReversalTransaction(jsonData.getString("transaction_type"))) {
                                    val dataReverse = withContext(Dispatchers.Default) {
                                        sendReverse(host,
                                            errMessage)
                                    }
                                    if (dataReverse.has("res_code")) {
                                        val (isApprove, meaning) = iso8583Message.checkBit39Payload(
                                            dataReverse.getString("res_code")
                                        )
                                        return if (isApprove as Boolean) {
                                            updateStan(host.host_record_index)
                                            saveReverseMassage(host.host_record_index, null)
                                            dataReverse
                                        } else {
                                            setReverseFlag(host.host_record_index, true)
                                            errMessage.value =
                                                "Send pending reverse not approve because $meaning"
                                            beeper.startBeep(500)
                                            JSONObject()
                                        }
                                    } else {
                                        setReverseFlag(host.host_record_index, true)
                                        errMessage.value = "Send pending reverse Failed"
                                        beeper.startBeep(500)
                                        return JSONObject()
                                    }
                                }
                                return JSONObject()
                            }
                        } else {
                            errMessage.value = "Write message Failed"
                            beeper.startBeep(500)
                            return JSONObject()
                        }
                    }
                    else {
                        errMessage.value = "Send reverse Failed"
                        beeper.startBeep(500)
                        return JSONObject()
                    }
                }
                else {
                    errMessage.value = "Connection Failed"
                    beeper.startBeep(500)
                    return JSONObject()
                }

            }
            catch (e: Exception) {
                errMessage.value = e.toString()
                beeper.startBeep(500)
                return JSONObject()
            }
        } else {
            errMessage.value = "Printer Error"
            beeper.startBeep(500)
            return JSONObject()
        }
    }
    else {
        errMessage.value = "Host or card data not found"
        beeper.startBeep(500)
        return JSONObject()
    }
}
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212

  • Function Reversal Transaction

Use to process reversal transaction consists of:
- Check connection
- Get reverse massage of host from database
- Send to host
- Check response
- Update reverse data in database

suspend fun sendReverse(
    host: ConfigHostRO, errMessage: MutableState<String>
): JSONObject {
    val socket = SocketCommunication(
        host.ip_address1!!, 
        host.port1!!, 
        10000
    )

    val checkStatus = withContext(Dispatchers.Default) { socket.run() }

    if (checkStatus) {
        val writeMessage =
            withContext(Dispatchers.Default) {
                socket.write(host.reversal_msg!!)
            }
        if (writeMessage) {
            val readStream = withContext(Dispatchers.Default) { socket.read() }
            if (readStream.size > 0) {
                delay(1500)

                withContext(Dispatchers.Default) {
                    Printer().printBitmap(
                        readStream,
                        "Response",
                        "${host.ip_address1!!}:${host.port1!!}"
                    )
                }
                val responeData = Utils().extractISO8583TOJSON(readStream)
                return responeData
            } else {
                errMessage.value = "Connection Timeout"
                return JSONObject()
            }
        } else {
            errMessage.value = "Write message Failed"
            return JSONObject()
        }
    } else {
        errMessage.value = "Connection failed"
        return JSONObject()
    }
}
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

  • Function Print Slip Transaction

Use to print slip transaction for today transaction page

fun printSlipTransaction(
    transaction: TransactionHistoryRO,
    context: Context,
    errMessage: MutableState<String>,
): Boolean{
    val printer: UPrinter = DeviceHelper.me().printer
    val beeper: UBeeper = DeviceHelper.me().beeper
    val jsonData = transactionToJson(transaction.txn_type, transaction)

    return if (jsonData.length() > 0) {
        if (printer.status == PrinterError.SUCCESS) {
            Printer().printSlip(jsonData, context, "merchant")
            true
        } else {
            errMessage.value = "Printer Error"
            beeper.startBeep(500)
            false
        }
    }
    else {
        errMessage.value = "Host or card data not found"
        beeper.startBeep(500)
        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 Check Allow Menu Entry Transaction

Use to check permission before make menu entry transaction of history transaction selected

fun checkAllowMenuEntryTransaction(transactionType: String, pervTransactionType: String): Boolean{
    return when (transactionType) {
        "void_sale" -> pervTransactionType == listOf("sale").find { txn -> pervTransactionType == txn }
        "void_refund" -> pervTransactionType == listOf("refund").find { txn -> pervTransactionType == txn }
        "sale_complete" -> pervTransactionType == listOf("pre_auth").find { txn -> pervTransactionType == txn }
        "offline_sale" -> pervTransactionType == listOf("offline_sale").find { txn -> pervTransactionType == txn }
        "tip_adjust" -> pervTransactionType == listOf("sale","ofline_sale").find { txn -> pervTransactionType == txn }
        else -> false
    }
}
1
2
3
4
5
6
7
8
9
10
Last Updated:
Contributors: Kittison Apaijit