Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file.
### Added
* ui: Add UI for deposit return vouchers (APPS-1643)
* core: Handle invalid items (APPS-2039)
* ui/core: Integrate new states for deposit return vouchers into the checkout process and handle them
### Changed
### Removed
* ui/core: Remove everything related to the old deposit return voucher feature
Expand Down
9 changes: 9 additions & 0 deletions core/src/main/java/io/snabble/sdk/checkout/Checkout.kt
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,15 @@ class Checkout @JvmOverloads constructor(
notifyStateChanged(CheckoutState.PAYMENT_ABORTED)
return
}
val hasAnyFailedDrvRedemptions =
checkoutProcess?.depositReturnVouchers
?.any { it.state == DepositReturnVoucherState.REDEEMING_FAILED }
?: false

if (hasAnyFailedDrvRedemptions) {
notifyStateChanged(CheckoutState.DEPOSIT_RETURN_REDEMPTION_FAILED)
return
}

Logger.d("Polling for approval state...")
Logger.d("RoutingTarget = $routingTarget")
Expand Down
26 changes: 26 additions & 0 deletions core/src/main/java/io/snabble/sdk/checkout/CheckoutApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -335,11 +335,37 @@ data class Fulfillment(
get() = links?.get("self")?.href
}

data class DepositReturnVoucher(
@SerializedName("refersTo")
val refersTo: String,
@SerializedName("state")
val state: DepositReturnVoucherState
)

enum class DepositReturnVoucherState {
@SerializedName("pending")
PENDING,

@SerializedName("redeemed")
REDEEMED,

@SerializedName("redeemingFailed")
REDEEMING_FAILED,

@SerializedName("rolledback")
ROLLED_BACK,

@SerializedName("rollbackFailed")
ROLLBACK_FAILED
}

