final code

This commit is contained in:
Venba 2023-12-08 09:48:17 +05:30
parent f59fcf56ac
commit 24330999bd
60 changed files with 6864 additions and 2497 deletions

View File

@ -11,13 +11,14 @@ apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle"
dependencies {
implementation project(':capacitor-app')
implementation project(':capacitor-camera')
implementation project(':capacitor-geolocation')
implementation project(':capacitor-haptics')
implementation project(':capacitor-keyboard')
implementation project(':capacitor-network')
implementation project(':capacitor-share')
implementation project(':capacitor-splash-screen')
implementation project(':capacitor-status-bar')
implementation "androidx.core:core:1.6.+"
}

View File

@ -35,4 +35,11 @@
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature android:name="android.hardware.location.gps" />
</manifest>

View File

@ -8,6 +8,9 @@ project(':capacitor-app').projectDir = new File('../node_modules/@capacitor/app/
include ':capacitor-camera'
project(':capacitor-camera').projectDir = new File('../node_modules/@capacitor/camera/android')
include ':capacitor-geolocation'
project(':capacitor-geolocation').projectDir = new File('../node_modules/@capacitor/geolocation/android')
include ':capacitor-haptics'
project(':capacitor-haptics').projectDir = new File('../node_modules/@capacitor/haptics/android')

View File

@ -13,4 +13,5 @@ ext {
androidxJunitVersion = '1.1.5'
androidxEspressoCoreVersion = '3.5.1'
cordovaAndroidVersion = '10.1.1'
playServicesLocationVersion = '21.0.1'
}

View File

@ -137,30 +137,6 @@
"src/**/*.html"
]
}
},
"ionic-cordova-serve": {
"builder": "@ionic/cordova-builders:cordova-serve",
"options": {
"cordovaBuildTarget": "app:ionic-cordova-build",
"devServerTarget": "app:serve"
},
"configurations": {
"production": {
"cordovaBuildTarget": "app:ionic-cordova-build:production",
"devServerTarget": "app:serve:production"
}
}
},
"ionic-cordova-build": {
"builder": "@ionic/cordova-builders:cordova-build",
"options": {
"browserTarget": "app:build"
},
"configurations": {
"production": {
"browserTarget": "app:build:production"
}
}
}
}
}

View File

@ -8,8 +8,11 @@ const config: CapacitorConfig = {
androidScheme: 'https'
},
plugins:{
Camera: {
synced: true
},
SplashScreen:{
launchShowDuration:2000,
launchShowDuration:3000,
launchAutoHide:true,
androidSplashResourceName:"splash",
// backgroundColor:"#fff",

View File

@ -93,9 +93,4 @@
<splash height="2436" src="resources/ios/splash/Default-2436h.png" width="1125" />
<splash height="2732" src="resources/ios/splash/Default@2x~universal~anyany.png" width="2732" />
</platform>
<plugin name="cordova-plugin-statusbar" spec="2.4.2" />
<plugin name="cordova-plugin-device" spec="2.0.2" />
<plugin name="cordova-plugin-splashscreen" spec="5.0.2" />
<plugin name="cordova-plugin-ionic-webview" spec="^5.0.0" />
<plugin name="cordova-plugin-ionic-keyboard" spec="^2.0.5" />
</widget>

View File

@ -2,6 +2,21 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>com.getcapacitor.capacitor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>mycustomscheme</string>
</array>
</dict>
</array>
<key>NSLocationAlwaysUsageDescription</key>
<string>Always allow location access to detemine nearby restaurants</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Allow location access while using the App to detemine nearby restaurants</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>

View File

@ -13,13 +13,13 @@ def capacitor_pods
pod 'CapacitorCordova', :path => '../../node_modules/@capacitor/ios'
pod 'CapacitorApp', :path => '../../node_modules/@capacitor/app'
pod 'CapacitorCamera', :path => '../../node_modules/@capacitor/camera'
pod 'CapacitorGeolocation', :path => '../../node_modules/@capacitor/geolocation'
pod 'CapacitorHaptics', :path => '../../node_modules/@capacitor/haptics'
pod 'CapacitorKeyboard', :path => '../../node_modules/@capacitor/keyboard'
pod 'CapacitorNetwork', :path => '../../node_modules/@capacitor/network'
pod 'CapacitorShare', :path => '../../node_modules/@capacitor/share'
pod 'CapacitorSplashScreen', :path => '../../node_modules/@capacitor/splash-screen'
pod 'CapacitorStatusBar', :path => '../../node_modules/@capacitor/status-bar'
pod 'CordovaPlugins', :path => '../capacitor-cordova-ios-plugins'
end
target 'App' do

9
ios/ios.iml Normal file
View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

4518
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -22,28 +22,31 @@
"@angular/platform-browser": "^16.0.0",
"@angular/platform-browser-dynamic": "^16.0.0",
"@angular/router": "^16.0.0",
"@awesome-cordova-plugins/core": "6.4.0",
"@capacitor/android": "5.5.1",
"@capacitor/app": "5.0.6",
"@capacitor/app": "^5.0.6",
"@capacitor/camera": "^5.0.7",
"@capacitor/core": "^5.5.1",
"@capacitor/geolocation": "^5.0.6",
"@capacitor/haptics": "5.0.6",
"@capacitor/ios": "5.5.1",
"@capacitor/keyboard": "5.0.6",
"@capacitor/network": "^5.0.6",
"@capacitor/share": "^5.0.6",
"@capacitor/splash-screen": "^5.0.6",
"@capacitor/status-bar": "5.0.6",
"@capacitor/status-bar": "^5.0.6",
"@ionic-native/app-version": "^5.0.0",
"@ionic-native/camera": "^5.0.0",
"@ionic-native/core": "^5.0.0",
"@ionic/angular": "^7.5.2",
"@ionic/cordova-builders": "^10.0.0",
"@ionic/pwa-elements": "^3.2.2",
"@ionic/storage-angular": "^4.0.0",
"amazon-cognito-identity-js": "^6.3.6",
"ionicons": "^7.0.0",
"ng2-pdf-viewer": "^10.0.0",
"ngx-image-compress": "^15.1.6",
"rxjs": "^7.8.1",
"tslib": "^2.3.0",
"watermarkjs": "^2.1.1",
"zone.js": "~0.13.0"
},
"devDependencies": {
@ -63,16 +66,6 @@
"@types/node": "^12.11.1",
"@typescript-eslint/eslint-plugin": "5.3.0",
"@typescript-eslint/parser": "5.3.0",
"cordova-android": "^12.0.1",
"cordova-ios": "^7.0.1",
"cordova-plugin-app-version": "^0.1.14",
"cordova-plugin-camera": "^7.0.0",
"cordova-plugin-device": "2.0.2",
"cordova-plugin-ionic-keyboard": "^2.0.5",
"cordova-plugin-ionic-webview": "^5.0.0",
"cordova-plugin-network-information": "^3.0.0",
"cordova-plugin-splashscreen": "5.0.2",
"cordova-plugin-statusbar": "^2.4.2",
"eslint": "^7.26.0",
"eslint-plugin-import": "2.22.1",
"eslint-plugin-jsdoc": "30.7.6",
@ -88,21 +81,5 @@
"ts-node": "^8.3.0",
"typescript": "~5.0.2"
},
"description": "An Ionic project",
"cordova": {
"plugins": {
"cordova-plugin-statusbar": {},
"cordova-plugin-device": {},
"cordova-plugin-splashscreen": {},
"cordova-plugin-ionic-webview": {},
"cordova-plugin-ionic-keyboard": {},
"cordova-plugin-camera": {},
"cordova-plugin-network-information": {},
"cordova-plugin-app-version": {}
},
"platforms": [
"ios",
"android"
]
}
"description": "An Ionic project"
}

View File

@ -1,29 +1 @@
<ion-app>
<ion-split-pane contentId="main-content">
<ion-menu contentId="main-content" type="overlay">
<ion-content>
<ion-list id="inbox-list">
<ion-list-header>Inbox</ion-list-header>
<ion-note>hi@ionicframework.com</ion-note>
<ion-menu-toggle auto-hide="false" *ngFor="let p of appPages; let i = index">
<ion-item routerDirection="root" [routerLink]="[p.url]" lines="none" detail="false" routerLinkActive="selected">
<ion-icon aria-hidden="true" slot="start" [ios]="p.icon + '-outline'" [md]="p.icon + '-sharp'"></ion-icon>
<ion-label>{{ p.title }}</ion-label>
</ion-item>
</ion-menu-toggle>
</ion-list>
<!--
<ion-list id="labels-list">
<ion-list-header>Labels</ion-list-header>
<ion-item *ngFor="let label of labels" lines="none">
<ion-icon aria-hidden="true" slot="start" ios="bookmark-outline" md="bookmark-sharp"></ion-icon>
<ion-label>{{ label }}</ion-label>
</ion-item>
</ion-list> -->
</ion-content>
</ion-menu>
<ion-router-outlet id="main-content"></ion-router-outlet>
</ion-split-pane>
</ion-app>
<ion-router-outlet></ion-router-outlet>

View File

@ -1,5 +1,18 @@
import { Component } from '@angular/core';
import { Component, ViewChild } from '@angular/core';
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
import { SplashScreen } from '@capacitor/splash-screen';
import { filter } from 'rxjs';
import { ConnectionStatus, NetworkDetectionService } from 'src/providers/network-detection/network-detection.service';
import { AuthService } from './authencation/auth-service/auth.service';
import { SalesPdService } from './pages/providers/sales-pd/sales-pd.service';
import { PdtriggerService } from 'src/providers/pdtrigger/pdtrigger.service';
import { AlertController, Platform } from '@ionic/angular';
import { PinLockComponent } from './authencation/pin-lock/pin-lock.component';
import { CognitoService } from './authencation/auth-service/cognito.service';
import { LoginComponent } from './authencation/login/login.component';
import { Capacitor } from '@capacitor/core';
import { App } from '@capacitor/app';
import { StatusBar, Style } from '@capacitor/status-bar';
@Component({
selector: 'app-root',
@ -7,207 +20,173 @@ import { SplashScreen } from '@capacitor/splash-screen';
styleUrls: ['app.component.scss'],
})
export class AppComponent {
public appPages = [
{ title: ' ', url: '/folder/inbox', icon: '' },
{ title: ' ', url: '/folder/outbox', icon: '' },
{ title: ' ', url: '/folder/favorites', icon: '' },
{ title: ' ', url: '/folder/archived', icon: '' },
{ title: ' ', url: '/folder/trash', icon: '' },
{ title: ' ', url: '/folder/spam', icon: '' },
];
public labels = [' ', ' ', ' ', ' ', ' ', ' '];
constructor() {}
hideTabs: boolean = false;
app_version: any;
userAccess:boolean = false;
alertShown:boolean = false;
rootPage: any = LoginComponent;
commonDetails: any;
userDetails: any;
constructor(private platform: Platform,public shared:CognitoService,private alertCtrl: AlertController,private route: ActivatedRoute,private router:Router,private networkProvider:NetworkDetectionService,public aws:AuthService,private salesPDService:SalesPdService,private pdtrigger:PdtriggerService) {
this.initializeApp();
// this.changeDecision();
console.log('first Open')
this.platform.backButton.subscribeWithPriority(3, () => {
alert('Handler was called!');
});
// // iOS only
// window.addEventListener('statusTap', function () {
// console.log('statusbar tapped');
// });
// // Display content under transparent status bar (Android only)
// StatusBar.setOverlaysWebView({ overlay: true });
// const setStatusBarStyleDark = async () => {
// await StatusBar.setStyle({ style: Style.Dark });
// };
// const setStatusBarStyleLight = async () => {
// await StatusBar.setStyle({ style: Style.Light });
// };
}
ngOnInit() {
this.initializeApp();
this.customizeStatusBar()
// Hide the splash screen once your app is ready
SplashScreen.hide();
}
private async customizeStatusBar() {
await StatusBar.setStyle({ style: Style.Light });
await StatusBar.setBackgroundColor({ color: '#ff0303' });
}
initializeApp() {
console.log('initializeApp')
this.platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
// this.appVersionProvide.getVersionNumber().then((version_number:any) => {
// console.log('version number', version_number);
// this.app_version = version_number;
// }, (err:any) => {
// console.log('Version Error', err);
// });
// StatusBar.setStyle({ style: StatusBarStyle.Light });
// StatusBar.setBackgroundColor({ color: '#E00201' });
SplashScreen.hide();
// Assuming shared is a service
this.shared.getAccessToken().then(() => {
console.log('initializeApp')
this.getuserDetails();
this.getCommonSettings();
this.router.navigate(['/auth/pin-lock']);
// this.rootPage = PinLockComponent;
}).catch(() => {
setTimeout(() => {
console.log('initializeApp')
this.router.navigate(['/auth']);
// this.rootPage = LoginComponent;
}, 1000);
});
this.networkDetection();
});
App.addListener('backButton', (data) => {
console.log('backButton')
if (this.router.url === '/auth' || this.router.url === '/sales-pd-list' || this.router.url === '/auth/pin-lock') {
console.log('backButton')
if (!this.alertShown) {
console.log('presentConfirm')
this.presentConfirm();
}
}
else if(this.router.url === '/section-list'){
// Handle other pages
alert('/section-list')
this.router.navigate(['/sales-pd-list']);
} else if(this.router.url === '/section9'){
alert('/section9')
this.router.navigate(['/section-list']);
}
});
}
async presentConfirm() {
const alert = await this.alertCtrl.create({
header: 'Confirm Exit',
message: 'Do You Want to Exit?',
buttons: [
{
text: 'Cancel',
role: 'cancel',
handler: () => {
console.log('Cancel clicked');
this.alertShown = false;
},
},
{
text: 'Yes',
handler: () => {
console.log('Exit');
if (Capacitor.isNativePlatform()) {
App.exitApp();
}
},
},
],
});
await alert.present();
this.alertShown = true;
}
networkDetection(){
this.networkProvider.onNetworkChange().subscribe((status: ConnectionStatus) => {
if (status == ConnectionStatus.online) {
// this.offlineManager.checkForEvents().subscribe();
}
});
}
getCommonSettings(){
this.pdtrigger.getCommonSettingsConfig().subscribe(res=>{
this.commonDetails = res;
if(this.commonDetails.dataStatus == true){
localStorage.setItem("commonSettings",JSON.stringify(this.commonDetails.records));
}
})
}
getuserDetails(){
let userid = this.aws.getlocale();
console.log(userid);
this.aws.getUserProfile(userid).subscribe(res=>{
this.userDetails = res;
if(this.userDetails.dataStatus == true)
{
this.userAccess = true;
this.userDetails = this.userDetails.records[0];
// this.events.publish('len_user_name',this.userDetails)
localStorage.setItem("user_details",JSON.stringify( this.userDetails));
}
});
}
}
// import { Component } from '@angular/core';
// import { AlertController, NavController, Platform } from '@ionic/angular';
// import { environment } from 'src/environments/environment';
// import { PdtriggerService } from 'src/providers/pdtrigger/pdtrigger.service';
// import { LoginComponent } from './authencation/login/login.component';
// import { PinLockComponent } from './authencation/pin-lock/pin-lock.component';
// import { AuthService } from './authencation/auth-service/auth.service';
// import { CognitoService } from './authencation/auth-service/cognito.service';
// import { AppVersion } from '@ionic-native/app-version/ngx'
// @Component({
// selector: 'app-root',
// templateUrl: 'app.component.html',
// styleUrls: ['app.component.scss'],
// })
// export class AppComponent {
// pages: { title: string; icon: string; method: () => any; }[];
// private env = environment
// protected app_version: any;
// rootPage: any = LoginComponent;
// userDetails: any = [];
// userAccess:boolean = false;
// constructor(public platform: Platform,private nav: NavController, public statusBar: StatusBar,public aws:AuthService,public shared:CognitoService,public alertCtrl:AlertController,private appVersionProvide:AppVersion,private events:Events,private pdtrigger:PdtriggerService) {
// this.initializeApp();
// // this.changeDecision();
// // used for an example of ngFor and navigation
// this.pages = [
// // { title: 'Home', component: HomePage, icon: 'home' },
// { title: 'Home', icon: 'home',method:()=>this.menulist(1) },
// { title: 'Logout', icon: 'md-exit',method:()=>this.menulist(2)}
// ];
// }
// initializeApp() {
// this.platform.ready().then(() => {
// this.statusBar.styleDefault();
// this.appVersionProvide.getVersionNumber().then((version_number: any) => {
// console.log("version number", version_number);
// this.app_version = version_number;
// }).catch((err:any) => {
// console.log("Version Error", err);
// });
// if (this.platform.is('android')) {
// this.statusBar.overlaysWebView(false);
// this.statusBar.backgroundColorByHexString('#E00201');
// }
// this.shared.getAccessToken().then(() => {
// this.getuserDetails();
// // this.getCommonSettings();
// this.rootPage = PinLockComponent;
// }).catch(() => {
// setTimeout(() => {
// this.rootPage = LoginComponent;
// }, 1000);
// });
// // this.networkDetection();
// });
// this.platform.registerBackButtonAction(() => {
// if (this.nav.length() === 1) {
// if (!this.alertShown) {
// let alert = this.alertCtrl.create({
// title: 'Confirm Exit',
// message: 'Do You Want to Exit?',
// buttons: [
// {
// text: 'Cancel',
// role: 'cancel',
// handler: () => {
// console.log("Cancel clicked");
// this.alertShown = false;
// }
// },
// {
// text: 'Yes',
// handler: () => {
// console.log("Exit");
// this.platform.exitApp();
// }
// }
// ]
// });
// alert.present();
// this.alertShown = true;
// }
// } else {
// this.nav.pop();
// }
// });
// }
// getuserDetails()
// {
// let userid = this.aws.getlocale();
// console.log(userid);
// this.aws.getUserProfile(userid).subscribe(res=>{
// this.userDetails = res;
// if(this.userDetails.dataStatus == true)
// {
// this.userAccess = true;
// this.userDetails = this.userDetails.records[0];
// this.events.publish('len_user_name',this.userDetails)
// localStorage.setItem("user_details",JSON.stringify( this.userDetails));
// }
// });
// }
// // getCommonSettings(){
// // // getCommonConfig
// // this.pdtrigger.getCommonSettingsConfig().subscribe(res=>{
// // this.commonDetails = res;
// // if(this.commonDetails.dataStatus == true){
// // localStorage.setItem("commonSettings",JSON.stringify(this.commonDetails.records));
// // }
// // })
// // }
// changeDecision(){
// this.events.subscribe('len_user_name',(data:any)=>{
// console.log("event data",data)
// this.userDetails=data
// this.userAccess=true;
// // if(data == 'MWISE'){
// // this.pages.splice(-1,1)
// // this.pages=this.pages.filter(ele=>ele.title != 'Sales PD')
// // this.pages.push( { title :'Sales PD',icon:'list',method:()=>this.menulist(3)},
// // { title: 'Logout', icon: 'md-exit',method:()=>this.menulist(2)})
// // }
// // else{
// // this.pages=this.pages.filter(ele=>ele.title != 'Sales PD')
// // }
// let role= this.aws.takeDecisionRouting(this.userDetails)
// if(role == 'sales'){
// this.pages[0].method=()=>this.menulist(3)
// this.pages=this.pages.filter(ele=>ele.title != 'Sales PD' && ele.title != 'Credit PD')
// }
// else{
// this.pages[0].method=()=>this.menulist(1)
// this.pages.splice(-1,1)
// this.pages=this.pages.filter(ele=>ele.title != 'Sales PD' && ele.title != 'Credit PD')
// this.pages.push( { title :'Sales PD',icon:'briefcase',method:()=>this.menulist(3)},
// // { title :'Credit PD',icon:'list',method:()=>this.menulist(4)},
// { title: 'Logout', icon: 'md-exit',method:()=>this.menulist(2)})
// }
// })
// }
// menulist(id: number): void {
// switch (id) {
// case 1:
// this.nav.navigateRoot('/pd-list'); // Use routing to navigate
// break;
// case 2:
// this.aws.logout().subscribe(() => {
// // this.salesPDService.clearLocalData();
// localStorage.removeItem('product_id_salesPD');
// localStorage.removeItem('sales_pd_type');
// this.nav.navigateRoot('/login'); // Use routing to navigate
// });
// break;
// case 3:
// this.nav.navigateRoot('/sales-pd-list'); // Use routing to navigate
// break;
// case 4:
// this.nav.navigateRoot('/credit-pd-list'); // Use routing to navigate
// break;
// }
// }
// logout(){
// // this.aws.logout();
// this.nav.navigateRoot('/auth');
// }
// }

