Skip to content

Commit 73d8ae7

Browse files
committed
add support for "activeShops", fix postfinance and twint not showing up on single shop projects, expose list instead of array for shops
1 parent f12df68 commit 73d8ae7

File tree

7 files changed

+142
-32
lines changed

7 files changed

+142
-32
lines changed

CHANGELOG.md

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

4+
## [0.40.0]
5+
6+
### Breaking Changes
7+
- Project.getShops now returns a List instead of an Array
8+
9+
### Added
10+
- Added support for "activeShops"
11+
12+
### Fixed
13+
- Fixed PostFinance and Twint not selectable when skipping over project specific payment methods
14+
415
## [0.39.13]
516

617
### Fixed

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

Lines changed: 60 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111

1212
import java.io.File;
1313
import java.lang.reflect.Type;
14-
import java.math.BigDecimal;
1514
import java.math.RoundingMode;
1615
import java.util.ArrayList;
16+
import java.util.Arrays;
1717
import java.util.Collections;
1818
import java.util.Currency;
1919
import java.util.HashMap;
@@ -22,9 +22,7 @@
2222
import java.util.Map;
2323
import java.util.Set;
2424
import java.util.concurrent.CopyOnWriteArrayList;
25-
import java.util.function.Consumer;
26-
import java.util.function.Predicate;
27-
import java.util.stream.Collectors;
25+
2826
import io.snabble.sdk.googlepay.GooglePayHelper;
2927
import io.snabble.sdk.auth.SnabbleAuthorizationInterceptor;
3028
import io.snabble.sdk.codes.templates.CodeTemplate;
@@ -33,15 +31,19 @@
3331
import io.snabble.sdk.utils.GsonHolder;
3432
import io.snabble.sdk.utils.JsonUtils;
3533
import io.snabble.sdk.utils.Logger;
34+
import io.snabble.sdk.utils.SimpleJsonCallback;
3635
import okhttp3.OkHttpClient;
36+
import okhttp3.Request;
37+
import okhttp3.Response;
38+
import okhttp3.ResponseBody;
3739

