Skip to content

Commit 8b1ae11

Browse files
committed
Add support for bundles when using online requests
1 parent 2869e69 commit 8b1ae11

File tree

4 files changed

+201
-68
lines changed

4 files changed

+201
-68
lines changed

build.gradle

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

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

3030
compileSdkVersion=28
@@ -39,8 +39,6 @@ allprojects {
3939
}
4040
}
4141

42-
43-
4442
task clean(type: Delete) {
4543
delete rootProject.buildDir
4644
}

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

Lines changed: 193 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import android.os.Handler;
44
import android.os.Looper;
5+
56
import com.google.gson.Gson;
67
import com.google.gson.GsonBuilder;
78
import com.google.gson.JsonParseException;
@@ -12,6 +13,7 @@
1213
import java.io.IOException;
1314
import java.io.InputStream;
1415
import java.nio.charset.Charset;
16+
import java.util.concurrent.CountDownLatch;
1517

1618
import io.snabble.sdk.utils.Logger;
1719
import okhttp3.Call;
@@ -50,6 +52,18 @@ private static class ApiWeighing {
5052
private String encodingUnit;
5153
}
5254

55+
private static class ApiProductGroup {
56+
private ApiProduct[] products;
57+
}
58+
59+
private interface ApiProductGroupCallback {
60+
void onProductsAvailable(Product[] products);
61+
62+
void onProductsNotFound();
63+
64+
void onError();
65+
}
66+
5367
private Gson gson;
5468
private SnabbleSdk sdkInstance;
5569
private OkHttpClient okHttpClient;
@@ -128,6 +142,117 @@ public void findByWeighItemId(String weighItemId, final OnProductAvailableListen
128142
get(url, productAvailableListener);
129143
}
130144

