commit f7d6e7f82308461bee4afc029400fa39cd1ecb4c
parent 7e5ed5c3027431ca83307b978b97ddef842d4a82
Author: Bohdan Potuzhnyi <bohdan.potuzhnyi@gmail.com>
Date: Sat, 17 Jan 2026 12:13:32 +0100
[merchant-terminal] fixing order with products can't be created
Diffstat:
5 files changed, 53 insertions(+), 7 deletions(-)
diff --git a/merchant-lib/src/main/java/net/taler/merchantlib/Orders.kt b/merchant-lib/src/main/java/net/taler/merchantlib/Orders.kt
@@ -29,8 +29,29 @@ data class PostOrderRequest(
val contractTerms: net.taler.common.Order,
@SerialName("refund_delay")
val refundDelay: RelativeTime? = null,
+ @SerialName("payment_target")
+ val paymentTarget: String? = null,
+ @SerialName("session_id")
+ val sessionId: String? = null,
+ @SerialName("inventory_products")
+ val inventoryProducts: List<MinimalInventoryProduct>? = null,
+ @SerialName("lock_uuids")
+ val lockUuids: List<String>? = null,
@SerialName("create_token")
val createToken: Boolean = true,
+ @SerialName("otp_id")
+ val otpId: String? = null,
+)
+
+@Serializable
+data class MinimalInventoryProduct(
+ @SerialName("product_id")
+ val productId: String,
+ val quantity: Int? = null,
+ @SerialName("unit_quantity")
+ val unitQuantity: String? = null,
+ @SerialName("product_money_pot")
+ val productMoneyPot: Int? = null,
)
@Serializable
diff --git a/merchant-lib/src/test/java/net/taler/merchantlib/MerchantApiTest.kt b/merchant-lib/src/test/java/net/taler/merchantlib/MerchantApiTest.kt
@@ -82,6 +82,7 @@ class MerchantApiTest {
"product_id": "${product.productId}",
"description": "${product.description}",
"price": "${product.price!!.toJSONString()}",
+ "prices_are_net": ${product.pricesAreNet},
"quantity": ${product.quantity}
}
]
diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/config/PosConfig.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/config/PosConfig.kt
@@ -95,6 +95,8 @@ data class ConfigProduct(
@SerialName("description_i18n")
override val descriptionI18n: Map<String, String>? = null,
override val price: Amount,
+ @SerialName("prices_are_net")
+ val pricesAreNet: Boolean = false,
@SerialName("delivery_location")
override val location: String? = null,
override val image: String? = null,
@@ -106,12 +108,14 @@ data class ConfigProduct(
fun toContractProduct() = ContractProduct(
productId = productId,
+ productName = productName ?: description,
description = description,
- descriptionI18n = descriptionI18n,
+ descriptionI18n = descriptionI18n?.takeIf { it.isNotEmpty() },
price = price,
- location = location,
- image = image,
- taxes = taxes,
+ pricesAreNet = pricesAreNet,
+ location = null,
+ image = image?.takeIf { it.isNotBlank() },
+ taxes = taxes?.takeIf { it.isNotEmpty() },
quantity = quantity
)
diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/payment/PaymentManager.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/payment/PaymentManager.kt
@@ -26,9 +26,12 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
+import kotlinx.serialization.encodeToString
+import kotlinx.serialization.json.Json
import net.taler.common.RelativeTime
import net.taler.common.assertUiThread
import net.taler.merchantlib.CheckPaymentResponse
+import net.taler.merchantlib.MinimalInventoryProduct
import net.taler.merchantlib.MerchantApi
import net.taler.merchantlib.PostOrderRequest
import net.taler.merchantpos.MainActivity.Companion.TAG
@@ -71,10 +74,24 @@ class PaymentManager(
fun createPayment(order: Order, includeProducts: Boolean = true) = scope.launch {
val merchantConfig = configManager.merchantConfig!!
mPayment.value = Payment(order, order.summary, configManager.currency!!)
+ val inventoryProducts = order.products.mapNotNull { product ->
+ val productId = product.productId ?: return@mapNotNull null
+ MinimalInventoryProduct(productId = productId, quantity = product.quantity)
+ }
+ val useInventoryProducts = inventoryProducts.isNotEmpty()
val request = PostOrderRequest(
- contractTerms = order.toContractTerms(includeProducts = includeProducts),
+ contractTerms = order.toContractTerms(
+ includeProducts = includeProducts && !useInventoryProducts
+ ),
refundDelay = RelativeTime.fromMillis(HOURS.toMillis(1))
+ ,
+ inventoryProducts = if (useInventoryProducts) inventoryProducts else null,
)
+ val requestJson = Json {
+ encodeDefaults = false
+ ignoreUnknownKeys = true
+ }.encodeToString(request)
+ Log.d(TAG, "PostOrderRequest: $requestJson")
api.postOrder(merchantConfig, request).handle(::onNetworkError) { orderResponse ->
assertUiThread()
mPayment.value = mPayment.value!!.copy(orderId = orderResponse.orderId)
diff --git a/taler-kotlin-android/src/main/java/net/taler/common/ContractTerms.kt b/taler-kotlin-android/src/main/java/net/taler/common/ContractTerms.kt
@@ -18,6 +18,7 @@ package net.taler.common
import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.ExperimentalSerializationApi
+import kotlinx.serialization.EncodeDefault
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonClassDiscriminator
@@ -198,6 +199,9 @@ data class ContractProduct(
@SerialName("description_i18n")
override val descriptionI18n: Map<String, String>? = null,
override val price: Amount? = null,
+ @SerialName("prices_are_net")
+ @EncodeDefault
+ val pricesAreNet: Boolean = false,
@SerialName("delivery_location")
override val location: String? = null,
override val image: String? = null,
@@ -296,4 +300,4 @@ object ContractTermsSerializer : JsonContentPolymorphicSerializer<ContractTerms>
else -> error("unknown contract version $type")
}
}
-}
-\ No newline at end of file
+}