3840
public class Project {
3941
private Snabble snabble;
4042
private String id;
4143
private String name;
4244

4345
private ProductDatabase productDatabase;
44-
private Shop[] shops;
46+
private ArrayList<Shop> shops;
4547
private Brand brand;
4648
private Company company;
4749
private Checkout checkout;
@@ -90,14 +92,14 @@ public class Project {
9092
Project(JsonObject jsonObject) throws IllegalArgumentException {
9193
snabble = Snabble.getInstance();
9294

93-
parse(jsonObject);
94-
9595
internalStorageDirectory = new File(snabble.getInternalStorageDirectory(), id + "/");
9696
okHttpClient = Snabble.getInstance().getOkHttpClient()
9797
.newBuilder()
9898
.addInterceptor(new SnabbleAuthorizationInterceptor(this))
9999
.build();
100100

101+
parse(jsonObject);
102+
101103
boolean generateSearchIndex = snabble.getConfig().generateSearchIndex;
102104

103105
productDatabase = new ProductDatabase(this, id + ".sqlite3", generateSearchIndex);
@@ -220,13 +222,7 @@ void parse(JsonObject jsonObject) {
220222

221223
availablePaymentMethods = paymentMethodList.toArray(new PaymentMethod[paymentMethodList.size()]);
222224

223-
if (jsonObject.has("shops")) {
224-
shops = Shop.fromJson(jsonObject.get("shops"));
225-
}
226-
227-
if (shops == null) {
228-
shops = new Shop[0];
229-
}
225+
parseShops(jsonObject);
230226

231227
if (jsonObject.has("company")) {
232228
company = GsonHolder.get().fromJson(jsonObject.get("company"), Company.class);
@@ -324,6 +320,51 @@ void parse(JsonObject jsonObject) {
324320
notifyUpdate();
325321
}
326322

323+
private void parseShops(JsonObject jsonObject) {
324+
shops = new ArrayList<>();
325+
326+
if (jsonObject.has("shops")) {
327+
Shop[] jsonShops = Shop.fromJson(jsonObject.get("shops"));
328+
if (jsonShops != null) {
329+
shops.addAll(Arrays.asList(jsonShops));
330+
}
331+
}
332+
}
333+
334+
void loadActiveShops(Runnable done) {
335+
if (snabble.getConfig().loadActiveShops) {
336+
String url = getActiveShopsUrl();
337+
if (url != null) {
338+
Request request = new Request.Builder()
339+
.get()
340+
.url(getActiveShopsUrl())
341+
.build();
342+
343+
okHttpClient.newCall(request).enqueue(new SimpleJsonCallback<JsonObject>(JsonObject.class) {
344+
@Override
345+
public void success(JsonObject jsonObject) {
346+
if (jsonObject.has("shops")) {
347+
Shop[] hiddenShops = Shop.fromJson(jsonObject.get("shops"));
348+
if (hiddenShops != null) {
349+
shops.clear();
350+
shops.addAll(Arrays.asList(hiddenShops));
351+
352+
if (done != null) {
353+
done.run();
354+
}
355+
}
356+
}
357+
}
358+
359+
@Override
360+
public void error(Throwable t) {
361+
Logger.e("Failed to load hidden shops, statusCode: %d", responseCode());
362+
}
363+
});
364+
}
365+
}
366+
}
367+
327368
public File getInternalStorageDirectory() {
328369
return internalStorageDirectory;
329370
}
@@ -394,6 +435,9 @@ public String getDatatransTokenizationUrl() {
394435
return urls.get("datatransTokenization");
395436
}
396437

438+
public String getActiveShopsUrl() {
439+
return urls.get("activeShops");
440+
}
397441
public BarcodeFormat[] getSupportedBarcodeFormats() {
398442
return supportedBarcodeFormats;
399443
}
@@ -455,8 +499,8 @@ public Shop getCheckedInShop() {
455499
/**
456500
* @return The available shops. Empty if no shops are defined.
457501
*/
458-
public Shop[] getShops() {
459-
return shops;
502+
public List<Shop> getShops() {
503+
return Collections.unmodifiableList(shops);
460504
}
461505

462506
public Company getCompany() {

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

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import java.lang.reflect.Type;
1414
import java.util.Arrays;
1515
import java.util.Map;
16+
import java.util.Objects;
1617

1718
import io.snabble.sdk.utils.GsonHolder;
1819
import io.snabble.sdk.utils.Logger;
@@ -117,6 +118,7 @@ public String toString() {
117118
private String country;
118119
private String state;
119120
private String phone;
121+
private boolean isPreLaunch;
120122
private Map<String, Href> links;
121123
@SerializedName("lat")
122124
private double latitude;
@@ -182,6 +184,10 @@ public String getName() {
182184
return name;
183185
}
184186

187+
public boolean getIsPreLaunch() {
188+
return isPreLaunch;
189+
}
190+
185191
public CustomerNetwork[] getCustomerNetworks() {
186192
return customerNetworks;
187193
}
@@ -203,19 +209,37 @@ static Shop[] fromJson(JsonElement json) {
203209
}
204210
}
205211

206-
@Override
207-
public int hashCode() {
208-
return id.hashCode();
209-
}
210-
211212
@Override
212213
public boolean equals(Object o) {
213214
if (this == o) return true;
214215
if (o == null || getClass() != o.getClass()) return false;
215-
216216
Shop shop = (Shop) o;
217+
return isPreLaunch == shop.isPreLaunch &&
218+
Double.compare(shop.latitude, latitude) == 0 &&
219+
Double.compare(shop.longitude, longitude) == 0 &&
220+
Objects.equals(id, shop.id) &&
221+
Objects.equals(externalId, shop.externalId) &&
222+
Objects.equals(name, shop.name) &&
223+
Arrays.equals(services, shop.services) &&
224+
Objects.equals(street, shop.street) &&
225+
Objects.equals(zipCode, shop.zipCode) &&
226+
Objects.equals(city, shop.city) &&
227+
Objects.equals(country, shop.country) &&
228+
Objects.equals(state, shop.state) &&
229+
Objects.equals(phone, shop.phone) &&
230+
Objects.equals(links, shop.links) &&
231+
Arrays.equals(customerNetworks, shop.customerNetworks) &&
232+
Arrays.equals(openingHoursSpecification, shop.openingHoursSpecification) &&
233+
Objects.equals(external, shop.external);
234+
}
217235

218-
return id.equals(shop.id);
236+
@Override
237+
public int hashCode() {
238+
int result = Objects.hash(id, externalId, name, street, zipCode, city, country, state, phone, isPreLaunch, links, latitude, longitude, external);
239+
result = 31 * result + Arrays.hashCode(services);
240+
result = 31 * result + Arrays.hashCode(customerNetworks);
241+
result = 31 * result + Arrays.hashCode(openingHoursSpecification);
242+
return result;
219243
}
220244

221245
public String toShortString() {
@@ -238,6 +262,7 @@ public String toString() {
238262
", country='" + country + '\'' +
239263
", state='" + state + '\'' +
240264
", phone='" + phone + '\'' +
265+
", isPreLaunch=" + isPreLaunch +
241266
", links=" + links +
242267
", latitude=" + latitude +
243268
", longitude=" + longitude +

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

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,10 @@ public void setup(Application app, Config config, final SetupCompletionListener
135135
if (config.bundledMetadataAssetPath != null) {
136136
readMetadata();
137137
setupCompletionListener.onReady();
138+
139+
if (config.loadActiveShops) {
140+
loadActiveShops();
141+
}
138142
} else {
139143
metadataDownloader.loadAsync(new Downloader.Callback() {
140144
@Override
@@ -151,6 +155,10 @@ protected void onDataLoaded(boolean wasStillValid) {
151155
}
152156

153157
setupCompletionListener.onReady();
158+
159+
if (config.loadActiveShops) {
160+
loadActiveShops();
161+
}
154162
}
155163

156164
@Override
@@ -479,15 +487,30 @@ private void updateMetadata() {
479487
protected void onDataLoaded(boolean wasStillValid) {
480488
if (!wasStillValid) {
481489
readMetadata();
490+
notifyMetadataUpdated();
491+
}
482492

483-
for (OnMetadataUpdateListener listener : onMetaDataUpdateListeners) {
484-
listener.onMetaDataUpdated();
485-
}
493+
if (config.loadActiveShops) {
494+
loadActiveShops();
486495
}
487496
}
488497
});
489498
}
490499

500+
private void loadActiveShops() {
501+
for (Project project : projects) {
502+
project.loadActiveShops(() -> {
503+
notifyMetadataUpdated();
504+
});
505+
}
506+
}
507+
508+
private void notifyMetadataUpdated() {
509+
for (OnMetadataUpdateListener listener : onMetaDataUpdateListeners) {
510+
listener.onMetaDataUpdated();
511+
}
512+
}
513+
491514
private void checkCartTimeouts() {
492515
for (Project project : projects) {
493516
project.getShoppingCart().checkForTimeout();
@@ -753,5 +776,10 @@ public static class Config {
753776

754777
/** Vibrate while adding a product to the cart, by default false */
755778
public boolean vibrateToConfirmCartFilled = false;
779+
780+
/** Set to true, to load shops that are marked as pre launch
781+
* and are not part of the original metadata in the backend
782+
* (for example for testing shops in production before a go-live) **/
783+
public boolean loadActiveShops = false;
756784
}
757785
}

sample/src/main/java/io/snabble/testapp/App.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,8 @@ public void onReady() {
8383
SnabbleUI.useProject(project);
8484

8585
// select the first shop for demo purposes
86-
if (project.getShops().length > 0) {
87-
project.setCheckedInShop(project.getShops()[0]);
86+
if (project.getShops().size() > 0) {
87+
project.setCheckedInShop(project.getShops().get(0));
8888
}
8989

9090
// you can update the local database asynchronously, you can still query

sample/src/main/java/io/snabble/testapp/HomeFragment.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ public void onItemSelected(AdapterView<?> parent, View view, int position, long
9999

100100
updateShops(v);
101101

102-
if (project.getShops().length > 0) {
103-
project.setCheckedInShop(project.getShops()[0]);
102+
if (project.getShops().size() > 0) {
103+
project.setCheckedInShop(project.getShops().get(0));
104104
}
105105
}
106106

@@ -117,7 +117,7 @@ public void onNothingSelected(AdapterView<?> parent) {
117117

118118
private void updateShops(View v) {
119119
Project project = SnabbleUI.getProject();
120-
final List<Shop> shopList = Arrays.asList(project.getShops());
120+
final List<Shop> shopList = project.getShops();
121121
Spinner shops = v.findViewById(R.id.shops);
122122
shops.setAdapter(new ArrayAdapter<Shop>(requireContext(), R.layout.item_dropdown, shopList) {
123123
@NonNull

ui/src/main/java/io/snabble/sdk/ui/payment/PaymentOptionsView.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,9 @@ open class PaymentOptionsView @JvmOverloads constructor(
180180
args.putSerializable(SelectPaymentMethodFragment.ARG_PAYMENT_METHOD_LIST, ArrayList(listOf(
181181
PaymentMethod.VISA,
182182
PaymentMethod.MASTERCARD,
183-
PaymentMethod.AMEX))
183+
PaymentMethod.AMEX,
184+
PaymentMethod.POST_FINANCE_CARD,
185+
PaymentMethod.TWINT))
184186
)
185187
args.putString(SelectPaymentMethodFragment.ARG_PROJECT_ID, project.id)
186188
dialogFragment.arguments = args

0 commit comments

Comments
 (0)