Skip to content

Commit 44e655c

Browse files
committed
Merge branch 'main' into scanner_accessibility
2 parents 8168499 + cb72d4c commit 44e655c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1161
-1052
lines changed

CHANGELOG.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,28 @@
11
# Changelog
22
All notable changes to this project will be documented in this file.
33

4+
## [0.62.2]
5+
6+
### Fixed
7+
- Fixed first data 3DS authentication flow
8+
9+
## [0.62.1]
10+
11+
### Changes
12+
- 'width' and 'height' is now optional for coupon images
13+
14+
## [0.62.0]
15+
16+
### Breaking Changes
17+
- Renamed Project.customerCardInfos to Project.customerCardInfo
18+
19+
### Added
20+
- Added CheckoutPreconditionHandler to CheckoutBar
21+
22+
### Fixed
23+
- Fixed double backing out of point of sale checkout aborts
24+
- Fixed rare crash when approving offline payment methods
25+
426
## [0.61.3]
527

628
### Fixed

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,14 @@ allprojects {
3131
}
3232

3333
project.ext {
34-
sdkVersion='0.61.3'
34+
sdkVersion='0.62.2'
3535
versionCode=1
3636

3737
compileSdkVersion=31
3838
minSdkVersion=21
3939
targetSdkVersion=31
4040

41-
okhttpVersion='4.9.1'
41+
okhttpVersion='4.9.3'
4242
desugarVersion='1.1.5'
4343

4444
sdkVersion += project.getProperties().get('versionSuffix', '')

core/build.gradle

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@ android {
1212
targetSdkVersion project.targetSdkVersion
1313
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
1414
consumerProguardFiles 'proguard-rules.pro'
15-
16-
// since AGP 4.1.0 this field is missing - WTF?
17-
buildConfigField 'String', 'VERSION_NAME', '"' + versionName + '"'
15+
buildConfigField 'String', 'VERSION_NAME', '"' + project.sdkVersion + '"'
1816
}
1917

2018
buildTypes {
@@ -60,7 +58,6 @@ dependencies {
6058
implementation 'com.google.android.gms:play-services-wallet:19.1.0'
6159
implementation 'androidx.appcompat:appcompat:1.4.1'
6260
implementation 'androidx.biometric:biometric:1.2.0-alpha04'
63-
6461
api "com.squareup.okhttp3:okhttp:${project.okhttpVersion}"
6562
implementation "com.squareup.okhttp3:logging-interceptor:${project.okhttpVersion}"
6663

core/src/main/java/io/snabble/sdk/Checkout.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,10 @@ public enum State {
148148
private boolean authorizePaymentRequestFailed;
149149
private List<Coupon> redeemedCoupons;
150150

151-
Checkout(Project project) {
151+
Checkout(Project project, ShoppingCart shoppingCart) {
152152
this.project = project;
153-
this.shoppingCart = project.getShoppingCart();
154-
this.checkoutApi = new CheckoutApi(project);
153+
this.shoppingCart = shoppingCart;
154+
this.checkoutApi = new CheckoutApi(project, shoppingCart);
155155
this.checkoutRetryer = new CheckoutRetryer(project, getFallbackPaymentMethod());
156156
}
157157

@@ -710,7 +710,7 @@ private void approve() {
710710
if (state != Checkout.State.PAYMENT_APPROVED) {
711711
Logger.d("Payment approved");
712712

713-
if (paymentMethod.isOfflineMethod()) {
713+
if (paymentMethod != null && paymentMethod.isOfflineMethod()) {
714714
shoppingCart.backup();
715715
}
716716

core/src/main/java/io/snabble/sdk/CheckoutApi.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -361,11 +361,13 @@ public interface PaymentAbortResult {
361361
}
362362

363363
private final Project project;
364+
private final ShoppingCart shoppingCart;
364365
private final OkHttpClient okHttpClient;
365366
private Call call;
366367

367-
CheckoutApi(Project project) {
368+
CheckoutApi(Project project, ShoppingCart shoppingCart) {
368369
this.project = project;
370+
this.shoppingCart = shoppingCart;
369371
this.okHttpClient = project.getOkHttpClient();
370372
}
371373

@@ -448,7 +450,7 @@ public void success(SignedCheckoutInfo signedCheckoutInfo) {
448450
.get("price")
449451
.getAsInt();
450452
} else {
451-
price = project.getShoppingCart().getTotalPrice();
453+
price = shoppingCart.getTotalPrice();
452454
}
453455

454456
PaymentMethodInfo[] availablePaymentMethods = signedCheckoutInfo.getAvailablePaymentMethods(clientAcceptedPaymentMethods);
@@ -476,9 +478,8 @@ public void failure(JsonObject obj) {
476478
}
477479

478480
List<Product> invalidProducts = new ArrayList<>();
479-
ShoppingCart cart = project.getShoppingCart();
480-
for (int i=0; i<cart.size(); i++) {
481-
Product product = cart.get(i).getProduct();
481+
for (int i=0; i<shoppingCart.size(); i++) {
482+
Product product = shoppingCart.get(i).getProduct();
482483
if (product != null) {
483484
if (invalidSkus.contains(product.getSku())) {
484485
invalidProducts.add(product);

core/src/main/java/io/snabble/sdk/CheckoutRetryer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public void processPendingCheckouts() {
9494
removeSavedCart(savedCart);
9595
}
9696

97-
final CheckoutApi checkoutApi = new CheckoutApi(project);
97+
final CheckoutApi checkoutApi = new CheckoutApi(project, project.getShoppingCart());
9898
checkoutApi.createCheckoutInfo(savedCart.backendCart, null, new CheckoutApi.CheckoutInfoResult() {
9999
@Override
100100
public void success(CheckoutApi.SignedCheckoutInfo signedCheckoutInfo, int onlinePrice, CheckoutApi.PaymentMethodInfo[] availablePaymentMethods) {

core/src/main/java/io/snabble/sdk/Coupons.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ data class Coupon (
3131
) : Parcelable {
3232
val isValid: Boolean
3333
get() = when(type) {
34-
CouponType.DIGITAL -> image != null && validFrom != null && validUntil != null
34+
CouponType.DIGITAL -> image != null
3535
CouponType.MANUAL -> name != null
3636
CouponType.PRINTED -> true
3737
}
@@ -52,8 +52,8 @@ data class CouponImage (
5252
@Parcelize
5353
data class CouponImageFormats (
5454
val contentType: String,
55-
val width: Int,
56-
val height: Int,
55+
val width: Int?,
56+
val height: Int?,
5757
val size: String,
5858
val url: String,
5959
) : Parcelable

core/src/main/java/io/snabble/sdk/Events.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,17 @@
3333

3434
public class Events {
3535
private final Project project;
36+
private final ShoppingCart shoppingCart;
3637
private String cartId;
3738
private Shop shop;
3839

3940
private final Handler handler = new Handler(Looper.getMainLooper());
4041
private boolean hasSentSessionStart = false;
4142

4243
@SuppressLint("SimpleDateFormat")
43-
Events(Project project) {
44+
Events(Project project, ShoppingCart shoppingCart) {
4445
this.project = project;
46+
this.shoppingCart = shoppingCart;
4547

4648
project.getShoppingCart().addListener(new ShoppingCart.SimpleShoppingCartListener() {
4749
@Override
@@ -70,8 +72,7 @@ public void onChanged(ShoppingCart cart) {
7072

7173
public void updateShop(Shop newShop) {
7274
if (newShop != null) {
73-
ShoppingCart cart = project.getShoppingCart();
74-
cartId = cart.getId();
75+
cartId = shoppingCart.getId();
7576
shop = newShop;
7677
} else {
7778
shop = null;

core/src/main/java/io/snabble/sdk/PriceFormatter.java

Lines changed: 0 additions & 102 deletions
This file was deleted.
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package io.snabble.sdk
2+
3+
import android.util.LruCache
4+
import kotlin.jvm.JvmOverloads
5+
import io.snabble.sdk.codes.ScannedCode
6+
import java.math.BigDecimal
7+
import java.text.NumberFormat
8+
9+
/**
10+
* A price formatter for formatting prices using the provided currency information.
11+
*
12+
*/
13+
class PriceFormatter(private val project: Project) {
14+
private val numberFormat: NumberFormat = NumberFormat.getCurrencyInstance(project.currencyLocale)
15+
private val cache: LruCache<Int, String> = LruCache(100)
16+
17+
init {
18+
numberFormat.currency = project.currency
19+
val fractionDigits = project.currencyFractionDigits
20+
numberFormat.minimumFractionDigits = fractionDigits
21+
numberFormat.maximumFractionDigits = fractionDigits
22+
}
23+
24+
/**
25+
* Format a price.
26+
*/
27+
@JvmOverloads
28+
fun format(price: Int, allowZeroPrice: Boolean = true): String {
29+
if (price == 0 && !allowZeroPrice) {
30+
return ""
31+
}
32+
33+
val cachedValue = cache[price]
34+
if (cachedValue != null) {
35+
return cachedValue
36+
}
37+
38+
val fractionDigits = project.currencyFractionDigits
39+
val bigDecimal = BigDecimal(price)
40+
val divider = BigDecimal(10).pow(fractionDigits)
41+
val dividedPrice = bigDecimal.divide(divider, fractionDigits, project.roundingMode)
42+
val formattedPrice = numberFormat.format(dividedPrice)
43+
44+
// Android 4.x and 6 (but not 5 and 7+) are shipping with ICU versions
45+
// that have the currency symbol set to HUF instead of Ft for Locale hu_HU
46+
//
47+
// including the whole ICU library as a dependency increased APK size by 10MB
48+
// so we are overriding the result here instead for consistency
49+
if (project.currency.currencyCode == "HUF") {
50+
return formattedPrice.replace("HUF", "Ft")
51+
}
52+
53+
cache.put(price, formattedPrice)
54+
return formattedPrice
55+
}
56+
57+
/**
58+
* Format a price of a Product.
59+
*
60+
* Display's in units for example gram's if a Product is using conversion units.
61+
*/
62+
fun format(product: Product, price: Int): String {
63+
var formattedString = format(price, false)
64+
val type = product.type
65+
var referenceUnit = product.referenceUnit
66+
if (referenceUnit == null) {
67+
referenceUnit = Unit.KILOGRAM
68+
}
69+
if (type == Product.Type.UserWeighed || type == Product.Type.PreWeighed) {
70+
formattedString += " / " + referenceUnit.displayValue
71+
}
72+
return formattedString
73+
}
74+
75+
/**
76+
* Format a price of a Product or a ScannedCode if the ScannedCode is containing price information.
77+
*
78+
* Display's in units for example gram's if a Product is using conversion units.
79+
*/
80+
@JvmOverloads
81+
fun format(product: Product, discountedPrice: Boolean = true, scannedCode: ScannedCode? = null): String {
82+
var price = product.listPrice
83+
if (discountedPrice) {
84+
price = product.getPrice(project.customerCardId)
85+
}
86+
if (scannedCode != null && scannedCode.hasPrice()) {
87+
price = scannedCode.price
88+
}
89+
return format(product, price)
90+
}
91+
}

0 commit comments

Comments
 (0)