Skip to content

Commit f0141a1

Browse files
committed
checkout limit improvements
1 parent 325922a commit f0141a1

File tree

8 files changed

+175
-26
lines changed

8 files changed

+175
-26
lines changed

CHANGELOG.md

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

4+
## [0.13.5]
5+
6+
### Added
7+
- Added new onCheckoutLimitReached and onOnlinePaymentLimitReached callbacks to ShoppingCartListener.
8+
9+
This is a minor breaking change if you use the verbose listener because of additional interface methods.
10+
11+
- Checkout has now an additional state: NO_PAYMENT_METHOD_AVAILABLE
12+
13+
### Changed
14+
- Added limit messages to shopping cart in addition to limit warnings in self scanning.
15+
- Added new message when no payment methods are available
16+
17+
### New string keys
18+
- Snabble.Payment.noMethodAvailable
19+
420
## [0.13.4]
521

622
### Fixed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ allprojects {
2323
}
2424

2525
project.ext {
26-
sdkVersion='0.13.4'
26+
sdkVersion='0.13.5'
2727
versionCode=1
2828

2929
compileSdkVersion=28

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

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ public enum State {
6363
* Invalid products detected. For example if a sale ∂stop was issued.
6464
*/
6565
INVALID_PRODUCTS,
66+
/**
67+
* No payment method available.
68+
*/
69+
NO_PAYMENT_METHOD_AVAILABLE,
6670
/**
6771
* No shop was selected.
6872
*/
@@ -229,7 +233,12 @@ public void invalidProducts(List<Product> products) {
229233
notifyStateChanged(State.INVALID_PRODUCTS);
230234
}
231235

232-
@Override
236+
@Override
237+
public void noAvailablePaymentMethod() {
238+
notifyStateChanged(State.NO_PAYMENT_METHOD_AVAILABLE);
239+
}
240+
241+
@Override
233242
public void error() {
234243
PaymentMethod fallback = getFallbackPaymentMethod();
235244
if(fallback != null) {
@@ -418,7 +427,12 @@ public void invalidProducts(List<Product> products) {
418427

419428
}
420429

421-
@Override
430+
@Override
431+
public void noAvailablePaymentMethod() {
432+
433+
}
434+
435+
@Override
422436
public void error() {
423437

424438
}

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

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ public interface CheckoutInfoResult {
156156
void success(SignedCheckoutInfo signedCheckoutInfo, int onlinePrice, PaymentMethod[] availablePaymentMethods);
157157
void noShop();
158158
void invalidProducts(List<Product> products);
159+
void noAvailablePaymentMethod();
159160
void error();
160161
}
161162

@@ -261,27 +262,38 @@ public void success(SignedCheckoutInfo signedCheckoutInfo) {
261262
@Override
262263
public void failure(JsonObject obj) {
263264
try {
264-
List<String> invalidSkus = new ArrayList<>();
265-
JsonArray arr = obj
266-
.get("error").getAsJsonObject()
267-
.get("details").getAsJsonArray();
268-
269-
for (int i=0; i<arr.size(); i++) {
270-
String sku = arr.get(0).getAsJsonObject().get("sku").getAsString();
271-
invalidSkus.add(sku);
265+
switch (obj.get("error").getAsJsonObject().get("type").getAsString()) {
266+
case "invalid_cart_item":
267+
List<String> invalidSkus = new ArrayList<>();
268+
JsonArray arr = obj
269+
.get("error").getAsJsonObject()
270+
.get("details").getAsJsonArray();
271+
272+
for (int i=0; i<arr.size(); i++) {
273+
String sku = arr.get(0).getAsJsonObject().get("sku").getAsString();
274+
invalidSkus.add(sku);
275+
}
276+
277+
List<Product> invalidProducts = new ArrayList<>();
278+
ShoppingCart cart = project.getShoppingCart();
279+
for (int i=0; i<cart.size(); i++) {
280+
Product product = cart.get(i).getProduct();
281+
if (invalidSkus.contains(product.getSku())) {
282+
invalidProducts.add(product);
283+
}
284+
}
285+
286+
Logger.e("Invalid products");
287+
checkoutInfoResult.invalidProducts(invalidProducts);
288+
break;
289+
case "no_available_method":
290+
checkoutInfoResult.noAvailablePaymentMethod();
291+
break;
292+
case "bad_shop_id":
293+
case "shop_not_found":
294+
checkoutInfoResult.noShop();
295+
break;
272296
}
273-
274-
List<Product> invalidProducts = new ArrayList<>();
275-
ShoppingCart cart = project.getShoppingCart();
276-
for (int i=0; i<cart.size(); i++) {
277-
Product product = cart.get(i).getProduct();
278-
if (invalidSkus.contains(product.getSku())) {
279-
invalidProducts.add(product);
280-
}
281-
}
282-
283-
Logger.e("Invalid products");
284-
checkoutInfoResult.invalidProducts(invalidProducts);
285297
} catch (Exception e) {
286298
error(e);
287299
}

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

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ public class ShoppingCart {
2727
private int modCount = 0;
2828
private int addCount = 0;
2929
private Integer onlineTotalPrice;
30+
31+
private boolean hasRaisedMaxCheckoutLimit;
32+
private boolean hasRaisedMaxOnlinePaymentLimit;
33+
3034
private transient List<ShoppingCartListener> listeners;
3135
private transient Handler handler;
3236
private transient Project project;
@@ -87,6 +91,7 @@ void insert(Item item, int index, boolean update) {
8791
items.remove(existing);
8892
items.add(index, item);
8993
modCount++;
94+
checkLimits();
9095
notifyQuantityChanged(this, item);
9196

9297
if (update) {
@@ -100,6 +105,7 @@ void insert(Item item, int index, boolean update) {
100105
addCount++;
101106
modCount++;
102107
items.add(index, item);
108+
checkLimits();
103109
notifyItemAdded(this, item);
104110

105111
if (update) {
@@ -146,7 +152,9 @@ public int indexOf(Item item) {
146152

147153
public void remove(int index) {
148154
modCount++;
149-
notifyItemRemoved(this, items.remove(index), index);
155+
Item item = items.remove(index);
156+
checkLimits();
157+
notifyItemRemoved(this, item, index);
150158
invalidateOnlinePrices();
151159
updatePrices(true);
152160
}
@@ -160,6 +168,7 @@ public void clear() {
160168
modCount = 0;
161169
addCount = 0;
162170
onlineTotalPrice = null;
171+
checkLimits();
163172
notifyCleared(this);
164173
}
165174

@@ -199,6 +208,7 @@ public void invalidateOnlinePrices() {
199208
}
200209
}
201210

211+
checkLimits();
202212
notifyPriceUpdate(this);
203213
}
204214

@@ -282,6 +292,27 @@ private void updateTimestamp() {
282292
lastModificationTime = System.currentTimeMillis();
283293
}
284294

295+
void checkLimits() {
296+
int totalPrice = getTotalPrice();
297+
if (totalPrice < project.getMaxCheckoutLimit()) {
298+
hasRaisedMaxCheckoutLimit = false;
299+
}
300+
301+
if (totalPrice < project.getMaxOnlinePaymentLimit()) {
302+
hasRaisedMaxOnlinePaymentLimit = false;
303+
}
304+
305+
if (!hasRaisedMaxCheckoutLimit && project.getMaxCheckoutLimit() > 0
306+
&& totalPrice >= project.getMaxCheckoutLimit()) {
307+
hasRaisedMaxCheckoutLimit = true;
308+
notifyCheckoutLimitReached(this);
309+
} else if (!hasRaisedMaxOnlinePaymentLimit && project.getMaxOnlinePaymentLimit() > 0
310+
&& totalPrice >= project.getMaxOnlinePaymentLimit()) {
311+
hasRaisedMaxOnlinePaymentLimit = true;
312+
notifyOnlinePaymentLimitReached(this);
313+
}
314+
}
315+
285316
public static class Item {
286317
private Product product;
287318
private ScannedCode scannedCode;
@@ -620,6 +651,10 @@ public interface ShoppingCartListener {
620651
void onProductsUpdated(ShoppingCart list);
621652

622653
void onPricesUpdated(ShoppingCart list);
654+
655+
void onCheckoutLimitReached(ShoppingCart list);
656+
657+
void onOnlinePaymentLimitReached(ShoppingCart list);
623658
}
624659

625660
public static abstract class SimpleShoppingCartListener implements ShoppingCartListener {
@@ -654,6 +689,16 @@ public void onItemRemoved(ShoppingCart list, Item item, int pos) {
654689
public void onPricesUpdated(ShoppingCart list) {
655690
onChanged(list);
656691
}
692+
693+
@Override
694+
public void onCheckoutLimitReached(ShoppingCart list) {
695+
696+
}
697+
698+
@Override
699+
public void onOnlinePaymentLimitReached(ShoppingCart list) {
700+
701+
}
657702
}
658703

659704
private void notifyItemAdded(final ShoppingCart list, final Item item) {
@@ -717,6 +762,27 @@ public void run() {
717762
});
718763
}
719764

765+
void notifyCheckoutLimitReached(final ShoppingCart list) {
766+
handler.post(new Runnable() {
767+
@Override
768+
public void run() {
769+
for (ShoppingCartListener listener : listeners) {
770+
listener.onCheckoutLimitReached(list);
771+
}
772+
}
773+
});
774+
}
775+
776+
void notifyOnlinePaymentLimitReached(final ShoppingCart list) {
777+
handler.post(new Runnable() {
778+
@Override
779+
public void run() {
780+
for (ShoppingCartListener listener : listeners) {
781+
listener.onOnlinePaymentLimitReached(list);
782+
}
783+
}
784+
});
785+
}
720786
/**
721787
* Notifies all {@link #listeners} that the shopping list was cleared of all entries.
722788
*

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ public void run() {
9898
return;
9999
}
100100

101+
cart.checkLimits();
101102
cart.notifyPriceUpdate(cart);
102103
}
103104
});
@@ -113,6 +114,11 @@ public void invalidProducts(List<Product> products) {
113114
cart.notifyPriceUpdate(cart);
114115
}
115116

117+
@Override
118+
public void noAvailablePaymentMethod() {
119+
cart.notifyPriceUpdate(cart);
120+
}
121+
116122
@Override
117123
public void error() {
118124
cart.notifyPriceUpdate(cart);

ui/src/main/java/io/snabble/sdk/ui/cart/ShoppingCartView.java

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,37 @@ public class ShoppingCartView extends FrameLayout implements Checkout.OnCheckout
7272

7373
private ShoppingCart.ShoppingCartListener shoppingCartListener = new ShoppingCart.SimpleShoppingCartListener() {
7474
@Override
75-
public void onChanged(ShoppingCart list) {
75+
public void onChanged(ShoppingCart cart) {
7676
swipeRefreshLayout.setRefreshing(false);
7777
submitList();
7878
update();
7979
}
80+
81+
@Override
82+
public void onCheckoutLimitReached(ShoppingCart list) {
83+
if (snackbar != null) {
84+
snackbar.dismiss();
85+
}
86+
87+
Project project = SnabbleUI.getProject();
88+
String message = getResources().getString(R.string.Snabble_limitsAlert_checkoutNotAvailable,
89+
project.getPriceFormatter().format(project.getMaxCheckoutLimit()));
90+
snackbar = UIUtils.snackbar(coordinatorLayout, message, UIUtils.SNACKBAR_LENGTH_VERY_LONG);
91+
snackbar.show();
92+
}
93+
94+
@Override
95+
public void onOnlinePaymentLimitReached(ShoppingCart list) {
96+
if (snackbar != null) {
97+
snackbar.dismiss();
98+
}
99+
100+
Project project = SnabbleUI.getProject();
101+
String message = getResources().getString(R.string.Snabble_limitsAlert_notAllMethodsAvailable,
102+
project.getPriceFormatter().format(project.getMaxOnlinePaymentLimit()));
103+
snackbar = UIUtils.snackbar(coordinatorLayout, message, UIUtils.SNACKBAR_LENGTH_VERY_LONG);
104+
snackbar.show();
105+
}
80106
};
81107

82108
public ShoppingCartView(Context context) {
@@ -273,10 +299,18 @@ public void onStateChanged(Checkout.State state) {
273299
}
274300

275301
progressDialog.dismiss();
276-
} else if (state == Checkout.State.CONNECTION_ERROR) {
302+
} else if (state == Checkout.State.CONNECTION_ERROR || state == Checkout.State.NO_SHOP) {
277303
UIUtils.snackbar(coordinatorLayout, R.string.Snabble_Payment_errorStarting, UIUtils.SNACKBAR_LENGTH_VERY_LONG)
278304
.show();
279305
progressDialog.dismiss();
306+
} else if (state == Checkout.State.NO_PAYMENT_METHOD_AVAILABLE) {
307+
new AlertDialog.Builder(getContext())
308+
.setCancelable(false)
309+
.setTitle(R.string.Snabble_saleStop_errorMsg_title)
310+
.setMessage(R.string.Snabble_Payment_noMethodAvailable)
311+
.setPositiveButton(R.string.Snabble_OK, null)
312+
.show();
313+
progressDialog.dismiss();
280314
} else if (state != Checkout.State.VERIFYING_PAYMENT_METHOD) {
281315
progressDialog.dismiss();
282316
}

ui/src/main/res/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
<string name="Snabble.PaymentSelection.title">Pay</string>
2323
<string name="Snabble.PaymentSelection.howToPay">How would you like to pay %s?</string>
2424
<string name="Snabble.PaymentSelection.payNow">Pay %s now</string>
25+
<string name="Snabble.Payment.noMethodAvailable">Unfortunately, this purchase can\'t be made using the app.</string>
2526
<string name="Snabble.QRCode.didPay">I\'ve paid</string>
2627
<string name="Snabble.QRCode.nextCode">Next Code</string>
2728
<string name="Snabble.QRCode.priceMayDiffer">Total price is calculated at the register and may differ from the one shown here.</string>

0 commit comments

Comments
 (0)