@pensasystems/pensa-react-native 0.1.0-beta.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/PensaSdkReactNative.podspec +1 -1
- package/README.md +99 -5
- package/android/build.gradle +1 -1
- package/android/src/main/java/com/pensasdkreactnative/PensaSdkReactNativeModule.kt +211 -9
- package/ios/PensaSdkReactNative-Bridging-Header.h +4 -0
- package/ios/PensaSdkReactNative.mm +19 -0
- package/ios/PensaSdkReactNative.swift +169 -0
- package/lib/module/index.js +15 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/types.js +16 -0
- package/lib/module/types.js.map +1 -1
- package/lib/typescript/src/index.d.ts +7 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +69 -0
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/package.json +1 -2
- package/src/index.tsx +40 -0
- package/src/types.ts +76 -0
package/README.md
CHANGED
|
@@ -7,17 +7,18 @@ The Pensa Mobile App SDK is a developer toolkit designed to simplify adding Pens
|
|
|
7
7
|
Integrating the Pensa SDK into your React Native project is simple. Follow the steps below to add the SDK and enable advanced shelf recognition features in your app:
|
|
8
8
|
|
|
9
9
|
### 1- Install the SDK Package
|
|
10
|
+
Registry: https://www.npmjs.com/package/@pensasystems/pensa-react-native
|
|
10
11
|
|
|
11
12
|
Add the npm package to your project:
|
|
12
13
|
|
|
13
14
|
```bash
|
|
14
|
-
npm install pensa-
|
|
15
|
+
npm install @pensasystems/pensa-react-native
|
|
15
16
|
```
|
|
16
17
|
|
|
17
18
|
or
|
|
18
19
|
|
|
19
20
|
```bash
|
|
20
|
-
yarn add pensa-
|
|
21
|
+
yarn add @pensasystems/pensa-react-native
|
|
21
22
|
```
|
|
22
23
|
|
|
23
24
|
### 2- Install Native Dependencies (iOS)
|
|
@@ -44,7 +45,7 @@ Initializing the Pensa SDK is straightforward. Follow the steps below to set up
|
|
|
44
45
|
Call `initPensa()` at the startup of your app, preferably in a root file like `index.js` before calling `AppRegistry.registerComponent`.
|
|
45
46
|
|
|
46
47
|
```tsx
|
|
47
|
-
import {initPensa} from 'pensa-
|
|
48
|
+
import {initPensa} from '@pensasystems/pensa-react-native';
|
|
48
49
|
|
|
49
50
|
initPensa({
|
|
50
51
|
clientId: 'YOUR_CLIENT_ID',
|
|
@@ -71,7 +72,7 @@ To listen to SDK events such as upload progress, success, or failure, you can cr
|
|
|
71
72
|
```tsx
|
|
72
73
|
// hooks/usePensaListeners.ts
|
|
73
74
|
import {useEffect} from 'react';
|
|
74
|
-
import {PensaEvents} from 'pensa-
|
|
75
|
+
import {PensaEvents} from '@pensasystems/pensa-react-native';
|
|
75
76
|
|
|
76
77
|
export const usePensaListeners = () => {
|
|
77
78
|
useEffect(() => {
|
|
@@ -151,7 +152,7 @@ import {
|
|
|
151
152
|
showScanArea,
|
|
152
153
|
showStockingScreen,
|
|
153
154
|
showStoreChecklist,
|
|
154
|
-
} from 'pensa-
|
|
155
|
+
} from '@pensasystems/pensa-react-native';
|
|
155
156
|
```
|
|
156
157
|
|
|
157
158
|
### Searching stores
|
|
@@ -273,6 +274,99 @@ showScanArea(scanId, storeId, globalStoreId)
|
|
|
273
274
|
|
|
274
275
|
This method allows you to navigate directly to a scan area without going through the store selection flow.
|
|
275
276
|
|
|
277
|
+
# Troubleshooting (Android)
|
|
278
|
+
|
|
279
|
+
## 1. Core Library Desugaring Required
|
|
280
|
+
|
|
281
|
+
If you see an error mentioning that `core library desugaring` must be enabled (typically referencing `AAR metadata` or `desugar_jdk_libs`), update your Android project as follows:
|
|
282
|
+
|
|
283
|
+
### **Step 1 — Add desugaring dependency**
|
|
284
|
+
|
|
285
|
+
In your app-level `build.gradle`:
|
|
286
|
+
|
|
287
|
+
```gradle
|
|
288
|
+
dependencies {
|
|
289
|
+
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5'
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### **Step 2 — Enable desugaring & set Java 17**
|
|
294
|
+
|
|
295
|
+
Inside `android { compileOptions { ... } }`:
|
|
296
|
+
|
|
297
|
+
```gradle
|
|
298
|
+
compileOptions {
|
|
299
|
+
sourceCompatibility JavaVersion.VERSION_17
|
|
300
|
+
targetCompatibility JavaVersion.VERSION_17
|
|
301
|
+
coreLibraryDesugaringEnabled true
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
This configuration is required because the native Pensa Android SDK uses Java 17 language features.
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
## 2. Min SDK Version Requirement
|
|
310
|
+
|
|
311
|
+
If your Android build fails with a message indicating:
|
|
312
|
+
|
|
313
|
+
> *minSdkVersion cannot be smaller than 26 for library com.pensasystems:pensasdk*
|
|
314
|
+
|
|
315
|
+
Then your `minSdkVersion` must be updated.
|
|
316
|
+
|
|
317
|
+
### **Fix**
|
|
318
|
+
|
|
319
|
+
In your app-level `build.gradle`:
|
|
320
|
+
|
|
321
|
+
```gradle
|
|
322
|
+
defaultConfig {
|
|
323
|
+
minSdkVersion 26
|
|
324
|
+
}
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
The native Pensa Android SDK requires **minSdk 26**.
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
## 3. Metro Bundler Cannot Connect in Debug Mode (Android Only)
|
|
332
|
+
|
|
333
|
+
If the Android app cannot connect to Metro (e.g., blank screen, “Unable to load script from assets”), update your debug network rules.
|
|
334
|
+
|
|
335
|
+
### **Step 1 — Create `network_security_config.xml`**
|
|
336
|
+
|
|
337
|
+
Create a file:
|
|
338
|
+
|
|
339
|
+
```
|
|
340
|
+
android/app/src/main/res/xml/network_security_config.xml
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
With the following content:
|
|
344
|
+
|
|
345
|
+
```xml
|
|
346
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
347
|
+
<network-security-config>
|
|
348
|
+
<domain-config cleartextTrafficPermitted="true">
|
|
349
|
+
<domain includeSubdomains="true">10.0.2.2</domain>
|
|
350
|
+
<domain includeSubdomains="true">localhost</domain>
|
|
351
|
+
<domain includeSubdomains="true">127.0.0.1</domain>
|
|
352
|
+
</domain-config>
|
|
353
|
+
</network-security-config>
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### **Step 2 — Reference it in `AndroidManifest.xml`**
|
|
357
|
+
|
|
358
|
+
Inside your `<application>` tag:
|
|
359
|
+
|
|
360
|
+
```xml
|
|
361
|
+
<application
|
|
362
|
+
android:networkSecurityConfig="@xml/network_security_config"
|
|
363
|
+
... >
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
This allows the Android emulator to access the React Native bundler during development.
|
|
367
|
+
|
|
368
|
+
---
|
|
369
|
+
|
|
276
370
|
### Example Project
|
|
277
371
|
|
|
278
372
|
For code examples and integration best practices, refer to our GitHub repository.
|
package/android/build.gradle
CHANGED
|
@@ -83,7 +83,7 @@ def kotlin_version = getExtOrDefault("kotlinVersion")
|
|
|
83
83
|
|
|
84
84
|
dependencies {
|
|
85
85
|
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5'
|
|
86
|
-
implementation "com.pensasystems:pensasdk:1.0.
|
|
86
|
+
implementation "com.pensasystems:pensasdk:1.0.22"
|
|
87
87
|
implementation "com.facebook.react:react-android"
|
|
88
88
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
89
89
|
}
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
package com.pensasdkreactnative
|
|
2
2
|
|
|
3
|
+
import com.facebook.react.bridge.Arguments
|
|
3
4
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
4
5
|
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
|
5
6
|
import com.facebook.react.bridge.ReactMethod
|
|
6
7
|
import com.facebook.react.bridge.Promise
|
|
8
|
+
import com.facebook.react.bridge.ReadableArray
|
|
7
9
|
import com.facebook.react.bridge.ReadableMap
|
|
10
|
+
import com.facebook.react.bridge.ReadableType
|
|
8
11
|
import com.pensasystems.pensasdk.PensaSdk
|
|
9
12
|
import com.pensasystems.pensasdk.PensaSdkConfiguration
|
|
10
|
-
import com.pensasystems.pensasdk.
|
|
11
|
-
import com.pensasystems.pensasdk.
|
|
13
|
+
import com.pensasystems.pensasdk.model.PensaReportType
|
|
14
|
+
import com.pensasystems.pensasdk.model.PensaShelfItem
|
|
12
15
|
|
|
13
16
|
class PensaSdkReactNativeModule(reactContext: ReactApplicationContext) :
|
|
14
17
|
ReactContextBaseJavaModule(reactContext) {
|
|
@@ -69,7 +72,7 @@ class PensaSdkReactNativeModule(reactContext: ReactApplicationContext) :
|
|
|
69
72
|
|
|
70
73
|
@ReactMethod
|
|
71
74
|
fun showShelfScans(promise: Promise) {
|
|
72
|
-
val activity = currentActivity
|
|
75
|
+
val activity = reactApplicationContext.currentActivity
|
|
73
76
|
if (activity != null) {
|
|
74
77
|
PensaSdk.showShelfScans(
|
|
75
78
|
context = activity,
|
|
@@ -82,7 +85,7 @@ class PensaSdkReactNativeModule(reactContext: ReactApplicationContext) :
|
|
|
82
85
|
}
|
|
83
86
|
@ReactMethod
|
|
84
87
|
fun showProductScans(promise: Promise) {
|
|
85
|
-
val activity = currentActivity
|
|
88
|
+
val activity = reactApplicationContext.currentActivity
|
|
86
89
|
if (activity != null) {
|
|
87
90
|
PensaSdk.showProductScans(
|
|
88
91
|
context = activity,
|
|
@@ -96,7 +99,7 @@ class PensaSdkReactNativeModule(reactContext: ReactApplicationContext) :
|
|
|
96
99
|
|
|
97
100
|
@ReactMethod
|
|
98
101
|
fun showStoreSearchView(promise: Promise) {
|
|
99
|
-
val activity = currentActivity
|
|
102
|
+
val activity = reactApplicationContext.currentActivity
|
|
100
103
|
if (activity != null) {
|
|
101
104
|
PensaSdk.showStoreSearchView(
|
|
102
105
|
context = activity,
|
|
@@ -110,7 +113,7 @@ class PensaSdkReactNativeModule(reactContext: ReactApplicationContext) :
|
|
|
110
113
|
|
|
111
114
|
@ReactMethod
|
|
112
115
|
fun showStoresScreen(promise: Promise) {
|
|
113
|
-
val activity = currentActivity
|
|
116
|
+
val activity = reactApplicationContext.currentActivity
|
|
114
117
|
if (activity != null) {
|
|
115
118
|
PensaSdk.showStoresScreen(
|
|
116
119
|
context = activity,
|
|
@@ -124,7 +127,7 @@ class PensaSdkReactNativeModule(reactContext: ReactApplicationContext) :
|
|
|
124
127
|
|
|
125
128
|
@ReactMethod
|
|
126
129
|
fun showScanArea(scanId: Int, storeId: Int?, globalStoreId: String?, promise: Promise) {
|
|
127
|
-
val activity = currentActivity
|
|
130
|
+
val activity = reactApplicationContext.currentActivity
|
|
128
131
|
if (activity != null) {
|
|
129
132
|
PensaSdk.showScanArea(
|
|
130
133
|
context = activity,
|
|
@@ -141,7 +144,7 @@ class PensaSdkReactNativeModule(reactContext: ReactApplicationContext) :
|
|
|
141
144
|
|
|
142
145
|
@ReactMethod
|
|
143
146
|
fun showStockingScreen(promise: Promise) {
|
|
144
|
-
val activity = currentActivity
|
|
147
|
+
val activity = reactApplicationContext.currentActivity
|
|
145
148
|
if (activity != null) {
|
|
146
149
|
PensaSdk.showStockingScreen(
|
|
147
150
|
context = activity,
|
|
@@ -155,7 +158,7 @@ class PensaSdkReactNativeModule(reactContext: ReactApplicationContext) :
|
|
|
155
158
|
|
|
156
159
|
@ReactMethod
|
|
157
160
|
fun showStoreChecklist(globalStoreId: String, guid: String?, sectionKey: String?, promise: Promise) {
|
|
158
|
-
val activity = currentActivity
|
|
161
|
+
val activity = reactApplicationContext.currentActivity
|
|
159
162
|
if (activity != null) {
|
|
160
163
|
PensaSdk.showStoreChecklist(
|
|
161
164
|
context = activity,
|
|
@@ -169,4 +172,203 @@ class PensaSdkReactNativeModule(reactContext: ReactApplicationContext) :
|
|
|
169
172
|
promise.reject("NO_ACTIVITY", "Current activity is null")
|
|
170
173
|
}
|
|
171
174
|
}
|
|
175
|
+
|
|
176
|
+
@ReactMethod
|
|
177
|
+
fun fetchScanStatuses(scanIds: ReadableArray, promise: Promise) {
|
|
178
|
+
try {
|
|
179
|
+
val ids = mutableListOf<Int>()
|
|
180
|
+
for (i in 0 until scanIds.size()) {
|
|
181
|
+
ids.add(scanIds.getInt(i))
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
PensaSdk.fetchScanStatuses(
|
|
185
|
+
scanIds = ids,
|
|
186
|
+
onSuccess = { statuses ->
|
|
187
|
+
val rnList = statuses.map { status ->
|
|
188
|
+
val map = Arguments.createMap()
|
|
189
|
+
map.putInt("id", status.id)
|
|
190
|
+
map.putString("created", status.created)
|
|
191
|
+
map.putString("fastStatus", status.fastStatus)
|
|
192
|
+
map.putString("scanTimestamp", status.scanTimestamp)
|
|
193
|
+
map.putString("scannerId", status.scannerId)
|
|
194
|
+
map.putString("status", status.status)
|
|
195
|
+
|
|
196
|
+
val metadata = Arguments.createMap()
|
|
197
|
+
metadata.putString("guid", status.metadata?.guid)
|
|
198
|
+
metadata.putString("serverUploadStarted", status.metadata?.serverUploadStarted)
|
|
199
|
+
map.putMap("metadata", metadata)
|
|
200
|
+
|
|
201
|
+
map
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
val result = Arguments.createArray()
|
|
205
|
+
rnList.forEach { result.pushMap(it) }
|
|
206
|
+
promise.resolve(result)
|
|
207
|
+
|
|
208
|
+
},
|
|
209
|
+
onError = { error ->
|
|
210
|
+
promise.reject("FETCH_SCAN_STATUSES_FAILED", error)
|
|
211
|
+
}
|
|
212
|
+
)
|
|
213
|
+
} catch (e: Exception) {
|
|
214
|
+
promise.reject("FETCH_SCAN_STATUSES_EXCEPTION", e)
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
@ReactMethod
|
|
219
|
+
fun fetchOnDemandReports(
|
|
220
|
+
scanId: Int,
|
|
221
|
+
projectId: Int?,
|
|
222
|
+
reportTypes: ReadableArray?,
|
|
223
|
+
promise: Promise
|
|
224
|
+
) {
|
|
225
|
+
try {
|
|
226
|
+
val finalReportTypes = parseReportTypes(reportTypes)
|
|
227
|
+
|
|
228
|
+
PensaSdk.fetchOnDemandReports(
|
|
229
|
+
scanId = scanId,
|
|
230
|
+
projectId = projectId,
|
|
231
|
+
reportTypes = finalReportTypes,
|
|
232
|
+
onSuccess = { report ->
|
|
233
|
+
val result = Arguments.createMap()
|
|
234
|
+
|
|
235
|
+
fun toProductMap(p: com.pensasystems.pensasdk.model.PensaOnDemandProduct) =
|
|
236
|
+
Arguments.createMap().apply {
|
|
237
|
+
putString("brand", p.brand)
|
|
238
|
+
p.brandId?.let { putInt("brandId", it) } ?: putNull("brandId")
|
|
239
|
+
|
|
240
|
+
putString("category", p.category)
|
|
241
|
+
p.categoryId?.let { putInt("categoryId", it) } ?: putNull("categoryId")
|
|
242
|
+
|
|
243
|
+
p.expectedFacings?.let { putInt("expectedFacings", it) } ?: putNull("expectedFacings")
|
|
244
|
+
p.facings?.let { putInt("facings", it) } ?: putNull("facings")
|
|
245
|
+
|
|
246
|
+
putString("manufacturer", p.manufacturer)
|
|
247
|
+
p.manufacturerId?.let { putInt("manufacturerId", it) } ?: putNull("manufacturerId")
|
|
248
|
+
|
|
249
|
+
putString("product", p.product)
|
|
250
|
+
p.productId?.let { putInt("productId", it) } ?: putNull("productId")
|
|
251
|
+
|
|
252
|
+
putString("upc", p.upc)
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
fun toBucketMap(b: com.pensasystems.pensasdk.model.PensaOnDemandReportBucket) =
|
|
256
|
+
Arguments.createMap().apply {
|
|
257
|
+
val arr = Arguments.createArray()
|
|
258
|
+
b.productList.forEach { arr.pushMap(toProductMap(it)) }
|
|
259
|
+
putArray("productList", arr)
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
fun putBucket(key: String, bucket: com.pensasystems.pensasdk.model.PensaOnDemandReportBucket?) {
|
|
263
|
+
if (bucket == null) result.putNull(key) else result.putMap(key, toBucketMap(bucket))
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Fill only requested
|
|
267
|
+
finalReportTypes.distinct().forEach { t ->
|
|
268
|
+
when (t) {
|
|
269
|
+
PensaReportType.FACINGS_SEEN -> putBucket("facingsSeen", report.facingsSeen)
|
|
270
|
+
PensaReportType.FULL_FACINGS -> putBucket("fullFacings", report.fullFacings)
|
|
271
|
+
PensaReportType.FULL_FACINGS_AND_PRODUCT_POSITIONS ->
|
|
272
|
+
putBucket("fullFacingsAndProductPositions", report.fullFacingsAndProductPositions)
|
|
273
|
+
PensaReportType.ITEMS_SEEN -> putBucket("itemsSeen", report.itemsSeen)
|
|
274
|
+
PensaReportType.NEW_PRODUCTS -> putBucket("newProducts", report.newProducts)
|
|
275
|
+
PensaReportType.NEW_PRODUCT_PACKAGING -> putBucket("newProductPackaging", report.newProductPackaging)
|
|
276
|
+
PensaReportType.NO_OOS -> putBucket("noOos", report.noOos)
|
|
277
|
+
PensaReportType.OOS -> putBucket("oos", report.oos)
|
|
278
|
+
PensaReportType.PRODUCT_POSITIONS -> putBucket("productPositions", report.productPositions)
|
|
279
|
+
PensaReportType.SCAN_FAILED -> putBucket("scanFailed", report.scanFailed)
|
|
280
|
+
PensaReportType.SCAN_REJECTED -> putBucket("scanRejected", report.scanRejected)
|
|
281
|
+
PensaReportType.SCAN_SKIPPED -> putBucket("scanSkipped", report.scanSkipped)
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Other fields
|
|
286
|
+
report.projectId?.let { result.putInt("projectId", it) } ?: result.putNull("projectId")
|
|
287
|
+
result.putString("projectName", report.projectName)
|
|
288
|
+
report.projectReportId?.let { result.putInt("projectReportId", it) } ?: result.putNull("projectReportId")
|
|
289
|
+
result.putString("projectReportName", report.projectReportName)
|
|
290
|
+
result.putString("realogramSignedUrl", report.realogramSignedUrl)
|
|
291
|
+
report.shelfId?.let { result.putInt("shelfId", it) } ?: result.putNull("shelfId")
|
|
292
|
+
result.putString("shelfName", report.shelfName)
|
|
293
|
+
result.putString("status", report.status)
|
|
294
|
+
|
|
295
|
+
promise.resolve(result)
|
|
296
|
+
},
|
|
297
|
+
onError = { error ->
|
|
298
|
+
promise.reject("FETCH_ON_DEMAND_REPORTS_FAILED", error)
|
|
299
|
+
}
|
|
300
|
+
)
|
|
301
|
+
} catch (e: Exception) {
|
|
302
|
+
promise.reject("ON_DEMAND_EXCEPTION", e)
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
@ReactMethod
|
|
307
|
+
fun fetchProductImageBase64(productId: Int, promise: Promise) {
|
|
308
|
+
try {
|
|
309
|
+
val activity = reactApplicationContext.currentActivity
|
|
310
|
+
if (activity != null) {
|
|
311
|
+
PensaSdk.fetchProductImageBase64(
|
|
312
|
+
context = activity,
|
|
313
|
+
productId = productId,
|
|
314
|
+
onSuccess = { base64 ->
|
|
315
|
+
promise.resolve(base64)
|
|
316
|
+
},
|
|
317
|
+
onError = { error ->
|
|
318
|
+
promise.reject("FETCH_PRODUCT_IMAGE_FAILED", error)
|
|
319
|
+
}
|
|
320
|
+
)
|
|
321
|
+
} else {
|
|
322
|
+
promise.reject("NO_ACTIVITY", "Current activity is null")
|
|
323
|
+
}
|
|
324
|
+
} catch (e: Exception) {
|
|
325
|
+
promise.reject("FETCH_PRODUCT_IMAGE_EXCEPTION", e)
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
@ReactMethod
|
|
330
|
+
fun fetchShelves(globalStoreId: String, promise: Promise) {
|
|
331
|
+
try {
|
|
332
|
+
PensaSdk.fetchShelves(
|
|
333
|
+
globalStoreId = globalStoreId,
|
|
334
|
+
onSuccess = { shelves ->
|
|
335
|
+
val result = Arguments.createArray()
|
|
336
|
+
|
|
337
|
+
shelves.forEach { shelf ->
|
|
338
|
+
val map = Arguments.createMap()
|
|
339
|
+
map.putInt("id", shelf.id)
|
|
340
|
+
map.putString("name", shelf.name)
|
|
341
|
+
result.pushMap(map)
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
promise.resolve(result)
|
|
345
|
+
},
|
|
346
|
+
onError = { error ->
|
|
347
|
+
promise.reject("FETCH_SHELVES_FAILED", error)
|
|
348
|
+
}
|
|
349
|
+
)
|
|
350
|
+
} catch (e: Exception) {
|
|
351
|
+
promise.reject("FETCH_SHELVES_EXCEPTION", e)
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// Helpers
|
|
356
|
+
|
|
357
|
+
private fun parseReportTypes(reportTypes: ReadableArray?): List<PensaReportType> {
|
|
358
|
+
if (reportTypes == null || reportTypes.size() == 0) return listOf(PensaReportType.ITEMS_SEEN)
|
|
359
|
+
|
|
360
|
+
val list = mutableListOf<PensaReportType>()
|
|
361
|
+
for (i in 0 until reportTypes.size()) {
|
|
362
|
+
if (reportTypes.getType(i) != ReadableType.String) continue
|
|
363
|
+
val raw = reportTypes.getString(i) ?: continue
|
|
364
|
+
val parsed = try {
|
|
365
|
+
PensaReportType.valueOf(raw)
|
|
366
|
+
} catch (e: Exception) {
|
|
367
|
+
null
|
|
368
|
+
}
|
|
369
|
+
if (parsed != null) list.add(parsed)
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
return if (list.isEmpty()) listOf(PensaReportType.ITEMS_SEEN) else list.distinct()
|
|
373
|
+
}
|
|
172
374
|
}
|
|
@@ -37,6 +37,10 @@ RCT_EXTERN_METHOD(showStoreChecklist:(NSString *)globalStoreId
|
|
|
37
37
|
withResolver:(RCTPromiseResolveBlock)resolve
|
|
38
38
|
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
39
39
|
|
|
40
|
+
RCT_EXTERN_METHOD(fetchShelves:(NSString *)globalStoreId
|
|
41
|
+
withResolver:(RCTPromiseResolveBlock)resolve
|
|
42
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
43
|
+
|
|
40
44
|
@end
|
|
41
45
|
|
|
42
46
|
@interface RCT_EXTERN_MODULE(PensaEventEmitter, RCTEventEmitter)
|
|
@@ -37,6 +37,25 @@ RCT_EXTERN_METHOD(showStoreChecklist:(NSString *)globalStoreId
|
|
|
37
37
|
withResolver:(RCTPromiseResolveBlock)resolve
|
|
38
38
|
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
39
39
|
|
|
40
|
+
RCT_EXTERN_METHOD(fetchScanStatuses:(NSArray *)scanIds
|
|
41
|
+
withResolver:(RCTPromiseResolveBlock)resolve
|
|
42
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
RCT_EXTERN_METHOD(fetchOnDemandReports:(nonnull NSNumber *)scanId
|
|
46
|
+
projectId:(nullable NSNumber *)projectId
|
|
47
|
+
reportTypes:(nullable NSArray *)reportTypes
|
|
48
|
+
withResolver:(RCTPromiseResolveBlock)resolve
|
|
49
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
50
|
+
|
|
51
|
+
RCT_EXTERN_METHOD(fetchProductImageBase64:(nonnull NSNumber *)productId
|
|
52
|
+
withResolver:(RCTPromiseResolveBlock)resolve
|
|
53
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
54
|
+
|
|
55
|
+
RCT_EXTERN_METHOD(fetchShelves:(NSString *)globalStoreId
|
|
56
|
+
withResolver:(RCTPromiseResolveBlock)resolve
|
|
57
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
58
|
+
|
|
40
59
|
+ (BOOL)requiresMainQueueSetup
|
|
41
60
|
{
|
|
42
61
|
return NO;
|
|
@@ -118,4 +118,173 @@ class PensaSdkReactNative: NSObject {
|
|
|
118
118
|
resolve(nil)
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
|
+
|
|
122
|
+
@objc(fetchScanStatuses:withResolver:withRejecter:)
|
|
123
|
+
func fetchScanStatuses(
|
|
124
|
+
scanIds: [NSNumber],
|
|
125
|
+
resolve: @escaping RCTPromiseResolveBlock,
|
|
126
|
+
reject: @escaping RCTPromiseRejectBlock
|
|
127
|
+
) {
|
|
128
|
+
let ids = scanIds.map { $0.intValue }
|
|
129
|
+
|
|
130
|
+
Pensa.shared.fetchScanStatuses(
|
|
131
|
+
scanIds: ids,
|
|
132
|
+
onSuccess: { statuses in
|
|
133
|
+
let mapped: [[String: Any]] = statuses.map { status in
|
|
134
|
+
var dict: [String: Any] = [:]
|
|
135
|
+
|
|
136
|
+
dict["id"] = status.id
|
|
137
|
+
dict["created"] = status.created ?? NSNull()
|
|
138
|
+
dict["fastStatus"] = status.fastStatus ?? NSNull()
|
|
139
|
+
dict["scanTimestamp"] = status.scanTimestamp ?? NSNull()
|
|
140
|
+
dict["scannerId"] = status.scannerId ?? NSNull()
|
|
141
|
+
dict["status"] = status.status ?? NSNull()
|
|
142
|
+
|
|
143
|
+
// metadata
|
|
144
|
+
if let metadata = status.metadata {
|
|
145
|
+
dict["metadata"] = [
|
|
146
|
+
"guid": (metadata.guid as Any?) ?? NSNull(),
|
|
147
|
+
"serverUploadStarted": (metadata.serverUploadStarted as Any?) ?? NSNull()
|
|
148
|
+
]
|
|
149
|
+
} else {
|
|
150
|
+
dict["metadata"] = NSNull()
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return dict
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
resolve(mapped)
|
|
157
|
+
},
|
|
158
|
+
onError: { error in
|
|
159
|
+
reject("FETCH_SCAN_STATUSES_FAILED", error.localizedDescription, error)
|
|
160
|
+
}
|
|
161
|
+
)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
@objc(fetchOnDemandReports:projectId:reportTypes:withResolver:withRejecter:)
|
|
165
|
+
func fetchOnDemandReports(
|
|
166
|
+
scanId: NSNumber,
|
|
167
|
+
projectId: NSNumber?,
|
|
168
|
+
reportTypes: NSArray?,
|
|
169
|
+
resolve: @escaping RCTPromiseResolveBlock,
|
|
170
|
+
reject: @escaping RCTPromiseRejectBlock
|
|
171
|
+
) {
|
|
172
|
+
func rn(_ value: Any?) -> Any { value ?? NSNull() }
|
|
173
|
+
|
|
174
|
+
let types: [PensaReportType] = {
|
|
175
|
+
guard let arr = reportTypes as? [String], !arr.isEmpty else { return [.itemsSeen] }
|
|
176
|
+
let mapped = arr.compactMap { PensaReportType(rawValue: $0) }
|
|
177
|
+
return mapped.isEmpty ? [.itemsSeen] : mapped
|
|
178
|
+
}()
|
|
179
|
+
|
|
180
|
+
Pensa.shared.fetchOnDemandReports(
|
|
181
|
+
scanId: scanId.intValue,
|
|
182
|
+
projectId: projectId?.intValue,
|
|
183
|
+
reportTypes: types,
|
|
184
|
+
onSuccess: { report in
|
|
185
|
+
|
|
186
|
+
var result: [String: Any] = [
|
|
187
|
+
"shelfId": rn(report.shelfId),
|
|
188
|
+
"shelfName": rn(report.shelfName),
|
|
189
|
+
"status": rn(report.status),
|
|
190
|
+
"projectId": rn(report.projectId),
|
|
191
|
+
"projectName": rn(report.projectName),
|
|
192
|
+
"projectReportId": rn(report.projectReportId),
|
|
193
|
+
"projectReportName": rn(report.projectReportName),
|
|
194
|
+
"realogramSignedUrl": rn(report.realogramSignedUrl)
|
|
195
|
+
]
|
|
196
|
+
|
|
197
|
+
func addBucket(_ key: String, _ bucket: PensaOnDemandReportBucket?) {
|
|
198
|
+
guard let bucket = bucket else { return } // istenen tip yoksa hiç ekleme
|
|
199
|
+
let products: [[String: Any]] = bucket.productList.map { p in
|
|
200
|
+
[
|
|
201
|
+
"brand": rn(p.brand),
|
|
202
|
+
"brandId": rn(p.brandId),
|
|
203
|
+
"category": rn(p.category),
|
|
204
|
+
"categoryId": rn(p.categoryId),
|
|
205
|
+
"expectedFacings": rn(p.expectedFacings),
|
|
206
|
+
"facings": rn(p.facings),
|
|
207
|
+
"manufacturer": rn(p.manufacturer),
|
|
208
|
+
"manufacturerId": rn(p.manufacturerId),
|
|
209
|
+
"product": rn(p.product),
|
|
210
|
+
"productId": rn(p.productId),
|
|
211
|
+
"upc": rn(p.upc)
|
|
212
|
+
]
|
|
213
|
+
}
|
|
214
|
+
result[key] = ["productList": products]
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
for t in types {
|
|
218
|
+
switch t {
|
|
219
|
+
case .itemsSeen:
|
|
220
|
+
addBucket("itemsSeen", report.itemsSeen?.report)
|
|
221
|
+
case .facingsSeen:
|
|
222
|
+
addBucket("facingsSeen", report.facingsSeen?.report)
|
|
223
|
+
case .fullFacings:
|
|
224
|
+
addBucket("fullFacings", report.fullFacings?.report)
|
|
225
|
+
case .fullFacingsAndProductPositions:
|
|
226
|
+
addBucket("fullFacingsAndProductPositions", report.fullFacingsAndProductPositions?.report)
|
|
227
|
+
case .newProducts:
|
|
228
|
+
addBucket("newProducts", report.newProducts?.report)
|
|
229
|
+
case .newProductPackaging:
|
|
230
|
+
addBucket("newProductPackaging", report.newProductPackaging?.report)
|
|
231
|
+
case .noOos:
|
|
232
|
+
addBucket("noOos", report.noOos?.report)
|
|
233
|
+
case .oos:
|
|
234
|
+
addBucket("oos", report.oos?.report)
|
|
235
|
+
case .productPositions:
|
|
236
|
+
addBucket("productPositions", report.productPositions?.report)
|
|
237
|
+
case .scanFailed:
|
|
238
|
+
addBucket("scanFailed", report.scanFailed?.report)
|
|
239
|
+
case .scanRejected:
|
|
240
|
+
addBucket("scanRejected", report.scanRejected?.report)
|
|
241
|
+
case .scanSkipped:
|
|
242
|
+
addBucket("scanSkipped", report.scanSkipped?.report)
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
resolve(result)
|
|
247
|
+
},
|
|
248
|
+
onError: { error in
|
|
249
|
+
reject("FETCH_ON_DEMAND_REPORTS_FAILED", error.localizedDescription, error)
|
|
250
|
+
}
|
|
251
|
+
)
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
@objc(fetchProductImageBase64:withResolver:withRejecter:)
|
|
255
|
+
func fetchProductImageBase64(productId: NSNumber,
|
|
256
|
+
resolve: @escaping RCTPromiseResolveBlock,
|
|
257
|
+
reject: @escaping RCTPromiseRejectBlock) {
|
|
258
|
+
Pensa.shared.fetchProductImageBase64(
|
|
259
|
+
productId: productId.intValue,
|
|
260
|
+
onSuccess: { base64 in
|
|
261
|
+
resolve(base64)
|
|
262
|
+
},
|
|
263
|
+
onError: { error in
|
|
264
|
+
reject("FETCH_PRODUCT_IMAGE_BASE64_FAILED", error.localizedDescription, error)
|
|
265
|
+
}
|
|
266
|
+
)
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
@objc(fetchShelves:withResolver:withRejecter:)
|
|
270
|
+
func fetchShelves(globalStoreId: NSString,
|
|
271
|
+
resolve: @escaping RCTPromiseResolveBlock,
|
|
272
|
+
reject: @escaping RCTPromiseRejectBlock) {
|
|
273
|
+
Pensa.shared.fetchShelves(
|
|
274
|
+
globalStoreId: globalStoreId as String,
|
|
275
|
+
onSuccess: { shelves in
|
|
276
|
+
let mapped: [[String: Any]] = shelves.map { shelf in
|
|
277
|
+
[
|
|
278
|
+
"id": shelf.id,
|
|
279
|
+
"name": shelf.name ?? NSNull()
|
|
280
|
+
]
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
resolve(mapped)
|
|
284
|
+
},
|
|
285
|
+
onError: { error in
|
|
286
|
+
reject("FETCH_SHELVES_FAILED", error.localizedDescription, error)
|
|
287
|
+
}
|
|
288
|
+
)
|
|
289
|
+
}
|
|
121
290
|
}
|
package/lib/module/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
import { NativeModules, Platform } from 'react-native';
|
|
4
|
+
import { PensaReportType } from "./types.js";
|
|
4
5
|
const LINKING_ERROR = `The package 'pensa-sdk-react-native' doesn't seem to be linked. Make sure: \n\n` + Platform.select({
|
|
5
6
|
ios: "- You have run 'pod install'\n",
|
|
6
7
|
default: ''
|
|
@@ -37,6 +38,20 @@ export const showStockingScreen = () => {
|
|
|
37
38
|
export const showStoreChecklist = (globalStoreId, guid, sectionKey) => {
|
|
38
39
|
return PensaSdkReactNative.showStoreChecklist(globalStoreId, guid, sectionKey);
|
|
39
40
|
};
|
|
41
|
+
export const fetchScanStatuses = scanIds => {
|
|
42
|
+
return PensaSdkReactNative.fetchScanStatuses(scanIds);
|
|
43
|
+
};
|
|
44
|
+
export const fetchOnDemandReports = (scanId, projectId, reportTypes) => {
|
|
45
|
+
const finalReportTypes = reportTypes && reportTypes.length > 0 ? reportTypes : [PensaReportType.ITEMS_SEEN];
|
|
46
|
+
return PensaSdkReactNative.fetchOnDemandReports(scanId, projectId ?? null, finalReportTypes);
|
|
47
|
+
};
|
|
48
|
+
export const fetchProductImageBase64 = productId => {
|
|
49
|
+
return PensaSdkReactNative.fetchProductImageBase64(productId);
|
|
50
|
+
};
|
|
51
|
+
export const fetchShelves = globalStoreId => {
|
|
52
|
+
return PensaSdkReactNative.fetchShelves(globalStoreId);
|
|
53
|
+
};
|
|
40
54
|
export * from "./events.js";
|
|
41
55
|
export * from "./types.js";
|
|
56
|
+
export { PensaReportType } from "./types.js";
|
|
42
57
|
//# sourceMappingURL=index.js.map
|
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["NativeModules","Platform","LINKING_ERROR","select","ios","default","PensaSdkReactNative","Proxy","get","Error","initPensa","config","isPensaStarted","showShelfScans","showProductScans","showStoreSearchView","showStoresScreen","showScanArea","scanId","storeId","globalStoreId","showStockingScreen","showStoreChecklist","guid","sectionKey"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SAASA,aAAa,EAAEC,QAAQ,QAAQ,cAAc;
|
|
1
|
+
{"version":3,"names":["NativeModules","Platform","PensaReportType","LINKING_ERROR","select","ios","default","PensaSdkReactNative","Proxy","get","Error","initPensa","config","isPensaStarted","showShelfScans","showProductScans","showStoreSearchView","showStoresScreen","showScanArea","scanId","storeId","globalStoreId","showStockingScreen","showStoreChecklist","guid","sectionKey","fetchScanStatuses","scanIds","fetchOnDemandReports","projectId","reportTypes","finalReportTypes","length","ITEMS_SEEN","fetchProductImageBase64","productId","fetchShelves"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SAASA,aAAa,EAAEC,QAAQ,QAAQ,cAAc;AAMtD,SAASC,eAAe,QAAQ,YAAS;AAEzC,MAAMC,aAAa,GACjB,iFAAiF,GACjFF,QAAQ,CAACG,MAAM,CAAC;EAAEC,GAAG,EAAE,gCAAgC;EAAEC,OAAO,EAAE;AAAG,CAAC,CAAC,GACvE,sDAAsD,GACtD,+BAA+B;AAEjC,MAAMC,mBAAmB,GAAGP,aAAa,CAACO,mBAAmB,GACzDP,aAAa,CAACO,mBAAmB,GACjC,IAAIC,KAAK,CACP,CAAC,CAAC,EACF;EACEC,GAAGA,CAAA,EAAG;IACJ,MAAM,IAAIC,KAAK,CAACP,aAAa,CAAC;EAChC;AACF,CACF,CAAC;AAEL,OAAO,MAAMQ,SAAS,GAAIC,MAIzB,IAAoB;EACnB,OAAOL,mBAAmB,CAACI,SAAS,CAACC,MAAM,CAAC;AAC9C,CAAC;AAED,OAAO,MAAMC,cAAc,GAAGA,CAAA,KAAwB;EACpD,OAAON,mBAAmB,CAACM,cAAc,CAAC,CAAC;AAC7C,CAAC;AAED,OAAO,MAAMC,cAAc,GAAGA,CAAA,KAAqB;EACjD,OAAOP,mBAAmB,CAACO,cAAc,CAAC,CAAC;AAC7C,CAAC;AAED,OAAO,MAAMC,gBAAgB,GAAGA,CAAA,KAAqB;EACnD,OAAOR,mBAAmB,CAACQ,gBAAgB,CAAC,CAAC;AAC/C,CAAC;AAED,OAAO,MAAMC,mBAAmB,GAAGA,CAAA,KAAqB;EACtD,OAAOT,mBAAmB,CAACS,mBAAmB,CAAC,CAAC;AAClD,CAAC;AAED,OAAO,MAAMC,gBAAgB,GAAGA,CAAA,KAAqB;EACnD,OAAOV,mBAAmB,CAACU,gBAAgB,CAAC,CAAC;AAC/C,CAAC;AAED,OAAO,MAAMC,YAAY,GAAGA,CAC1BC,MAAc,EACdC,OAAgB,EAChBC,aAAsB,KACJ;EAClB,OAAOd,mBAAmB,CAACW,YAAY,CACrCC,MAAM,EACNC,OAAO,IAAI,IAAI,EACfC,aAAa,IAAI,IACnB,CAAC;AACH,CAAC;AAED,OAAO,MAAMC,kBAAkB,GAAGA,CAAA,KAAqB;EACrD,OAAOf,mBAAmB,CAACe,kBAAkB,CAAC,CAAC;AACjD,CAAC;AAED,OAAO,MAAMC,kBAAkB,GAAGA,CAChCF,aAAqB,EACrBG,IAAa,EACbC,UAAmB,KACD;EAClB,OAAOlB,mBAAmB,CAACgB,kBAAkB,CAC3CF,aAAa,EACbG,IAAI,EACJC,UACF,CAAC;AACH,CAAC;AAED,OAAO,MAAMC,iBAAiB,GAC5BC,OAAiB,IACc;EAC/B,OAAOpB,mBAAmB,CAACmB,iBAAiB,CAACC,OAAO,CAAC;AACvD,CAAC;AAED,OAAO,MAAMC,oBAAoB,GAAGA,CAClCT,MAAc,EACdU,SAAkB,EAClBC,WAA+B,KACE;EACjC,MAAMC,gBAAgB,GACpBD,WAAW,IAAIA,WAAW,CAACE,MAAM,GAAG,CAAC,GACjCF,WAAW,GACX,CAAC5B,eAAe,CAAC+B,UAAU,CAAC;EAElC,OAAO1B,mBAAmB,CAACqB,oBAAoB,CAC7CT,MAAM,EACNU,SAAS,IAAI,IAAI,EACjBE,gBACF,CAAC;AACH,CAAC;AAED,OAAO,MAAMG,uBAAuB,GAAIC,SAAiB,IAAsB;EAC7E,OAAO5B,mBAAmB,CAAC2B,uBAAuB,CAACC,SAAS,CAAC;AAC/D,CAAC;AAED,OAAO,MAAMC,YAAY,GACvBf,aAAqB,IACS;EAC9B,OAAOd,mBAAmB,CAAC6B,YAAY,CAACf,aAAa,CAAC;AACxD,CAAC;AAED,cAAc,aAAU;AACxB,cAAc,YAAS;AACvB,SAASnB,eAAe,QAAQ,YAAS","ignoreList":[]}
|
package/lib/module/types.js
CHANGED
|
@@ -1,2 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
|
|
3
|
+
export let PensaReportType = /*#__PURE__*/function (PensaReportType) {
|
|
4
|
+
PensaReportType["FACINGS_SEEN"] = "FACINGS_SEEN";
|
|
5
|
+
PensaReportType["FULL_FACINGS"] = "FULL_FACINGS";
|
|
6
|
+
PensaReportType["FULL_FACINGS_AND_PRODUCT_POSITIONS"] = "FULL_FACINGS_AND_PRODUCT_POSITIONS";
|
|
7
|
+
PensaReportType["ITEMS_SEEN"] = "ITEMS_SEEN";
|
|
8
|
+
PensaReportType["NEW_PRODUCTS"] = "NEW_PRODUCTS";
|
|
9
|
+
PensaReportType["NEW_PRODUCT_PACKAGING"] = "NEW_PRODUCT_PACKAGING";
|
|
10
|
+
PensaReportType["NO_OOS"] = "NO_OOS";
|
|
11
|
+
PensaReportType["OOS"] = "OOS";
|
|
12
|
+
PensaReportType["PRODUCT_POSITIONS"] = "PRODUCT_POSITIONS";
|
|
13
|
+
PensaReportType["SCAN_FAILED"] = "SCAN_FAILED";
|
|
14
|
+
PensaReportType["SCAN_REJECTED"] = "SCAN_REJECTED";
|
|
15
|
+
PensaReportType["SCAN_SKIPPED"] = "SCAN_SKIPPED";
|
|
16
|
+
return PensaReportType;
|
|
17
|
+
}({});
|
|
2
18
|
//# sourceMappingURL=types.js.map
|
package/lib/module/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sourceRoot":"../../src","sources":["types.ts"],"mappings":"","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["PensaReportType"],"sourceRoot":"../../src","sources":["types.ts"],"mappings":";;AAsFA,WAAYA,eAAe,0BAAfA,eAAe;EAAfA,eAAe;EAAfA,eAAe;EAAfA,eAAe;EAAfA,eAAe;EAAfA,eAAe;EAAfA,eAAe;EAAfA,eAAe;EAAfA,eAAe;EAAfA,eAAe;EAAfA,eAAe;EAAfA,eAAe;EAAfA,eAAe;EAAA,OAAfA,eAAe;AAAA","ignoreList":[]}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { PensaOnDemandReport, PensaScanStatus, PensaShelfItem } from './types';
|
|
2
|
+
import { PensaReportType } from './types';
|
|
1
3
|
export declare const initPensa: (config: {
|
|
2
4
|
clientId: string;
|
|
3
5
|
clientSecret: string;
|
|
@@ -11,6 +13,11 @@ export declare const showStoresScreen: () => Promise<void>;
|
|
|
11
13
|
export declare const showScanArea: (scanId: number, storeId?: number, globalStoreId?: string) => Promise<void>;
|
|
12
14
|
export declare const showStockingScreen: () => Promise<void>;
|
|
13
15
|
export declare const showStoreChecklist: (globalStoreId: string, guid?: string, sectionKey?: string) => Promise<void>;
|
|
16
|
+
export declare const fetchScanStatuses: (scanIds: number[]) => Promise<PensaScanStatus[]>;
|
|
17
|
+
export declare const fetchOnDemandReports: (scanId: number, projectId?: number, reportTypes?: PensaReportType[]) => Promise<PensaOnDemandReport>;
|
|
18
|
+
export declare const fetchProductImageBase64: (productId: number) => Promise<string>;
|
|
19
|
+
export declare const fetchShelves: (globalStoreId: string) => Promise<PensaShelfItem[]>;
|
|
14
20
|
export * from './events';
|
|
15
21
|
export * from './types';
|
|
22
|
+
export { PensaReportType } from './types';
|
|
16
23
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,mBAAmB,EACnB,eAAe,EACf,cAAc,EACf,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAmB1C,eAAO,MAAM,SAAS,GAAI,QAAQ;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,KAAG,OAAO,CAAC,IAAI,CAEf,CAAC;AAEF,eAAO,MAAM,cAAc,QAAO,OAAO,CAAC,OAAO,CAEhD,CAAC;AAEF,eAAO,MAAM,cAAc,QAAO,OAAO,CAAC,IAAI,CAE7C,CAAC;AAEF,eAAO,MAAM,gBAAgB,QAAO,OAAO,CAAC,IAAI,CAE/C,CAAC;AAEF,eAAO,MAAM,mBAAmB,QAAO,OAAO,CAAC,IAAI,CAElD,CAAC;AAEF,eAAO,MAAM,gBAAgB,QAAO,OAAO,CAAC,IAAI,CAE/C,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,QAAQ,MAAM,EACd,UAAU,MAAM,EAChB,gBAAgB,MAAM,KACrB,OAAO,CAAC,IAAI,CAMd,CAAC;AAEF,eAAO,MAAM,kBAAkB,QAAO,OAAO,CAAC,IAAI,CAEjD,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,eAAe,MAAM,EACrB,OAAO,MAAM,EACb,aAAa,MAAM,KAClB,OAAO,CAAC,IAAI,CAMd,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,SAAS,MAAM,EAAE,KAChB,OAAO,CAAC,eAAe,EAAE,CAE3B,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,MAAM,EACd,YAAY,MAAM,EAClB,cAAc,eAAe,EAAE,KAC9B,OAAO,CAAC,mBAAmB,CAW7B,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,WAAW,MAAM,KAAG,OAAO,CAAC,MAAM,CAEzE,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,eAAe,MAAM,KACpB,OAAO,CAAC,cAAc,EAAE,CAE1B,CAAC;AAEF,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -23,4 +23,73 @@ export type PensaEventPayloads = {
|
|
|
23
23
|
onScanUploadFailed: OnScanUploadFailed;
|
|
24
24
|
onCantScanReported: OnCantScanReported;
|
|
25
25
|
};
|
|
26
|
+
export type PensaScanMetadata = {
|
|
27
|
+
guid: string | null;
|
|
28
|
+
serverUploadStarted: string | null;
|
|
29
|
+
};
|
|
30
|
+
export type PensaScanStatus = {
|
|
31
|
+
created: string | null;
|
|
32
|
+
fastStatus: string | null;
|
|
33
|
+
id: number;
|
|
34
|
+
metadata: PensaScanMetadata | null;
|
|
35
|
+
scanTimestamp: string | null;
|
|
36
|
+
scannerId: string | null;
|
|
37
|
+
status: string | null;
|
|
38
|
+
};
|
|
39
|
+
export type PensaOnDemandProduct = {
|
|
40
|
+
brand: string | null;
|
|
41
|
+
brandId: number | null;
|
|
42
|
+
category: string | null;
|
|
43
|
+
categoryId: number | null;
|
|
44
|
+
expectedFacings: number | null;
|
|
45
|
+
facings: number | null;
|
|
46
|
+
manufacturer: string | null;
|
|
47
|
+
manufacturerId: number | null;
|
|
48
|
+
product: string | null;
|
|
49
|
+
productId: number | null;
|
|
50
|
+
upc: string | null;
|
|
51
|
+
};
|
|
52
|
+
export type PensaOnDemandReportBucket = {
|
|
53
|
+
productList: PensaOnDemandProduct[];
|
|
54
|
+
};
|
|
55
|
+
export type PensaOnDemandReport = {
|
|
56
|
+
facingsSeen: PensaOnDemandReportBucket | null;
|
|
57
|
+
fullFacings: PensaOnDemandReportBucket | null;
|
|
58
|
+
fullFacingsAndProductPositions: PensaOnDemandReportBucket | null;
|
|
59
|
+
itemsSeen: PensaOnDemandReportBucket | null;
|
|
60
|
+
newProducts: PensaOnDemandReportBucket | null;
|
|
61
|
+
newProductPackaging: PensaOnDemandReportBucket | null;
|
|
62
|
+
noOos: PensaOnDemandReportBucket | null;
|
|
63
|
+
oos: PensaOnDemandReportBucket | null;
|
|
64
|
+
productPositions: PensaOnDemandReportBucket | null;
|
|
65
|
+
scanFailed: PensaOnDemandReportBucket | null;
|
|
66
|
+
scanRejected: PensaOnDemandReportBucket | null;
|
|
67
|
+
scanSkipped: PensaOnDemandReportBucket | null;
|
|
68
|
+
projectId: number | null;
|
|
69
|
+
projectName: string | null;
|
|
70
|
+
projectReportId: number | null;
|
|
71
|
+
projectReportName: string | null;
|
|
72
|
+
realogramSignedUrl: string | null;
|
|
73
|
+
shelfId: number | null;
|
|
74
|
+
shelfName: string | null;
|
|
75
|
+
status: string | null;
|
|
76
|
+
};
|
|
77
|
+
export declare enum PensaReportType {
|
|
78
|
+
FACINGS_SEEN = "FACINGS_SEEN",
|
|
79
|
+
FULL_FACINGS = "FULL_FACINGS",
|
|
80
|
+
FULL_FACINGS_AND_PRODUCT_POSITIONS = "FULL_FACINGS_AND_PRODUCT_POSITIONS",
|
|
81
|
+
ITEMS_SEEN = "ITEMS_SEEN",
|
|
82
|
+
NEW_PRODUCTS = "NEW_PRODUCTS",
|
|
83
|
+
NEW_PRODUCT_PACKAGING = "NEW_PRODUCT_PACKAGING",
|
|
84
|
+
NO_OOS = "NO_OOS",
|
|
85
|
+
OOS = "OOS",
|
|
86
|
+
PRODUCT_POSITIONS = "PRODUCT_POSITIONS",
|
|
87
|
+
SCAN_FAILED = "SCAN_FAILED",
|
|
88
|
+
SCAN_REJECTED = "SCAN_REJECTED",
|
|
89
|
+
SCAN_SKIPPED = "SCAN_SKIPPED"
|
|
90
|
+
}
|
|
91
|
+
export type PensaShelfItem = {
|
|
92
|
+
id: number;
|
|
93
|
+
name: string | null;
|
|
94
|
+
};
|
|
26
95
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,0BAA0B,EAAE,0BAA0B,CAAC;IACvD,qBAAqB,EAAE,qBAAqB,CAAC;IAC7C,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,kBAAkB,EAAE,kBAAkB,CAAC;CACxC,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pensasystems/pensa-react-native",
|
|
3
|
-
"version": "0.1.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "The Pensa Mobile App SDK is a developer toolkit designed to simplify adding Pensa’s capabilities to your mobile applications. It provides pre-built libraries, tools, and APIs to accelerate development and integration, offering streamlined SDK integration, easy initialization, and comprehensive functionality. With the Pensa SDK, you can enhance your app’s features or seamlessly integrate with other services for a cohesive user experience.",
|
|
5
5
|
"source": "./src/index.tsx",
|
|
6
6
|
"main": "./lib/module/index.js",
|
|
@@ -68,7 +68,6 @@
|
|
|
68
68
|
"@release-it/conventional-changelog": "^9.0.2",
|
|
69
69
|
"@types/jest": "^29.5.5",
|
|
70
70
|
"@types/react": "^19.0.0",
|
|
71
|
-
"commitlint": "^19.6.1",
|
|
72
71
|
"del-cli": "^5.1.0",
|
|
73
72
|
"eslint": "^9.22.0",
|
|
74
73
|
"eslint-config-prettier": "^10.1.1",
|
package/src/index.tsx
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import { NativeModules, Platform } from 'react-native';
|
|
2
|
+
import type {
|
|
3
|
+
PensaOnDemandReport,
|
|
4
|
+
PensaScanStatus,
|
|
5
|
+
PensaShelfItem,
|
|
6
|
+
} from './types';
|
|
7
|
+
import { PensaReportType } from './types';
|
|
2
8
|
|
|
3
9
|
const LINKING_ERROR =
|
|
4
10
|
`The package 'pensa-sdk-react-native' doesn't seem to be linked. Make sure: \n\n` +
|
|
@@ -73,5 +79,39 @@ export const showStoreChecklist = (
|
|
|
73
79
|
);
|
|
74
80
|
};
|
|
75
81
|
|
|
82
|
+
export const fetchScanStatuses = (
|
|
83
|
+
scanIds: number[]
|
|
84
|
+
): Promise<PensaScanStatus[]> => {
|
|
85
|
+
return PensaSdkReactNative.fetchScanStatuses(scanIds);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
export const fetchOnDemandReports = (
|
|
89
|
+
scanId: number,
|
|
90
|
+
projectId?: number,
|
|
91
|
+
reportTypes?: PensaReportType[]
|
|
92
|
+
): Promise<PensaOnDemandReport> => {
|
|
93
|
+
const finalReportTypes =
|
|
94
|
+
reportTypes && reportTypes.length > 0
|
|
95
|
+
? reportTypes
|
|
96
|
+
: [PensaReportType.ITEMS_SEEN];
|
|
97
|
+
|
|
98
|
+
return PensaSdkReactNative.fetchOnDemandReports(
|
|
99
|
+
scanId,
|
|
100
|
+
projectId ?? null,
|
|
101
|
+
finalReportTypes
|
|
102
|
+
);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
export const fetchProductImageBase64 = (productId: number): Promise<string> => {
|
|
106
|
+
return PensaSdkReactNative.fetchProductImageBase64(productId);
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
export const fetchShelves = (
|
|
110
|
+
globalStoreId: string
|
|
111
|
+
): Promise<PensaShelfItem[]> => {
|
|
112
|
+
return PensaSdkReactNative.fetchShelves(globalStoreId);
|
|
113
|
+
};
|
|
114
|
+
|
|
76
115
|
export * from './events';
|
|
77
116
|
export * from './types';
|
|
117
|
+
export { PensaReportType } from './types';
|
package/src/types.ts
CHANGED
|
@@ -27,3 +27,79 @@ export type PensaEventPayloads = {
|
|
|
27
27
|
onScanUploadFailed: OnScanUploadFailed;
|
|
28
28
|
onCantScanReported: OnCantScanReported;
|
|
29
29
|
};
|
|
30
|
+
|
|
31
|
+
export type PensaScanMetadata = {
|
|
32
|
+
guid: string | null;
|
|
33
|
+
serverUploadStarted: string | null;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export type PensaScanStatus = {
|
|
37
|
+
created: string | null;
|
|
38
|
+
fastStatus: string | null;
|
|
39
|
+
id: number;
|
|
40
|
+
metadata: PensaScanMetadata | null;
|
|
41
|
+
scanTimestamp: string | null;
|
|
42
|
+
scannerId: string | null;
|
|
43
|
+
status: string | null;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export type PensaOnDemandProduct = {
|
|
47
|
+
brand: string | null;
|
|
48
|
+
brandId: number | null;
|
|
49
|
+
category: string | null;
|
|
50
|
+
categoryId: number | null;
|
|
51
|
+
expectedFacings: number | null;
|
|
52
|
+
facings: number | null;
|
|
53
|
+
manufacturer: string | null;
|
|
54
|
+
manufacturerId: number | null;
|
|
55
|
+
product: string | null;
|
|
56
|
+
productId: number | null;
|
|
57
|
+
upc: string | null;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export type PensaOnDemandReportBucket = {
|
|
61
|
+
productList: PensaOnDemandProduct[];
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export type PensaOnDemandReport = {
|
|
65
|
+
facingsSeen: PensaOnDemandReportBucket | null;
|
|
66
|
+
fullFacings: PensaOnDemandReportBucket | null;
|
|
67
|
+
fullFacingsAndProductPositions: PensaOnDemandReportBucket | null;
|
|
68
|
+
itemsSeen: PensaOnDemandReportBucket | null;
|
|
69
|
+
newProducts: PensaOnDemandReportBucket | null;
|
|
70
|
+
newProductPackaging: PensaOnDemandReportBucket | null;
|
|
71
|
+
noOos: PensaOnDemandReportBucket | null;
|
|
72
|
+
oos: PensaOnDemandReportBucket | null;
|
|
73
|
+
productPositions: PensaOnDemandReportBucket | null;
|
|
74
|
+
scanFailed: PensaOnDemandReportBucket | null;
|
|
75
|
+
scanRejected: PensaOnDemandReportBucket | null;
|
|
76
|
+
scanSkipped: PensaOnDemandReportBucket | null;
|
|
77
|
+
projectId: number | null;
|
|
78
|
+
projectName: string | null;
|
|
79
|
+
projectReportId: number | null;
|
|
80
|
+
projectReportName: string | null;
|
|
81
|
+
realogramSignedUrl: string | null;
|
|
82
|
+
shelfId: number | null;
|
|
83
|
+
shelfName: string | null;
|
|
84
|
+
status: string | null;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export enum PensaReportType {
|
|
88
|
+
FACINGS_SEEN = 'FACINGS_SEEN',
|
|
89
|
+
FULL_FACINGS = 'FULL_FACINGS',
|
|
90
|
+
FULL_FACINGS_AND_PRODUCT_POSITIONS = 'FULL_FACINGS_AND_PRODUCT_POSITIONS',
|
|
91
|
+
ITEMS_SEEN = 'ITEMS_SEEN',
|
|
92
|
+
NEW_PRODUCTS = 'NEW_PRODUCTS',
|
|
93
|
+
NEW_PRODUCT_PACKAGING = 'NEW_PRODUCT_PACKAGING',
|
|
94
|
+
NO_OOS = 'NO_OOS',
|
|
95
|
+
OOS = 'OOS',
|
|
96
|
+
PRODUCT_POSITIONS = 'PRODUCT_POSITIONS',
|
|
97
|
+
SCAN_FAILED = 'SCAN_FAILED',
|
|
98
|
+
SCAN_REJECTED = 'SCAN_REJECTED',
|
|
99
|
+
SCAN_SKIPPED = 'SCAN_SKIPPED',
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export type PensaShelfItem = {
|
|
103
|
+
id: number;
|
|
104
|
+
name: string | null;
|
|
105
|
+
};
|