145+
private void getBundlesOfProduct(final String sku, final ApiProductGroupCallback callback) {
146+
String url = sdkInstance.getBundlesOfProductUrl();
147+
if (url == null) {
148+
Logger.e("Could not check product bundles online, no bundlesOfProduct url provided in metadata");
149+
150+
// return not found, so that normal product requests still work even when not bundle url is provided
151+
callback.onProductsNotFound();
152+
return;
153+
}
154+
155+
if (sku == null) {
156+
callback.onProductsNotFound();
157+
return;
158+
}
159+
160+
url = url.replace("{bundledSku}", sku);
161+
162+
final Request request = new Request.Builder()
163+
.url(sdkInstance.absoluteUrl(url))
164+
.get()
165+
.build();
166+
167+
okHttpClient.newCall(request).enqueue(new Callback() {
168+
@Override
169+
public void onResponse(Call call, Response response) throws IOException {
170+
if (response.isSuccessful()) {
171+
ResponseBody body = response.body();
172+
if (body == null) {
173+
callback.onError();
174+
return;
175+
}
176+
177+
InputStream inputStream = body.byteStream();
178+
String json = IOUtils.toString(inputStream, Charset.forName("UTF-8"));
179+
inputStream.close();
180+
181+
try {
182+
final ApiProductGroup apiProductGroup = gson.fromJson(json, ApiProductGroup.class);
183+
if (apiProductGroup != null && apiProductGroup.products != null) {
184+
final Product[] products = new Product[apiProductGroup.products.length];
185+
final CountDownLatch countDownLatch = new CountDownLatch(apiProductGroup.products.length);
186+
final boolean[] error = new boolean[1];
187+
188+
for (int i = 0; i < apiProductGroup.products.length; i++) {
189+
final int index = i;
190+
final ApiProduct apiProduct = apiProductGroup.products[i];
191+
192+
getDepositProduct(apiProduct, new OnProductAvailableListener() {
193+
@Override
194+
public void onProductAvailable(Product product, boolean wasOnlineProduct) {
195+
countDownLatch.countDown();
196+
products[index] = toProduct(apiProduct, product, null);
197+
}
198+
199+
@Override
200+
public void onProductNotFound() {
201+
countDownLatch.countDown();
202+
error[1] = true;
203+
}
204+
205+
@Override
206+
public void onError() {
207+
countDownLatch.countDown();
208+
error[1] = true;
209+
}
210+
});
211+
}
212+
213+
countDownLatch.await();
214+
215+
if (error[0]) {
216+
callback.onError();
217+
} else {
218+
callback.onProductsAvailable(products);
219+
}
220+
} else {
221+
if (apiProductGroup != null) {
222+
callback.onProductsNotFound();
223+
} else {
224+
callback.onError();
225+
}
226+
}
227+
} catch (JsonParseException e) {
228+
callback.onError();
229+
} catch (InterruptedException e) {
230+
callback.onError();
231+
}
232+
} else {
233+
if (response.code() == 404) {
234+
callback.onProductsNotFound();
235+
} else {
236+
callback.onError();
237+
}
238+
}
239+
}
240+
241+
@Override
242+
public void onFailure(Call call, IOException e) {
243+
callback.onError();
244+
}
245+
});
246+
}
247+
248+
private void getDepositProduct(final ApiProduct apiProduct, final OnProductAvailableListener productAvailableListener) {
249+
if (apiProduct.depositProduct != null && !apiProduct.depositProduct.equals("")) {
250+
findBySku(apiProduct.depositProduct, productAvailableListener);
251+
} else {
252+
productAvailableListener.onProductAvailable(null, true);
253+
}
254+
}
255+
131256
private void get(final String url, final OnProductAvailableListener productAvailableListener) {
132257
final Request request = new Request.Builder()
133258
.url(sdkInstance.absoluteUrl(url))
@@ -155,88 +280,94 @@ public void run() {
155280

156281
try {
157282
final ApiProduct apiProduct = gson.fromJson(json, ApiProduct.class);
158-
if (apiProduct.depositProduct != null && !apiProduct.depositProduct.equals("")) {
159-
findBySku(apiProduct.depositProduct, new OnProductAvailableListener() {
160-
@Override
161-
public void onProductAvailable(final Product product, boolean wasOnlineProduct) {
162-
handler.post(new Runnable() {
163-
@Override
164-
public void run() {
165-
productAvailableListener.onProductAvailable(toProduct(apiProduct, product), true);
166-
}
167-
});
168-
}
169-
170-
@Override
171-
public void onProductNotFound() {
172-
handler.post(new Runnable() {
173-
@Override
174-
public void run() {
175-
productAvailableListener.onProductNotFound();
176-
}
177-
});
178-
}
179-
180-
@Override
181-
public void onError() {
182-
handler.post(new Runnable() {
183-
@Override
184-
public void run() {
185-
productAvailableListener.onError();
186-
}
187-
});
188-
}
189-
});
190-
} else {
191-
handler.post(new Runnable() {
192-
@Override
193-
public void run() {
194-
productAvailableListener.onProductAvailable(toProduct(apiProduct, null), true);
195-
}
196-
});
197-
}
198-
} catch (JsonParseException e) {
199-
handler.post(new Runnable() {
283+
getDepositProduct(apiProduct, new OnProductAvailableListener() {
200284
@Override
201-
public void run() {
202-
productAvailableListener.onError();
285+
public void onProductAvailable(final Product product, boolean wasOnlineProduct) {
286+
getBundlesOfProduct(apiProduct.sku, new ApiProductGroupCallback() {
287+
@Override
288+
public void onProductsAvailable(final Product[] products) {
289+
Product p = toProduct(apiProduct, product, products);
290+
success(productAvailableListener, p);
291+
}
292+
293+
@Override
294+
public void onProductsNotFound() {
295+
Product p = toProduct(apiProduct, product, null);
296+
success(productAvailableListener, p);
297+
}
298+
299+
@Override
300+
public void onError() {
301+
error(productAvailableListener);
302+
}
303+
});
304+
}
305+
306+
@Override
307+
public void onProductNotFound() {
308+
notFound(productAvailableListener);
309+
}
310+
311+
@Override
312+
public void onError() {
313+
error(productAvailableListener);
203314
}
204315
});
316+
} catch (JsonParseException e) {
317+
error(productAvailableListener);
205318
}
206319
} else {
207-
handler.post(new Runnable() {
208-
@Override
209-
public void run() {
210-
if (response.code() == 404) {
211-
productAvailableListener.onProductNotFound();
212-
} else {
213-
productAvailableListener.onError();
214-
}
215-
}
216-
});
320+
if (response.code() == 404) {
321+
notFound(productAvailableListener);
322+
} else {
323+
error(productAvailableListener);
324+
}
217325
}
218326
}
219327

220328
@Override
221329
public void onFailure(Call call, IOException e) {
222-
handler.post(new Runnable() {
223-
@Override
224-
public void run() {
225-
productAvailableListener.onError();
226-
}
227-
});
330+
error(productAvailableListener);
331+
}
332+
});
333+
}
334+
335+
private void success(final OnProductAvailableListener onProductAvailableListener, final Product product) {
336+
handler.post(new Runnable() {
337+
@Override
338+
public void run() {
339+
onProductAvailableListener.onProductAvailable(product, true);
340+
}
341+
});
342+
}
343+
344+
private void notFound(final OnProductAvailableListener onProductAvailableListener) {
345+
handler.post(new Runnable() {
346+
@Override
347+
public void run() {
348+
onProductAvailableListener.onProductNotFound();
349+
}
350+
});
351+
}
352+
353+
private void error(final OnProductAvailableListener onProductAvailableListener) {
354+
handler.post(new Runnable() {
355+
@Override
356+
public void run() {
357+
onProductAvailableListener.onError();
228358
}
229359
});
230360
}
231361

