@os1-platform/dispatch-mobile 2.1.6 → 2.1.7

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.
Files changed (102) hide show
  1. package/lib/commonjs/analytics/firebase/FirebaseLogging.js +11 -2
  2. package/lib/commonjs/analytics/firebase/FirebaseLogging.js.map +1 -1
  3. package/lib/commonjs/analytics/sentry/SentryAnalyticsUtils.js +6 -2
  4. package/lib/commonjs/analytics/sentry/SentryAnalyticsUtils.js.map +1 -1
  5. package/lib/commonjs/analytics/sentry/SentrySdkConstants.js +3 -0
  6. package/lib/commonjs/analytics/sentry/SentrySdkConstants.js.map +1 -1
  7. package/lib/commonjs/components/executiontasks/doodle/SignatureET.js +8 -1
  8. package/lib/commonjs/components/executiontasks/doodle/SignatureET.js.map +1 -1
  9. package/lib/commonjs/components/executiontasks/imageCapture/CaptureSchema.js.map +1 -1
  10. package/lib/commonjs/components/executiontasks/imageCapture/CaptureUtils.js +16 -15
  11. package/lib/commonjs/components/executiontasks/imageCapture/CaptureUtils.js.map +1 -1
  12. package/lib/commonjs/components/executiontasks/imageCapture/ImageCapture.js +9 -1
  13. package/lib/commonjs/components/executiontasks/imageCapture/ImageCapture.js.map +1 -1
  14. package/lib/commonjs/index.js +7 -0
  15. package/lib/commonjs/index.js.map +1 -1
  16. package/lib/commonjs/manager/location/LocationManager.js +9 -2
  17. package/lib/commonjs/manager/location/LocationManager.js.map +1 -1
  18. package/lib/commonjs/manager/sdk/DispatchSDKManager.js +3 -3
  19. package/lib/commonjs/manager/sdk/DispatchSDKManager.js.map +1 -1
  20. package/lib/commonjs/manager/sdk/callbacksHandler.js +8 -1
  21. package/lib/commonjs/manager/sdk/callbacksHandler.js.map +1 -1
  22. package/lib/commonjs/manager/syncmanager/DBConfig.js +3 -1
  23. package/lib/commonjs/manager/syncmanager/DBConfig.js.map +1 -1
  24. package/lib/commonjs/manager/syncmanager/document/DocumentHttpClient.js +77 -3
  25. package/lib/commonjs/manager/syncmanager/document/DocumentHttpClient.js.map +1 -1
  26. package/lib/commonjs/manager/syncmanager/document/DocumentManager.js +17 -3
  27. package/lib/commonjs/manager/syncmanager/document/DocumentManager.js.map +1 -1
  28. package/lib/commonjs/manager/syncmanager/document/DocumentSyncManager.js +206 -6
  29. package/lib/commonjs/manager/syncmanager/document/DocumentSyncManager.js.map +1 -1
  30. package/lib/commonjs/models/sdk.js.map +1 -1
  31. package/lib/commonjs/utils/ExecTaskUtils.js.map +1 -1
  32. package/lib/commonjs/utils/SyncManagerUtils.js +12 -2
  33. package/lib/commonjs/utils/SyncManagerUtils.js.map +1 -1
  34. package/lib/commonjs/utils/utils.js +24 -0
  35. package/lib/commonjs/utils/utils.js.map +1 -1
  36. package/lib/module/analytics/firebase/FirebaseLogging.js +11 -2
  37. package/lib/module/analytics/firebase/FirebaseLogging.js.map +1 -1
  38. package/lib/module/analytics/sentry/SentryAnalyticsUtils.js +6 -2
  39. package/lib/module/analytics/sentry/SentryAnalyticsUtils.js.map +1 -1
  40. package/lib/module/analytics/sentry/SentrySdkConstants.js +3 -0
  41. package/lib/module/analytics/sentry/SentrySdkConstants.js.map +1 -1
  42. package/lib/module/components/executiontasks/doodle/SignatureET.js +8 -1
  43. package/lib/module/components/executiontasks/doodle/SignatureET.js.map +1 -1
  44. package/lib/module/components/executiontasks/imageCapture/CaptureSchema.js.map +1 -1
  45. package/lib/module/components/executiontasks/imageCapture/CaptureUtils.js +16 -15
  46. package/lib/module/components/executiontasks/imageCapture/CaptureUtils.js.map +1 -1
  47. package/lib/module/components/executiontasks/imageCapture/ImageCapture.js +9 -1
  48. package/lib/module/components/executiontasks/imageCapture/ImageCapture.js.map +1 -1
  49. package/lib/module/index.js +2 -0
  50. package/lib/module/index.js.map +1 -1
  51. package/lib/module/manager/location/LocationManager.js +9 -2
  52. package/lib/module/manager/location/LocationManager.js.map +1 -1
  53. package/lib/module/manager/sdk/DispatchSDKManager.js +3 -3
  54. package/lib/module/manager/sdk/DispatchSDKManager.js.map +1 -1
  55. package/lib/module/manager/sdk/callbacksHandler.js +8 -1
  56. package/lib/module/manager/sdk/callbacksHandler.js.map +1 -1
  57. package/lib/module/manager/syncmanager/DBConfig.js +3 -1
  58. package/lib/module/manager/syncmanager/DBConfig.js.map +1 -1
  59. package/lib/module/manager/syncmanager/document/DocumentHttpClient.js +77 -3
  60. package/lib/module/manager/syncmanager/document/DocumentHttpClient.js.map +1 -1
  61. package/lib/module/manager/syncmanager/document/DocumentManager.js +17 -3
  62. package/lib/module/manager/syncmanager/document/DocumentManager.js.map +1 -1
  63. package/lib/module/manager/syncmanager/document/DocumentSyncManager.js +207 -7
  64. package/lib/module/manager/syncmanager/document/DocumentSyncManager.js.map +1 -1
  65. package/lib/module/models/sdk.js.map +1 -1
  66. package/lib/module/utils/ExecTaskUtils.js.map +1 -1
  67. package/lib/module/utils/SyncManagerUtils.js +12 -2
  68. package/lib/module/utils/SyncManagerUtils.js.map +1 -1
  69. package/lib/module/utils/utils.js +22 -0
  70. package/lib/module/utils/utils.js.map +1 -1
  71. package/lib/typescript/analytics/sentry/SentrySdkConstants.d.ts +3 -0
  72. package/lib/typescript/components/executiontasks/imageCapture/CaptureSchema.d.ts +4 -0
  73. package/lib/typescript/components/executiontasks/imageCapture/CaptureUtils.d.ts +7 -1
  74. package/lib/typescript/index.d.ts +2 -0
  75. package/lib/typescript/manager/location/LocationManager.d.ts +1 -0
  76. package/lib/typescript/manager/sdk/callbacksHandler.d.ts +3 -1
  77. package/lib/typescript/manager/syncmanager/DBConfig.d.ts +4 -0
  78. package/lib/typescript/manager/syncmanager/document/DocumentManager.d.ts +3 -1
  79. package/lib/typescript/manager/syncmanager/document/DocumentSyncManager.d.ts +5 -1
  80. package/lib/typescript/models/sdk.d.ts +1 -0
  81. package/lib/typescript/utils/SyncManagerUtils.d.ts +1 -1
  82. package/lib/typescript/utils/utils.d.ts +4 -0
  83. package/package.json +6 -5
  84. package/src/analytics/firebase/FirebaseLogging.ts +22 -10
  85. package/src/analytics/sentry/SentryAnalyticsUtils.ts +8 -2
  86. package/src/analytics/sentry/SentrySdkConstants.ts +3 -0
  87. package/src/components/executiontasks/doodle/SignatureET.tsx +14 -1
  88. package/src/components/executiontasks/imageCapture/CaptureSchema.ts +4 -0
  89. package/src/components/executiontasks/imageCapture/CaptureUtils.ts +32 -17
  90. package/src/components/executiontasks/imageCapture/ImageCapture.tsx +10 -2
  91. package/src/index.tsx +2 -0
  92. package/src/manager/location/LocationManager.ts +8 -1
  93. package/src/manager/sdk/DispatchSDKManager.ts +8 -2
  94. package/src/manager/sdk/callbacksHandler.ts +12 -1
  95. package/src/manager/syncmanager/DBConfig.ts +4 -0
  96. package/src/manager/syncmanager/document/DocumentHttpClient.ts +105 -5
  97. package/src/manager/syncmanager/document/DocumentManager.ts +28 -2
  98. package/src/manager/syncmanager/document/DocumentSyncManager.ts +230 -5
  99. package/src/models/sdk.ts +1 -0
  100. package/src/utils/ExecTaskUtils.ts +1 -1
  101. package/src/utils/SyncManagerUtils.ts +20 -2
  102. package/src/utils/utils.ts +23 -0