data class CheckoutProcessResponse(
val links: Map<String, Href>? = null,
val checks: List<Check> = emptyList(),
@SerializedName("orderID")
val orderId: String? = null,
@SerializedName("depositReturnVouchers")
val depositReturnVouchers: List<DepositReturnVoucher>? = null,
val aborted: Boolean = false,
val paymentMethod: PaymentMethod? = null,
val paymentInformation: PaymentInformation? = null,
Expand Down
5 changes: 5 additions & 0 deletions core/src/main/java/io/snabble/sdk/checkout/CheckoutState.kt
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,9 @@ enum class CheckoutState {
* will not be communicated
*/
PAYMENT_TRANSFERRED,

/**
* One of the deposit return vouchers added couldn't be redeemed
*/
DEPOSIT_RETURN_REDEMPTION_FAILED
}
10 changes: 10 additions & 0 deletions core/src/main/java/io/snabble/sdk/shoppingcart/ShoppingCart.kt
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,16 @@ class ShoppingCart(
notifyItemRemoved(this, removedItem, index)
}

/**
* Removes a cart item from the cart by its id
*/
fun removeItem(itemId: String) {
val index = indexOf(firstOrNull { it?.id == itemId })
if (index != -1) {
remove(index)
}
}

/**
* The number items in the cart.
*
Expand Down
34 changes: 34 additions & 0 deletions ui/src/main/java/io/snabble/sdk/ui/cart/CheckoutBar.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import io.snabble.sdk.Snabble
import io.snabble.sdk.Snabble.instance
import io.snabble.sdk.checkout.Checkout
import io.snabble.sdk.checkout.CheckoutState
import io.snabble.sdk.checkout.DepositReturnVoucherState
import io.snabble.sdk.config.ExternalBillingSubjectLength
import io.snabble.sdk.config.ProjectId
import io.snabble.sdk.extensions.getApplicationInfoCompat
Expand Down Expand Up @@ -449,6 +450,11 @@ open class CheckoutBar @JvmOverloads constructor(
}
}

CheckoutState.DEPOSIT_RETURN_REDEMPTION_FAILED -> {
progressDialog.dismiss()
handleFailedDepositReturns()
}

CheckoutState.PAYMENT_ABORTED -> {
progressDialog.dismiss()
}
Expand Down Expand Up @@ -498,6 +504,34 @@ open class CheckoutBar @JvmOverloads constructor(
}
}

private fun handleFailedDepositReturns() {
val failedDepositReturnVouchers =
project.checkout.checkoutProcess?.depositReturnVouchers
?.filter { it.state == DepositReturnVoucherState.REDEEMING_FAILED }
?: return

val message = failedDepositReturnVouchers
.mapNotNull { cart.getByItemId(it.refersTo)?.displayName }
.joinToString(separator = "/n") { it }

AlertDialog.Builder(context)
.setCancelable(false)
.setTitle(context.getString(R.string.Snabble_ShoppingCart_DepositVoucher_RedemptionFailed_title))
.setMessage(
resources.getQuantityString(
R.plurals.Snabble_ShoppingCart_DepositVoucher_RedemptionFailed_message,
failedDepositReturnVouchers.size,
message
)
)
.setPositiveButton(R.string.Snabble_ShoppingCart_DepositVoucher_RedemptionFailed_button) { _, _ ->
failedDepositReturnVouchers
.map { it.refersTo }
.forEach(cart::removeItem)
}
.show()
}

private fun getMaxSubjectLength(): Int? = Snabble.checkedInProject.value
?.id
?.let { id ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ class CheckoutActivity : FragmentActivity() {
}
}

CheckoutState.DEPOSIT_RETURN_REDEMPTION_FAILED,
CheckoutState.PAYMENT_ABORTED -> {
finish()
null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,6 @@ val CheckoutState.isCheckoutState: Boolean
CheckoutState.PAYMENT_ABORT_FAILED,
CheckoutState.PAYMENT_PROCESSING_ERROR,
CheckoutState.PAYMENT_TRANSFERRED,
CheckoutState.DEPOSIT_RETURN_REDEMPTION_FAILED,
CheckoutState.PAYONE_SEPA_MANDATE_REQUIRED -> true
}
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,11 @@ class PaymentStatusView @JvmOverloads constructor(
handlePaymentAborted()
}

CheckoutState.DEPOSIT_RETURN_REDEMPTION_FAILED -> {
Telemetry.event(Telemetry.Event.CheckoutDepositReturnRedemptionFailed)
handlePaymentAborted()
}

CheckoutState.PAYMENT_ABORTED -> {
Telemetry.event(Telemetry.Event.CheckoutAbortByUser)
handlePaymentAborted()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public enum Event {
ClickCheckout,
SelectedPaymentMethod,
CheckoutSuccessful,
CheckoutDepositReturnRedemptionFailed,
CheckoutDeniedByTooYoung,
CheckoutDeniedBySupervisor,
CheckoutDeniedByPaymentProvider,
Expand Down
7 changes: 7 additions & 0 deletions ui/src/main/res/values-de/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@
<string name="Snabble.Shop.List.Expand.accessibility">aufklappen</string>
<string name="Snabble.Shop.List.ShowDetails.accessibility">Shop-Details anzeigen</string>
<string name="Snabble.Shopping.title">Einkaufen</string>
<string name="Snabble.ShoppingCart.DepositVoucher.RedemptionFailed.title">Ungültiger Leergutbon</string>
<string name="Snabble.ShoppingCart.DepositReturn.message">Damit der Leergutbon eingelöst werden kann, fülle deinen Warenkorb mit deinen Wunschprodukten.</string>
<string name="Snabble.ShoppingCart.DepositReturn.title">Leergutbon</string>
<string name="Snabble.ShoppingCart.Product.Invalid.button">Entfernen</string>
Expand Down Expand Up @@ -465,4 +466,10 @@
<string name="Snabble.save">Speichern</string>
<string name="Snabble.undo">Rückgängig</string>
<string name="Snabble.yes">Ja</string>
<string name="Snabble.ShoppingCart.DepositVoucher.RedemptionFailed.button">Entfernen</string>
<plurals name="Snabble.ShoppingCart.DepositVoucher.RedemptionFailed.message">
<item quantity="zero"></item>
<item quantity="one">Dieser Leergutbon kann derzeit leider nicht in der App eingelöst werden: \n\n%s\n\nBitte versuche es an der Kassen.</item>
<item quantity="other">Diese Leergutbon\'s können derzeit leider nicht in der App eingelöst werden: \n\n%s\n\nBitte versuche es an der Kassen.</item>
</plurals>
</resources>
9 changes: 8 additions & 1 deletion ui/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@
<string name="Snabble.Shopping.title">Shopping</string>
<string name="Snabble.ShoppingCart.DepositReturn.message">To redeem your voucher, fill your shopping basket with the products you wish to purchase.</string>
<string name="Snabble.ShoppingCart.DepositReturn.title">Deposit voucher</string>
<string name="Snabble.ShoppingCart.DepositVoucher.RedemptionFailed.title">Invalid deposit voucher</string>
<string name="Snabble.ShoppingCart.Product.Invalid.button">Remove</string>
<plurals name="Snabble.ShoppingCart.Product.Invalid.message">
<item quantity="zero"></item>
Expand Down Expand Up @@ -407,7 +408,7 @@
<string name="Snabble.Shoppingcart.Accessibility.quantity">Quantity</string>
<string name="Snabble.Shoppingcart.Accessibility.selected">Selected</string>
<string name="Snabble.Shoppingcart.BuyProducts.now">Pay now</string>
<string name="Snabble.Shoppingcart.BuyProducts.one">Buy %1$d product for %2$s</string>
<string name="Snabble.Shoppingcart.BuyProducts.one">Buy %1$d product for %2$s</string>1
<string name="Snabble.Shoppingcart.BuyProducts.selectPaymentMethod">Select payment method</string>
<string name="Snabble.Shoppingcart.EmptyState.buttonTitle">Scan now</string>
<string name="Snabble.Shoppingcart.EmptyState.description">Visit a store that supports Snabble and scan the barcodes of products you wish to purchase.</string>
Expand Down Expand Up @@ -465,4 +466,10 @@
<string name="Snabble.save">Save</string>
<string name="Snabble.undo">Undo</string>
<string name="Snabble.yes">Yes</string>
<string name="Snabble.ShoppingCart.DepositVoucher.RedemptionFailed.button">Remove</string>
<plurals name="Snabble.ShoppingCart.DepositVoucher.RedemptionFailed.message">
<item quantity="zero"></item>
<item quantity="one">Unfortunately, this deposit voucher cannot currently be redeemed in the app: \n\n%s\n\nPlease try for it at the cash desk.</item>
<item quantity="other">Unfortunately, these deposit vouchers cannot currently be redeemed in the app: \n\n%s\n\nPlease try for it at the cash desk.</item>
</plurals>
</resources>
Loading