232-
private Product toProduct(ApiProduct apiProduct, Product depositProduct) {
362+
private Product toProduct(ApiProduct apiProduct, Product depositProduct, Product[] bundleProducts) {
233363
Product.Builder builder = new Product.Builder()
234364
.setSku(apiProduct.sku)
235365
.setName(apiProduct.name)
236366
.setDescription(apiProduct.description)
237367
.setSubtitle(apiProduct.subtitle)
238368
.setBoost(apiProduct.boost)
239369
.setDepositProduct(depositProduct)
370+
.setBundleProducts(bundleProducts)
240371
.setIsDeposit("deposit".equals(apiProduct.productType))
241372
.setImageUrl(apiProduct.imageUrl)
242373
.setScannableCodes(apiProduct.eans)
@@ -252,7 +383,7 @@ private Product toProduct(ApiProduct apiProduct, Product depositProduct) {
252383
if (apiProduct.weighing.weighByCustomer) {
253384
builder.setType(Product.Type.UserWeighed);
254385
} else {
255-
if("piece".equals(apiProduct.weighing.encodingUnit)) {
386+
if ("piece".equals(apiProduct.weighing.encodingUnit)) {
256387
builder.setType(Product.Type.Article);
257388
} else {
258389
builder.setType(Product.Type.PreWeighed);

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,10 @@ String getProductByCodeUrl() {
520520
return metadataDownloader.getUrls().get("productByCode");
521521
}
522522

523+
String getBundlesOfProductUrl() {
524+
return metadataDownloader.getUrls().get("bundlesForSku");
525+
}
526+
523527
String getProductByWeighItemIdUrl() {
524528
return metadataDownloader.getUrls().get("productByWeighItemId");
525529
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -665,11 +665,11 @@ public void run() {
665665
mainThreadHandler.post(new Runnable() {
666666
@Override
667667
public void run() {
668-
if (decodeEnabled && callback != null && isAttachedToWindow) {
668+
if (decodeEnabled && callback != null && isAttachedToWindow && !isPaused) {
669669
Barcode barcode = new Barcode(
670670
BarcodeFormat.valueOf(finalResult.getBarcodeFormat()),
671-
finalResult.getText(),
672-
finalResult.getTimestamp());
671+
finalResult.getText(),
672+
finalResult.getTimestamp());
673673

674674
Logger.d("Detected barcode: " + barcode.toString());
675675
callback.onBarcodeDetected(barcode);

0 commit comments

Comments
 (0)