diff --git a/.github/workflows/newBuild.yml b/.github/workflows/newBuild.yml
index 559bb7a9..8d211e9c 100644
--- a/.github/workflows/newBuild.yml
+++ b/.github/workflows/newBuild.yml
@@ -330,7 +330,7 @@ jobs:
# git config --local user.email "${{ github.actor }}@github.com"
git config --local user.name "${{ github.actor }}"
git tag $TAG_NAME
- git push origin $TAG_NAME
+ git push origin $TAG_NAME --no-verify
env:
GITHUB_TOKEN: ${{ secrets.MY_REPO_PAT }}
- name: Create release tag
diff --git a/App.tsx b/App.tsx
index 32ae8c79..d3d93e59 100644
--- a/App.tsx
+++ b/App.tsx
@@ -125,6 +125,10 @@ function App() {
case codePush.SyncStatus.UP_TO_DATE:
modalRef.current?.hide();
break;
+ case codePush.SyncStatus.UNKNOWN_ERROR:
+ addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_CODEPUSH_UNKNOWN_ERROR, {});
+ modalRef.current?.hide();
+ break;
default:
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_CODEPUSH_DEFAULT_STATUS, {});
modalRef.current?.hide();
diff --git a/package.json b/package.json
index 7659d333..5e25d078 100644
--- a/package.json
+++ b/package.json
@@ -7,18 +7,18 @@
"android:dev": "yarn move:dev && react-native run-android",
"android:qa": "yarn move:qa && react-native run-android",
"android:prod": "yarn move:prod && react-native run-android",
- "android-field:dev": "yarn move:dev && react-native run-android --variant=fieldAgentsQADebug",
- "android-field:qa": "yarn move:qa && react-native run-android --variant=fieldAgentsQADebug",
- "android-field:prod": "yarn move:prod && react-native run-android --variant=fieldAgentsProdDebug",
- "release-field:dev": "yarn move:dev && yarn prepare-field-build && react-native run-android --variant=fieldAgentsQARelease && cd android && ./gradlew assemblefieldAgentsQARelease",
- "release-field:qa": "yarn move:qa && yarn prepare-field-build && react-native run-android --variant=fieldAgentsQARelease && cd android && ./gradlew assemblefieldAgentsQARelease",
- "release-field:prod": "yarn move:prod && yarn prepare-field-build && react-native run-android --variant=fieldAgentsProdRelease && cd android && ./gradlew assemblefieldAgentsProdRelease",
- "android-calling:dev": "yarn move:dev && yarn prepare-tele-build && react-native run-android --variant=callingAgentsQADebug",
- "android-calling:qa": "yarn move:qa && yarn prepare-tele-build && react-native run-android --variant=callingAgentsQADebug",
- "android-calling:prod": "yarn move:prod && yarn prepare-tele-build && react-native run-android --variant=callingAgentsProdDebug",
- "release-calling:dev": "yarn move:dev && react-native run-android --variant=callingAgentsQARelease && cd android && ./gradlew assemblecallingAgentsQARelease",
- "release-calling:qa": "yarn move:qa && react-native run-android --variant=callingAgentsQARelease && cd android && ./gradlew assemblecallingAgentsQARelease",
- "release-calling:prod": "yarn move:prod && react-native run-android --variant=callingAgentsProdRelease && cd android && ./gradlew assemblecallingAgentsProdRelease",
+ "android-field:dev": "yarn move:dev && react-native run-android --mode=fieldAgentsQADebug",
+ "android-field:qa": "yarn move:qa && react-native run-android --mode=fieldAgentsQADebug",
+ "android-field:prod": "yarn move:prod && react-native run-android --mode=fieldAgentsProdDebug",
+ "release-field:dev": "yarn move:dev && yarn prepare-field-build && react-native run-android --mode=fieldAgentsQARelease && cd android && ./gradlew assemblefieldAgentsQARelease",
+ "release-field:qa": "yarn move:qa && yarn prepare-field-build && react-native run-android --mode=fieldAgentsQARelease && cd android && ./gradlew assemblefieldAgentsQARelease",
+ "release-field:prod": "yarn move:prod && yarn prepare-field-build && react-native run-android --mode=fieldAgentsProdRelease && cd android && ./gradlew assemblefieldAgentsProdRelease",
+ "android-calling:dev": "yarn move:dev && yarn prepare-tele-build && react-native run-android --mode=callingAgentsQADebug",
+ "android-calling:qa": "yarn move:qa && yarn prepare-tele-build && react-native run-android --mode=callingAgentsQADebug",
+ "android-calling:prod": "yarn move:prod && yarn prepare-tele-build && react-native run-android --mode=callingAgentsProdDebug",
+ "release-calling:dev": "yarn move:dev && react-native run-android --mode=callingAgentsQARelease && cd android && ./gradlew assemblecallingAgentsQARelease",
+ "release-calling:qa": "yarn move:qa && react-native run-android --mode=callingAgentsQARelease && cd android && ./gradlew assemblecallingAgentsQARelease",
+ "release-calling:prod": "yarn move:prod && react-native run-android --mode=callingAgentsProdRelease && cd android && ./gradlew assemblecallingAgentsProdRelease",
"ios": "react-native run-ios",
"start": "react-native start",
"test": "jest",
diff --git a/src/action/appDownloadAction.ts b/src/action/appDownloadAction.ts
index 5203abbe..13338629 100644
--- a/src/action/appDownloadAction.ts
+++ b/src/action/appDownloadAction.ts
@@ -1,6 +1,8 @@
-import { BuildFlavours } from '@common/Constants';
+import { BuildFlavours, CLICKSTREAM_EVENT_NAMES } from '@common/Constants';
import { ApiKeys, getApiUrl } from '@components/utlis/apiHelper';
+import { getBuildVersion } from '@components/utlis/commonFunctions';
import { logError } from '@components/utlis/errorUtils';
+import { addClickstreamEvent } from '@services/clickstreamEventService';
import axios from 'axios';
import { Linking, NativeModules } from 'react-native';
import RNFetchBlob from 'react-native-blob-util';
@@ -24,17 +26,33 @@ export const deleteCachedApkFiles = async () => {
}
};
-export const downloadApkFromS3 = async (s3Url: string, fileName: string) => {
+export const downloadApkFromS3 = async (s3Url: string, fileName: string, newAppVersion: number) => {
deleteCachedApkFiles();
const dirs = RNFetchBlob.fs.dirs;
const pathToSaveAPK = `${dirs.CacheDir}/latest-app/${fileName}.apk`;
+ const oldAppVersion = getBuildVersion();
try {
+ addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_APK_UPDATE_DOWNLOAD_STARTED, {
+ downloadPath: pathToSaveAPK,
+ oldAppVersion,
+ newAppVersion,
+ });
const res = await RNFetchBlob.config({
path: pathToSaveAPK,
fileCache: true,
}).fetch('GET', s3Url, {});
+ addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_APK_UPDATE_DOWNLOAD_SUCCESS, {
+ downloadPath: res.path(),
+ oldAppVersion,
+ newAppVersion,
+ });
return res.path();
} catch (err) {
+ addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_APK_UPDATE_DOWNLOAD_FAILED, {
+ errorMessage: (err as Error)?.message,
+ oldAppVersion,
+ newAppVersion,
+ });
logError(err as Error, 'Error while downloading the latest app');
}
};
@@ -56,21 +74,28 @@ const openApkDownloadLink = (url: string) => {
export const openFallbackLonghornLink = (fallbackUrl?: string) => {
if (fallbackUrl) {
+ addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_APK_UPDATE_FALLBACK_TRIGGERED, {
+ fallbackUrl,
+ });
openApkDownloadLink(fallbackUrl);
}
};
-export const downloadLatestApkAndGetFilePath = async (buildFlavour: BuildFlavours) => {
+export const downloadLatestApkAndGetFilePath = async (
+ buildFlavour: BuildFlavours,
+ appVersion: number
+) => {
const appUrl = await downloadLatestAppS3Url(buildFlavour);
if (!appUrl) {
return '';
}
const appFileUrl = await downloadApkFromS3(
appUrl,
- `Cosmos_${BuildFlavours.FIELD_AGENTS}_${Date.now()}`
+ `Cosmos_${BuildFlavours.FIELD_AGENTS}_${Date.now()}`,
+ appVersion
);
if (!appFileUrl) {
return '';
}
return appFileUrl;
-};
+};
\ No newline at end of file
diff --git a/src/common/BlockerScreen.tsx b/src/common/BlockerScreen.tsx
index 985f959b..e3148085 100644
--- a/src/common/BlockerScreen.tsx
+++ b/src/common/BlockerScreen.tsx
@@ -1,8 +1,6 @@
import React, { ReactNode, useCallback, useState } from 'react';
import { AppState, Linking } from 'react-native';
import { useSelector } from 'react-redux';
-
-
import { RootState } from '../store/store';
import { IAppState } from '../reducer/metadataSlice';
import { getBuildVersion } from '../components/utlis/commonFunctions';
@@ -28,6 +26,9 @@ import {
openFallbackLonghornLink,
} from '@actions/appDownloadAction';
import AppUpdate from './AppUpdate';
+import ReactNativeBlobUtil from 'react-native-blob-util';
+import { setShouldUpdate } from '@reducers/appUpdateSlice';
+import PostOperativeHours from './PostOperativeHours';
interface IBlockerScreen {
children?: ReactNode;
@@ -44,15 +45,13 @@ const BlockerScreen = (props: IBlockerScreen) => {
const approvalStatus = useAppSelector((state) => state.profile?.approvalStatus);
const isLoading = useAppSelector((state) => state.profile?.isLoading);
const roles = useAppSelector((state) => state.user?.agentRoles);
+ const shouldUpdate = useAppSelector((state) => state.appUpdate.shouldUpdate) || {};
+ const withinOperativeHours = useAppSelector((state) => state.user?.withinOperativeHours);
+ const isLoggedIn = useAppSelector((state: RootState) => state.user?.isLoggedIn);
const isFieldAgent =
(roles?.length === 1 && roles.includes(IUserRole.ROLE_FIELD_AGENT)) ||
roles.includes(IUserRole.ROLE_OMA);
- const [shouldUpdate, setShouldUpdate] = useState({
- newApkCachedUrl: '',
- switchToFallback: false,
- });
-
const [showActionBtnLoader, setShowActionBtnLoader] = useState(false);
const dispatch = useAppDispatch();
@@ -63,15 +62,21 @@ const BlockerScreen = (props: IBlockerScreen) => {
let apkFileUrl;
if (GLOBAL.BUILD_FLAVOUR.includes(BuildFlavours.FIELD_AGENTS)) {
// Download app for Field agent
- apkFileUrl = await downloadLatestApkAndGetFilePath(BuildFlavours.FIELD_AGENTS);
+ apkFileUrl = await downloadLatestApkAndGetFilePath(
+ BuildFlavours.FIELD_AGENTS,
+ appState?.fieldAgents?.version
+ );
} else {
// Download app for Calling agent
- apkFileUrl = await downloadLatestApkAndGetFilePath(BuildFlavours.CALLING_AGENTS);
+ apkFileUrl = await downloadLatestApkAndGetFilePath(
+ BuildFlavours.CALLING_AGENTS,
+ appState?.callingAgents?.version
+ );
}
if (apkFileUrl) {
- setShouldUpdate({ newApkCachedUrl: apkFileUrl, switchToFallback: false });
+ dispatch(setShouldUpdate({ newApkCachedUrl: apkFileUrl, switchToFallback: false }));
} else {
- setShouldUpdate({ newApkCachedUrl: '', switchToFallback: true });
+ dispatch(setShouldUpdate({ newApkCachedUrl: '', switchToFallback: true }));
}
};
@@ -82,8 +87,14 @@ const BlockerScreen = (props: IBlockerScreen) => {
if (GLOBAL.BUILD_FLAVOUR.includes('fieldAgents')) {
fallbackLonghornUrl = appState?.fieldAgents?.currentProdAPK;
} else {
+ newAppVersion = appState?.callingAgents?.version;
fallbackLonghornUrl = appState?.callingAgents?.currentProdAPK;
}
+ addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_APK_UPDATE_BUTTON_CLICKED, {
+ apkPath: shouldUpdate.newApkCachedUrl,
+ oldAppVersion,
+ newAppVersion,
+ });
if (!shouldUpdate.newApkCachedUrl) {
openFallbackLonghornLink(fallbackLonghornUrl);
return;
@@ -125,11 +136,16 @@ const BlockerScreen = (props: IBlockerScreen) => {
currentBuildNumber < flavorToUpdate.version
) {
downloadLatestApp();
- } else {
- setShouldUpdate({
- newApkCachedUrl: '',
- switchToFallback: false,
+ } else if (shouldUpdate.newApkCachedUrl) {
+ addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_APK_UPDATE_INSTALL_SUCCESS, {
+ appVersion: currentBuildNumber,
});
+ dispatch(
+ setShouldUpdate({
+ newApkCachedUrl: '',
+ switchToFallback: false,
+ })
+ );
deleteCachedApkFiles();
}
}, [appState]);
@@ -168,6 +184,9 @@ const BlockerScreen = (props: IBlockerScreen) => {
}
};
+ // Higher Priotrity to Post Operative Hours
+ if (!withinOperativeHours && isLoggedIn && !GLOBAL.IS_IMPERSONATED && GLOBAL.BUILD_FLAVOUR === BuildFlavours.FIELD_AGENTS) return ;
+
if (shouldUpdate.newApkCachedUrl) {
return ;
}
@@ -245,4 +264,4 @@ const BlockerScreen = (props: IBlockerScreen) => {
return <>{props.children}>;
};
-export default BlockerScreen;
+export default BlockerScreen;
\ No newline at end of file
diff --git a/src/common/TrackingComponent.tsx b/src/common/TrackingComponent.tsx
index bf4a8874..6e82cf1f 100644
--- a/src/common/TrackingComponent.tsx
+++ b/src/common/TrackingComponent.tsx
@@ -54,7 +54,7 @@ import {
} from './AgentActivityConfigurableConstants';
import { GlobalImageMap } from './CachedImage';
import { addClickstreamEvent } from '../services/clickstreamEventService';
-import { CLICKSTREAM_EVENT_NAMES, LocalStorageKeys } from './Constants';
+import { BuildFlavours, CLICKSTREAM_EVENT_NAMES, LocalStorageKeys } from './Constants';
import useResyncFirebase from '@hooks/useResyncFirebase';
import { imageSyncService, sendImagesToServer } from '@services/imageSyncService';
import { sendAudiosToServer } from '@services/audioSyncService';
@@ -346,12 +346,6 @@ const TrackingComponent: React.FC = ({ children }) => {
delay: 3 * MILLISECONDS_IN_A_MINUTE, // 3 minutes
onLoop: true,
},
- {
- taskId: FOREGROUND_TASKS.COSMOS_SYNC_WITH_LONGHORN,
- task: taskSyncToLonghorn,
- delay: 15 * MILLISECONDS_IN_A_SECOND,
- onLoop: true,
- },
{
taskId: FOREGROUND_TASKS.WIFI_DETAILS_SYNC,
task: getWifiDetailsSyncUrl,
@@ -368,6 +362,16 @@ const TrackingComponent: React.FC = ({ children }) => {
onLoop: true,
});
}
+
+ if(GLOBAL?.BUILD_FLAVOUR === BuildFlavours.CALLING_AGENTS) {
+ tasks.push({
+ taskId: FOREGROUND_TASKS.COSMOS_SYNC_WITH_LONGHORN,
+ task: taskSyncToLonghorn,
+ delay: 15 * MILLISECONDS_IN_A_SECOND,
+ onLoop: true,
+ });
+ }
+
const handleDataSync = () => {
if (!isOnline) {
return;
diff --git a/src/components/form/components/AddressSelection.tsx b/src/components/form/components/AddressSelection.tsx
index 1c7b0698..b4debdb4 100644
--- a/src/components/form/components/AddressSelection.tsx
+++ b/src/components/form/components/AddressSelection.tsx
@@ -196,7 +196,6 @@ const AddressSelection: React.FC = (props) => {
orientation="vertical"
>
{addresses?.map((address) => {
- if(isGeolocation) return <>>;
const addressLabel = isGeolocation
? (address as IGeolocation)?.tag
: getAddressString(address as Address);
diff --git a/src/components/utlis/apiHelper.ts b/src/components/utlis/apiHelper.ts
index ac4a6f40..cf07b27a 100644
--- a/src/components/utlis/apiHelper.ts
+++ b/src/components/utlis/apiHelper.ts
@@ -211,7 +211,6 @@ API_URLS[ApiKeys.SEND_COMMUNICATION_NAVI_ACCOUNT] = '/navi-communications/{loanA
API_URLS[ApiKeys.GENERATE_DYNAMIC_DOCUMENT] = '/documents/generate/{loanAccountNumber}';
API_URLS[ApiKeys.DOWNLOAD_LATEST_APP] = 'https://longhorn.navi.com/api/app/download';
API_URLS[ApiKeys.ALL_ESCALATIONS] = '/customer-escalation';
-API_URLS[ApiKeys.DOWNLOAD_LATEST_APP] = 'https://longhorn.navi.com/api/app/download';
API_URLS[ApiKeys.GET_UNGROUPED_ADDRESSES] =
'/collection-cases/{loanAccountNumber}/ungrouped/addresses';
API_URLS[ApiKeys.GET_GROUPED_ADDRESSES_AND_GEOLOCATIONS] =
diff --git a/src/screens/addressGeolocation/constant.ts b/src/screens/addressGeolocation/constant.ts
index 19de6d7d..e12e2c9a 100644
--- a/src/screens/addressGeolocation/constant.ts
+++ b/src/screens/addressGeolocation/constant.ts
@@ -24,10 +24,10 @@ export const ADDRESSES_TABS = [
key: 'address',
label: 'Addresses',
},
- // {
- // key: 'geolocation',
- // label: 'Geolocations',
- // },
+ {
+ key: 'geolocation',
+ label: 'Geolocations',
+ },
];
export enum AddressGeolocationTabEnum {
diff --git a/src/screens/caseDetails/ViewAddressSection.tsx b/src/screens/caseDetails/ViewAddressSection.tsx
index 590c9d86..7b68d9fe 100644
--- a/src/screens/caseDetails/ViewAddressSection.tsx
+++ b/src/screens/caseDetails/ViewAddressSection.tsx
@@ -22,9 +22,9 @@ const ViewAddressSection = ({ caseId }: IViewAddressSection) => {
const { addressString, loanAccountNumber, customerReferenceId, addressStringType } = caseDetail;
const getTabName = () => {
- // if (addressStringType === AddressTabType.GEO_LOCATION) {
- // return AddressGeolocationTabEnum.GEOLOCATION;
- // }
+ if (addressStringType === AddressTabType.GEO_LOCATION) {
+ return AddressGeolocationTabEnum.GEOLOCATION;
+ }
return AddressGeolocationTabEnum.ADDRESS;
};