@@ -6,6 +6,11 @@ import { FileSystemUploadResult, FileSystemUploadType } from 'expo-file-system';
6
6
  import DispatchSdkCache from '../../sdk/DispatchSdkCache';
7
7
  import Logger, { LOG_TYPE } from '../../../utils/Logger';
8
8
  import type { DispatchSDKConfig } from '../../../models/sdk';
9
+ import RNFS from 'react-native-fs';
10
+ import { stat } from 'react-native-fs';
11
+ import { ScreenNameSdkConstants, SentryEventNameSdkConstants, SeverityLevelValue } from '../../../analytics/sentry/SentrySdkConstants';
12
+ import { fireEventWithScreenName } from '../../../analytics/sentry/SentryAnalyticsUtils';
13
+ import { flattenObject } from '../../../utils/utils';
9
14
 
10
15
  const cache = DispatchSdkCache.getInstance();
11
16
  const cacheKeys = DispatchSdkCache.KEYS;
@@ -16,6 +21,33 @@ export default class DocumentHttpClient extends HttpClient {
16
21
  public async uploadDocument(document: DocumentRow): Promise<string | null> {
17
22
  if (document.base64 && document.data != null) {
18
23
  const response = await this.uploadBase64File(document);
24
+
25
+ let info = '';
26
+ if (
27
+ response &&
28
+ response.data !== null &&
29
+ response.data.body !== null &&
30
+ response.status !== 202
31
+ ) {
32
+ let body = response.data.body;
33
+ info = body.substring(40);
34
+ } else {
35
+ info = String(response.status);
36
+ }
37
+ let extraParameters = { response: info };
38
+
39
+ fireEventWithScreenName({
40
+ severityLevel: SeverityLevelValue.LOG,
41
+ eventName: SentryEventNameSdkConstants.API_RESPONSE,
42
+ screenName: 'Upload_Base64_File_Response',
43
+ extraParams: extraParameters,
44
+ });
45
+
46
+ Logger.getInstance().logEvent(
47
+ 'uploadBase64FileResponse',
48
+ flattenObject(extraParameters),
49
+ LOG_TYPE.SDK_ERROR
50
+ );
19
51
  if (
20
52
  response &&
21
53
  response.data != null &&
@@ -29,10 +61,29 @@ export default class DocumentHttpClient extends HttpClient {
29
61
  }
30
62
  } else {
31
63
  const uploadResponse = await this.uploadBinaryFile(document);
64
+ let info = '';
65
+ if (
66
+ uploadResponse &&
67
+ uploadResponse.body !== null &&
68
+ uploadResponse.status !== 202
69
+ ) {
70
+ let body = uploadResponse.body;
71
+ info = body.substring(40);
72
+ } else {
73
+ info = String(uploadResponse.status);
74
+ }
75
+ let extraParams = { response: info };
76
+
77
+ fireEventWithScreenName({
78
+ severityLevel: SeverityLevelValue.LOG,
79
+ eventName: SentryEventNameSdkConstants.API_RESPONSE,
80
+ screenName: 'Upload_Binary_File_Response',
81
+ extraParams: extraParams,
82
+ });
32
83
  Logger.getInstance().logEvent(
33
- 'uploadDocument',
34
- JSON.stringify(uploadResponse),
35
- LOG_TYPE.SDK_INFO
84
+ 'uploadBinaryFileResponse',
85
+ flattenObject(extraParams),
86
+ LOG_TYPE.SDK_ERROR
36
87
  );
37
88
  if (
38
89
  uploadResponse != null &&
@@ -40,6 +91,8 @@ export default class DocumentHttpClient extends HttpClient {
40
91
  uploadResponse.body != null
41
92
  ) {
42
93
  FileSystem.deleteAsync(document.file_path).then().catch(); // WE DELETE FILE HERE
94
+ FileSystem.deleteAsync(document.processed_file_path).then().catch(); // WE DELETE FILE HERE
95
+
43
96
  return JSON.parse(uploadResponse.body)?.data?.id;
44
97
  } else {
45
98
  return null;
@@ -47,11 +100,20 @@ export default class DocumentHttpClient extends HttpClient {
47
100
  }
48
101
  }
49
102
 
103
+ // This function will upload processed base64 data (overlayed base64 data ) if exist otherwise will uplaod original base 64 data for pod signature.
50
104
  public async uploadBase64File(document: DocumentRow): Promise<AxiosResponse> {
105
+ let dataToUpload = document.data;
106
+ if (
107
+ document.processed_file_path !== null &&
108
+ document.processed_file_path !== undefined &&
109
+ document.processed_file_path !== ''
110
+ ) {
111
+ dataToUpload = document.processed_file_path;
112
+ }
51
113
  let requestBody = JSON.stringify({
52
114
  file: {
53
115
  type: 'FILE',
54
- data: document.data,
116
+ data: dataToUpload,
55
117
  },
56
118
  description: document.desc,
57
119
  tags: [
@@ -65,6 +127,22 @@ export default class DocumentHttpClient extends HttpClient {
65
127
  const sdkConfig = (await cache.getObjectFromCache(
66
128
  cacheKeys.SDK_CONFIG
67
129
  )) as DispatchSDKConfig;
130
+ let extraParams = {
131
+ fileName: document.file_name,
132
+ folderName: document.fms_folder_id,
133
+ };
134
+
135
+ fireEventWithScreenName({
136
+ severityLevel: SeverityLevelValue.LOG,
137
+ eventName: SentryEventNameSdkConstants.API_CALL,
138
+ screenName: 'Upload_Base64_File_Request',
139
+ extraParams: extraParams,
140
+ });
141
+ Logger.getInstance().logEvent(
142
+ 'uploadBase64FileRequest',
143
+ flattenObject(extraParams),
144
+ LOG_TYPE.SDK_ERROR
145
+ );
68
146
  return this.instance.post(
69
147
  `/api/folders/${document.fms_folder_id}/files`,
70
148
  requestBody,
@@ -79,15 +157,37 @@ export default class DocumentHttpClient extends HttpClient {
79
157
  }
80
158
  );
81
159
  }
160
+
161
+ // This function will upload processed (overlayed file) if exist otherwise will uplaod original file for pod images.
82
162
  private async uploadBinaryFile(
83
163
  document: DocumentRow
84
164
  ): Promise<FileSystemUploadResult> {
85
165
  const sdkConfig = (await cache.getObjectFromCache(
86
166
  cacheKeys.SDK_CONFIG
87
167
  )) as DispatchSDKConfig;
168
+ let filePathToUpload = document.file_path;
169
+ let processedFileExist = await RNFS.exists(document.processed_file_path);
170
+ if (processedFileExist) {
171
+ filePathToUpload = document.processed_file_path;
172
+ }
88
173
  const url =
89
174
  sdkConfig.tenantBaseURL + `/api/folders/${document.fms_folder_id}/files`;
90
- return FileSystem.uploadAsync(url, document.file_path, {
175
+ let extraParams = {
176
+ fileName: document.file_name,
177
+ folderName: document.fms_folder_id,
178
+ };
179
+ fireEventWithScreenName({
180
+ severityLevel: SeverityLevelValue.LOG,
181
+ eventName: SentryEventNameSdkConstants.API_CALL,
182
+ screenName: 'Upload_Binary_File_Request',
183
+ extraParams: extraParams,
184
+ });
185
+ Logger.getInstance().logEvent(
186
+ 'uploadBinaryFileRequest',
187
+ flattenObject(extraParams),
188
+ LOG_TYPE.SDK_ERROR
189
+ );
190
+ return FileSystem.uploadAsync(url, filePathToUpload, {
91
191
  headers: {
92
192
  'accept': 'application/json',
93
193
  'Content-Type': 'multipart/form-data',
@@ -31,11 +31,17 @@ export default class DocumentManager {
31
31
  ${DOCUMENT_COLUMNS.FMS_FOLDER_ID} TEXT,\
32
32
  ${DOCUMENT_COLUMNS.PRIORITY} INTEGER NOT NULL DEFAULT 1,\
33
33
  ${DOCUMENT_COLUMNS.SYNC_ERROR} TEXT,\
34
+ ${DOCUMENT_COLUMNS.GEO_TIMESTAMP} TEXT,\
35
+ ${DOCUMENT_COLUMNS.PROCESSED_FILE_PATH} TEXT,\
34
36
  ${DOCUMENT_COLUMNS.DESCRIPTION} TEXT);`,
35
37
  []
36
38
  );
37
39
  }
38
40
 
41
+ public async truncateDocumentTable(): Promise<void> {
42
+ await Database.executeQuery(`DELETE FROM ${DOCUMENT_TABLE};`, []);
43
+ }
44
+
39
45
  public async insertDocument(
40
46
  fmsFolderID: string | null,
41
47
  desc: string,
@@ -47,8 +53,11 @@ export default class DocumentManager {
47
53
  fileType: string,
48
54
  data?: string | null,
49
55
  filePath?: string | null,
56
+ geoTimeStamp?: string | null,
57
+ processedFilePath?: string | null,
50
58
  priority?: number
51
59
  ): Promise<SQLResultSet> {
60
+ console.log('insertDocument2:', fmsFolderID);
52
61
  return await Database.executeQuery(
53
62
  `INSERT INTO ${DOCUMENT_TABLE}(\
54
63
  ${DOCUMENT_COLUMNS.DATA},\
@@ -59,8 +68,10 @@ export default class DocumentManager {
59
68
  ${DOCUMENT_COLUMNS.FILE_NAME},\
60
69
  ${DOCUMENT_COLUMNS.FILE_TYPE},\
61
70
  ${DOCUMENT_COLUMNS.DESCRIPTION},\
62
- ${DOCUMENT_COLUMNS.PRIORITY}) \
63
- values (?,?,?,?,?,?,?,?,?)`,
71
+ ${DOCUMENT_COLUMNS.PRIORITY},\
72
+ ${DOCUMENT_COLUMNS.GEO_TIMESTAMP},\
73
+ ${DOCUMENT_COLUMNS.PROCESSED_FILE_PATH}) \
74
+ values (?,?,?,?,?,?,?,?,?,?,?)`,
64
75
  [
65
76
  data,
66
77
  dspID,
@@ -71,6 +82,8 @@ export default class DocumentManager {
71
82
  fileType,
72
83
  desc,
73
84
  priority ? priority : 1,
85
+ geoTimeStamp,
86
+ processedFilePath,
74
87
  ]
75
88
  );
76
89
  }
@@ -117,6 +130,19 @@ export default class DocumentManager {
117
130
  );
118
131
  }
119
132
 
133
+ // This function is updating processed_file_path column for the base64 overlayed data and overlayed image file for POD. Also if it is base 64 then it is also storing temprary file path in file_path as original bae64 image.
134
+ public async updateProcesedFilePath(
135
+ id: number,
136
+ origialFilePath: String,
137
+ processedFilePath: String
138
+ ): Promise<void> {
139
+ if (!id || !processedFilePath) return;
140
+ await Database.executeQuery(
141
+ `UPDATE ${DOCUMENT_TABLE} SET ${DOCUMENT_COLUMNS.FILE_PATH} = ?, ${DOCUMENT_COLUMNS.PROCESSED_FILE_PATH} = ? WHERE ${DOCUMENT_COLUMNS.ID} = ?;`,
142
+ [origialFilePath, processedFilePath, id]
143
+ );
144
+ }
145
+
120
146
  public async updateDocSyncError(
121
147
  id: number,
122
148
  uploadError: string
@@ -1,7 +1,7 @@
1
1
  import type { DocumentRow } from '../DBConfig';
2
2
  import DocumentManager from './DocumentManager';
3
3
  import DocumentHttpClient from './DocumentHttpClient';
4
- import { isEmptyOrBlank } from '../../../utils/utils';
4
+ import { isEmptyOrBlank, flattenObject } from '../../../utils/utils';
5
5
  import { BaseError } from '../../../errors/BaseError';
6
6
  import BaseErrorCodes, {
7
7
  InvalidArgumentsError,
@@ -11,6 +11,18 @@ import BaseErrorCodes, {
11
11
  import Logger, { LOG_TYPE } from '../../../utils/Logger';
12
12
  import type { SQLResultSet } from 'expo-sqlite';
13
13
  import NetworkUtil from '../../../utils/NetworkUtil';
14
+ import Marker, {
15
+ Position,
16
+ TextBackgroundType,
17
+ ImageFormat,
18
+ } from 'react-native-image-marker';
19
+ import RNFS from 'react-native-fs';
20
+ import Storage from '../../../utils/storage';
21
+ import { Platform } from 'react-native';
22
+ import { ScreenNameSdkConstants, SentryEventNameSdkConstants, SeverityLevelValue } from '../../../analytics/sentry/SentrySdkConstants';
23
+ import { fireEventWithScreenName } from '../../../analytics/sentry/SentryAnalyticsUtils';
24
+ const latlngToDms = require('latlng-to-dms');
25
+
14
26
 
15
27
  export default class DocumentSyncManager {
16
28
  private documentHttpClient: DocumentHttpClient | undefined;
@@ -105,6 +117,8 @@ export default class DocumentSyncManager {
105
117
  filePath: string | null,
106
118
  fileType: string,
107
119
  fileName: string,
120
+ geoTimeStamp: string,
121
+ processedFilePath: string,
108
122
  priority: number = 1
109
123
  ): Promise<SQLResultSet> {
110
124
  if (
@@ -130,6 +144,7 @@ export default class DocumentSyncManager {
130
144
  );
131
145
  this.docManager = await DocumentManager.getInstance();
132
146
  }
147
+ console.log('insertDocument1:',fmsFolderID);
133
148
  let insertResponse = await this.docManager?.insertDocument(
134
149
  fmsFolderID,
135
150
  desc,
@@ -141,6 +156,8 @@ export default class DocumentSyncManager {
141
156
  fileType,
142
157
  data,
143
158
  filePath,
159
+ geoTimeStamp,
160
+ processedFilePath,
144
161
  priority
145
162
  );
146
163
  return insertResponse;
@@ -166,6 +183,28 @@ export default class DocumentSyncManager {
166
183
  }
167
184
  }
168
185
 
186
+ // This function is updating processed_file_path column for the base64 overlayed data and overlayed image file for POD. Also if it is base 64 then it is also storing temprary file path in file_path as original bae64 image.
187
+ private async updateDocumentProcessedPath(
188
+ documentRow: DocumentRow,
189
+ origialFilePath: String,
190
+ processedPath: String
191
+ ) {
192
+ if (!this.docManager) this.docManager = await DocumentManager.getInstance();
193
+ try {
194
+ await this.docManager.updateProcesedFilePath(
195
+ documentRow.id,
196
+ origialFilePath,
197
+ processedPath
198
+ );
199
+ } catch (err: any) {
200
+ Logger.getInstance().logEvent(
201
+ 'updateDocument',
202
+ err.message,
203
+ LOG_TYPE.SDK_WARNING
204
+ );
205
+ }
206
+ }
207
+
169
208
  private async updateDocError(documentRow: DocumentRow, uploadError: string) {
170
209
  if (!this.docManager) this.docManager = await DocumentManager.getInstance();
171
210
  try {
@@ -187,23 +226,209 @@ export default class DocumentSyncManager {
187
226
  }
188
227
  }
189
228
 
229
+ // This function will generate overlay image and update documents table for processed_file_path columns with overlayed image path.
230
+ private async processImageData(documentRow: DocumentRow) {
231
+ // If processed_file_path of overlayed image already existing then do not generate it again.
232
+ if (
233
+ documentRow.processed_file_path === null ||
234
+ documentRow.processed_file_path === ''
235
+ ) {
236
+ let pFilePath = 'processed_' + documentRow.file_name; // File name for processed file.
237
+ let strGeoStamp = documentRow.geo_timestamp; // Saved geostamp string
238
+ let objGeoStamp = JSON.parse(strGeoStamp); // Conversion to geostamp object
239
+ let dateTime = objGeoStamp.dateTime; // Date time stamp in UTC format
240
+ let lat = objGeoStamp.lat; // Latitide
241
+ let lng = objGeoStamp.lng; // Longitude
242
+ let accuracy = objGeoStamp.accuracy; // Location accuracy
243
+ let strDMS = latlngToDms(`${lat}, ${lng}`); // Location in degree format
244
+ let strDMSWithAccuracy = strDMS;
245
+ if (accuracy !== '') {
246
+ strDMSWithAccuracy = strDMS + ' (Accuracy: ' + accuracy + 'm)'; // Appedning accuracy in location
247
+ }
248
+ let fontSize = 14;
249
+
250
+ let fileSize = await Storage.getInstance().getItem('maxSize'); // File max size
251
+ let cRatio = await Storage.getInstance().getItem('cRatio'); // File compression ratio
252
+ let nFileSize = Number(fileSize);
253
+ let ncRatio = Number(cRatio);
254
+ let wholeRatio = Math.round(ncRatio * 100); // Compression ratio to be made
255
+ if (Platform.OS !== 'android') {
256
+ fontSize = 28;
257
+ }
258
+ if(wholeRatio >= 75){
259
+ wholeRatio = 25;
260
+ }
261
+ const options = {
262
+ backgroundImage: { // Image for overlay
263
+ src: documentRow.file_path,
264
+ scale: 1,
265
+ },
266
+ watermarkTexts: [
267
+ {
268
+ text: `${dateTime}\n${strDMSWithAccuracy}`, //Overlay text
269
+ position: {
270
+ position: Position.topLeft, // Overlay text position
271
+ },
272
+ style: { // Style for overlay
273
+ color: '#ffffff',
274
+ fontSize: fontSize,
275
+ fontName: 'Arial',
276
+ textBackgroundStyle: {
277
+ padding: '1% 1%',
278
+ type: TextBackgroundType.none,
279
+ color: '#444444CC',
280
+ },
281
+ },
282
+ },
283
+ ],
284
+ scale: 1,
285
+ quality: 100 - wholeRatio, // Compressio ratio in which file will generate
286
+ maxSize: nFileSize, // Max file size in which file will generate
287
+ filename: pFilePath,
288
+ saveFormat: ImageFormat.jpg, // Saving in jpeg format
289
+ };
290
+ let processedFilePath = await Marker.markText(options); // Generating overlay image
291
+ if (processedFilePath !== null && processedFilePath !== '') {
292
+ let completeFilePath = processedFilePath;
293
+ // If processd image file path does not have prefix file:// then we are addding manually
294
+ if (!processedFilePath.includes('file')) {
295
+ completeFilePath = 'file://' + processedFilePath;
296
+ }
297
+ // Updating document document table with overlayed image path
298
+ this.updateDocumentProcessedPath(
299
+ documentRow,
300
+ documentRow.file_path, //original file path catprued from camera
301
+ completeFilePath // completeFilePath is the path with file:// of processed file
302
+ );
303
+ documentRow.processed_file_path = completeFilePath;
304
+ }
305
+ }
306
+ return documentRow;
307
+ }
308
+
309
+ // This function will generate overlay base64 data and update documents table for processed_file_path columns with overlayed base64 data.
310
+ private async processBase64Data(documentRow: DocumentRow) {
311
+ // If base64 overlayed data already existing then do not generate it again.
312
+ if (
313
+ documentRow.processed_file_path === null ||
314
+ documentRow.processed_file_path === ''
315
+ ) {
316
+ let filePath = '';
317
+ // If templrary base 64 file already exist then do not create again
318
+ if (documentRow.file_path === null || documentRow.file_path === '') {
319
+ const imagePath = `${RNFS.TemporaryDirectoryPath}/${documentRow.file_name}`;
320
+ await RNFS.writeFile(imagePath, documentRow.data, 'base64'); // Write file to temprary location
321
+ filePath = imagePath;
322
+ // If file generated frommbase64 data does not have file:// then we are adding manually.
323
+ if (!imagePath.includes('file')) {
324
+ filePath = `file://${imagePath}`;
325
+ }
326
+ documentRow.file_path = filePath;
327
+ } else {
328
+ filePath = documentRow.file_path;
329
+ }
330
+ let pFilePath = 'processed_' + documentRow.file_name; // File name for processed file.
331
+ let strGeoStamp = documentRow.geo_timestamp; // Saved geostamp string
332
+ let objGeoStamp = JSON.parse(strGeoStamp); // Conversion to geostamp object
333
+ let dateTime = objGeoStamp.dateTime; // Date time stamp in UTC format
334
+ let lat = objGeoStamp.lat; // Latitide
335
+ let lng = objGeoStamp.lng; // Longitude
336
+ let accuracy = objGeoStamp.accuracy; // Location accuracy
337
+ let strDMS = latlngToDms(`${lat}, ${lng}`); // Location in degree format
338
+ let strDMSWithAccuracy = strDMS;
339
+ if (accuracy !== '') {
340
+ strDMSWithAccuracy = strDMS + ' (Accuracy: ' + accuracy + 'm)'; // Appedning accuracy in location
341
+ }
342
+ const options = {
343
+ backgroundImage: {
344
+ src: filePath, // Image for overlay
345
+ scale: 1,
346
+ },
347
+ watermarkTexts: [
348
+ {
349
+ text: `${dateTime}\n${strDMSWithAccuracy}`, // Ooverlay text
350
+ position: {
351
+ position: Position.topLeft, // Overlay text position
352
+ },
353
+ style: { // Style for overlay
354
+ color: '#ffffff',
355
+ fontSize: 14,
356
+ fontName: 'Arial',
357
+ textBackgroundStyle: {
358
+ padding: '1% 1%',
359
+ type: TextBackgroundType.none,
360
+ color: '#444444CC',
361
+ },
362
+ },
363
+ },
364
+ ],
365
+ scale: 1,
366
+ quality: 100,
367
+ filename: pFilePath,
368
+ saveFormat: ImageFormat.base64, // Saving in base6 format
369
+ };
370
+ let processedBase64 = await Marker.markText(options); // Generating overlay image
371
+ if (processedBase64 !== null && processedBase64 !== '') {
372
+ // Fetching base64 data from processed data.
373
+ var splittedDase64Data = processedBase64.split(
374
+ 'data:image/png;base64,'
375
+ );
376
+ // Updating document document table with overlayed base64 data
377
+ await this.updateDocumentProcessedPath(
378
+ documentRow,
379
+ filePath,
380
+ splittedDase64Data[1]
381
+ );
382
+ documentRow.processed_file_path = splittedDase64Data[1];
383
+ }
384
+ }
385
+ return documentRow;
386
+ }
387
+
388
+ // This function will calling respective overlay method for base64 (for signature POD) or image (for image POD).
389
+ private async processPODData(documentRow: DocumentRow) {
390
+ if (documentRow.base64 && documentRow.data != null) {
391
+ return await this.processBase64Data(documentRow);
392
+ } else {
393
+ return await this.processImageData(documentRow);
394
+ }
395
+ }
396
+
190
397
  private async uploadDocToServer(documentRow: DocumentRow) {
191
398
  try {
399
+ let docRow = await this.processPODData(documentRow);
400
+ console.log('uploadDocToServer999:', docRow);
192
401
  let fmsID = await this.documentHttpClient?.uploadDocument(documentRow);
402
+
403
+ let extraParameters = {
404
+ fmsID: fmsID ?? '',
405
+ fileName: docRow.file_name,
406
+ folderName: docRow.fms_folder_id
407
+ };
193
408
  // TODO: SOLELY DEPENDS ON FMS_ID WHICH IS WRONG => IT SHOULD BE Response.status = 202
194
409
  if (fmsID) {
195
410
  this._retries = 0;
196
- await this.updateDocument(documentRow, fmsID);
411
+ await this.updateDocument(docRow, fmsID);
197
412
  } else {
198
413
  this._retries++;
199
414
  Logger.getInstance().logEvent(
200
- 'uploadDocToServer-sync-error',
201
- 'Unexpected Error',
415
+ 'uploadDocToServer-empty-fms-id',
416
+ flattenObject(extraParameters),
202
417
  LOG_TYPE.SDK_ERROR
203
418
  );
204
- await this.updateDocError(documentRow, 'Unexpected Error');
419
+ await this.updateDocError(docRow, 'Unexpected Error');
205
420
  }
206
421
  } catch (error: any) {
422
+ const cta = 'uploadDocToServer-error';
423
+ fireEventWithScreenName({
424
+ severityLevel: SeverityLevelValue.ERROR,
425
+ eventName: SentryEventNameSdkConstants.API_ERROR,
426
+ screenName: cta,
427
+ cta: cta,
428
+ extraParams: {
429
+ error: error.message,
430
+ },
431
+ });
207
432
  this._retries++;
208
433
  Logger.getInstance().logEvent(
209
434
  'uploadDocToServer-sync-error',
package/src/models/sdk.ts CHANGED
@@ -25,6 +25,7 @@ export interface DispatchSDKConfig {
25
25
  fetchPhoneNumbersCallback?: (
26
26
  sdsIds: string[]
27
27
  ) => Promise<{ key: string; value: string[] }>;
28
+ fetchDateTimeCallback?: () => Promise<string>;
28
29
  };
29
30
  }
30
31
 
@@ -149,7 +149,7 @@ export function onTaskStart(
149
149
  let lastLocation = LocationManager.getInstance().getLastLocation();
150
150
  let location = {
151
151
  latitude: lastLocation.latitude,
152
- longitude: lastLocation.longitude
152
+ longitude: lastLocation.longitude,
153
153
  }
154
154
  console.log("onTaskStart:lastLocation:",location)
155
155
  await cache.setKeyInCache(keys.TASK_START_TIME, Date.now().toString());
@@ -14,6 +14,7 @@ import type {
14
14
  ExecEngineSyncType,
15
15
  } from '../manager/syncmanager/DBConfig';
16
16
  import Storage from './storage';
17
+ import LocationManager from '../manager/location/LocationManager';
17
18
 
18
19
  const keys = DispatchSdkCache.KEYS;
19
20
  const cache = DispatchSdkCache.getInstance();
@@ -135,8 +136,23 @@ export async function insertDocumentInDB(
135
136
  // objRef: string,
136
137
  base64Image: string | null,
137
138
  imageDesc: string,
138
- filePath: string | null
139
+ filePath: string | null,
140
+ dateTime: string | null,
141
+ lat: string,
142
+ lng: string,
143
+ accuracy: string
139
144
  ): Promise<number | undefined> {
145
+ let geoTimeStamp = {
146
+ dateTime: dateTime,
147
+ lat: lat,
148
+ lng: lng,
149
+ accuracy: accuracy,
150
+ };
151
+ let geoTimeStampStr = JSON.stringify(geoTimeStamp);
152
+ console.log('geoTimeStampStr:', geoTimeStampStr);
153
+ console.log('insertDocumentInDB1:', fmsFolderName);
154
+
155
+ let processedFilePath = '';
140
156
  try {
141
157
  const dspID = await cache.getKeyFromCache(keys.DISPATCH_ID);
142
158
  let response = await DocumentSyncManager.getInstance().insertDocument(
@@ -149,7 +165,9 @@ export async function insertDocumentInDB(
149
165
  // objRef,
150
166
  filePath,
151
167
  'image',
152
- fileName
168
+ fileName,
169
+ geoTimeStampStr,
170
+ processedFilePath
153
171
  );
154
172
  AppSyncManager.getInstance().startSDKSyncManager();
155
173
  return response.insertId;
@@ -28,3 +28,26 @@ export function isTokenExpired(accessToken: string) {
28
28
  let decodedData: any = jwtDecode(accessToken);
29
29
  return !(decodedData && decodedData.exp * 1000 > Date.now());
30
30
  }
31
+
32
+ export function flattenObject(obj: Record<string, any>, prefix = ''): string {
33
+ return JSON.stringify(obj);
34
+ // return Object.keys(obj).reduce((acc, key) => {
35
+ // const flatKey = prefix ? `${prefix}.${key}` : key;
36
+ // if (typeof obj[key] === 'object' && !Array.isArray(obj[key])) {
37
+ // return acc ?? '' + flattenObject(obj[key], flatKey);
38
+ // } else {
39
+ // return acc ?? '' + `${flatKey}: ${JSON.stringify(obj[key])}\n`;
40
+ // }
41
+ // }, '');
42
+ }
43
+
44
+
45
+ export function createObjectWithoutNullValues<T extends { [key: string]: any }>(obj: T): Partial<T> {
46
+ const newObj: Partial<T> = {};
47
+ for (const key in obj) {
48
+ if (Object.prototype.hasOwnProperty.call(obj, key) && obj[key] !== null && obj[key] !== 'request' && obj[key] !== 'headers') {
49
+ newObj[key] = obj[key];
50
+ }
51
+ }
52
+ return newObj;
53
+ }