Skip to content

Commit 834e828

Browse files
committed
Added support for (broken) 0 amount ean codes
1 parent 7e57a18 commit 834e828

File tree

6 files changed

+109
-68
lines changed

6 files changed

+109
-68
lines changed

build.gradle

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

2626
project.ext {
27-
sdkVersion='0.8.17'
27+
sdkVersion='0.8.18'
2828
versionCode=1
2929

3030
compileSdkVersion=28

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ private static class ApiProduct {
4747
private static class ApiWeighing {
4848
private String[] weighedItemIds;
4949
private boolean weighByCustomer;
50+
private String encodingUnit;
5051
}
5152

5253
private Gson gson;
@@ -251,7 +252,11 @@ private Product toProduct(ApiProduct apiProduct, Product depositProduct) {
251252
if (apiProduct.weighing.weighByCustomer) {
252253
builder.setType(Product.Type.UserWeighed);
253254
} else {
254-
builder.setType(Product.Type.PreWeighed);
255+
if("piece".equals(apiProduct.weighing.encodingUnit)) {
256+
builder.setType(Product.Type.Article);
257+
} else {
258+
builder.setType(Product.Type.PreWeighed);
259+
}
255260
}
256261
} else {
257262
builder.setType(Product.Type.Article);

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

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ private static class Entry {
2727
private Integer price = null;
2828
private Integer amount = null;
2929

30+
// flag for products that have the quantity normally encoded in code
31+
// but can still be modified in the cart because the initial amount was set by the user
32+
// which happens when the amount of the original scanned code is 0
33+
private boolean isZeroAmountProduct = false;
34+
3035
private Entry(Product product, int quantity) {
3136
this.sku = product.getSku();
3237
this.product = product;
@@ -79,6 +84,10 @@ public void add(Product product, int quantity, ScannableCode scannedCode) {
7984
insert(product, items.size(), quantity, scannedCode);
8085
}
8186

87+
public void add(Product product, int quantity, ScannableCode scannedCode, boolean isZeroAmountProduct) {
88+
insert(product, items.size(), quantity, scannedCode, isZeroAmountProduct);
89+
}
90+
8291
public void insert(Product product, int index) {
8392
insert(product, index, 1);
8493
}
@@ -91,22 +100,27 @@ public void insert(Product product, int index, int quantity) {
91100
insert(product, index, quantity, null);
92101
}
93102

94-
public void insert(Product product, int index, int quantity, ScannableCode scannedCode) {
103+
public void insert(Product product, int index, int quantity, ScannableCode scannedCode, boolean isZeroAmountProduct) {
95104
Entry e = getEntryBySku(product.getSku());
96105

97-
if (e == null
106+
if (e == null || scannedCode.hasUnitData()
98107
|| product.getType() == Product.Type.UserWeighed
99108
|| product.getType() == Product.Type.PreWeighed) {
100109
if(quantity > 0) {
101110
Entry entry = new Entry(product, quantity);
102111
setScannedCodeForEntry(entry, scannedCode);
112+
entry.isZeroAmountProduct = isZeroAmountProduct;
103113
addEntry(entry, index);
104114
}
105115
} else {
106116
setEntryQuantity(e, e.quantity + quantity);
107117
}
108118
}
109119

120+
public void insert(Product product, int index, int quantity, ScannableCode scannedCode) {
121+
insert(product, index, quantity, scannedCode, false);
122+
}
123+
110124
public void setQuantity(int index, int quantity) {
111125
setQuantity(index, quantity, null);
112126
}
@@ -119,7 +133,7 @@ public void setQuantity(int index, int quantity, ScannableCode scannedCode) {
119133
setScannedCodeForEntry(e, scannedCode);
120134
}
121135

122-
setEntryQuantity(e, quantity);
136+
setEntryQuantity(e, quantity);
123137
}
124138
}
125139

@@ -174,6 +188,11 @@ public String getScannedCode(int index) {
174188
return entry.scannedCode;
175189
}
176190

191+
public boolean isZeroAmountProduct(int index) {
192+
Entry entry = getEntry(index);
193+
return entry != null && entry.isZeroAmountProduct;
194+
}
195+
177196
public Integer getEmbeddedWeight(int index) {
178197
Entry entry = getEntry(index);
179198
if (entry == null) {
@@ -298,6 +317,13 @@ private Entry getEntryBySku(final String sku) {
298317
}
299318
}
300319

320+
public void setScannedCode(int index, ScannableCode scannableCode) {
321+
Entry e = getEntry(index);
322+
if(e != null) {
323+
setScannedCodeForEntry(e, scannableCode);
324+
}
325+
}
326+
301327
private void setScannedCodeForEntry(Entry entry, ScannableCode scannedCode){
302328
entry.scannedCode = findCodeByScannedCode(entry.product, scannedCode);
303329

@@ -308,6 +334,8 @@ private void setScannedCodeForEntry(Entry entry, ScannableCode scannedCode){
308334
} else if(scannedCode.hasUnitData()){
309335
entry.amount = scannedCode.getEmbeddedData();
310336
}
337+
338+
notifyQuantityChanged(this, entry.product);
311339
}
312340

313341
// finds the code matching the code in the product if it was scanned with leading zeros

core/src/main/java/io/snabble/sdk/codes/EAN13.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,25 @@ public boolean isEmbeddedDataOk() {
123123
return check == digit;
124124
}
125125

126+
public static EAN13 generateNewCodeWithEmbeddedData(SnabbleSdk sdkInstance,
127+
String code,
128+
int newEmbeddedData) {
129+
StringBuilder stringBuilder = new StringBuilder();
130+
stringBuilder.append(code.substring(0, code.length() - 6));
131+
String dataStr = String.valueOf(newEmbeddedData);
132+
133+
int remaining = 5 - dataStr.length();
134+
for(int i=0; i<remaining; i++) {
135+
stringBuilder.append("0");
136+
}
137+
138+
stringBuilder.append(dataStr);
139+
stringBuilder.replace(6, 7, String.valueOf(EAN13.internalChecksum(stringBuilder.toString())));
140+
stringBuilder.append(String.valueOf(EAN13.checksum(stringBuilder.toString())));
141+
142+
return (EAN13)ScannableCode.parse(sdkInstance, stringBuilder.toString());
143+
}
144+
126145
/**
127146
* Calculates the checksum of an given ean string.
128147
* <p>

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

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import io.snabble.sdk.Product;
3838
import io.snabble.sdk.ShoppingCart;
3939
import io.snabble.sdk.SnabbleSdk;
40+
import io.snabble.sdk.codes.EAN13;
4041
import io.snabble.sdk.codes.ScannableCode;
4142
import io.snabble.sdk.ui.PriceFormatter;
4243
import io.snabble.sdk.ui.R;
@@ -415,15 +416,25 @@ public void bindTo(final int position) {
415416
switch (type) {
416417
case Article:
417418
if (embeddedAmount != null) {
418-
controlsDefault.setVisibility(View.GONE);
419+
if (cart.isZeroAmountProduct(position)) {
420+
controlsDefault.setVisibility(View.VISIBLE);
421+
} else {
422+
controlsDefault.setVisibility(View.GONE);
423+
}
424+
419425
controlsUserWeighed.setVisibility(View.GONE);
420426
} else {
421427
controlsDefault.setVisibility(View.VISIBLE);
422428
controlsUserWeighed.setVisibility(View.INVISIBLE);
423429
}
424430
break;
425431
case PreWeighed:
426-
controlsDefault.setVisibility(View.GONE);
432+
if (cart.isZeroAmountProduct(position)) {
433+
controlsDefault.setVisibility(View.VISIBLE);
434+
} else {
435+
controlsDefault.setVisibility(View.GONE);
436+
}
437+
427438
controlsUserWeighed.setVisibility(View.GONE);
428439
break;
429440
case UserWeighed:
@@ -435,18 +446,30 @@ public void bindTo(final int position) {
435446
plus.setOnClickListener(new OnClickListener() {
436447
@Override
437448
public void onClick(View v) {
438-
cart.setQuantity(getAdapterPosition(), quantity + 1);
449+
int p = getAdapterPosition();
450+
451+
if(cart.isZeroAmountProduct(p)){
452+
cart.setScannedCode(p,
453+
EAN13.generateNewCodeWithEmbeddedData(SnabbleUI.getSdkInstance(),
454+
cart.getScannedCode(p), embeddedAmount + 1));
455+
} else {
456+
cart.setQuantity(p, quantity + 1);
457+
}
458+
439459
recyclerViewAdapter.notifyItemChanged(getAdapterPosition());
440460
}
441461
});
442462

443463
minus.setOnClickListener(new OnClickListener() {
444464
@Override
445465
public void onClick(View v) {
466+
int p = getAdapterPosition();
467+
446468
String str = getResources().getString(
447469
R.string.Snabble_Shoppingcart_removeItem,
448470
product.getName());
449-
int q = quantity - 1;
471+
boolean isZeroAmountProduct = cart.isZeroAmountProduct(p);
472+
int q = isZeroAmountProduct ? embeddedAmount - 1 : quantity - 1;
450473
if (q <= 0) {
451474
new AlertDialog.Builder(getContext())
452475
.setMessage(str)
@@ -463,7 +486,14 @@ public void onClick(DialogInterface dialog, int which) {
463486
.create()
464487
.show();
465488
} else {
466-
cart.setQuantity(getAdapterPosition(), q);
489+
if(isZeroAmountProduct){
490+
cart.setScannedCode(p,
491+
EAN13.generateNewCodeWithEmbeddedData(SnabbleUI.getSdkInstance(),
492+
cart.getScannedCode(p), q));
493+
} else {
494+
cart.setQuantity(p, q);
495+
}
496+
467497
recyclerViewAdapter.notifyItemChanged(getAdapterPosition());
468498
}
469499
}

ui/src/main/java/io/snabble/sdk/ui/scanner/ProductConfirmationDialog.java

Lines changed: 17 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
import io.snabble.sdk.ui.SnabbleUI;
3434
import io.snabble.sdk.ui.telemetry.Telemetry;
3535
import io.snabble.sdk.ui.utils.InputFilterMinMax;
36-
import io.snabble.sdk.ui.utils.UIUtils;
3736

3837
class ProductConfirmationDialog {
3938
private Context context;
@@ -100,43 +99,15 @@ public void show(Product newProduct, ScannableCode scannedCode) {
10099
subtitle.setText(product.getSubtitle());
101100
}
102101

103-
Product.Type type = product.getType();
104-
if (type == Product.Type.UserWeighed || scannedCode.hasEmbeddedData()) {
105-
quantityAnnotation.setText("g");
106-
plus.setVisibility(View.GONE);
107-
minus.setVisibility(View.GONE);
108-
quantityAnnotation.setVisibility(View.VISIBLE);
109-
} else {
110-
quantityAnnotation.setVisibility(View.GONE);
111-
}
112-
113102
if (scannedCode.hasEmbeddedData() && scannedCode.getEmbeddedData() > 0) {
114103
quantity.setEnabled(false);
115104
}
116105

117106
price.setVisibility(View.VISIBLE);
118-
119-
if(scannedCode.hasWeighData()) {
120-
quantityAnnotation.setText("g");
121-
plus.setVisibility(View.GONE);
122-
minus.setVisibility(View.GONE);
123-
quantityAnnotation.setVisibility(View.VISIBLE);
124-
} else if(scannedCode.hasPriceData()){
125-
quantityAnnotation.setText(SnabbleUI.getSdkInstance().getCurrency().getSymbol());
126-
plus.setVisibility(View.GONE);
127-
minus.setVisibility(View.GONE);
128-
quantityAnnotation.setVisibility(View.GONE);
129-
price.setVisibility(View.GONE);
130-
} else if(scannedCode.hasUnitData()){
131-
quantityAnnotation.setVisibility(View.GONE);
132-
plus.setVisibility(View.GONE);
133-
minus.setVisibility(View.GONE);
134-
} else {
135-
quantityAnnotation.setVisibility(View.GONE);
136-
}
137-
138107
quantity.clearFocus();
139108

109+
Product.Type type = product.getType();
110+
140111
int cartQuantity = shoppingCart.getQuantity(product);
141112

142113
if (scannedCode.hasEmbeddedData()) {
@@ -174,7 +145,9 @@ public void show(Product newProduct, ScannableCode scannedCode) {
174145
} else if (type == Product.Type.UserWeighed) {
175146
quantityAnnotation.setVisibility(View.VISIBLE);
176147
quantityAnnotation.setText("g");
177-
quantity.setText(""); // initial value ?
148+
plus.setVisibility(View.GONE);
149+
minus.setVisibility(View.GONE);
150+
quantity.setText("");
178151
}
179152

180153
quantity.setFilters(new InputFilter[]{new InputFilterMinMax(1, ShoppingCart.MAX_QUANTITY)});
@@ -243,7 +216,7 @@ public void onClick(View v) {
243216
}
244217
});
245218

246-
if (cartQuantity > 0 && product.getType() == Product.Type.Article) {
219+
if (cartQuantity > 0 && product.getType() == Product.Type.Article && !scannedCode.hasUnitData()) {
247220
addToCart.setText(R.string.Snabble_Scanner_updateCart);
248221
} else {
249222
addToCart.setText(R.string.Snabble_Scanner_addToCart);
@@ -292,10 +265,11 @@ private void updatePrice() {
292265
String singlePrice = priceFormatter.format(product);
293266

294267
int q = getQuantity();
295-
if(q > 1){
296-
if(scannedCode.hasWeighData() || product.getType() == Product.Type.UserWeighed){
297-
price.setText(String.format("%sg * %s = %s", String.valueOf(q), singlePrice, priceText));
298-
} else if(scannedCode.hasUnitData()){
268+
269+
if(q > 0 && (scannedCode.hasWeighData() || product.getType() == Product.Type.UserWeighed)){
270+
price.setText(String.format("%sg * %s = %s", String.valueOf(q), singlePrice, priceText));
271+
} else if(q > 1){
272+
if(scannedCode.hasUnitData()){
299273
price.setText(String.format("%s * %s = %s",
300274
String.valueOf(q),
301275
priceFormatter.format(product.getPrice()),
@@ -334,17 +308,21 @@ private void addToCart() {
334308
int q = getQuantity();
335309

336310
if(scannedCode.hasEmbeddedData()){
311+
boolean isZeroAmountProduct = false;
312+
337313
// generate new code when the embedded data contains 0
338314
if (scannedCode.getEmbeddedData() == 0) {
339-
generateNewCodeWithEmbeddedData();
315+
scannedCode = EAN13.generateNewCodeWithEmbeddedData(SnabbleUI.getSdkInstance(),
316+
scannedCode.getCode(), getQuantity());
317+
isZeroAmountProduct = true;
340318
}
341319

342320
// if the user entered 0, shake
343321
if(scannedCode.getEmbeddedData() == 0) {
344322
shake();
345323
return;
346324
} else {
347-
shoppingCart.add(product, 1, scannedCode);
325+
shoppingCart.add(product, 1, scannedCode, isZeroAmountProduct);
348326
}
349327
} else if (product.getType() == Product.Type.Article) {
350328
shoppingCart.setQuantity(product, q, scannedCode);
@@ -368,25 +346,6 @@ private void shake() {
368346
quantity.startAnimation(shake);
369347
}
370348

371-
private void generateNewCodeWithEmbeddedData() {
372-
String code = scannedCode.getCode();
373-
374-
StringBuilder stringBuilder = new StringBuilder();
375-
stringBuilder.append(code.substring(0, code.length() - 6));
376-
String dataStr = String.valueOf(getQuantity());
377-
378-
int remaining = 5 - dataStr.length();
379-
for(int i=0; i<remaining; i++) {
380-
stringBuilder.append("0");
381-
}
382-
383-
stringBuilder.append(dataStr);
384-
stringBuilder.replace(6, 7, String.valueOf(EAN13.internalChecksum(stringBuilder.toString())));
385-
stringBuilder.append(String.valueOf(EAN13.checksum(stringBuilder.toString())));
386-
387-
scannedCode = ScannableCode.parse(SnabbleUI.getSdkInstance(), stringBuilder.toString());
388-
}
389-
390349
private int getQuantity() {
391350
try {
392351
return Integer.parseInt(quantity.getText().toString());

0 commit comments

Comments
 (0)