View File

@ -21,10 +21,13 @@ import { ReqTokenInterceptor } from 'src/providers/_guard/req-token.interceptor'
import { SalesPdService } from './pages/providers/sales-pd/sales-pd.service';
import { HomeModule } from './pages/home/home.module';
import { NetworkDetectionService } from 'src/providers/network-detection/network-detection.service';
import { CameraService } from './pages/providers/camera/camera.service';
// import { AppVersion } from '@ionic-native/app-version/ngx'
import { PdfViewerModule } from 'ng2-pdf-viewer'
import { PdfViewerComponent } from './pages/report-pdf-viewer/pdf-viewer.component';
@NgModule({
declarations: [AppComponent],
declarations: [AppComponent,PdfViewerComponent],
imports: [
BrowserModule,
IonicModule.forRoot(),
@ -34,10 +37,12 @@ import { NetworkDetectionService } from 'src/providers/network-detection/network
FormsModule,
BrowserAnimationsModule,
PageModule,
HomeModule,
PageRoutingModule,
IonicStorageModule.forRoot(),
PdfViewerModule
],
providers: [NetworkDetectionService,SalesPdService,ReqTokenInterceptor,PdtriggerService,ToastService,IonicStorageService,AuthService,CognitoService,{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
providers: [NetworkDetectionService,ReqTokenInterceptor,PdtriggerService,ToastService,IonicStorageService,GeolocationPosition,CameraService,AuthService,CognitoService,{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
{
provide:HTTP_INTERCEPTORS,
useClass:ReqTokenInterceptor,

View File

@ -5,15 +5,18 @@ import { Observable, catchError, map } from 'rxjs';
import { AuthenticationDetails, CognitoUser, CognitoUserPool, CognitoUserSession } from 'amazon-cognito-identity-js';
import { IonicStorageService } from 'src/providers/ionic-storage/ionic-storage.service';
import { CognitoService } from './cognito.service';
import { ConnectionStatus, NetworkDetectionService } from 'src/providers/network-detection/network-detection.service';
const currentDate = new Date().toJSON().slice(0,19).replace('T',' ');
@Injectable({
providedIn: 'root'
})
export class AuthService {
apiurl: any
lenderUserPool: any;
constructor(private http:HttpClient,public shared:CognitoService,private ionicStorageProvider:IonicStorageService) {
constructor(private networkProvider:NetworkDetectionService,private http:HttpClient,public shared:CognitoService,private ionicStorageProvider:IonicStorageService) {
this.apiurl = environment
const lender_poolData = {
UserPoolId:this.apiurl.lenUserPoolId, // Username :SPARQ_LENDER_DEV
@ -36,6 +39,36 @@ export class AuthService {
}
}
searchValue(exist_data:any,value:any,option:any){
// console.log("option",option)
let returnDataVal:any
if(!exist_data){
return
}
let searchVal=value
if(!searchVal){
returnDataVal=exist_data.slice();
}
else{
searchVal = searchVal.toLowerCase()
}
if(option=='state'){
returnDataVal=exist_data.filter((res:any)=>res.name.toLowerCase().indexOf(searchVal) > -1)
}
else if(option=='city'){
returnDataVal=exist_data.filter((res:any)=>res.city_name.toLowerCase().indexOf(searchVal) > -1)
}
else if(option=='pin'){
returnDataVal=exist_data.filter((res:any)=>res.pincode.toLowerCase().indexOf(searchVal) > -1)
}
else{
returnDataVal=exist_data.filter((res:any)=>res.answer.toLowerCase().indexOf(searchVal) > -1)
}
return returnDataVal
}
async getBase64ImageFromUrl(imageUrl:any) {
var res = await fetch(imageUrl);
@ -128,23 +161,29 @@ export class AuthService {
}
}
getUserProfile(userid: any): Observable<any> {
// alert();
getUserProfile(userid: any) {
const roles = {'userid': userid};
console.log(userid)
return this.http.post(this.apiurl.url + 'getUsersDetails', roles)
.pipe(
map((result: any) => {
if (this.networkProvider.getCurrentNetworkStatus() === ConnectionStatus.online) {
return this.http.post<any>(`${this.apiurl.url}getUsersDetails`, roles).pipe(
map(result => {
this.ionicStorageProvider.checkAndInsertApiDataLocally(result, {'userid': userid}, 'getUsersDetails');
return result;
}),
catchError((error: any) => {
return this.ionicStorageProvider.getApiDataFromLocally({ 'userid': userid }, 'getUsersDetails');
})
);
} else {
return this.ionicStorageProvider.getApiDataFromLocally({'userid': userid}, 'getUsersDetails');
}
}
userPinUpdate(pin:any){
let userid = this.getlocale();
let records = {'mpin':pin,'updatedon':currentDate,'fk_updatedby':userid,'userid':userid};
let formdata = new FormData();
formdata.append('records',JSON.stringify(records));
return this.http.post(this.apiurl.url+'updateExistUser',formdata);
}
logout(){
return Observable.create((observe:any)=>{

View File

@ -8,19 +8,19 @@ import { OtpComponent } from './otp/otp/otp.component';
const routes: Routes = [
{
path: '',
component: LoginComponent
component: LoginComponent,
},
{
path: 'pin-lock',
component: PinLockComponent
component: PinLockComponent,
},
{
path: 'password',
component: PasswordComponent
component: PasswordComponent,
},
{
path: 'otp',
component: OtpComponent
component: OtpComponent,
}
];

View File

@ -24,6 +24,7 @@ export class LoginComponent implements OnInit {
forgetpin: any;
commonDetails: any;
private env = environment
tabBarElement: any;
constructor(private modalController: ModalController,private toast:ToastService,private route: ActivatedRoute,private router:Router,private fb:FormBuilder, private auth:AuthService,public Menu:MenuController,private loadingController: LoadingController,public navCtrl:NavController,private pdtrigger:PdtriggerService) {
this.loginForm = new FormGroup({
email: new FormControl('', [Validators.required, Validators.email,Validators.pattern(
@ -34,8 +35,22 @@ export class LoginComponent implements OnInit {
// '^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%^&*_=+-]).{8,12}$'
// )])
});
this.tabBarElement = document.querySelector('#tabs ion-tabbar-section');
}
onPageDidEnter()
{
this.tabBarElement.style.display = 'none';
}
onPageWillLeave()
{
this.tabBarElement.style.display = 'block';
}
ngOnInit() {
// this.hide = true;
}
@ -109,7 +124,7 @@ export class LoginComponent implements OnInit {
console.log(userid)
this.auth.getUserProfile(userid).subscribe((res) => {
this.userDetails = res;
console.log(this.userDetails)
if (this.userDetails.dataStatus === true) {
this.userDetails = this.userDetails.records[0];
@ -119,12 +134,13 @@ export class LoginComponent implements OnInit {
let role = this.auth.takeDecisionRouting(this.userDetails);
// Use ActivatedRoute to get the 'resetlogin' parameter
this.route.queryParams.subscribe((params) => {
console.log(params)
this.forgetpin = params['resetlogin'];
if (this.forgetpin === 'true') {
this.navCtrl.navigateRoot('/pin-lock', { queryParams: { resetpin: this.forgetpin } });
this.navCtrl.navigateRoot('/auth/pin-lock', { queryParams: { resetpin: this.forgetpin } });
} else if (role === 'sales') {
console.log(console.log('sales'))
console.log('sales true')
this.pdtrigger.initiateMasterApis('sales');
// this.router.navigate(['/sales-pd-list'])
this.navCtrl.navigateRoot('/sales-pd-list');

View File

@ -1,3 +1,106 @@
<p>
pin-lock works!
</p>
<ion-content padding>
<mat-card *ngIf="mpinaccess">
<mat-card-header>
</mat-card-header>
<ion-row>
<ion-col class="ion-text-center">
<img [src]="commonImage || '../../assets/img/misc/avatar.jpg'" alt="Circle Image" class="rounded-circle img-fluid">
</ion-col>
</ion-row>
<mat-card-content>
<ion-row>
<ion-col class="ion-text-center">
<h4>PIN</h4>
<span style="color: red;">Should be 4 digit</span>
</ion-col>
</ion-row>
<ion-row>
<ion-col class="ion-text-center">
<mat-form-field>
<input type="number"
oninput="javascript: if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);"
matInput placeholder="New PIN" #newpassword pattern="[0-9]{4}" maxlength="4" style="width: 100%;" required>
</mat-form-field>
<br/>
<mat-form-field>
<input type="number"
oninput="javascript: if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);"
matInput placeholder="Confirm PIN" #confirmPassword pattern="[0-9]{4}" maxlength="4" style="width: 100%;" required
>
</mat-form-field>
</ion-col>
</ion-row>
</mat-card-content>
<mat-card-footer>
<ion-row>
<ion-col class="ion-text-center">
<button mat-raised-button color="primary" (click)="setnewpin(newpassword,confirmPassword)">Submit</button>
</ion-col>
</ion-row>
<ion-row *ngIf="isPinReset">
<ion-col class="ion-text-center">
<button mat-button style="color: blue;font-style:italic;text-decoration: underline;" (click)="goBack()">Back</button>
</ion-col>
</ion-row>
</mat-card-footer>
</mat-card>
<mat-card *ngIf="!mpinaccess">
<mat-card-header>
</mat-card-header>
<ion-row>
<ion-col class="ion-text-center">
<img [src]="commonImage" alt="Circle Image" class="rounded-circle img-fluid">
</ion-col>
</ion-row>
<mat-card-content>
<ion-row>
<ion-col class="ion-text-center">
<h4>PIN</h4>
</ion-col>
</ion-row>
<ion-row>
<ion-col class="ion-text-center">
<mat-form-field>
<input matInput type="number"
oninput="javascript: if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);"
style="-webkit-text-security:disc;" placeholder="PIN" #pin pattern="[0-9]{4}" maxlength="4" style="width: 100%;" required>
</mat-form-field>
</ion-col>
</ion-row>
<ion-row style="justify-content: flex-end;">
<button mat-button style="color: blue;font-style:italic;text-decoration: underline;" (click)="resetPin()">Forgot Pin</button>
</ion-row>
</mat-card-content>
<mat-card-footer>
<!-- <mat-card-actions class="ion-text-center text-color"> -->
<ion-row>
<ion-col class="ion-text-center">
<button mat-raised-button color="primary" (click)="checkpin(pin.value)">UNLOCK</button>
</ion-col>
</ion-row>
<!-- </mat-card-actions> -->
<div align="center" class="text-color">(or)</div>
<h5 align="center" class="text-color">Login Using FingerPrint</h5>
<div align="center" class="text-color" style="font-size: 11px;">Place your finger on fingerprint scanner to login</div>
<!-- <mat-card-actions class="ion-text-center" (click)="checkfingerprint()"> -->
<ion-row>
<ion-col class="ion-text-center">
<ion-icon (click)="checkfingerprint()" name="finger-print"></ion-icon>
</ion-col>
</ion-row>
<!-- </mat-card-actions> -->
</mat-card-footer>
</mat-card>
</ion-content>

View File

@ -0,0 +1,52 @@
.scroll-content{
background-color: #eee;
}
::ng-deep .mdc-text-field--filled:not(.mdc-text-field--disabled) {
background-color: unset !important;
}
.text-color{
color: black;
}
.mat-card{
width: 80% !important;
margin-left: 10% !important;
margin-top: 15% !important;
border-radius: 10px !important;
box-shadow: 0 16px 38px -12px rgba(0,0,0,.56), 0 4px 25px 0 rgba(0,0,0,.12), 0 8px 10px -5px rgba(0,0,0,.2) !important;
}
h4{
font-weight: normal;
color: black;
}
button.mat-primary {
background-color: #E00201 !important;
}
.mat-raised-button{
border-radius: 30px;
padding: 19px 45px;
line-height: 0px;
box-shadow: 0 16px 38px -12px rgba(0,0,0,.56), 0 4px 25px 0 rgba(0,0,0,.12), 0 8px 10px -5px rgba(0,0,0,.2) !important;
}
.rounded-circle {
border-radius: 50%!important;
}
.img-fluid{
max-width: 30%;
height: auto;
margin-top:-70px;
box-shadow: 0 16px 38px -12px rgba(0,0,0,.56), 0 4px 25px 0 rgba(0,0,0,.12), 0 8px 10px -5px rgba(0,0,0,.2);
}
ion-icon{
font-size:2.2em;
color: black;
}
input.mat-input-element {
-webkit-text-security: disc;
}
ion-content {
--padding-start: 35px;
--padding-end: 35px;
--padding-top: 50%;
--padding-bottom: 50%;
--background: #eeeeee !important;
}

View File

@ -1,14 +1,193 @@
import { Component, OnInit } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { MenuController, NavController, NavParams } from '@ionic/angular';
import { CognitoService } from '../auth-service/cognito.service';
import { ToastService } from 'src/providers/common-provider/toast.service';
import { AuthService } from '../auth-service/auth.service';
import { LoadingService } from 'src/providers/common-provider/loading.service';
import { environment } from 'src/environments/environment';
import { ActivatedRoute, Router } from '@angular/router';
import { switchMap } from 'rxjs';
interface ApiResponse {
dataStatus: boolean;
records: any[]; // Adjust the type accordingly
}
@Component({
selector: 'app-pin-lock',
templateUrl: './pin-lock.component.html',
styleUrls: ['./pin-lock.component.scss'],
})
export class PinLockComponent implements OnInit {
commonImage: any;
pinAccess: any;
newpindetails: any;
userDetails: any;
resetlogin:any;
pinreset: Boolean=true;
pin:any;
mpinaccess:boolean=false;
newpassword:any;
ConfirmPassword:any;
private env = environment
resetpin: any;
isPinReset: any;
constructor() { }
constructor(private router: Router,public route:ActivatedRoute,public navCtrl: NavController,public Menu:MenuController,public fb:FormBuilder,public shared:CognitoService,public toast:ToastService,public aws:AuthService,public loadingCtrl:LoadingService) {
let pinLockImage = localStorage.getItem('pinLockImage')
if(pinLockImage) {
this.commonImage = pinLockImage
}
else {
this.commonImage = this.env.commonimage;
this.aws.getBase64ImageFromUrl(this.commonImage).then((base64LockImg:any)=>{
if(base64LockImg) {
localStorage.setItem('pinLockImage',base64LockImg);
}
})
}
console.log("entered")
this.shared.refresh()
this.getuserDetails();
}
ngOnInit() {}
ionViewDidLoad() {
console.log('ionViewDidLoad AuthPage');
}
ionViewDidEnter(){
this.Menu.enable(false);
}
ionViewWillLeave(){
this.Menu.enable(true);
}
// Update the subscribe method in getuserDetails
async getuserDetails() {
try {
const userid = this.aws.getlocale();
this.aws.getUserProfile(userid).subscribe({
next: (res: ApiResponse) => {
this.userDetails = res;
if (this.userDetails.dataStatus === true) {
this.userDetails = this.userDetails.records;
this.route.queryParams.pipe(switchMap((params) => {
console.log(params);
this.resetpin = params['resetpin'];
console.log(this.resetpin);
const resetpinAsBoolean = Boolean(this.resetpin);
console.log(this.userDetails,resetpinAsBoolean,this.mpinaccess);
// console.log(typeof this.resetpin);
if (resetpinAsBoolean == true) {
console.log('enter')
this.mpinaccess = true;
this.isPinReset = true;
console.log(this.mpinaccess);
return [];
}
if (this.userDetails[0].mpin == null) {
this.mpinaccess = true;
} else {
this.mpinaccess = false;
}
return [];
})
)
.subscribe();
} else {
this.toast.lenderappmessage('This App is only for PD Officers');
localStorage.clear();
}
},
error: (error: any) => {
console.error(error);
this.loadingCtrl.dismissLoader();
}
});
} catch (error) {
console.error(error);
this.loadingCtrl.dismissLoader();
}
}
resetPin() {
this.router.navigate(['/auth'], { queryParams: { resetlogin: this.pinreset } });
}
goBack() {
this.isPinReset = false
this.mpinaccess = false
}
setnewpin(newpin:any, confirmPin:any) {
if (!newpin.checkValidity()) {
alert(newpin.validationMessage);
return;
}
if (newpin.value.toString().length < 4) {
this.toast.lenderappmessage("Pin must be 4 digits");
return;
}
if (newpin.value !== confirmPin.value) {
this.toast.lenderappmessage("Confirm Pin does not match.");
return;
}
this.aws.userPinUpdate(newpin.value).subscribe((res:any) => {
this.newpindetails = res;
if (this.newpindetails.dataStatus === true) {
if (this.userDetails[0].mpin !== null) {
this.toast.lenderappmessage("Pin Reset Successfully");
this.userDetails[0].mpin = newpin.value;
this.mpinaccess = false;
// Redirect to the appropriate page based on the user role
const role = this.aws.takeDecisionRouting(this.userDetails[0]);
if (role === 'sales') {
this.router.navigate(['/auth/pin-lock'], { queryParams: { userDetails: this.userDetails } });
}
// else {
// this.router.navigate(['/pd-list'], { state: { userDetails: this.userDetails } });
// }
}
}
});
}
checkpin(pin:any) {
console.log(pin);
if (pin !== '' && pin !== null) {
if (this.userDetails[0].mpin === pin) {
const role = this.aws.takeDecisionRouting(this.userDetails[0]);
if (role === 'sales') {
this.router.navigate(['/sales-pd-list']);
}
// else {
// this.router.navigate(['/pd-list'], { state: { userDetails: this.userDetails } });
// }
} else {
this.toast.lenderappmessage('Enter The Correct PIN');
}
} else {
this.toast.lenderappmessage('Enter The PIN');
}
}
checkfingerprint(){
}
}

View File

@ -1,7 +1,10 @@
<!-- <ion-header style="background: #ff7f507d">
<ion-header style="background-color: #ff0303 !important;">
<ion-toolbar color="optblue">
<ion-title>{{question_data.section_name}}</ion-title>
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
</ion-buttons>
<ion-title class="ion-justify-content-center p-0">{{question_data.section_name}}</ion-title>
</ion-toolbar>
<span *ngIf="network_status == 1" style="width: 100%; height: 34px; text-align: center;">
@ -14,7 +17,7 @@
<ion-content class="ion-padding">
<mat-card *ngIf="question_data.questions.length > 0">
<mat-card-content>
<ques-template (emitter)="navigate($event)" [questions_JSON]="question_data" (imageUploadCheck)="setGroupControl($event)"></ques-template>
<app-ques-template (emitter)="navigate($event)" [questions_JSON]="question_data" (imageUploadCheck)="setGroupControl($event)"></app-ques-template>
</mat-card-content>
</mat-card>
@ -23,4 +26,4 @@
<h5>No Templates Found</h5>
</mat-card-content>
</mat-card>
</ion-content> -->
</ion-content>

View File

@ -1,6 +1,7 @@
.header-md{
background-color: #ff0303 !important;
color: #fff !important;
}
.mat-radio-label {
cursor: pointer;
@ -10,6 +11,10 @@
vertical-align: middle;
}
.p-0{
padding: 0px !important;
}
.mat-radio-button{
min-width: 35%;
}
@ -21,6 +26,13 @@
text-align: center;
}
}
.sizeE{
font-size: medium;
width: 30px;
height: 20px;
}
h6{
// margin: 2px 0;
font-size: 16px !important;
@ -33,8 +45,11 @@ ion-content {
--padding-end: 16px; // Adjust as needed
--padding-top: 16px; // Adjust as needed
--padding-bottom: 16px; // Adjust as needed
--background: #eeeeee !important;
}
.mt{
margin-top: 1rem;
}
::ng-deep .mdc-text-field--filled:not(.mdc-text-field--disabled) {
background-color: unset !important;
}

View File

@ -4,7 +4,8 @@ import { ToastService } from 'src/providers/common-provider/toast.service';
import { PdtriggerService } from 'src/providers/pdtrigger/pdtrigger.service';
import { SalesPdService } from '../providers/sales-pd/sales-pd.service';
import { LoadingService } from 'src/providers/common-provider/loading.service';
import { ActivatedRoute } from '@angular/router';
import { ActivatedRoute, Router } from '@angular/router';
import { ConnectionStatus, NetworkDetectionService } from 'src/providers/network-detection/network-detection.service';
@Component({
// selector: 'app-home',
@ -25,7 +26,7 @@ export class HomeComponent implements OnInit {
id:"2",
dis_name:"Telephonic PD"
}]
constructor(public Menu:MenuController,public navCtrl: NavController, private route: ActivatedRoute,private toastProvider:ToastService,private pdTriggerProvider:PdtriggerService,private salesPDService:SalesPdService){
constructor(private router: Router,public Menu:MenuController,public navCtrl: NavController, private route: ActivatedRoute,private toastProvider:ToastService,private pdTriggerProvider:PdtriggerService,private salesPDService:SalesPdService){
this.getProducts()
}
@ -102,6 +103,10 @@ export class HomeComponent implements OnInit {
}
}
goToBack(){
this.router.navigate(['/sales-pd-list']);
}
@ -120,12 +125,15 @@ export class Section1 {
raw_data:any;
section_local:number=1
all_sections:any;
network_status: ConnectionStatus | undefined;
formGroupValue: any = null;
constructor(public navCtrl: NavController, private route: ActivatedRoute,private SalesPDService:SalesPdService,private toastProvider:ToastService) {
constructor(private router: Router,private networkDetectionProvider:NetworkDetectionService,public navCtrl: NavController, private route: ActivatedRoute,private SalesPDService:SalesPdService,private toastProvider:ToastService) {
let product_id;
this.route.queryParams.subscribe(params => {
product_id = params['product_id'];
console.log(product_id)
// Use product_id and sales_pd_type as needed
});
@ -155,13 +163,25 @@ export class Section1 {
}
ngOnInit() {
console.log('ionViewDidLoad HomePage');
// this.cameraProvider.enableAccuracy()
}
ionViewDidLoad() {
console.log('ionViewDidLoad HomePage');
console.log("######Entered");
this.networkDetectionProvider.onNetworkChange().subscribe(result=>{
this.network_status = result
console.log(this.network_status);
})
}
setGroupControl(event:any){
this.formGroupValue=event
}
navigate(event: any) {
console.log(event);
@ -172,6 +192,10 @@ export class Section1 {
}
}
goToBack(){
this.router.navigate(['/section-list']);
}
}
@ -184,8 +208,10 @@ export class Section2 {
raw_data:any;
section_local:number=2
all_sections:any;
network_status: ConnectionStatus | undefined;
formGroupValue: any = null;
constructor(public navCtrl: NavController, private route: ActivatedRoute,private SalesPDService:SalesPdService) {
constructor(private router: Router,private networkDetectionProvider:NetworkDetectionService,public navCtrl: NavController, private route: ActivatedRoute,private SalesPDService:SalesPdService) {
// if(this.navParams.get('sec_no')){
// this.section_local=this.navParams.get('sec_no')
// }
@ -198,18 +224,30 @@ export class Section2 {
ionViewDidLoad() {
console.log('ionViewDidLoad HomePage');
console.log("######Entered");
this.networkDetectionProvider.onNetworkChange().subscribe(result=>{
this.network_status = result
console.log(this.network_status);
})
}
onChange(){
this.navCtrl.navigateRoot('/home');
}
setGroupControl(event:any){
this.formGroupValue=event
}
navigate(event:any){
console.log(event);
this.navCtrl.navigateRoot('/section3');
}
goToBack(){
this.router.navigate(['/section-list']);
}
}
@Component({
@ -221,8 +259,10 @@ export class Section3 {
raw_data:any;
section_local:number=3
all_sections:any;
network_status: ConnectionStatus | undefined;
formGroupValue: any = null;
constructor(public navCtrl: NavController, private route: ActivatedRoute,private SalesPDService:SalesPdService) {
constructor(private router: Router,private networkDetectionProvider:NetworkDetectionService,public navCtrl: NavController, private route: ActivatedRoute,private SalesPDService:SalesPdService) {
// if(this.navParams.get('sec_no')){
// this.section_local=this.navParams.get('sec_no')
// }
@ -242,12 +282,21 @@ export class Section3 {
ionViewDidLoad() {
console.log('ionViewDidLoad HomePage');
console.log("######Entered");
this.networkDetectionProvider.onNetworkChange().subscribe(result=>{
this.network_status = result
console.log(this.network_status);
})
}
onChange(){
this.navCtrl.navigateRoot('/home');
}
setGroupControl(event:any){
this.formGroupValue=event
}
navigate(event:any){
console.log(event);
@ -260,6 +309,10 @@ export class Section3 {
}
}
goToBack(){
this.router.navigate(['/section-list']);
}
}
@Component({
@ -271,8 +324,10 @@ export class Section4 {
raw_data:any;
section_local:number=4
all_sections:any;
network_status: ConnectionStatus | undefined;
formGroupValue: any = null;
constructor(public navCtrl: NavController, private route: ActivatedRoute,private SalesPDService:SalesPdService) {
constructor(private router: Router,private networkDetectionProvider:NetworkDetectionService,public navCtrl: NavController, private route: ActivatedRoute,private SalesPDService:SalesPdService) {
// if(this.navParams.get('sec_no')){
// this.section_local=this.navParams.get('sec_no')
// }
@ -292,13 +347,21 @@ export class Section4 {
ionViewDidLoad() {
console.log('ionViewDidLoad HomePage');
console.log("######Entered");
this.networkDetectionProvider.onNetworkChange().subscribe(result=>{
this.network_status = result
console.log(this.network_status);
})
}
onChange(){
this.navCtrl.navigateRoot('/home');
}
setGroupControl(event:any){
this.formGroupValue=event
}
navigate(event:any){
console.log(event);
if(this.all_sections[this.all_sections.length - 1] != event.section_id){
@ -310,6 +373,10 @@ export class Section4 {
}
}
goToBack(){
this.router.navigate(['/section-list']);
}
}
@Component({
@ -321,8 +388,10 @@ export class Section5 {
raw_data:any;
section_local:number=5
all_sections:any;
network_status: ConnectionStatus | undefined;
formGroupValue: any = null;
constructor(public navCtrl: NavController, private route: ActivatedRoute,private SalesPDService:SalesPdService) {
constructor(private router: Router,private networkDetectionProvider:NetworkDetectionService,public navCtrl: NavController, private route: ActivatedRoute,private SalesPDService:SalesPdService) {
// if(this.navParams.get('sec_no')){
// this.section_local=this.navParams.get('sec_no')
// }
@ -342,13 +411,21 @@ export class Section5 {
ionViewDidLoad() {
console.log('ionViewDidLoad HomePage');
console.log("######Entered");
this.networkDetectionProvider.onNetworkChange().subscribe(result=>{
this.network_status = result
console.log(this.network_status);
})
}
onChange(){
this.navCtrl.navigateRoot('/home');
}
setGroupControl(event:any){
this.formGroupValue=event
}
navigate(event:any){
@ -362,6 +439,10 @@ export class Section5 {
}
}
goToBack(){
this.router.navigate(['/section-list']);
}
}
@Component({
@ -373,8 +454,10 @@ export class Section6 {
raw_data:any;
section_local:number=6
all_sections:any;
network_status: ConnectionStatus | undefined;
formGroupValue: any = null;
constructor(public navCtrl: NavController, private route: ActivatedRoute,private SalesPDService:SalesPdService) {
constructor(private router: Router,private networkDetectionProvider:NetworkDetectionService,public navCtrl: NavController, private route: ActivatedRoute,private SalesPDService:SalesPdService) {
// if(this.navParams.get('sec_no')){
// this.section_local=this.navParams.get('sec_no')
// }
@ -394,12 +477,22 @@ export class Section6 {
ionViewDidLoad() {
console.log('ionViewDidLoad HomePage');
console.log("######Entered");
this.networkDetectionProvider.onNetworkChange().subscribe(result=>{
this.network_status = result
console.log(this.network_status);
})
}
onChange(){
this.navCtrl.navigateRoot('/home');
}
setGroupControl(event:any){
this.formGroupValue=event
}
navigate(event:any){
console.log(event);
@ -412,6 +505,10 @@ export class Section6 {
}
}
goToBack(){
this.router.navigate(['/section-list']);
}
}
@Component({
@ -423,8 +520,11 @@ export class Section7 {
raw_data:any;
section_local:number=7
all_sections:any;
network_status: ConnectionStatus | undefined;
formGroupValue: any = null;
constructor(public navCtrl: NavController, private route: ActivatedRoute,private SalesPDService:SalesPdService,private toastProvider:ToastService) {
constructor(private router: Router,private networkDetectionProvider:NetworkDetectionService,public navCtrl: NavController, private route: ActivatedRoute,private SalesPDService:SalesPdService,private toastProvider:ToastService) {
// if(this.navParams.get('sec_no')){
// this.section_local=this.navParams.get('sec_no')
// }
@ -442,14 +542,25 @@ export class Section7 {
console.log(this.question_data)
}
ionViewDidLoad() {
console.log('ionViewDidLoad HomePage');
console.log("######Entered");
this.networkDetectionProvider.onNetworkChange().subscribe(result=>{
this.network_status = result
console.log(this.network_status);
})
}
onChange(){
this.navCtrl.navigateRoot('/home');
}
setGroupControl(event:any){
this.formGroupValue=event
}
navigate(event:any){
console.log(event);
@ -465,12 +576,17 @@ export class Section7 {
this.SalesPDService.clearLocalData()
localStorage.removeItem('product_id_salesPD')
setTimeout(()=>{
this.navCtrl.navigateRoot('/section-list');
this.router.navigate(['/sales-pd-list']);
// this.navCtrl.navigateRoot('/section-list');
},2000)
}
}
goToBack(){
this.router.navigate(['/section-list']);
}
}
@Component({
@ -482,8 +598,10 @@ export class Section8 {
raw_data:any;
section_local:number=8
all_sections:any;
network_status: ConnectionStatus | undefined;
formGroupValue: any = null;
constructor(public navCtrl: NavController, private route: ActivatedRoute,private SalesPDService:SalesPdService,private toastProvider:ToastService) {
constructor(private router: Router,private networkDetectionProvider:NetworkDetectionService,public navCtrl: NavController, private route: ActivatedRoute,private SalesPDService:SalesPdService,private toastProvider:ToastService) {
// if(this.navParams.get('sec_no')){
// this.section_local=this.navParams.get('sec_no')
// }
@ -501,15 +619,26 @@ export class Section8 {
console.log(this.question_data)
}
ionViewDidLoad() {
console.log('ionViewDidLoad HomePage');
console.log("######Entered");
this.networkDetectionProvider.onNetworkChange().subscribe(result=>{
this.network_status = result
console.log(this.network_status);
})
}
onChange(){
this.navCtrl.navigateRoot('/home');
}
setGroupControl(event:any){
this.formGroupValue=event
}
navigate(event:any){
console.log(event);
@ -527,12 +656,17 @@ export class Section8 {
this.SalesPDService.clearLocalData()
localStorage.removeItem('product_id_salesPD')
setTimeout(()=>{
this.navCtrl.navigateRoot('/section-list');
this.router.navigate(['/sales-pd-list']);
// this.navCtrl.navigateRoot('/section-list');
},2000)
}
}
goToBack(){
this.router.navigate(['/section-list']);
}
}
@Component({
@ -545,45 +679,38 @@ export class Section9 {
section_local:number=9
all_sections:any;
formGroupValue: any=null;
// network_status: ConnectionStatus
network_status: ConnectionStatus | undefined
constructor(public navCtrl: NavController, private route: ActivatedRoute,private SalesPDService:SalesPdService,private loadingProvider:LoadingService,private toastProvider:ToastService
constructor(private router: Router,public navCtrl: NavController, private route: ActivatedRoute,private SalesPDService:SalesPdService,private loadingProvider:LoadingService,private toastProvider:ToastService,private networkDetectionProvider:NetworkDetectionService
) {
this.raw_data=localStorage.getItem('question_temp_salespd')
this.raw_data=JSON.parse(this.raw_data)
this.all_sections=this.raw_data.sections.map((val:any)=>val.section_id)
console.log(this.all_sections)
this.route.queryParams.subscribe(params => {
this.section_local = params['section_id']
console.log(this.section_local)
this.question_data=this.raw_data.sections.filter((val:any) => val.order_id == this.section_local)[0]
console.log(this.question_data)
// product_id = params['product_id'];
// Use product_id and sales_pd_type as needed
});
}
// this.SalesPDService.getData().subscribe(result=>{
// this.raw_data=result['records']
// this.all_sections=this.raw_data.sections.map(val=>val.section_id)
// this.question_data=this.raw_data.sections.filter(val => val.section_id == this.section_local)[0]
// console.log(this.question_data)
// })
ngOnInit() {
this.raw_data=localStorage.getItem('question_temp_salespd')
this.raw_data=JSON.parse(this.raw_data)
this.all_sections=this.raw_data.sections.map((val:any)=>val.section_id)
console.log(this.all_sections)
this.question_data=this.raw_data.sections.filter((val:any) => val.order_id == this.section_local)[0]
console.log(this.question_data)
// if(this.question_data.section_id == 9){
// this.sendDatatoApi()
// }
}
ionViewDidLoad() {
// console.log('ionViewDidLoad HomePage');
// console.log("######Entered");
// this.networkDetectionProvider.onNetworkChange().subscribe(result=>{
// this.network_status = result
// console.log(this.network_status);
// })
console.log('ionViewDidLoad HomePage');
console.log("######Entered");
this.networkDetectionProvider.onNetworkChange().subscribe(result=>{
this.network_status = result
console.log(this.network_status);
})
}
@ -661,8 +788,11 @@ checkTheUploadingProgress(sec_value:any){
navigate(event:any){
console.log(event,this.all_sections[this.all_sections.length - 1]);
if(this.all_sections[this.all_sections.length - 1] != event.section_id){
this.navCtrl.pop()
console.log('this.navCtrl.pop()')
// this.navCtrl.pop()
this.navCtrl.navigateBack('/section-list')
}
else{
// this.sendData()
@ -676,10 +806,15 @@ checkTheUploadingProgress(sec_value:any){
this.SalesPDService.clear_local_key('sales_pd_id_PRIMARYKEY');
localStorage.removeItem('product_id_salesPD')
setTimeout(()=>{
this.navCtrl.navigateRoot('/section-list');
this.router.navigate(['/sales-pd-list']);
// this.navCtrl.navigateRoot('/section-list');
},2000)
}
}
goToBack(){
this.router.navigate(['/section-list']);
}
// sendDatatoApi(){
// this.loadingProvider.pdloader('Please Wait...')
// this.SalesPDService.sendData(this.all_sections).then((res:any)=>{

View File

@ -4,11 +4,15 @@ import { SharedModule } from 'src/shared/shared.module';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatNativeDateModule } from '@angular/material/core';
import { IonicModule } from '@ionic/angular';
import { HomeComponent, Section1, Section2, Section3, Section4, Section5, Section6, Section7, Section8, Section9 } from './home.component';
import { QuesTempModule } from '../ques-template/ques-temp.module';
import { SalesPdService } from '../providers/sales-pd/sales-pd.service';
import { NgxImageCompressService } from 'ngx-image-compress';
@NgModule({
declarations: [],
declarations: [HomeComponent,Section1,Section2,Section3,Section4,Section5,Section6,Section7,Section8,Section9],
imports: [
CommonModule,
SharedModule,
@ -16,7 +20,9 @@ import { IonicModule } from '@ionic/angular';
ReactiveFormsModule,
MatNativeDateModule,
IonicModule.forRoot(),
QuesTempModule
],
providers:[SalesPdService,NgxImageCompressService],
schemas: [
CUSTOM_ELEMENTS_SCHEMA
]

View File

@ -1,10 +1,10 @@
<ion-header>
<ion-toolbar color="optblue">
<!-- <ion-buttons slot="start">
<ion-menu-button></ion-menu-button>
</ion-buttons> -->
<ion-title>Choose the Product</ion-title>
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
</ion-buttons>
<ion-title class="ion-justify-content-center p-0">Choose the Product</ion-title>
</ion-toolbar>
</ion-header>

View File

@ -3,56 +3,61 @@ import { RouterModule, Routes } from '@angular/router';
import { PdListComponent } from './pd-list/pd-list.component';
import { HomeComponent, Section1, Section2, Section3, Section4, Section5, Section6, Section7, Section8, Section9 } from './home/home.component';
import { SectionListComponent } from './section-list/section-list.component';
import { PdfViewerComponent } from './report-pdf-viewer/pdf-viewer.component';
const routes: Routes = [
{
path: 'sales-pd-list',
component: PdListComponent
component: PdListComponent,
},
{
path: 'home',
component:HomeComponent
component:HomeComponent,
},
{
path: 'section-list',
component:SectionListComponent
component:SectionListComponent,
},
{
path: 'section1',
component:Section1
component:Section1,
},
{
path: 'section2',
component:Section2
component:Section2,
},
{
path: 'section3',
component:Section3
component:Section3,
},
{
path: 'section4',
component:Section4
component:Section4,
},
{
path: 'section5',
component:Section5
component:Section5,
},
{
path: 'section6',
component:Section6
component:Section6,
},
{
path: 'section7',
component:Section7
component:Section7,
},
{
path: 'section8',
component:Section8
component:Section8,
},
{
path: 'section9',
component:Section9
component:Section9,
},
{
path: 'pdf-viewer',
component:PdfViewerComponent,
}
];
@NgModule({

View File

@ -10,10 +10,11 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatNativeDateModule } from '@angular/material/core';
import { HomeComponent, Section1, Section2 } from './home/home.component';
import { SectionListComponent } from './section-list/section-list.component';
import { QuesTemplateComponent } from './ques-template/ques-template.component';
@NgModule({
declarations: [PdListComponent,PdAdvanceFilterComponent,HomeComponent,SectionListComponent],
declarations: [PdListComponent,PdAdvanceFilterComponent,SectionListComponent],
imports: [
CommonModule,
PageRoutingModule,

View File

@ -1,6 +1,11 @@
@import '../../../../theme/filter-modal.scss';
.header-md{
// background-color: #ff0303 !important;
// color: black !important;
--background: #fff;
--color: black;
}
::ng-deep .toolbar-background{
--background: none; /* Set it to none to clear the background */
border-color: #b2b2b2 ;

View File

@ -31,9 +31,6 @@
<ion-fab-button (click)="openFilterModal()">
<ion-icon name="options"></ion-icon>
</ion-fab-button>
<ion-fab-button (click)="takePicture()">
<ion-icon name="camera-outline"></ion-icon>
</ion-fab-button>
<ion-fab-button (click)="newForm()" *ngIf="is_sales_login">
<ion-icon name="add"></ion-icon>
</ion-fab-button>
@ -53,10 +50,10 @@
</div> -->
<ion-list>
<ion-item-sliding *ngFor="let val of sales_displayValue" style="padding: 0px">
<ion-item>
<ion-item (click)="val.status != 'COMPLETED' ? editForm(val) : salesPDpdf(val)">
<ion-grid>
<ion-row class="ion-align-items-center">
<ion-col class="applicant_name" col-6 *ngIf="val.applicant_name != null" (click)="val.status != 'COMPLETED' ? editForm(val) : presentActionSheet(val)">
<ion-col class="applicant_name" col-6 *ngIf="val.applicant_name != null" >
<h1>{{val.applicant_name}}</h1>
</ion-col>
<ion-col col-6 *ngIf="val.applicant_name == null">
@ -69,7 +66,7 @@
</ion-col>
</ion-row>
<ion-row class="ion-align-items-center">
<ion-col col-6 (click)="val.status != 'COMPLETED' ? editForm(val) : presentActionSheet(val)">
<ion-col col-6>
<h6 class="app_id">{{val.sales_pd_type == '1' ? 'Physical PD' : 'Telephonic PD'}}</h6>
</ion-col>
<ion-col col-6 class="ion-text-end">
@ -100,4 +97,32 @@
<ion-icon name="add"></ion-icon>
</ion-fab-button>
</ion-fab> -->
</ion-content>
<ion-footer>
<!-- <ion-tabs>
<ion-tab-button (click)="redirectToAnotherPage()">
<ion-icon name="list"></ion-icon>
<ion-label>List</ion-label>
</ion-tab-button>
</ion-tabs> -->
<ion-tabs>
<ion-tab-bar slot="bottom">
<ion-tab-button>
<ion-icon name="home"></ion-icon>
<ion-label>Home</ion-label>
</ion-tab-button>
<ion-tab-button>
<ion-icon name="add"></ion-icon>
<ion-label>PD</ion-label>
</ion-tab-button>
<ion-tab-button>
<ion-icon name="power"></ion-icon>
<ion-label>Logout</ion-label>
</ion-tab-button>
</ion-tab-bar>
</ion-tabs>
</ion-footer>

View File

@ -1,5 +1,6 @@
.header-md{
background-color: #ff0303 !important;
color: #fff !important;
}
ion-item-sliding{
border-bottom: 1px solid #b4b5b9;
@ -85,3 +86,23 @@ padding: 10px;
float: center;
}
::ng-deep .action-sheet-title.sc-ion-action-sheet-md {
color: #000 !important;
// text-align: center !important;
}
::ng-deep .action-sheet-button.sc-ion-action-sheet-md {
color: #000 !important;
// text-align: center !important;
}
::ng-deep .action-sheet-group.sc-ion-action-sheet-md:first-child{
color: #000 !important;
}
::ng-deep .action-sheet-icon.sc-ion-action-sheet-md{
color: #000;
}

View File

@ -1,5 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { ActionSheetController, MenuController, ModalController, NavController } from '@ionic/angular';
import { ActionSheetController, LoadingController, MenuController, ModalController, NavController } from '@ionic/angular';
import { AuthService } from 'src/app/authencation/auth-service/auth.service';
import { LoadingService } from 'src/providers/common-provider/loading.service';
import { ToastService } from 'src/providers/common-provider/toast.service';
@ -8,6 +8,10 @@ import { SalesPdService } from '../providers/sales-pd/sales-pd.service';
import { environment } from 'src/environments/environment';
import { Camera, CameraResultType } from '@capacitor/camera';
import { PdAdvanceFilterComponent } from './pd-advance-filter/pd-advance-filter.component';
import { Router } from '@angular/router';
import { CameraService } from '../providers/camera/camera.service';
import { PdfViewerComponent } from '../report-pdf-viewer/pdf-viewer.component';
import { finalize } from 'rxjs';
const pd_key ='local_sales_PDs'
@ -18,6 +22,26 @@ const pd_key ='local_sales_PDs'
})
export class PdListComponent implements OnInit {
// public actionSheetButtons = [
// {
// text: 'View Report',
// icon: 'eye',
// role: 'destructive',
// data: {
// action: 'delete',
// },
// },
// {
// text: 'Cancel',
// icon: 'arrow-back',
// role: 'cancel',
// data: {
// action: 'cancel',
// },
// },
// ];
is_sales_login:boolean = false
common: any;
sales_displayValue: any=[];
@ -39,8 +63,8 @@ export class PdListComponent implements OnInit {
status: any;
bgColorPast: any=[];
constructor(private modalController: ModalController,public Menu:MenuController,public aws:AuthService,public actionSheetCtrl: ActionSheetController,public navCtrl: NavController,private toastProvider:ToastService,private loaderProvider:LoadingService,private modalCtrl:ModalController,
private ionicStorageService:IonicStorageService,public salesPDService:SalesPdService) {
constructor(private router: Router,private loadingController: LoadingController,private modalController: ModalController,public Menu:MenuController,public aws:AuthService,public actionSheetCtrl: ActionSheetController,public navCtrl: NavController,private toastProvider:ToastService,private loaderProvider:LoadingService,private modalCtrl:ModalController,
private ionicStorageService:IonicStorageService,public salesPDService:SalesPdService,private cameraProvider:CameraService) {
let userDetails:any = localStorage.getItem('user_details');
console.log('userdetails');
@ -70,7 +94,7 @@ export class PdListComponent implements OnInit {
this.common = this.common.count + ' ' + this.common.factor;
}
}, 300);
// this.cameraProvider.checkGPSPermission();
this.cameraProvider.checkAndRequestGPSPermission();
// this.salesPDService.clearLocalData();
}
@ -245,53 +269,80 @@ export class PdListComponent implements OnInit {
});
});
}
// async presentActionSheet(valueObj:any) {
// const actionSheet = await this.actionSheetCtrl.create({
// header: 'Select Option',
// buttons: [
// {
// text: 'View Report',
// icon: 'eye',
// role: 'destructive',
// handler: () => {
// // Call your function here
// this.salesPDpdf(valueObj.sales_pd_id);
// },
// },
// {
// text: 'Cancel',
// icon: 'arrow-back',
// role: 'cancel',
// handler: () => {
// console.log('Cancel clicked');
// },
// },
// ],
// });
presentActionSheet(value_obj:any) {
let buttons = [
{
text: 'View Report',
icon: 'eye',
role: 'destructive',
handler: () => {
// this.salesPDpdf(value_obj.sales_pd_id);
}
},
{
text: 'Cancel',
role: 'cancel',
icon: 'arrow-round-back',
handler: () => {
console.log('Cancel clicked');
}
}
];
let actionSheet:any = this.actionSheetCtrl.create({
buttons: buttons
});
actionSheet.present();
}
// salesPDpdf(pdfdetail:any){
// this.loaderProvider.pdloader("Processing..")
// this.salesPDService.getSalesPdpdf(pdfdetail)
// .subscribe(data => {
// if (data.status == 200) {
// let profileModal:any = this.modalCtrl.create(ReportViewer,{'report_link':data.records});
// profileModal.present();
// await actionSheet.present();
// }
// this.loaderProvider.dismissLoader();
// },err=>{
// this.loaderProvider.dismissLoader()
// async salesPDpdf(valueObj:any) {
// const loader = await this.loadingController.create({
// message: 'Processing...',
// });
// loader.present();
// this.salesPDService.getSalesPdpdf(valueObj.sales_pd_id)
// .subscribe(
// (data) => {
// if (data.status === 200) {
// this.presentReportViewerModal(data.records);
// }
// loader.dismiss();
// },
// (err) => {
// loader.dismiss();
// console.log(err);
// let profileModal = this.modalCtrl.create(ReportViewer,{'error_msg':'Please check your internet connection to view PD reports. They are available only if you are connected.'});
// profileModal.present();
// this.presentErrorModal();
// }
// );
// }
// async presentReportViewerModal(reportLink: any) {
// await this.navCtrl.navigateRoot('/pdf-viewer', { queryParams: { reportLink: reportLink } });
// }
// async presentErrorModal() {
// await this.navCtrl.navigateRoot('/pdf-viewer', { queryParams: { error_msg: 'Please check your internet connection to view PD reports. They are available only if you are connected.' }});
// }
async salesPDpdf(valueObj:any) {
this.loaderProvider.pdloader('Processing..');
try {
const data:any = await this.salesPDService.getSalesPdpdf(valueObj.sales_pd_id).pipe(finalize(() => this.loaderProvider.dismissLoader())).toPromise();
if (data.status === 200) {
const profileModal = await this.modalCtrl.create({ component: PdfViewerComponent, componentProps: { report_link: data.records } });
await profileModal.present();
}
} catch (err) {
console.log(err);
const profileModal = await this.modalCtrl.create({ component: PdfViewerComponent, componentProps: { error_msg: 'Please check your internet connection to view PD reports. They are available only if you are connected.' } });
await profileModal.present();
}
}
updateVisibleItems() {
this.visibleItems = this.sales_displayValue.slice(this.startIndex, this.startIndex + this.itemsPerView);
@ -405,4 +456,9 @@ export class PdListComponent implements OnInit {
}
}
// redirectToAnotherPage() {
// // Navigate to another page when the "List" tab is clicked
// this.navCtrl.navigateForward('/tabs/another-page');
// }
}

View File

@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { CameraService } from './camera.service';
describe('CameraService', () => {
let service: CameraService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(CameraService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

View File

@ -0,0 +1,212 @@
import { DatePipe } from '@angular/common';
import { Injectable } from '@angular/core';
import { Camera, CameraResultType, CameraSource } from '@capacitor/camera';
import { Geolocation } from '@capacitor/geolocation'
// import watermark from 'watermarkjs';
import { NgxImageCompressService } from 'ngx-image-compress';
@Injectable({
providedIn: 'root'
})
export class CameraService {
geoCords: any;
pipe: DatePipe;
constructor(private imageCompress: NgxImageCompressService) {
console.log('Hello CameraProvider Provider');
this.pipe=new DatePipe('en-US')
}
async enableAccuracy(): Promise<any> {
try {
const permissionStatus = await Geolocation.checkPermissions();
console.log('Current Position:', permissionStatus.location);
if(permissionStatus?.location == 'granted'){
return this.getGeoTag();
}
// Continue with your logic for handling the geocoordinates
} catch (error) {
console.error('Error getting current position:', error);
// Handle the error and return false or perform any necessary actions
alert('We need location access to capture the geocoordinates of your place. Please turn on the location to continue');
return false;
}
}
async getGeoTag(): Promise<any> {
try {
const coordinates = await Geolocation.getCurrentPosition({
timeout: 30000,
enableHighAccuracy: true,
});
console.log("res from getGeoTag", coordinates.coords);
console.log("res from provider", new Date(coordinates.timestamp));
const { latitude, longitude } = coordinates.coords;
const curr_pos = `${latitude},${longitude}`;
return curr_pos;
} catch (err) {
console.log("error in getGeoTag", err);
throw err; // Handle the error at the calling location if needed
}
}
async getpicture() {
try {
localStorage.removeItem('current_coordinates');
const coordinates = await this.getGeoTag();
this.geoCords = coordinates;
console.log(this.geoCords)
localStorage.setItem('current_coordinates', this.geoCords);
// const image = await Camera.getPhoto({
// quality: 100,
// allowEditing: false,
// resultType: CameraResultType.DataUrl,
// });
// // Here you get the image as result.
// const theActualPicture = image.dataUrl;
const image = await Camera.getPhoto({
quality: 75,
allowEditing: false, // Set to true if you want to enable image editing
resultType: CameraResultType.Base64,
source: CameraSource.Camera,
width: 600,
height: 600,
correctOrientation: true,
});
const base64Image = `data:image/jpeg;base64,${image.base64String}`;
this.imageInfo(base64Image, 'Captured :');
return base64Image;
} catch (error) {
localStorage.removeItem('current_coordinates');
console.error('CAMERA ERROR ->', error);
return 'error';
}
}
imageInfo(img:any,label:any){
let img_dummy= new Image()
img_dummy.src = img
img_dummy.onload = e => {
fetch(img_dummy.src).then(resp => resp.blob())
.then(blob => {
console.warn(label+" size in bytes",blob.size/1000)
console.warn(label+" Image Resolution",img_dummy.width + ' x ' +img_dummy.height)
});
};
}
async addWatermarks(base64Img: string) {
return new Promise<string>(async (resolve, reject) => {
const geoCords = localStorage.getItem('current_coordinates');
console.log('coords', geoCords);
const today = new Date();
const today_loc = new DatePipe('en-US').transform(today, 'yyyy-MM-dd, h:mm a');
const dateTime = 'Date : ' + today_loc;
try {
// const watermarkedImg = await watermark([base64Img, 'assets/img/PD_watermark.png'])
// .image(watermark.image.upperRight());
// const text = watermark.text;
// const locationText = `Location : ${geoCords}`;
// const watermarkedWithDateTime = await watermark([watermarkedImg.src])
// .image(text.upperLeft(dateTime, '18px sans-serif', '#ff0000', 1.0, 40));
// const finalWatermarkedImg = await watermark([watermarkedWithDateTime.src])
// .image(text.upperLeft(locationText, '18px sans-serif', '#ff0000', 1.0));
const lastWatermarked = base64Img
this.imageInfo(lastWatermarked, 'Watermarked :');
localStorage.removeItem('current_coordinates');
try {
const compressedImg = await this.compressTheImage(lastWatermarked);
this.imageInfo(compressedImg, 'Compressed :');
resolve(compressedImg);
} catch (err) {
console.log(err);
reject();
}
} catch (error) {
console.log('Watermarking Error', error);
resolve(base64Img);
}
});
}
compressTheImage(img: string): Promise<string> {
return new Promise((resolve, reject) => {
this.imageCompress.compressFile(img, -1, 100, 75).then(
(result: string) => {
console.warn('Size in bytes is now:', this.imageCompress.byteCount(result) / 1000);
resolve(result);
},
(err: any) => {
console.log(err);
reject(err);
}
);
});
}
async checkAndRequestGPSPermission() {
try {
const permissionStatus = await Geolocation.checkPermissions();
if (permissionStatus.location === 'granted') {
// GPS permission is granted
return this.askToTurnOnGPS();
} else {
// GPS permission is not granted, request it
const requestResult = await Geolocation.requestPermissions();
if (requestResult.location === 'granted') {
// User granted GPS permission, proceed to turn on GPS
return this.askToTurnOnGPS();
} else {
// User denied GPS permission
console.error('GPS permission denied');
return null; // You might want to handle this case differently
}
}
} catch (error) {
console.error('Error checking or requesting GPS permission', error);
return null;
}
}
async askToTurnOnGPS(): Promise<string> {
try {
await Geolocation.requestPermissions({ permissions: ['location'] });
// When GPS Turned ON, call method to get accurate location coordinates
const geoCords = await this.getGeoTag();
return geoCords;
} catch (error) {
console.error('askToTurnOnGPS Error requesting location permissions', error);
throw error; // Handle the error at the calling location if needed
}
}
}

View File

@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { QuesServiceService } from './ques-service.service';
describe('QuesServiceService', () => {
let service: QuesServiceService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(QuesServiceService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

View File

@ -0,0 +1,371 @@
import { DatePipe } from '@angular/common';
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { AbstractControl, FormArray, FormBuilder, FormControl, FormGroup, ValidationErrors, Validators } from '@angular/forms';
import { SalesPdService } from '../sales-pd/sales-pd.service';
@Injectable({
providedIn: 'root'
})
export class QuesServiceService {
datepipe: DatePipe;
curr_pd_info: any;
constructor(public http: HttpClient,private _fb:FormBuilder,private salesPDProvider:SalesPdService) {
console.log('Hello QuesServiceProvider Provider');
this.datepipe=new DatePipe('en-US')
}
assignFormControl_array(formgroup: FormGroup, ques_data: any) {
// this.curr_pd_info = this.apiService.curr_credit_pd_data
console.log(formgroup, ques_data)
const control: any = formgroup.get('questions') as FormArray
ques_data.forEach((val:any, index:any) => {
console.log("quees", val)
if (val.hasOwnProperty('is_repeatable') && val.is_repeatable == '1') {
control.push(this._fb.group({
"is_repeatable": [val.is_repeatable || null],
"is_multi_disabled":[val.is_multi_disabled || '0'],
"group_title": [val.group_title || null], "group_type": [val.group_type || null]
,"question_key":[val.question && val.question.length > 0 ? val.question[0].question_key : val.question_key]
}))
control.controls[index].addControl('questions_group', this._fb.array([]))
let childControl: any = control.controls[index].get('questions_group') as FormArray
childControl.push(this._fb.group({ 'questions': this._fb.array([]) }))
console.log("cc", childControl, control, index)
let sub_childControl: any = childControl.controls[0].get('questions') as FormArray
val.question.forEach((group_indi:any, arr_index:any) => {
console.log("api pro", val.api_properties)
group_indi.raw_validations = group_indi.validations
sub_childControl.push(this.createValue(group_indi))
this.addAdditionalControl(group_indi, sub_childControl, arr_index)
// sub_childControl.controls[index].addControl('select_search',new FormControl(val.field_type))
// }
if (group_indi.api_properties != null) {
this.apiPropertiesCall(group_indi).then((res:any) => {
if (res != false) {
group_indi.answers = []
// group_indi.answers=this.convertArrayNames(val.api_properties.fields,res)
sub_childControl.controls[arr_index]['controls'].answers.setValue(this.convertArrayNames(group_indi.api_properties.fields, res))
}
})
}
})
console.log("dd112", formgroup, childControl)
}
else {
val.raw_validations = val.validations
control.push(this.createValue(val))
// for checkbox remove the form control and add the formarray for multiple values
this.addAdditionalControl(val, control, index)
if (val.api_properties != null) {
this.apiPropertiesCall(val).then((res:any) => {
console.log("chekc", res)
if (res != false) {
control.controls[index]['controls'].answers.setValue(this.convertArrayNames(val.api_properties.fields, res))
}
}, (err:any) => console.log(err))
}
console.log(formgroup)
}
}, (err:any) => console.log(err))
return formgroup
}
// FOR CREATING THE FORM CONTROL FOR SPECIFIC FORM ARRAY
createValue(data:any){
let is_amt_in_words=false
let answer_value_loc='';
let answers_from_client=[]
if(data.hasOwnProperty('answer_value') && data.answer_value != '' || null){
let values_for_cli:any = this.getAnswerValue(data)
if(values_for_cli.flag == 1){
answer_value_loc=values_for_cli.values
}
else{
answers_from_client=values_for_cli.values
}
}
return this._fb.group({
"answer_value":[{value:answer_value_loc,disabled:answer_value_loc != '' ? true : false}], // OLD VALIDATION >>>> data.type != '6' ? Validators.compose([Validators.required]) : ''
"question":[data.question],
"question_key":[data.question_key],
"type":[data.type],
"raw_validations":[data.raw_validations],
"validations":[data.raw_validations],
"api_properties":[data.api_properties],
"onchange_properties":[data.onchange_properties],
"answers":[answers_from_client.length != 0 ? answers_from_client: data.answers],
"is_repeatable":[data.is_repeatable || null],
"is_multiple":[data.is_multiple || 0],
"group_title":[data.group_title || null]
})
}
// END OF CREATEVALUE FUN
// FOR REQUESTING THE API AUTOMATICALLY FROM JSON
apiPropertiesCall(val:any){
return new Promise((resolve,reject)=>{
if(val.api_properties != null && typeof(val.api_properties) == 'object'){
let pd_info = this.curr_pd_info
console.log(pd_info)
let params = val.api_properties.params
if(val.api_properties.hasOwnProperty('params_type') && val.api_properties.params_type == 'expression') {
params = eval(val.api_properties.params)
console.log(params,this.curr_pd_info.smc_credit_pd)
// debugger;
}
this.salesPDProvider.api_post_method(val.api_properties.api,params,val.api_properties.api_method).subscribe(res=>{
if(res['dataStatus']){
if(res.hasOwnProperty('records')){
res=res['records']
}
resolve(res)
console.log(res)
// val.answers=res
}
else{
resolve(false)
}
})
}
else{
resolve(false)
}
})
}
// END OF API PROPERTIES CALL
// ---FOR CONVERTING THE ANSWER KEYS UNIQUE
convertArrayNames(fieldName:any,data_from_api:any){
let val1=[]
let modified_json = data_from_api.map(
(obj:any) => {
if(fieldName.length > 0) {
return {
"answer_id" : obj[fieldName[0]],
"answer":obj[fieldName[1]],
}
}
else {
return {
"answer_id" : obj,
"answer":obj,
}
}
});
return modified_json
}
// END OF CONVERTARRAYNAMES FUN--
// --- FOR SETTING THE VALUE DEFAULT WITH DISABLED AND GENERATE THE ANSWERS FOR FIELDS(EX. refer 'GET_FY_YEARS' switch)
getAnswerValue(value_obj:any) {
if (value_obj != null && value_obj.hasOwnProperty('answer_value')) {
let return_value = { flag: 1, values: '' };
let user_det: any = localStorage.getItem("user_details")
user_det = JSON.parse(user_det);
switch (value_obj.answer_value) {
case 'CURRENT_USER':
console.log("current user", user_det)
return_value.values = user_det.user_first_name + ' ' + user_det.user_last_name
break;
case "CURRENT_DESIGNATION":
return_value.values = user_det.designation_name != null ? user_det.designation_name : ''
break;
case "CURRENT_DATE":
let date = new Date();
let formattedDate = this.datepipe.transform(date, 'dd-MM-yyyy, h:mm:ss a');
return_value.values = formattedDate !== null ? formattedDate : '';
break;
case "GET_FY_YEARS":
return_value.values = this.getCurrentFyYears()
return_value.flag = 2
break;
default:
return_value.values = ''
break
}
return return_value
}
return ''
}
// --END OF GETANSWERVALUE FUN
addAdditionalControl(data:any,curr_control:any,curr_index:any,purpose?:any){
//FOR CHECKBOX CHANGE THE VALUE STORAGE AS ARRAY
if(data.type == '5'){
curr_control.controls[curr_index].removeControl('answer_value');
curr_control.controls[curr_index].addControl('answer_value',this._fb.array([]))
}
//FOR numeric of string field
if(data.type == '1'){
curr_control.controls[curr_index].addControl('field_type',new FormControl(data.field_type))
curr_control.controls[curr_index].addControl('place_holder',new FormControl(data.place_holder))
}
//FOR SEARCHABLE FIELD VALUE KEY ()
if(data.type == '8'){
curr_control.controls[curr_index].addControl('select_search',new FormControl(data.field_type))
}
if(purpose == 'additional_field'){
curr_control.controls[curr_index].addControl('additional_field',new FormControl(1))
}
// FOR IMAGE STATUS
if(data.type == '6'){
curr_control.controls[curr_index].addControl('is_loader',new FormControl(''))
curr_control.controls[curr_index].addControl('is_saved',new FormControl(''))
curr_control.controls[curr_index].addControl('is_image_status',new FormControl(false))
}
if(data.hasOwnProperty('question_enable') && data.question_enable != null && data.question_enable) {
let expression= data.question_enable;
console.log("Check started",expression,expression.includes('PD_FORM_VALUES'));
if(expression.includes('PD_FORM_VALUES')) {
this.salesPDProvider.getData_fromLocal('sales_pd_id_PRIMARYKEY').then(sales_pd_id => {
if(sales_pd_id) {
let PD_FORM_VALUES = localStorage.getItem('PD_FORM_VALUES-'+sales_pd_id)
if(PD_FORM_VALUES) {
PD_FORM_VALUES = JSON.parse(PD_FORM_VALUES)
// expression = expression.split('PD_FORM_VALUES').join(local_pd_form_values)
console.log("ex",expression)
let result = eval(expression)
console.log(result);
if(!result) {
curr_control.removeAt(curr_index);
}
}
}
})
}
// expression = expression.split(res).join(control_value_obj.answer_value)
}
//FOR SETTING THE VALIDATORS
this.settingArrayofValidators(data,curr_control.controls[curr_index],curr_index)
}
// FOR SETTING THE ARRAY OF VALIDATORS COMING FROM JSON Temp,
settingArrayofValidators(data:any,curr_control:any,curr_index:any){
console.log("entered",data);
if(data.hasOwnProperty('validations') && data.validations.length > 0 ){
const validList :any= [];
let validator_value
data.validations=data.validations.filter((val:any)=>val.isactive != '0')
data.validations.forEach((valid:any) => {
if(valid.value != null && !valid.hasOwnProperty('validation_to')){
validator_value= this.getvalidatorValue(valid)
}
else{
validator_value=this.setValueForValidator(valid)
console.log("cc",validator_value)
}
validList.push(validator_value);
});
console.log(validList)
// curr_control.controls[curr_index].controls.answer_value.setValidators(validList)
curr_control.controls.answer_value.setValidators(validList)
console.log("ddvdeeqq",validList)
curr_control.controls.answer_value.updateValueAndValidity()
console.log("after setting validators",curr_control)
}
}
// END OF SETTINGARRAYOFVALIDATORS FUN
// FOR GETTING THE VALIDATION VALUE
getvalidatorValue(value_obj: any): string | false | ((control: AbstractControl<any, any>) => ValidationErrors | null) | undefined {
if (value_obj != null && value_obj.hasOwnProperty('value')) {
let value_of_validator;
switch (value_obj.value) {
case 'CURRENT_YEAR':
value_of_validator = new Date().getFullYear();
break;
default:
value_of_validator = '';
break;
}
value_obj.validator = String(value_of_validator);
return this.setValueForValidator(value_obj);
}
// Add a return statement for other cases or a default value
return ''; // Or return something of the expected type
}
// END OF GETVALIDATORVALUE FUN
// FOR GENERATING THE FY YEAR FIELD ANSWERS
getCurrentFyYears(){
let month=new Date().getMonth()
let year=new Date().getFullYear()
let fy:any=[];
if(month >=3){
fy.push({fy_year:year-1+'-'+(year),curr:year})
}
else{
fy.push({fy_year:year-2+'-'+(year-1),curr:year-1})
}
console.log(fy)
for(let i=0;i<=2;i++){
fy.push({fy_year:(fy[i].curr-2)+'-'+(fy[i].curr-1),curr:fy[i].curr-1})
}
return fy.map((val:any)=>({answer:val.fy_year,answer_id:val.fy_year}))
}
// END OF GETCURRFYYEARS FUN
// FOR CREATING THE CORRECT VALIDATION
setValueForValidator(value_obj:any){
console.log("setvlaue of validator",value_obj.validator,typeof(value_obj.validator))
let return_value
if(value_obj != null && value_obj.hasOwnProperty('validator')){
switch(value_obj.name)
{
case 'required':
return_value=Validators.required
break;
case 'minLength':
return_value=Validators.minLength(value_obj.validator)
break;
case 'maxLength':
return_value=Validators.maxLength(value_obj.validator)
break;
case 'min':
return_value=Validators.min(value_obj.validator)
break;
case 'max':
return_value=Validators.max(value_obj.validator)
break;
case 'pattern':
return_value=Validators.pattern(value_obj.validator)
break;
default:
return_value=''
break;
}
return return_value
}
else{
return false
}
}
// END OF SETVALUEFORVALIDATOR FUN
}

View File

@ -1,12 +1,13 @@
import { HttpClient, HttpParams } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, Observer, forkJoin, tap } from 'rxjs';
import { Observable, Observer, forkJoin, map, tap } from 'rxjs';
import { environment } from 'src/environments/environment';
import { IonicStorageService } from 'src/providers/ionic-storage/ionic-storage.service';
import { Storage } from '@ionic/storage-angular'
import { Capacitor } from '@capacitor/core';
import { ConnectionStatus, NetworkDetectionService } from 'src/providers/network-detection/network-detection.service';
import { OfflineManagerService } from '../offline-manager/offline-manager.service';
import { CameraService } from '../camera/camera.service';
const pd_key ='local_sales_PDs'
@Injectable({
@ -17,11 +18,13 @@ export class SalesPdService {
original_rawData:any;
available_sections:any;
current_section:any;
constructor(public http: HttpClient, private ionicStorageProvider:IonicStorageService,private storage: Storage,private networkProvider:NetworkDetectionService,private offlineManagerProvider:OfflineManagerService) { }
constructor(public http: HttpClient, private ionicStorageProvider:IonicStorageService,private storage: Storage,private networkProvider:NetworkDetectionService,private offlineManagerProvider:OfflineManagerService,private cameraService:CameraService) { }
getData(product_id: any, sales_pd_type?: any): Observable<any> {
const users:any = localStorage.getItem('user_details');
console.log(users)
const parsedUsers = JSON.parse(users);
console.log(parsedUsers)
const params = {
records: {
lender_id: parsedUsers.fk_entity_id,
@ -29,7 +32,7 @@ export class SalesPdService {
sales_pd_type: sales_pd_type,
},
};
console.log(params)
return new Observable((observer: any) => {
if (this.networkProvider.getCurrentNetworkStatus() == ConnectionStatus.online) {
console.log('Capacitor.isNative',Capacitor.isNative);
@ -135,13 +138,13 @@ export class SalesPdService {
}
else if(this.networkProvider.getCurrentNetworkStatus() == ConnectionStatus.online) {
let values={sales_pd_id:params.sales_pd_id,dataStatus:true}
return this.http.post(this.apiUrl+'getSalesPDSectionData',{records:params}).subscribe(result =>{
return this.http.post(this.apiUrl+'getSalesPDSectionData',{records:params}).subscribe((result:any) =>{
let modified_values:any =result
modified_values.section_id = params.section_id
let resultDetails = modified_values['dataStatus']
if(resultDetails) {
// let resultDetails = modified_values['dataStatus']
if(result['dataStatus']) {
if(params.section_id != 'all') {
modified_values = resultDetails[0]
modified_values = result['records'][0]
modified_values.is_synced = true
}
if(this.networkProvider.getCurrentNetworkStatus() == ConnectionStatus.online) {
@ -377,10 +380,14 @@ callMultipleApisForTemplate(product_arr:any) {
}
getData_fromLocal(key:any){
// console.log("get data key",this.getKey(key));
// console.log("get data provider",this.storage.get(key))
// console.log("all key in storage",this.storage.keys())
// getData_fromLocal(key:any){
// // console.log("get data key",this.getKey(key));
// // console.log("get data provider",this.storage.get(key))
// // console.log("all key in storage",this.storage.keys())
// return this.storage.get(key);
// }
getData_fromLocal(key: any): Promise<any> {
return this.storage.get(key);
}
@ -394,4 +401,384 @@ clearLocalData(){
})
}
api_post_method(apiName: string, params: any, apiMethod?: string): Observable<any> {
if (this.networkProvider.getCurrentNetworkStatus() === ConnectionStatus.online) {
return new Observable((observer: Observer<any>) => {
if (apiMethod?.toUpperCase() === 'POST') {
this.http.post(this.apiUrl + apiName, params).subscribe(result => {
if ((result as any)['dataStatus']) {
this.ionicStorageProvider.checkAndInsertApiDataLocally(result, params, apiName, true).then(
r => {
observer.next(result);
observer.complete();
},
err => console.log("Ionic storage error", err)
);
} else {
observer.next(result);
observer.complete();
}
});
} else {
this.http.get(this.apiUrl + apiName).subscribe(result => {
this.ionicStorageProvider.checkAndInsertApiDataLocally(result, params, apiName).then(
rr => {
observer.next(result);
observer.complete();
},
err => console.log("Ionic storage error", err)
);
});
}
});
}
// else if (apiName === 'getStakeHoldersInfo') {
// return this.creditPDService.getStakeholderInfo().map(res => {
// console.log(res);
// if (res['dataStatus']) {
// let sectionData = res['records'][0].sectionData; // Adjust the property name based on the actual response structure
// sectionData = JSON.parse(sectionData);
// let stakeholderQues = sectionData.questions.filter((vv: any) => vv.isRepeatable === '1')[0]; // Adjust property names
// console.log(stakeholderQues);
// if (stakeholderQues?.questionsGroup?.length > 0) {
// let applicants = stakeholderQues.questionsGroup.map((vv: any) => vv.questions[0].answerValue); // Adjust property names
// console.log(applicants);
// return { dataStatus: true, records: applicants };
// }
// }
// return res;
// });
// }
else {
return this.ionicStorageProvider.getApiDataFromLocally(params, apiName);
}
}
generateSatelliteImg(params:any,form_structure:any):Observable<Response> {
return Observable.create((observer:Observer<any>)=>{
this.getData_fromLocal('sales_pd_id_PRIMARYKEY').then(key_value=>{
params.sales_pd_id = key_value
let values={sales_pd_id:key_value,dataStatus:true}
let section_data=JSON.stringify({section_id:form_structure.section_id,section_name:form_structure.section_name,onsubmit:null,questions:form_structure.questions})
let modified_params = form_structure
if(this.networkProvider.getCurrentNetworkStatus() == ConnectionStatus.online && (key_value != null ? (typeof(key_value) == 'string' ? !key_value.includes('local') : true) : true)) {
this.http.post(this.apiUrl+'generateSatelliteImg',params).pipe()
.subscribe(result =>{
observer.next(result);
observer.complete();
}
,err=>{
console.clear();
console.log("err>>>>",err)
observer.next(err);
observer.complete();
})
}
else {
console.log("#######params",modified_params)
let offline_params = modified_params
offline_params.request_items=[{url:this.apiUrl+'generateSatelliteImg',
params:JSON.stringify(params),method:'POST'}]
offline_params.is_synced = false
offline_params.section_data = section_data
console.log(offline_params.request_items.params)
this.checkAndCreatePDLocally(values,'','offline','',offline_params).then(res=>{
observer.next({dataStatus:true});
observer.complete()
})
}
})
})
}
getSalesPDImgDataCusLink(params:any) {
return this.http.post(this.apiUrl+'getSalesPDImgDataCusLink',params)
}
saveSalesPDImage(params:any,form_structure?:any): Observable<Response>{
return Observable.create((observer:Observer<any>) => {
this.getData_fromLocal('sales_pd_id_PRIMARYKEY').then(key_value=>{
// this.cameraService.getGeoTag().then((geoCords:any)=>{
// params.location=geoCords
params.fk_sales_pd_id=key_value
if(this.networkProvider.getCurrentNetworkStatus() == ConnectionStatus.online && (key_value != null ? (typeof(key_value) == 'string' ? !key_value.includes('local') : true) : true)) {
this.http.post(this.apiUrl+'saveSalesPDImage',{records:params},{
reportProgress: true,
}).pipe().subscribe(result => {
observer.next(result);
observer.complete();
},err=>{
console.clear();
// console.log("err>>>>",err)
observer.next(err);
observer.complete();
})
}
else {
observer.next({dataStatus:true});
observer.complete()
// })
}
// })
})
})
}
updateSectionDataLocally(params:any,form_structure:any){
return Observable.create((observer:Observer<any>) => {
this.getData_fromLocal('sales_pd_id_PRIMARYKEY').then(key_value=>{
// params.location=geoCords
params.fk_sales_pd_id=key_value
let values={sales_pd_id:key_value,dataStatus:true}
let section_data=JSON.stringify({section_id:form_structure.section_id,section_name:form_structure.section_name,onsubmit:null,questions:form_structure.questions})
let modified_params = form_structure
if(this.networkProvider.getCurrentNetworkStatus() == ConnectionStatus.online && (key_value != null ? (typeof(key_value) == 'string' ? !key_value.includes('local') : true) : true)) {
modified_params.is_synced = true
modified_params.section_data = section_data
this.checkAndCreatePDLocally(values,'','online','',modified_params).then(res=>{
observer.next('');
observer.complete();
})
// },err=>{
// console.clear();
// // console.log("err>>>>",err)
// observer.next(err);
// observer.complete();
// })
}
else {
// console.log("#######params",modified_params)
let offline_params = modified_params
offline_params.request_items=[{url:this.apiUrl+'saveSalesPDImage',
params:JSON.stringify({records:params}),method:'POST'}]
offline_params.is_synced = false
offline_params.section_data = section_data
console.log(offline_params)
this.checkAndCreatePDLocally(values,'','offline','',offline_params).then(res=>{
observer.next({dataStatus:true});
observer.complete()
})
}
})
})
}
saveSalesPDSection(params: any): Observable<any> {
let users:any=localStorage.getItem('user_details')
users=JSON.parse(users)
params.fk_createdby=users.userid
return Observable.create((observer: Observer<any>) => {
this.getData_fromLocal('sales_pd_id_PRIMARYKEY').then((key_value) => {
params.sales_pd_id = key_value;
let values = { sales_pd_id: key_value, dataStatus: true };
let section_data = JSON.stringify({ section_id: params.section_id, section_name: params.section_name, onsubmit: null, questions: params.questions });
let modified_params = params;
if (this.networkProvider.getCurrentNetworkStatus() == ConnectionStatus.online && (key_value != null ? (typeof (key_value) == 'string' ? !key_value.includes('local') : true) : true)) {
this.http.post(this.apiUrl + 'saveSalesPDsection', { records: params }).pipe().subscribe(response => {
modified_params.is_synced = true;
modified_params.section_data = section_data;
if (modified_params.section_id != '9') {
this.checkAndCreatePDLocally(values, '', 'online', '', modified_params).then(res => {
observer.next(response);
observer.complete();
});
} else {
observer.next(response);
observer.complete();
}
});
} else if (modified_params.section_id != '9') {
let offline_params = modified_params;
offline_params.request_items = {
url: this.apiUrl + 'saveSalesPDsection',
params: JSON.stringify({ records: params }),
method: 'POST'
};
offline_params.is_synced = false;
offline_params.section_data = section_data;
this.checkAndCreatePDLocally(values, '', 'offline', '', offline_params).then(res => {
observer.next({ dataStatus: true });
observer.complete();
});
} else {
observer.next({ dataStatus: true });
observer.complete();
}
});
});
}
saveQuestions(params: any): Observable<Response> {
let result_from_api: any;
let userid: any = localStorage.getItem("user_details");
userid = JSON.parse(userid).userid;
params.createdby = userid;
let product_id = localStorage.getItem('product_id_salesPD');
let sales_pd_type = localStorage.getItem('sales_pd_type');
let users: any = localStorage.getItem('user_details');
users = JSON.parse(users);
return new Observable((observer: Observer<any>) => {
this.getData_fromLocal('sales_pd_id_PRIMARYKEY').then(key_value => {
params.sales_pd_id = key_value;
params.lender_id = users.fk_entity_id;
params.product_id = product_id;
params.sales_pd_type = sales_pd_type;
let modified_values = params;
if (this.networkProvider.getCurrentNetworkStatus() == ConnectionStatus.online &&
(key_value != null ? (typeof (key_value) == 'string' ? !key_value.includes('local') : true) : true)) {
this.http.post(this.apiUrl + 'saveSalesPD', { records: params }).pipe().subscribe((result: any) => {
result_from_api = result;
if (!params.hasOwnProperty('status') && params.status != 'COMPLETED') {
if (params.sales_pd_id != null) {
modified_values.sales_pd_id = params.sales_pd_id;
} else {
modified_values.sales_pd_id = result['records'];
}
}
if (params.hasOwnProperty('status') && params.status == 'COMPLETED') {
if (!result_from_api.hasOwnProperty('pd_status') && result_from_api['pd_status'] != 'DRAFT') {
this.offlineManagerProvider.deleteCompletedPD(params.sales_pd_id).then(rd => {
observer.next(result_from_api);
observer.complete();
});
} else {
observer.next(result_from_api);
observer.complete();
}
} else {
this.checkAndCreatePDLocally(modified_values, params, 'online').then(lc => {
observer.next(result_from_api);
observer.complete();
});
}
});
} else if (params.hasOwnProperty('status') && params.status == 'COMPLETED') {
let pd_id_key = this.offlineManagerProvider.getThePDType(modified_values.sales_pd_id);
this.offlineManagerProvider.checkTheExistingPDLocally(modified_values.sales_pd_id, pd_id_key).then(result => {
if (result && result.hasOwnProperty('section_datas') && result.section_datas.length > 0) {
let pd_section_datas = result.section_datas.filter((val: any) => val.section_id != 'all').map((val1: any) => val1.section_name);
let template_sections: any = localStorage.getItem('question_temp_salespd');
template_sections = JSON.parse(template_sections).sections.map((val1: any) => val1.section_name);
if (template_sections.length != pd_section_datas.length) {
let unsavedSections = template_sections.filter(function (item: any) {
return !pd_section_datas.includes(item);
});
let unsavedObj: any = [];
unsavedSections.forEach((val: any, index: any) => {
unsavedObj.push({ id: index, sectin_name: val });
});
if (unsavedSections.length > 0) {
let local_result = {
'pd_status': 'DRAFT',
'records': unsavedObj,
'dataStatus': true
};
observer.next(local_result);
observer.complete();
return;
}
}
}
let req_params = { url: this.apiUrl + 'saveSalesPD', params: JSON.stringify({ records: params }), method: 'POST' };
this.checkAndCreatePDLocally(modified_values, params, 'offline', req_params).then(lc => {
if (params.hasOwnProperty('status') && params.status != 'COMPLETED') {
result_from_api = { dataStatus: true, records: lc.local_pd_id };
} else {
result_from_api = { dataStatus: true, records: true };
}
observer.next(result_from_api);
observer.complete();
});
});
} else {
if (params.hasOwnProperty('status') && params.status != 'COMPLETED') {
modified_values.sales_pd_id = null;
}
let req_params = { url: this.apiUrl + 'saveSalesPD', params: JSON.stringify({ records: params }), method: 'POST' };
let dd = { product_id: modified_values.product_id, lender_id: modified_values.lender_id };
this.getProductAbbrbyId(dd).then((product_abbr: any) => {
modified_values.abbr = product_abbr;
this.checkAndCreatePDLocally(modified_values, params, 'offline', req_params).then(lc => {
if (params.hasOwnProperty('status') && params.status != 'COMPLETED') {
result_from_api = { dataStatus: true, records: lc.local_pd_id };
} else {
result_from_api = { dataStatus: true, records: true };
}
observer.next(result_from_api);
observer.complete();
});
});
}
});
});
}
getProductAbbrbyId(obj: any): Promise<string | undefined> {
if (obj) {
return new Promise((resolve, reject) => {
return this.getEntityPreferences(obj.lender_id).subscribe((result: any) => {
if (result && result['dataStatus']) {
const productforLender = result['records'].salespd_products;
if (productforLender && productforLender.length > 0) {
const product_abbr = productforLender
.filter((val: any) => val.product_id == obj.product_id)
.map((va: any) => va.product_abbr)[0];
resolve(product_abbr);
} else {
resolve(undefined); // Handle the case where product_abbr is undefined
}
} else {
resolve(undefined); // Handle the case where dataStatus is falsy
}
});
});
} else {
return Promise.resolve(undefined); // Handle the case where obj is falsy
}
}
// ...
getEntityPreferences(entity_id: any) {
let params = { entity_id: entity_id };
if (this.networkProvider.getCurrentNetworkStatus() == ConnectionStatus.online) {
return this.http.get(this.apiUrl + 'getEntityPreferences/' + entity_id)
.pipe(
map((result: any) => {
this.ionicStorageProvider.checkAndInsertApiDataLocally(result, params, 'getEntityPreferences');
return result;
})
);
} else {
return this.ionicStorageProvider.getApiDataFromLocally(params, 'getEntityPreferences');
}
}
}

View File

@ -0,0 +1,14 @@
export const photoJSONStructure ={"answer_value": "",
"question": "Approach to PD Location",
"question_key": "approach_to_pd_location",
"type": "6",
"raw_validations": [],
"validations": [],
"api_properties": null,
"onchange_properties": null,
"answers": null,
"is_repeatable": null,
"group_title": null,
"is_loader": "",
"is_saved": "",
"is_image_status": false}

View File

@ -0,0 +1,25 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { SharedModule } from 'src/shared/shared.module';
import { MatNativeDateModule } from '@angular/material/core';
import { IonicModule } from '@ionic/angular';
import { QuesTemplateComponent } from './ques-template.component';
import { QuesServiceService } from '../providers/ques-service/ques-service.service';
@NgModule({
declarations: [QuesTemplateComponent],
imports: [
CommonModule,
SharedModule,
FormsModule,
ReactiveFormsModule,
MatNativeDateModule,
IonicModule.forRoot(),
],
exports: [QuesTemplateComponent],
providers:[QuesServiceService]
})
export class QuesTempModule { }

View File

@ -0,0 +1,422 @@
<!-- Generated template for the QuesTemplateComponent component -->
<div *ngIf="questions_JSON.questions.length > 0" #whole_form>
<form [formGroup]="quesAnsForm" >
<div *ngIf="quesAnsForm.controls['questions']">
<div formArrayName="questions">
<div *ngFor="let parent_ques of quesAnsForm.controls['questions'].controls;let p_i=index">
<div [formGroupName]="p_i">
<div *ngIf="parent_ques.get('is_repeatable').value != '1'">
<mat-form-field style="width: 100%" *ngIf="parent_ques.get('type').value == '1'" [ngStyle]="{'margin-bottom':parent_ques.get('field_type').value == 'numtoword' ? '5%' : '0' }">
<mat-label>{{parent_ques.get('question').value}}</mat-label>
<input matInput [type]="parent_ques.get('field_type').value == 'num' || parent_ques.get('field_type').value == 'numtoword' ? 'number' : parent_ques.get('field_type').value == 'string' ? 'text' : parent_ques.get('field_type').value" formControlName="answer_value"
[placeholder]="parent_ques.value.hasOwnProperty('place_holder') ? parent_ques.get('place_holder').value : ''"
autocomplete="off" (change)="onChangeProperty($event,parent_ques,'','',p_i)"
>
<!-- [placeholder]="parent_ques.get('field_type').value == 'num' || parent_ques.get('field_type').value == 'numtoword' ? 'Entert the Number' : 'Enter the Text'" -->
<!-- <mat-hint *ngIf="parent_ques.get('answer_value').value != '' && parent_ques.get('field_type').value == 'numtoword'" align="end" style="font-size: 12px;">{{"&#8377;"}}{{parent_ques.get('answer_value').value | numToWords}}</mat-hint> -->
<!-- <mat-hint align="end" style="font-size: 11.5px;color: gray;" *ngIf="parent_ques.get('is_amt_in_words').value == true">One Lack</mat-hint> -->
<ng-container *ngFor="let validation of parent_ques.get('validations').value;" ngProjectAs="mat-error">
<mat-error align="end" *ngIf="parent_ques.get('answer_value').hasError(validation.name.toLowerCase())">{{validation.message}}</mat-error>
</ng-container>
</mat-form-field>
<!-- <mat-form-field> -->
<div class="radio-gap" *ngIf="parent_ques.get('type').value == '2'">
<mat-label>{{parent_ques.get('question').value}}</mat-label><br/>
<mat-radio-group aria-label="Select an option" formControlName="answer_value" (change)="onChangeProperty($event,parent_ques,'','',p_i)">
<mat-radio-button class="radio-btn-gap" *ngFor="let val of parent_ques.get('answers').value" [value]="val.hasOwnProperty('answer_id') ? val.answer_id : val.answer">{{val.answer}}</mat-radio-button><br />
</mat-radio-group>
<ng-container *ngFor="let validation of parent_ques.get('validations').value;" ngProjectAs="mat-error">
<mat-error align="end" *ngIf="parent_ques.get('answer_value').hasError(validation.name.toLowerCase())">{{validation.message}}</mat-error>
</ng-container>
</div>
<mat-form-field style="width: 100%" *ngIf="parent_ques.get('type').value == '3'">
<mat-label>{{parent_ques.get('question').value}}</mat-label>
<mat-select formControlName="answer_value" (selectionChange)="onChangeProperty($event,parent_ques,'','',p_i)">
<mat-option *ngFor="let val of parent_ques.get('answers').value" [value]="val.hasOwnProperty('answer_id') ? val.answer_id : val.answer">{{val.answer}}</mat-option>
</mat-select>
<!-- <mat-error align="end" style="font-style: italic;margin-right: 5px;">Field is Required</mat-error> -->
<ng-container *ngFor="let validation of parent_ques.get('validations').value;" ngProjectAs="mat-error">
<mat-error align="end" *ngIf="parent_ques.get('answer_value').hasError(validation.name.toLowerCase())">{{validation.message}}</mat-error>
</ng-container>
</mat-form-field>
<div class="radio-gap" formArrayName="answer_value" *ngIf="parent_ques.get('type').value == '5'">
<mat-label>{{parent_ques.get('question').value}}</mat-label>
<mat-checkbox class="radio-btn-gap" *ngFor="let val of parent_ques.get('answers').value" [value]="val.hasOwnProperty('answer_id') ? val.answer_id : val.answer" (change)="onChange_checkbox($event,parent_ques)">{{val.answer}}</mat-checkbox><br />
<ng-container *ngFor="let validation of parent_ques.get('validations').value;" ngProjectAs="mat-error">
<mat-error align="end" *ngIf="parent_ques.get('answer_value').hasError(validation.name.toLowerCase())">{{validation.message}}</mat-error>
</ng-container>
</div>
<mat-form-field style="width: 100%" *ngIf="parent_ques.get('type').value == '4'">
<mat-label>{{parent_ques.get('question').value}}</mat-label>
<mat-select multiple formControlName="answer_value" (selectionChange)="onChangeProperty($event,parent_ques,'','',p_i)">
<mat-option *ngFor="let val of parent_ques.get('answers').value" [value]="val.hasOwnProperty('answer_id') ? val.answer_id : val.answer">{{val.answer}}</mat-option>
</mat-select>
<!-- <mat-error align="end" style="font-style: italic;margin-right: 5px;">Field is Required</mat-error> -->
<ng-container *ngFor="let validation of parent_ques.get('validations').value;" ngProjectAs="mat-error">
<mat-error align="end" *ngIf="parent_ques.get('answer_value').hasError(validation.name.toLowerCase())">{{validation.message}}</mat-error>
</ng-container>
</mat-form-field>
<div *ngIf="parent_ques.get('type').value == '6'">
<ion-grid >
<ion-row>
<ion-col col-6 no-padding align-self: center text-center >
<div >
<img *ngIf="parent_ques.get('answer_value').value != ''" [src]="parent_ques.get('answer_value').value" imageViewer class="doc-image-bucket"><br/>
<h5 >{{parent_ques.get('question').value}}</h5>
<!-- <input *ngIf="image.Name =='' && image.option != 'dummy'" width="20px" ion-input type="text" placeholder="Document Name" (blur)="changeName($event.target.value,i,image.image)"> -->
<!-- <button *ngIf="image.option != 'dummy'" ion-button clear color="optblue" (click)="removeImg(i)"><ion-icon style="font-size:22px" name="md-trash"></ion-icon></button> -->
</div>
<ion-row style="justify-content: center">
<ion-col col-8>
<ion-button [disabled]="sales_pd_type == '2'" (click)="captureImg(p_i,parent_ques)">
<ion-icon name="camera" style="font-size: 18px; color: #fff;"></ion-icon>
</ion-button>
</ion-col>
<!-- IMAGE STATUS ICON FOR INPROGRESS, COMPLETED AND FAILED -->
<ion-col col-4 *ngIf="parent_ques.get('is_image_status').value == true">
<ion-spinner name="crescent" style="width: 20px;
height: 20px;" (click)="cancelLoader(parent_ques)"
*ngIf="parent_ques.get('is_loader').value == true"></ion-spinner>
<ion-icon style="color: #008828;float: right;
margin-right: 30%;" *ngIf="parent_ques.get('is_saved').value == true" name="checkmark-circle-outline"></ion-icon>
<span style="margin:0px;" *ngIf="(parent_ques.get('is_saved').value == false &&
parent_ques.get('is_loader').value == false) && (parent_ques.value.hasOwnProperty('is_saved') &&
parent_ques.value.hasOwnProperty('is_loader'))" (click)="imageReupload(parent_ques)">
<ion-row style="margin-top: -17px;padding:0px;">
<ion-button >
<ion-icon name="refresh" style="font-size: 18px; color: #fff;"></ion-icon>
</ion-button>
</ion-row>
<ion-row style="margin-top: -20px;padding:0px;"><p style="font-size: 10px">Click to ReUpload</p></ion-row>
</span>
</ion-col>
</ion-row>
<!-- <ng-container ngProjectAs="mat-hint">
<mat-error >Please capture the image</mat-error>
</ng-container> -->
</ion-col>
<hr/>
</ion-row>
</ion-grid>
<ng-container *ngFor="let validation of parent_ques.get('validations').value;" ngProjectAs="mat-error">
<mat-error align="end" *ngIf="parent_ques.get('answer_value').hasError(validation.name.toLowerCase())">{{validation.message}}</mat-error>
</ng-container>
<!-- <ng-container ngProjectAs="mat-hint">
<mat-error align="end">Please capture the image</mat-error>
</ng-container> -->
</div>
<mat-form-field style="width: 100%" *ngIf="parent_ques.get('type').value == '7'">
<mat-label>{{parent_ques.get('question').value}}</mat-label>
<textarea matInput type="text" rows="3" formControlName="answer_value" placeholder="Enter the Text"
autocomplete="off" ></textarea>
<!-- <mat-error align="end" style="font-style: italic;margin-right: 5px;">Field is Required</mat-error> -->
<ng-container *ngFor="let validation of parent_ques.get('validations').value;" ngProjectAs="mat-error">
<mat-error align="end" *ngIf="parent_ques.get('answer_value').hasError(validation.name.toLowerCase())">{{validation.message}}</mat-error>
</ng-container>
</mat-form-field>
<mat-form-field style="width: 100%" *ngIf="parent_ques.get('type').value == '8'">
<mat-label>{{parent_ques.get('question').value}}</mat-label>
<mat-select formControlName="answer_value" (selectionChange)="onChangeProperty($event,parent_ques,'','',p_i)" [multiple] = "parent_ques.value.hasOwnProperty('is_multiple') && parent_ques.get('is_multiple').value == '1'">
<mat-option>
<!-- <ngx-mat-select-search formControlName="select_search"
[placeholderLabel]="'Search'"
[noEntriesFoundLabel]="'No Matching Result'" (keyup)="searchFun(parent_ques,p_i)">
<ion-icon name="md-close" ngxMatSelectSearchClear></ion-icon>
</ngx-mat-select-search> -->
</mat-option>
<mat-option *ngIf="parent_ques.get('is_multiple').value != '1'">--</mat-option>
<mat-option *ngFor="let val of fileredSearchValue.length > 0 ? fileredSearchValue[p_i] : parent_ques.get('answers').value" [value]="val.hasOwnProperty('answer_id') ? val.answer_id : val.answer">{{val.answer}}</mat-option>
</mat-select>
<!-- <mat-error align="end" style="font-style: italic;margin-right: 5px;">Field is Required</mat-error> -->
<ng-container *ngFor="let validation of parent_ques.get('validations').value;" ngProjectAs="mat-error">
<mat-error align="end" *ngIf="parent_ques.get('answer_value').hasError(validation.name.toLowerCase())">{{validation.message}}</mat-error>
</ng-container>
</mat-form-field>
</div>
<div class="radio-gap" *ngIf="parent_ques.get('is_repeatable').value == '1' && parent_ques.controls['questions_group']">
<!-- <mat-card> -->
<!-- <mat-card-header>
<mat-card-title>
{{parent_ques.get('group_title').value}}
</mat-card-title>
</mat-card-header> -->
<div formArrayName="questions_group" *ngIf="parent_ques.get('group_type').value != '6'">
<span
*ngFor="let group_ques of parent_ques.controls.questions_group['controls'];let g_i=index;let g_l=last"
[formGroupName]="g_i">
<mat-accordion *ngIf="parent_ques.get('group_type').value != '6'" #accordion="matAccordion">
<mat-expansion-panel [expanded]="step === g_i" #mapanel="matExpansionPanel">
<mat-expansion-panel-header>
<mat-panel-title>
{{parent_ques.get('group_title').value}} {{g_i+1}}
</mat-panel-title>
<!-- <mat-panel-description>
Type your name and age
</mat-panel-description> -->
</mat-expansion-panel-header>
<div formArrayName="questions" *ngIf="group_ques.controls['questions']">
<div
*ngFor="let single_ques of group_ques.controls.questions['controls'];let s_i=index;let s_l=last"
[formGroupName]="s_i">
<mat-form-field style="width: 100%" *ngIf="single_ques.get('type').value == '1'" [ngStyle]="{'margin-bottom':single_ques.value.hasOwnProperty('field_type') ? single_ques.get('field_type').value == 'numtoword' ? '5%' : '0' : '' }">
<mat-label>{{single_ques.get('question').value}}</mat-label>
<input matInput [type]="single_ques.value.hasOwnProperty('field_type') ? single_ques.get('field_type').value == 'num' || single_ques.get('field_type').value == 'numtoword' ? 'number' : single_ques.get('field_type').value == 'string' ? 'text' : single_ques.get('field_type').value: ''" formControlName="answer_value"
[placeholder]="single_ques.value.hasOwnProperty('place_holder') ? single_ques.get('place_holder').value : ''"
autocomplete="off" (change)="onChangeProperty($event,single_ques,group_ques,2,s_i)">
<!-- <mat-hint *ngIf="single_ques.get('answer_value').value != '' && single_ques.value.hasOwnProperty('field_type') && single_ques.get('field_type').value == 'numtoword'" align="end" style="font-size: 10px;">{{"&#8377;"}}{{single_ques.get('answer_value').value | numToWords}}</mat-hint> -->
<!-- <mat-error align="end" style="font-style: italic;margin-right: 5px;">Field is Required</mat-error> -->
<ng-container *ngFor="let validation of single_ques.get('validations').value;" ngProjectAs="mat-error">
<mat-error align="end" *ngIf="single_ques.get('answer_value').hasError(validation.name.toLowerCase())">{{validation.message}}</mat-error>
</ng-container>
</mat-form-field>
<div class="radio-gap" *ngIf="single_ques.get('type').value == '2'">
<mat-label>{{single_ques.get('question').value}}</mat-label><br/>
<mat-radio-group aria-label="Select an option" formControlName="answer_value" (change)="onChangeProperty($event,single_ques,group_ques,2,s_i)">
<mat-radio-button class="radio-btn-gap" *ngFor="let val of single_ques.get('answers').value" [value]="val.hasOwnProperty('answer_id') ? val.answer_id : val.answer">{{val.answer}}</mat-radio-button><br />
</mat-radio-group>
<ng-container *ngFor="let validation of single_ques.get('validations').value;" ngProjectAs="mat-error">
<mat-error align="end" *ngIf="single_ques.get('answer_value').hasError(validation.name.toLowerCase())">{{validation.message}}</mat-error>
</ng-container>
</div>
<mat-form-field style="width: 100%" *ngIf="single_ques.get('type').value == '3'">
<mat-label>{{single_ques.get('question').value}}</mat-label>
<mat-select formControlName="answer_value" (selectionChange)="onChangeProperty($event,single_ques,group_ques,2,s_i)">
<mat-option *ngFor="let val of single_ques.get('answers').value" [value]="val.hasOwnProperty('answer_id') ? val.answer_id : val.answer">{{val.answer}}</mat-option>
</mat-select>
<!-- <mat-error align="end" style="font-style: italic;margin-right: 5px;">Field is Required</mat-error> -->
<ng-container *ngFor="let validation of single_ques.get('validations').value;" ngProjectAs="mat-error">
<mat-error align="end" *ngIf="single_ques.get('answer_value').hasError(validation.name.toLowerCase())">{{validation.message}}</mat-error>
</ng-container>
</mat-form-field>
<div class="radio-gap" formArrayName="answer_value" *ngIf="single_ques.get('type').value == '5'">
<mat-label>{{single_ques.get('question').value}}</mat-label>
<mat-checkbox class="radio-btn-gap" *ngFor="let val of single_ques.get('answers').value" [value]="val.hasOwnProperty('answer_id') ? val.answer_id : val.answer" (change)="onChange_checkbox($event,single_ques)">{{val.answer}}</mat-checkbox><br />
<ng-container *ngFor="let validation of single_ques.get('validations').value;" ngProjectAs="mat-error">
<mat-error align="end" *ngIf="single_ques.get('answer_value').hasError(validation.name.toLowerCase())">{{validation.message}}</mat-error>
</ng-container>
</div>
<mat-form-field style="width: 100%" *ngIf="single_ques.get('type').value == '4'">
<mat-label>{{single_ques.get('question').value}}</mat-label>
<mat-select multiple formControlName="answer_value">
<mat-option *ngFor="let val of single_ques.get('answers').value" [value]="val.hasOwnProperty('answer_id') ? val.answer_id : val.answer">{{val.answer}}</mat-option>
</mat-select>
<!-- <mat-error align="end" style="font-style: italic;margin-right: 5px;">Field is Required</mat-error> -->
<ng-container *ngFor="let validation of single_ques.get('validations').value;" ngProjectAs="mat-error">
<mat-error align="end" *ngIf="single_ques.get('answer_value').hasError(validation.name.toLowerCase())">{{validation.message}}</mat-error>
</ng-container>
</mat-form-field>
<mat-form-field style="width: 100%" *ngIf="single_ques.get('type').value == '7'">
<mat-label>{{single_ques.get('question').value}}</mat-label>
<textarea matInput type="text" rows="3" formControlName="answer_value" placeholder="Enter the Text"
autocomplete="off" ></textarea>
<!-- <mat-error align="end" style="font-style: italic;margin-right: 5px;">Field is Required</mat-error> -->
<ng-container *ngFor="let validation of single_ques.get('validations').value;" ngProjectAs="mat-error">
<mat-error align="end" *ngIf="single_ques.get('answer_value').hasError(validation.name.toLowerCase())">{{validation.message}}</mat-error>
</ng-container>
</mat-form-field>
<mat-form-field style="width: 100%" *ngIf="single_ques.get('type').value == '8'">
<mat-label>{{parent_ques.get('question').value}}</mat-label>
<mat-select formControlName="answer_value" (selectionChange)="onChangeProperty($event,parent_ques,p_i)" [multiple] = "parent_ques.value.hasOwnProperty('is_multiple') && parent_ques.get('is_multiple').value == '1'">
<mat-option>
<!-- <ngx-mat-select-search formControlName="select_search"
[placeholderLabel]="'Search'"
[noEntriesFoundLabel]="'No Matching Result'" (keyup)="searchFun(parent_ques,p_i)">
<ion-icon name="md-close" ngxMatSelectSearchClear></ion-icon>
</ngx-mat-select-search> -->
</mat-option>
<mat-option *ngIf="parent_ques.get('is_multiple').value != '1'">--</mat-option>
<mat-option *ngFor="let val of fileredSearchValue.length > 0 ? fileredSearchValue[p_i] : parent_ques.get('answers').value" [value]="val.hasOwnProperty('answer_id') ? val.answer_id : val.answer">{{val.answer}}</mat-option>
</mat-select>
<!-- <mat-error align="end" style="font-style: italic;margin-right: 5px;">Field is Required</mat-error> -->
<ng-container *ngFor="let validation of single_ques.get('validations').value;" ngProjectAs="mat-error">
<mat-error align="end" *ngIf="single_ques.get('answer_value').hasError(validation.name.toLowerCase())">{{validation.message}}</mat-error>
</ng-container>
</mat-form-field>
<div *ngIf="single_ques.controls['subfield_key']">
<!-- <div *ngIf="parent_ques.controls[parent_ques.get('subfield_key').value]"> -->
<mat-form-field style="width: 100%" >
<mat-label>{{single_ques.get('subfield_caption').value}}</mat-label>
<input matInput type="text" formControlName="subfield_value" placeholder="Enter the Text"
autocomplete="off">
</mat-form-field>
<!-- </div> -->
</div>
</div>
</div>
<ion-row>
<ion-col class="ion-text-end">
<ion-button *ngIf="g_i != 0" (click)="removeData(g_i,parent_ques)">
<ion-icon name="trash" style="font-size: 18px; color: #fff;"></ion-icon>
</ion-button>
<ion-button *ngIf="g_l" (click)="addData(g_i,parent_ques,group_ques.get('questions').value,$event)">
<ion-icon name="add-circle-outline" style="font-size: 18px; color: #fff;"></ion-icon>
</ion-button>
</ion-col>
</ion-row>
<!-- <ion-buttons end>
<ion-col col-3 offset-3>
<button ion-button clear color="optblue" *ngIf="g_i != 0" (click)="removeData(g_i,parent_ques)">
<ion-icon style="font-size: 22px" name="md-trash"></ion-icon>
</button>
</ion-col>
<ion-col col-2 offset-1>
<button ion-button clear color="optblue" *ngIf="g_l"
(click)="addData(g_i,parent_ques,group_ques.get('questions').value,$event)">
<ion-icon style="font-size: 24px" name="add-circle"></ion-icon>
</button>
</ion-col>
</ion-buttons> -->
</mat-expansion-panel>
</mat-accordion>
</span>
</div>
<div formArrayName="questions_group" *ngIf="parent_ques.get('group_type').value == '6'">
<hr class="hr">
<mat-card-header>
<mat-card-title>
<h5> {{parent_ques.get('group_title').value}}</h5>
</mat-card-title>
</mat-card-header>
<ion-grid >
<ion-row>
<span
*ngFor="let group_ques of parent_ques.controls.questions_group['controls'];let g_i=index;let g_l=last"
[formGroupName]="g_i">
<!-- </mat-card> -->
<span formArrayName="questions" *ngIf="group_ques.controls['questions'] && parent_ques.get('group_type').value == '6'" >
<!-- <div > -->
<!-- <div *ngIf="single_ques.get('type').value == '10'"> -->
<ion-col align-self: center col-6 no-padding text-center *ngFor="let single_ques of group_ques.controls.questions['controls'];let s_i=index;let s_l=last"
[formGroupName]="s_i">
<div style="width: 100%;justify-content: center;text-align: center;align-content: center;margin:2%;" *ngIf="single_ques.get('answer_value').value != ''">
<ion-row style="width: 100%">
<img [src]="single_ques.get('answer_value').value" imageViewer class="doc-image-bucket" ><br/>
</ion-row>
<ion-row style="width: 130px;margin-bottom: 5px;text-align: left">
<ion-col col-8>
<span style="font-size: 12px;padding: 0px;margin: 0px;">{{single_ques.get('question').value}} {{g_i+1}}</span>
</ion-col>
<!-- IMAGE STATUS ICON FOR INPROGRESS, COMPLETED AND FAILED -->
<ion-col col-4 *ngIf="single_ques.get('is_image_status').value == true">
<ion-spinner name="crescent" style="width: 20px;
height: 20px;" (click)="cancelLoader(single_ques)"
*ngIf="single_ques.get('is_loader').value == true"></ion-spinner>
<ion-icon style="color: #008828;float: right;
margin-right: 30%;" *ngIf="single_ques.get('is_saved').value == true" name="checkmark-circle-outline"></ion-icon>
<span style="margin:0px;" *ngIf="(single_ques.get('is_saved').value == false &&
single_ques.get('is_loader').value == false) && (single_ques.value.hasOwnProperty('is_saved') &&
single_ques.value.hasOwnProperty('is_loader'))" (click)="imageReupload(single_ques)">
<ion-row style="margin-top: -17px;padding:0px;">
<ion-button >
<ion-icon name="refresh" style="font-size: 18px; color: #fff;"></ion-icon>
</ion-button>
</ion-row>
<ion-row style="margin-top: -20px;padding:0px;"><p style="font-size: 10px">Click to ReUpload</p></ion-row>
</span>
</ion-col>
<!-- <input *ngIf="image.Name =='' && image.option != 'dummy'" width="20px" ion-input type="text" placeholder="Document Name" (blur)="changeName($event.target.value,i,image.image)"> -->
<!-- <button ion-button clear color="optblue" (click)="removeData(g_i,parent_ques)"><ion-icon style="font-size:22px" name="md-trash"></ion-icon></button> -->
</ion-row>
</div>
<!-- <div style="justify-content: center">
<button ion-button clear color="optblue" (click)="captureImg()"><ion-icon style="font-size: 30px" name="md-camera"></ion-icon></button>
</div> -->
<!-- {{single_ques.value | json}} -->
<div class="add-more-image" *ngIf="g_l">
<ion-button [disabled]="sales_pd_type == '2'" (click)="addData(g_i,parent_ques,group_ques.get('questions').value,$event,'camera',single_ques)">
<ion-icon name="camera" style="font-size: 18px; color: #fff;"></ion-icon>+
</ion-button>
</div>
</ion-col>
<!-- </div> -->
<!-- </div> -->
</span>
<div *ngIf="g_l" style="justify-content: flex-end">
</div>
</span>
</ion-row>
<!-- <ng-container *ngFor="let validation of single_ques.get('validations').value;" ngProjectAs="mat-error">
<mat-error align="end" *ngIf="single_ques.get('answer_value').hasError(validation.name.toLowerCase())">{{validation.message}}</mat-error>
</ng-container> -->
</ion-grid>
<hr class="hr">
</div>
</div>
<div *ngIf="parent_ques.controls['subfield_key']">
<!-- <div *ngIf="parent_ques.controls[parent_ques.get('subfield_key').value]"> -->
<mat-form-field style="width: 100%" >
<mat-label>{{parent_ques.get('subfield_caption').value}}</mat-label>
<input matInput type="text" formControlName="subfield_value" placeholder="Enter the Text"
autocomplete="off">
</mat-form-field>
<!-- </div> -->
</div>
</div>
</div>
</div>
</div>
<!-- <ion-col *ngIf="!spinner_access">
<button class="btn-no-pad" medium ion-button round outline color="optblue" (click)="onSubmit(0)">Save as Draft</button>
</ion-col> -->
<ion-row class="mt" *ngIf="!spinner_access">
<ion-col class="ion-text-end">
<ion-button (click)="onSubmit(1)">
<ion-icon name="checkmark-circle"></ion-icon>
{{submit_btn ? 'Complete' : 'Save'}}
</ion-button>
</ion-col>
</ion-row>
<ion-spinner name="dots" color="optblue" style="font-size: 24px;width:50px;height: 50px;" *ngIf="spinner_access"></ion-spinner>
</form>
</div>

View File

@ -0,0 +1,65 @@
.header-md{
background-color: #ff0303 !important;
color: #fff !important;
}
::ng-deep .mdc-text-field--filled:not(.mdc-text-field--disabled) {
background-color: unset !important;
}
mat-radio-button,mat-checkbox{
margin-top: 13px;
}
.radio-gap{
margin-top: 10px;
margin-bottom: 10px;
}
.radio-btn-gap{
margin:10px;
}
.doc-image-bucket{
padding:0 5px 0 0 !important;
width: 120px;
height: 80px !important;
color:black;
//width:130px;
//border:3px solid black;
//border-radius: 20px;
//background-color: gray;
}
.add-more-image{
width: 60%;
padding:0 5px 0 0 !important;
width: 120px;
height: 80px !important;
// border: 2px solid gainsboro;
// border-style: dashed;
// border-radius: 10px;
}
.p-0{
padding: 0px !important;
}
.hr, hr{
font-size: 25px;
background: rgb(105 89 89 / 12%);
}
h5{
font-size: 14px;
color: black;
}
// .btn-no-pad{
// padding: 8px 8px 8px 5px;
// }
.save-btn{
margin-top: 3%;
}
// .mat-input-invalid .mat-input-placeholder {
// color: red;
// }
// .mat-input-invalid .mat-input-ripple {
// background-color: red;
// }
.mat-expansion-panel{
margin-bottom: 1rem !important;
}

View File

@ -0,0 +1,24 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { QuesTemplateComponent } from './ques-template.component';
describe('QuesTemplateComponent', () => {
let component: QuesTemplateComponent;
let fixture: ComponentFixture<QuesTemplateComponent>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ QuesTemplateComponent ],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(QuesTemplateComponent);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,48 @@
<ion-header>
<ion-toolbar color="optblue">
<ion-title>{{ title }}</ion-title>
<ion-buttons slot="end">
<ion-button (click)="dismiss()" strong style="width:115%;text-align:center;">
<ion-icon name="close" style="color:white;font-size:170% !important"></ion-icon>
</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content *ngIf="pdf">
<div id="outerContainer">
<div class="pdf-container">
<pdf-viewer
[src]="pdf"
[rotation]="0"
[original-size]="false"
[show-all]="true"
[fit-to-page]="false"
[zoom]="1"
[zoom-scale]="'page-width'"
[stick-to-page]="false"
[render-text]="true"
[external-link-target]="'blank'"
[autoresize]="true"
[show-borders]="false"
style="width: 100%; height: 600px;"
></pdf-viewer>
</div>
</div>
<!-- <div style="text-align:right;position: absolute;bottom:15px;right: 6px;display:block;justify-content:space-between; flex-direction:row;">
<ion-button (click)="zoomIn()" style="color:#fff">
<ion-icon style="font-size:30px" name="add"></ion-icon>
</ion-button>
<ion-button (click)="zoomOut()" style="color:#fff">
<ion-icon style="font-size:30px" name="remove"></ion-icon>
</ion-button>
</div> -->
</ion-content>
<ion-content padding *ngIf="error_msg">
<h6 style="text-align:center;color: red">{{ error_msg }}</h6>
</ion-content>

View File

@ -0,0 +1,4 @@
.header-md{
background-color: #ff0303 !important;
color: #fff !important;
}

View File

@ -0,0 +1,24 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { PdfViewerComponent } from './pdf-viewer.component';
describe('PdfViewerComponent', () => {
let component: PdfViewerComponent;
let fixture: ComponentFixture<PdfViewerComponent>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ PdfViewerComponent ],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(PdfViewerComponent);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,104 @@
import { Component, Input, OnInit } from '@angular/core';
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
import { ActivatedRoute } from '@angular/router';
import { ModalController, NavController, NavParams } from '@ionic/angular';
@Component({
selector: 'app-pdf-viewer',
templateUrl: './pdf-viewer.component.html',
styleUrls: ['./pdf-viewer.component.scss'],
})
export class PdfViewerComponent implements OnInit {
title: string;
zoom: number = 1;
page: number = 1;
pdf_sanatized: any;
currentZoom: any;
isLoaded: boolean = false;
doubleTap:boolean=false
error_msg: any;
pdf: any;
pdfSource: SafeUrl = '';
totalPages: any;
constructor(private navParams: NavParams,public navCtrl: NavController, private route: ActivatedRoute,public sanitizer: DomSanitizer,private modalController: ModalController) {
// this.route.queryParams.subscribe((params) => {
// console.log(params,params['reportLink'])
// if (params['reportLink']) {
// this.pdf = params['reportLink'];
// this.pdfSource = this.sanitizer.bypassSecurityTrustResourceUrl(this.pdf);
// console.log(this.pdf,this.pdfSource)
// } else if (params['error_msg']) {
// this.error_msg = params['error_msg'];
// }
// });
if(this.navParams.get('report_link')){
this.pdf =navParams.get('report_link') ;
this.pdfSource=this.sanitizer.bypassSecurityTrustResourceUrl(this.pdf);
}
else if(this.navParams.get('error_msg')) {
this.error_msg = this.navParams.get('error_msg');
}
this.title = "Report";
}
ngOnInit() {}
zoomIn() {
this.zoom += 0.20;
}
zoomOut() {
if(this.zoom > 1)
this.zoom -= 0.20;
}
nextPage() {
this.page += 1;
}
previousPage() {
this.page -= 1;
}
download() {
window.open(this.pdf, '_system', 'location=no');
}
pinchin(event: any): void {
this.zoom -= 0.04;
}
pinchout(event: any): void {
this.zoom += 0.04;
}
tapped(event:any):void{
if(event.tapCount == 2){
if(!this.doubleTap){
this.zoom += 0.20;
this.doubleTap=!this.doubleTap
}
else{
this.zoom -= 0.20;
this.doubleTap=!this.doubleTap
}
}
}
afterLoadComplete(pdfData: any) {
this.totalPages = pdfData.numPages;
this.isLoaded = true;
}
dismiss(){
this.modalController.dismiss()
}
}

View File

@ -1,27 +1,37 @@
<ion-header>
<ion-toolbar color="optblue">
<ion-buttons slot="start">
<ion-menu-button></ion-menu-button>
<ion-back-button></ion-back-button>
</ion-buttons>
<ion-title>Section List</ion-title>
<ion-buttons slot="end">
<a [href]="link" target="{{link}}">
<ion-icon style="color: white; font-size: 40px; padding-left: 100px;" name="link"></ion-icon>
</a>
</ion-buttons>
<ion-buttons slot="end" *ngIf="is_sync_btn">
<ion-title class="ion-justify-content-center p-0">Section List</ion-title>
<!-- <ion-buttons slot="end" *ngIf="is_sync_btn">
<ion-button outline round (click)="syncPDWithSections()">
<ion-icon name="sync"></ion-icon>&nbsp;&nbsp;Sync
</ion-button>
</ion-buttons>
</ion-buttons> -->
</ion-toolbar>
</ion-header>
<ion-content padding>
<ion-fab slot="fixed" vertical="top" horizontal="end" [edge]="true">
<ion-fab-button size="small">
<ion-icon name="chevron-down-circle"></ion-icon>
</ion-fab-button>
<ion-fab-list side="bottom">
<ion-fab-button *ngIf="customer_link != '' && sales_pd_type == '2'" (click)="copyToClipBoard(customer_link_with_text, 'Customer Link is copied')">
<ion-icon name="copy"></ion-icon>
</ion-fab-button>
<ion-fab-button *ngIf="customer_link != '' && sales_pd_type == '2'" (click)="shareViaSMS()">
<ion-icon name="mail"></ion-icon>
</ion-fab-button>
<ion-fab-button (click)="goToUrl('')">
<ion-icon name="link"></ion-icon>
</ion-fab-button>
<ion-fab-button *ngIf="is_sync_btn" (click)="syncPDWithSections()">
<ion-icon name="sync"></ion-icon>
</ion-fab-button>
</ion-fab-list>
</ion-fab>
<div class="completed_note" *ngIf="is_sync_btn && pd_completed.is_synced == false && pd_completed.is_completed &&
pd_completed.pd_complete_request_items != null">
<p>
@ -46,7 +56,7 @@
</ion-col>
</ion-row>
</mat-card>
<!--
<ion-fab vertical="bottom" horizontal="end" #fab color="optblue" *ngIf="customer_link != '' && sales_pd_type == '2'">
<ion-fab-button color="mickyColor">
<ion-icon name="link"></ion-icon>
@ -62,6 +72,6 @@
<ion-label>Send Link via SMS</ion-label>
</ion-fab-button>
</ion-fab-list>
</ion-fab>
</ion-fab> -->
</ion-content>

View File

@ -1,6 +1,15 @@
ion-content {
contain: size style;
.header-md{
background-color: #ff0303 !important;
color: #fff !important;
}
.sizeE{
font-size: medium;
width: 30px;
height: 20px;
}
.p-0{
padding: 0px !important;
}
.card-class{
h6{
@ -98,4 +107,9 @@
// }
ion-content {
--padding-start: 16px; // Adjust as needed
--padding-end: 16px; // Adjust as needed
--padding-top: 16px; // Adjust as needed
--padding-bottom: 16px; // Adjust as needed
}

View File

@ -1,5 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { NavController, NavParams } from '@ionic/angular';
import { MenuController, NavController, NavParams } from '@ionic/angular';
import { SalesPdService } from '../providers/sales-pd/sales-pd.service';
import { ToastService } from 'src/providers/common-provider/toast.service';
import { OfflineManagerService } from '../providers/offline-manager/offline-manager.service';
@ -27,12 +27,13 @@ export class SectionListComponent implements OnInit {
config_expression: any;
link: any;
private apiUrl = environment
constructor(public navCtrl: NavController, public route: ActivatedRoute,private SalesPDService:SalesPdService,private toastProvider:ToastService,
constructor(public Menu:MenuController,public navCtrl: NavController, public route: ActivatedRoute,private SalesPDService:SalesPdService,private toastProvider:ToastService,
private offlineManager:OfflineManagerService,private router: Router) {
this.route.queryParams.subscribe(params => {
console.log(params,params.hasOwnProperty('product_id'),params['product_id'])
if(params.hasOwnProperty('product_id')){
this.product_id = params['product_id']
this.getTemplate()
// this.link = this.navParams.get('link')
// console.log(this.link)
}
@ -40,11 +41,13 @@ export class SectionListComponent implements OnInit {
this.sales_pd_type = localStorage.getItem('sales_pd_type')
this.getTemplate()
//alert(this.link);
}
ngOnInit() {}
ngOnInit() {
this.getSectionStats()
}
ionViewDidLoad() {
console.log('ionViewDidLoad SectionListPage');
@ -52,7 +55,14 @@ export class SectionListComponent implements OnInit {
}
ionViewWillLeave(){
this.Menu.enable(true);
}
ionViewDidEnter(){
this.Menu.enable(false);
setTimeout(()=>{
this.getSectionStats()
},50)
@ -324,13 +334,15 @@ export class SectionListComponent implements OnInit {
}
goto(section_id: any) {
console.log(section_id)
if (this.sales_pd_id == null && section_id != '1') {
this.toastProvider.lenderappmessage("Please Fill General Section First !!");
return;
}
setTimeout(() => {
this.router.navigate(['section9', { section_id: section_id }]);
// this.navCtrl.navigateForward(`/section9/${section_id}`);
this.navCtrl.navigateForward('/section9', { queryParams:{ section_id: section_id }});
}, 10);
}
@ -384,4 +396,12 @@ export class SectionListComponent implements OnInit {
}
}
goToUrl(url:any){
window.open(url, '_blank');
}
goToBack(){
this.router.navigate(['/sales-pd-list']);
}
}

View File

@ -0,0 +1,10 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class TabsRoutingModule { }

View File

@ -0,0 +1,3 @@
<p>
tabs works!
</p>

View File

View File

@ -0,0 +1,24 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { TabsComponent } from './tabs.component';
describe('TabsComponent', () => {
let component: TabsComponent;
let fixture: ComponentFixture<TabsComponent>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ TabsComponent ],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(TabsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,14 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-tabs',
templateUrl: './tabs.component.html',
styleUrls: ['./tabs.component.scss'],
})
export class TabsComponent implements OnInit {
constructor() { }
ngOnInit() {}
}

View File

@ -0,0 +1,14 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { TabsRoutingModule } from './tabs-routing.module';
@NgModule({
declarations: [],
imports: [
CommonModule,
TabsRoutingModule
]
})
export class TabsModule { }

View File

@ -26,6 +26,12 @@
@import "@ionic/angular/css/text-transformation.css";
@import "@ionic/angular/css/flex-utils.css";
.example-content {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
// ion-content {
@ -34,3 +40,7 @@
// --padding-top: 16px; // Adjust as needed
// --padding-bottom: 16px; // Adjust as needed
// }

View File

@ -70,7 +70,7 @@ export class ToastService {
{
text: 'Ok',
handler: () => {
return false;
// Returning true or nothing allows the alert to close
}
}
]

View File

@ -12,6 +12,7 @@ export enum ConnectionStatus {
@Injectable({
providedIn: 'root'
})
export class NetworkDetectionService {
// private networkStatus: BehaviorSubject<ConnectionStatus> = new BehaviorSubject(ConnectionStatus.offline);
private networkStatus: BehaviorSubject<ConnectionStatus> = new BehaviorSubject<ConnectionStatus>(ConnectionStatus.offline);
@ -56,4 +57,5 @@ export class NetworkDetectionService {
public getCurrentNetworkStatus(): ConnectionStatus {
return this.networkStatus.getValue();
}
}

View File

@ -15,6 +15,7 @@ import { MatListModule } from '@angular/material/list';
import { MatDatepickerModule } from '@angular/material/datepicker'
import { MatSelectModule } from '@angular/material/select'
import { MatRadioModule } from '@angular/material/radio'
import { MatExpansionModule } from '@angular/material/expansion'
@ -34,7 +35,7 @@ import { MatRadioModule } from '@angular/material/radio'
MatDatepickerModule,
// MatDialogModule,
// MatDividerModule,
// MatExpansionModule,
MatExpansionModule,
MatFormFieldModule,
MatGridListModule,
MatIconModule,
@ -78,7 +79,7 @@ import { MatRadioModule } from '@angular/material/radio'
MatDatepickerModule,
// MatDialogModule,
// MatDividerModule,
// MatExpansionModule,
MatExpansionModule,
MatFormFieldModule,
MatGridListModule,
MatIconModule,