CINXE.COM
<!doctype html> <html prefix="ng: http://angularjs.org" id="ng-app" data-ng-app="ctsApp" lang="en-CA" class="standard"> <head> <meta charset="UTF-8"> <title data-ng-bind="lang == 'ar' ? '‫'+title : title">Home</title> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="viewport" content="width=device-width"> <style> :root { --ui-primary-colour: #bd2319; } </style> <link href='https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css' rel='stylesheet'/> <link href='css/style.min.css?v=4.92' type='text/css' rel='stylesheet'/> <script src="config/js/libs.min.js?v=4.92"></script> <script> var ctsApp = angular.module('ctsApp', ['ngRoute','ngAria','ngSanitize']).run(function($rootScope, $http, $location, $timeout, $route, $window, $filter) { //console.log('en-CA'); moment.locale('en-CA'); //$rootScope.cts = JSON.parse(``); $rootScope.cts = {"settings":{"defaultQueueExternalId":"mainqueue","returnToSite":{"BGOTA_fr":"http:\/\/www.canadainternational.gc.ca\/colombia-colombie\/index.aspx?lang=fra","GTMLA_en":"https:\/\/www.international.gc.ca\/country-pays\/guatemala\/guatemala_city.aspx?lang=eng","LNGLS_en":"https:\/\/international.gc.ca\/world-monde\/country-pays\/united_states-etats_unis\/los_angeles.aspx?lang=eng","BAIRS_en":"https:\/\/www.canadainternational.gc.ca\/argentina-argentine\/index.aspx?lang=eng","GANZU_fr":"https:\/\/www.canadainternational.gc.ca\/china-chine\/offices-bureaux\/guangzhou\/index.aspx?lang=fra","ALGER_fr":"http:\/\/www.canadainternational.gc.ca\/algeria-algerie\/index.aspx?lang=fra","CRMEN_en":"https:\/\/www.canadainternational.gc.ca\/mexico-mexique\/offices-bureaux\/consoff-burcons.aspx?lang=en","APLCO_fr":"https:\/\/www.canadainternational.gc.ca\/mexico-mexique\/offices-bureaux\/consoff-burcons.aspx?lang=fra","MXICO_fr":"https:\/\/www.canadainternational.gc.ca\/mexico-mexique\/index.aspx?lang=fra","DOHA_en":"https:\/\/www.canadainternational.gc.ca\/qatar\/index.aspx?lang=eng","BRLIN_fr":"https:\/\/www.international.gc.ca\/country-pays\/germany-allemagne\/berlin.aspx?lang=fra","BRU_fr":"https:\/\/www.canadainternational.gc.ca\/belgium-belgique\/offices-bureaux\/embassy-ambassade.aspx?lang=fra","JEDDA_fr":"http:\/\/www.canadainternational.gc.ca\/saudi_arabia-arabie_saoudite\/offices-bureaux\/consulate_jeddah-djeddah_consulat.aspx?lang=fra","BRSLA_fr":"https:\/\/international.gc.ca\/world-monde\/country-pays\/brazil-bresil\/index.aspx?lang=fra","OUAGA_en":"https:\/\/www.canadainternational.gc.ca\/burkinafaso\/index.aspx?lang=eng","SJCRA_fr":"https:\/\/www.canadainternational.gc.ca\/costa_rica\/contact-contactez.aspx?lang=fra","ABUJA_en":"https:\/\/www.canadainternational.gc.ca\/nigeria\/index.aspx?lang=eng","DELHI_fr":"https:\/\/international.gc.ca\/world-monde\/india-inde\/new_delhi.aspx?lang=fra","WSHDC_en":"https:\/\/international.gc.ca\/world-monde\/country-pays\/united_states-etats_unis\/washington.aspx?lang=eng","MANIL_fr":"http:\/\/www.canadainternational.gc.ca\/philippines\/consular_services_consulaires\/index.aspx?lang=fra","JKRTA_en":"https:\/\/www.international.gc.ca\/country-pays\/indonesia-indonesie\/jakarta.aspx?lang=eng","GQUIL_fr":"https:\/\/www.canadainternational.gc.ca\/ecuador-equateur\/contact-guayaquil-contactez.aspx?lang=fra","CRMEN_fr":"https:\/\/www.canadainternational.gc.ca\/mexico-mexique\/offices-bureaux\/consoff-burcons.aspx?lang=fr","BRLIN_en":"https:\/\/www.international.gc.ca\/country-pays\/germany-allemagne\/berlin.aspx?lang=eng","LDN_en":"https:\/\/www.canadainternational.gc.ca\/united_kingdom-royaume_uni\/index.aspx?lang=eng","LAGOS_fr":"https:\/\/www.canadainternational.gc.ca\/nigeria\/contact-lagos-contactez.aspx?lang=fra","BGOTA_en":"http:\/\/www.canadainternational.gc.ca\/colombia-colombie\/index.aspx?lang=eng","DOHA_fr":"https:\/\/www.canadainternational.gc.ca\/qatar\/index.aspx?lang=fra","BRSLA_en":"https:\/\/international.gc.ca\/world-monde\/country-pays\/brazil-bresil\/index.aspx?lang=eng","PVRTA_fr":"https:\/\/www.canadainternational.gc.ca\/mexico-mexique\/offices-bureaux\/consoff-burcons.aspx?lang=fra","PPLAT_fr":"https:\/\/www.international.gc.ca\/country-pays\/dominican_republic-republique_dominicaine\/puerto_plata.aspx?lang=fra","ABDBI_fr":"https:\/\/www.canadainternational.gc.ca\/uae-eau\/contact-contactez.aspx?lang=fra","BLZCT_en":"https:\/\/www.international.gc.ca\/country-pays\/belize\/belize_city.aspx?lang=eng","MNTRY_fr":"https:\/\/www.canadainternational.gc.ca\/mexico-mexique\/offices-bureaux\/consoff-burcons.aspx?lang=fra","GJARA_en":"https:\/\/www.canadainternational.gc.ca\/mexico-mexique\/offices-bureaux\/consoff-burcons.aspx?lang=en","RMLAH_en":"https:\/\/www.canadainternational.gc.ca\/west_bank_gaza-cisjordanie_bande_de_gaza\/index.aspx?lang=eng","MANIL_en":"http:\/\/www.canadainternational.gc.ca\/philippines\/consular_services_consulaires\/index.aspx?lang=eng","DELHI_en":"https:\/\/international.gc.ca\/world-monde\/india-inde\/new_delhi.aspx?lang=eng","MDRID_fr":"https:\/\/www.canadainternational.gc.ca\/spain-espagne\/offices-bureaux\/contact_embassy-contactez_ambassade.aspx?lang=fra","LAGOS_en":"https:\/\/www.canadainternational.gc.ca\/nigeria\/contact-lagos-contactez.aspx?lang=eng","LAPAZ_en":"https:\/\/www.international.gc.ca\/country-pays\/bolivia-bolivie\/index.aspx?lang=eng","LDN_fr":"https:\/\/www.canadainternational.gc.ca\/united_kingdom-royaume_uni\/index.aspx?lang=fra","PRET_fr":"https:\/\/www.canadainternational.gc.ca\/southafrica-afriquedusud\/contact-contactez.aspx?lang=fra","MNTRY_en":"https:\/\/www.canadainternational.gc.ca\/mexico-mexique\/offices-bureaux\/consoff-burcons.aspx?lang=en","TAPEI_en":"https:\/\/www.international.gc.ca\/country-pays\/taiwan\/taipei.aspx?lang=eng","DUBLN_fr":"https:\/\/international.gc.ca\/world-monde\/ireland-irlande\/dublin.aspx?lang=fra","PVRTA_en":"https:\/\/www.canadainternational.gc.ca\/mexico-mexique\/offices-bureaux\/consoff-burcons.aspx?lang=en","ISTBL_fr":"https:\/\/www.canadainternational.gc.ca\/turkey-turquie\/consular_services_consulaires\/service_points-points_de_service.aspx?lang=fra","CNGNY_en":"https:\/\/international.gc.ca\/world-monde\/country-pays\/united_states-etats_unis\/new_york.aspx?lang=eng","GJARA_fr":"https:\/\/www.canadainternational.gc.ca\/mexico-mexique\/offices-bureaux\/consoff-burcons.aspx?lang=fra","KNSHA_fr":"https:\/\/www.international.gc.ca\/country-pays\/democratic_republic_congo-republique_democratique_congo\/kinshasa.aspx?lang=fra","TAVIV_en":"http:\/\/www.canadainternational.gc.ca\/israel\/contact-contactez.aspx?lang=eng","MXICO_en":"https:\/\/www.canadainternational.gc.ca\/mexico-mexique\/index.aspx?lang=eng","SDMGO_en":"https:\/\/www.international.gc.ca\/country-pays\/dominican_republic-republique_dominicaine\/santo_domingo.aspx?lang=eng","ROME_fr":"https:\/\/www.canadainternational.gc.ca\/italy-italie\/index.aspx?lang=fra","BAIRS_fr":"https:\/\/www.canadainternational.gc.ca\/argentina-argentine\/index.aspx?lang=fra","DUBLN_en":"https:\/\/international.gc.ca\/world-monde\/ireland-irlande\/dublin.aspx?lang=eng","SFRAN_en":"https:\/\/international.gc.ca\/world-monde\/country-pays\/united_states-etats_unis\/san_francisco.aspx?lang=eng","BPEST_fr":"https:\/\/www.canadainternational.gc.ca\/hungary-hongrie\/index.aspx?lang=fra","GTMLA_fr":"https:\/\/www.international.gc.ca\/country-pays\/guatemala\/guatemala_city.aspx?lang=fra","MDRID_en":"https:\/\/www.canadainternational.gc.ca\/spain-espagne\/offices-bureaux\/contact_embassy-contactez_ambassade.aspx?lang=eng","LAPAZ_fr":"https:\/\/www.international.gc.ca\/country-pays\/bolivia-bolivie\/index.aspx?lang=fra","BRU_en":"https:\/\/www.canadainternational.gc.ca\/belgium-belgique\/offices-bureaux\/embassy-ambassade.aspx?lang=eng","ABDBI_en":"https:\/\/www.canadainternational.gc.ca\/uae-eau\/contact-contactez.aspx?lang=eng","WSAW_en":"https:\/\/www.international.gc.ca\/country-pays\/poland-pologne\/warsaw-varsovie.aspx?lang=eng","ISTBL_en":"https:\/\/www.canadainternational.gc.ca\/turkey-turquie\/consular_services_consulaires\/service_points-points_de_service.aspx?lang=eng","TAPEI_fr":"https:\/\/www.international.gc.ca\/country-pays\/taiwan\/taipei.aspx?lang=fra","AMMAN_en":"http:\/\/international.gc.ca\/world-monde\/jordan-jordanie\/index.aspx?lang=eng","TAVIV_fr":"http:\/\/www.canadainternational.gc.ca\/israel\/contact-contactez.aspx?lang=fra","ADDIS_en":"https:\/\/www.canadainternational.gc.ca\/ethiopia-ethiopie\/contact-contactez.aspx?lang=eng","CHADG_fr":"https:\/\/international.gc.ca\/world-monde\/india-inde\/chandigarh.aspx?lang=fra","DUBAI_en":"http:\/\/www.canadainternational.gc.ca\/uae-eau\/consulate_contact-contactez_consulat.aspx?lang=eng","ROME_en":"https:\/\/www.canadainternational.gc.ca\/italy-italie\/index.aspx?lang=eng","JKRTA_fr":"https:\/\/www.international.gc.ca\/country-pays\/indonesia-indonesie\/jakarta.aspx?lang=fra","SDMGO_fr":"https:\/\/www.international.gc.ca\/country-pays\/dominican_republic-republique_dominicaine\/santo_domingo.aspx?lang=fra","ACCRA_fr":"https:\/\/www.canadainternational.gc.ca\/ghana\/index.aspx?lang=fra","OSLO_en":"https:\/\/www.international.gc.ca\/country-pays\/norway-norvege\/oslo.aspx?lang=eng","SEOUL_en":"http:\/\/www.canadainternational.gc.ca\/korea-coree\/index.aspx?lang=eng","SPORE_en":"http:\/\/www.canadainternational.gc.ca\/singapore-singapour\/consular_services_consulaires\/index.aspx?lang=eng","HANOI_en":"https:\/\/www.canadainternational.gc.ca\/vietnam\/offices-bureaux\/hanoi.aspx?lang=eng","KNSHA_en":"https:\/\/www.international.gc.ca\/country-pays\/democratic_republic_congo-republique_democratique_congo\/kinshasa.aspx","MIAMI_en":"https:\/\/www.international.gc.ca\/country-pays\/us-eu\/miami.aspx?lang=eng","MNGUA_fr":"https:\/\/www.international.gc.ca\/country-pays\/nicaragua\/managua.aspx?lang=fra","SOFIA_fr":"https:\/\/www.international.gc.ca\/country-pays\/bulgaria-bulgarie\/index.aspx?lang=fra","BERN_fr":"https:\/\/www.canadainternational.gc.ca\/switzerland-suisse\/index.aspx?lang=fra","LIMA_en":"http:\/\/www.canadainternational.gc.ca\/peru-perou\/contact-contactez.aspx?lang=eng","TOKYO_fr":"https:\/\/www.canadainternational.gc.ca\/japan-japon\/index.aspx?lang=fra","BUCST_fr":"https:\/\/www.canadainternational.gc.ca\/romania-roumanie\/index.aspx?lang=fra","PANAM_en":"https:\/\/www.international.gc.ca\/country-pays\/panama\/panama_city-ville_de_panama.aspx?lang=eng","SOFIA_en":"https:\/\/www.international.gc.ca\/country-pays\/bulgaria-bulgarie\/index.aspx?lang=eng","HANOI_fr":"https:\/\/www.canadainternational.gc.ca\/vietnam\/offices-bureaux\/hanoi.aspx?lang=fra","PRET_en":"https:\/\/www.canadainternational.gc.ca\/southafrica-afriquedusud\/contact-contactez.aspx?lang=eng","OSLO_fr":"https:\/\/www.international.gc.ca\/country-pays\/norway-norvege\/oslo.aspx?lang=fra","MMBAI_fr":"https:\/\/international.gc.ca\/world-monde\/india-inde\/mumbai.aspx?lang=fra","RABAT_fr":"https:\/\/www.canadainternational.gc.ca\/morocco-maroc\/contact-contactez.aspx?lang=fra","TOKYO_en":"https:\/\/www.canadainternational.gc.ca\/japan-japon\/index.aspx?lang=eng","LIMA_fr":"http:\/\/www.canadainternational.gc.ca\/peru-perou\/contact-contactez.aspx?lang=fra","CAIRO_en":"http:\/\/www.international.gc.ca\/world-monde\/egypt-egypte\/cairo-caire.aspx?lang=eng","HKONG_en":"https:\/\/www.canadainternational.gc.ca\/hong_kong\/index.aspx?lang=eng","KNGTN_en":"https:\/\/www.canadainternational.gc.ca\/jamaica-jamaique\/index.aspx?lang=eng","HOCHI_en":"https:\/\/www.canadainternational.gc.ca\/vietnam\/offices-bureaux\/ho_chi_minh_city-ho_chi_minh_ville.aspx?lang=eng","CNCUN_fr":"https:\/\/www.canadainternational.gc.ca\/mexico-mexique\/offices-bureaux\/consoff-burcons.aspx?lang=fra","PANAM_fr":"https:\/\/www.international.gc.ca\/country-pays\/panama\/panama_city-ville_de_panama.aspx?lang=fra","HAGUE_en":"https:\/\/www.canadainternational.gc.ca\/netherlands-pays_bas\/contact-contactez.aspx?lang=eng","PARIS_fr":"https:\/\/www.canadainternational.gc.ca\/france\/index.aspx?lang=fra","BNGKK_fr":"http:\/\/www.canadainternational.gc.ca\/thailand-thailande\/index.aspx?lang=fra","LSBON_en":"https:\/\/www.canadainternational.gc.ca\/portugal\/index.aspx?lang=eng","RABAT_en":"https:\/\/www.canadainternational.gc.ca\/morocco-maroc\/contact-contactez.aspx?lang=eng","SPALO_en":"https:\/\/international.gc.ca\/world-monde\/country-pays\/brazil-bresil\/index.aspx?lang=eng","BSBGN_fr":"https:\/\/www.canadainternational.gc.ca\/brunei_darussalam\/index.aspx?lang=fra","PPLAT_en":"https:\/\/www.international.gc.ca\/country-pays\/dominican_republic-republique_dominicaine\/puerto_plata.aspx?lang=eng","APLCO_en":"https:\/\/www.canadainternational.gc.ca\/mexico-mexique\/offices-bureaux\/consoff-burcons.aspx?lang=en","CAIRO_fr":"http:\/\/www.international.gc.ca\/world-monde\/egypt-egypte\/cairo-caire.aspx?lang=fra","ALGER_en":"http:\/\/www.canadainternational.gc.ca\/algeria-algerie\/index.aspx?lang=eng","HOCHI_fr":"https:\/\/www.canadainternational.gc.ca\/vietnam\/offices-bureaux\/ho_chi_minh_city-ho_chi_minh_ville.aspx?lang=fra","LNGLS_fr":"https:\/\/international.gc.ca\/world-monde\/country-pays\/united_states-etats_unis\/los_angeles.aspx?lang=fra","MNGUA_en":"https:\/\/www.international.gc.ca\/country-pays\/nicaragua\/managua.aspx?lang=eng","HKONG_fr":"https:\/\/www.canadainternational.gc.ca\/hong_kong\/index.aspx?lang=fra","MIAMI_fr":"https:\/\/www.international.gc.ca\/country-pays\/us-eu\/miami.aspx?lang=fra","KNGTN_fr":"https:\/\/www.canadainternational.gc.ca\/jamaica-jamaique\/index.aspx?lang=fra","SEOUL_fr":"http:\/\/www.canadainternational.gc.ca\/korea-coree\/index.aspx?lang=fra","SJCRA_en":"https:\/\/www.canadainternational.gc.ca\/costa_rica\/contact-contactez.aspx?lang=eng","BERN_en":"https:\/\/www.canadainternational.gc.ca\/switzerland-suisse\/index.aspx?lang=eng","CNCUN_en":"https:\/\/www.canadainternational.gc.ca\/mexico-mexique\/offices-bureaux\/consoff-burcons.aspx?lang=en","BNGKK_en":"http:\/\/www.canadainternational.gc.ca\/thailand-thailande\/index.aspx?lang=eng","HAGUE_fr":"https:\/\/www.canadainternational.gc.ca\/netherlands-pays_bas\/contact-contactez.aspx?lang=fra","LSBON_fr":"https:\/\/www.canadainternational.gc.ca\/portugal\/index.aspx?lang=fra","MMBAI_en":"https:\/\/international.gc.ca\/world-monde\/india-inde\/mumbai.aspx?lang=eng","BSBGN_en":"https:\/\/www.canadainternational.gc.ca\/brunei_darussalam\/index.aspx?lang=eng","GQUIL_en":"https:\/\/www.canadainternational.gc.ca\/ecuador-equateur\/contact-guayaquil-contactez.aspx?lang=eng","SSAL_fr":"https:\/\/www.canadainternational.gc.ca\/el_salvador-salvador\/index.aspx?lang=fra","STAGO_fr":"https:\/\/www.canadainternational.gc.ca\/chile-chili\/contact-contactez.aspx?lang=fra","ATHNS_en":"https:\/\/www.international.gc.ca\/country-pays\/greece-grece\/athens-athenes.aspx?lang=eng","PARIS_en":"https:\/\/www.canadainternational.gc.ca\/france\/index.aspx?lang=eng","DAKAR_fr":"https:\/\/www.international.gc.ca\/country-pays\/senegal\/dakar.aspx?lang=fra","BAGLR_en":"http:\/\/international.gc.ca\/world-monde\/india-inde\/bengaluru.aspx?lang=eng","PCANA_fr":"https:\/\/www.international.gc.ca\/country-pays\/dominican_republic-republique_dominicaine\/punta_cana.aspx?lang=fra","SSAL_en":"https:\/\/www.canadainternational.gc.ca\/el_salvador-salvador\/index.aspx?lang=eng","BOSTN_en":"https:\/\/international.gc.ca\/world-monde\/country-pays\/united_states-etats_unis\/boston.aspx?lang=eng","ANKRA_fr":"https:\/\/www.canadainternational.gc.ca\/turkey-turquie\/consular_services_consulaires\/services_for_canadians-services_pour_canadiens.aspx?lang=fra","DAKAR_en":"https:\/\/www.international.gc.ca\/country-pays\/senegal\/dakar.aspx?lang=eng","PCANA_en":"https:\/\/www.international.gc.ca\/country-pays\/dominican_republic-republique_dominicaine\/punta_cana.aspx?lang=eng","SYDNY_en":"http:\/\/www.canadainternational.gc.ca\/australia-australie\/contact-sydney-contactez.aspx?lang=eng","ATHNS_fr":"https:\/\/www.international.gc.ca\/country-pays\/greece-grece\/athens-athenes.aspx?lang=fra","SPALO_fr":"https:\/\/international.gc.ca\/world-monde\/country-pays\/brazil-bresil\/index.aspx?lang=fra","RYADH_fr":"http:\/\/www.canadainternational.gc.ca\/saudi_arabia-arabie_saoudite\/offices-bureaux\/contact-embassy-contactez-ambassade.aspx?lang=fra","BAGLR_fr":"http:\/\/international.gc.ca\/world-monde\/india-inde\/bengaluru.aspx?lang=fra","KLMPR_en":"http:\/\/www.canadainternational.gc.ca\/malaysia-malaisie\/consular_services_consulaires\/index.aspx?lang=eng","PRGUE_en":"https:\/\/www.international.gc.ca\/country-pays\/czechia-tchequie\/prague.aspx?lang=eng","KWAIT_en":"https:\/\/www.canadainternational.gc.ca\/kuwait-koweit\/contact-contactez.aspx?lang=eng","RIO_en":"https:\/\/international.gc.ca\/world-monde\/country-pays\/brazil-bresil\/index.aspx?lang=eng","ANKRA_en":"https:\/\/www.canadainternational.gc.ca\/turkey-turquie\/consular_services_consulaires\/services_for_canadians-services_pour_canadiens.aspx?lang=eng","BOSTN_fr":"https:\/\/international.gc.ca\/world-monde\/country-pays\/united_states-etats_unis\/boston.aspx?lang=fra","GENEV_en":"https:\/\/www.international.gc.ca\/country-pays\/switzerland-suisse\/geneva-geneve.aspx?lang=eng","LCABO_fr":"https:\/\/www.canadainternational.gc.ca\/mexico-mexique\/offices-bureaux\/consoff-burcons.aspx?lang=fra","BRTSV_en":"https:\/\/www.canadainternational.gc.ca\/austria-autriche\/offices-bureaux\/contact_embassy_slov_contactez_ambassade.aspx?lang=eng","RYADH_en":"http:\/\/www.canadainternational.gc.ca\/saudi_arabia-arabie_saoudite\/offices-bureaux\/contact-embassy-contactez-ambassade.aspx?lang=eng","SPORE_fr":"http:\/\/www.canadainternational.gc.ca\/singapore-singapour\/consular_services_consulaires\/index.aspx?lang=fra","YNGON_en":"https:\/\/www.international.gc.ca\/country-pays\/myanmar\/index.aspx?lang=eng","RIO_fr":"https:\/\/international.gc.ca\/world-monde\/country-pays\/brazil-bresil\/index.aspx?lang=fra","PRGUE_fr":"https:\/\/www.international.gc.ca\/country-pays\/czechia-tchequie\/prague.aspx?lang=fra","KWAIT_fr":"https:\/\/www.canadainternational.gc.ca\/kuwait-koweit\/contact-contactez.aspx?lang=fra","SYDNY_fr":"http:\/\/www.canadainternational.gc.ca\/australia-australie\/contact-sydney-contactez.aspx?lang=fra","KGALI_en":"https:\/\/www.international.gc.ca\/country-pays\/rwanda\/kigali.aspx?lang=eng","QUITO_en":"https:\/\/www.canadainternational.gc.ca\/ecuador-equateur\/contact-contactez.aspx?lang=eng","BEJING_fr":"https:\/\/www.canadainternational.gc.ca\/china-chine\/offices-bureaux\/index.aspx?lang=fra","NROBI_fr":"https:\/\/www.international.gc.ca\/country-pays\/kenya\/nairobi.aspx?lang=fra","BRTSV_fr":"https:\/\/www.canadainternational.gc.ca\/austria-autriche\/offices-bureaux\/contact_embassy_slov_contactez_ambassade.aspx?lang=fra","BUCST_en":"https:\/\/www.canadainternational.gc.ca\/romania-roumanie\/index.aspx?lang=eng","GENEV_fr":"https:\/\/www.international.gc.ca\/country-pays\/switzerland-suisse\/geneva-geneve.aspx?lang=fra","HAVAN_fr":"https:\/\/www.canadainternational.gc.ca\/cuba\/index.aspx?lang=fra","BERUT_fr":"https:\/\/international.gc.ca\/world-monde\/lebanon-liban\/beirut-beyrouth.aspx?lang=fra","SFRAN_fr":"https:\/\/international.gc.ca\/world-monde\/country-pays\/united_states-etats_unis\/san_francisco.aspx?lang=fra","VIENN_fr":"http:\/\/www.canadainternational.gc.ca\/austria-autriche\/index.aspx?lang=fra","WSAW_fr":"https:\/\/www.international.gc.ca\/country-pays\/poland-pologne\/warsaw-varsovie.aspx?lang=fra","KGALI_fr":"https:\/\/www.international.gc.ca\/country-pays\/rwanda\/kigali.aspx?lang=fra","BPEST_en":"https:\/\/www.canadainternational.gc.ca\/hungary-hongrie\/index.aspx?lang=eng","DUBAI_fr":"http:\/\/www.canadainternational.gc.ca\/uae-eau\/consulate_contact-contactez_consulat.aspx?lang=fra","TUNIS_en":"https:\/\/www.canadainternational.gc.ca\/tunisia-tunisie\/index.aspx?lang=eng","BEJING_en":"https:\/\/www.canadainternational.gc.ca\/china-chine\/offices-bureaux\/index.aspx?lang=eng","QUITO_fr":"https:\/\/www.canadainternational.gc.ca\/ecuador-equateur\/contact-contactez.aspx?lang=fra","MVDEO_en":"https:\/\/www.international.gc.ca\/country-pays\/uruguay\/montevideo.aspx","YNGON_fr":"https:\/\/www.international.gc.ca\/country-pays\/myanmar\/index.aspx?lang=fra","BMAKO_fr":"https:\/\/www.international.gc.ca\/country-pays\/mali\/bamako.aspx?lang=fra","MZLTN_en":"https:\/\/www.canadainternational.gc.ca\/mexico-mexique\/offices-bureaux\/consoff-burcons.aspx?lang=en","CHONQ_fr":"https:\/\/www.canadainternational.gc.ca\/china-chine\/offices-bureaux\/chongqing\/index.aspx?lang=fra","CHADG_en":"https:\/\/international.gc.ca\/world-monde\/india-inde\/chandigarh.aspx?lang=eng","MACAO_fr":"https:\/\/www.canadainternational.gc.ca\/hong_kong\/index.aspx?lang=fra","AMMAN_fr":"http:\/\/international.gc.ca\/world-monde\/jordan-jordanie\/index.aspx?lang=fra","NROBI_en":"https:\/\/www.international.gc.ca\/country-pays\/kenya\/nairobi.aspx?lang=eng","ACCRA_en":"https:\/\/www.canadainternational.gc.ca\/ghana\/index.aspx?lang=eng","PRNCE_en":"https:\/\/www.canadainternational.gc.ca\/haiti\/index.aspx?lang=eng","DSLAM_fr":"https:\/\/www.canadainternational.gc.ca\/tanzania-tanzanie\/index.aspx?lang=fra","ADDIS_fr":"https:\/\/www.canadainternational.gc.ca\/ethiopia-ethiopie\/contact-contactez.aspx?lang=fra","PNPEN_fr":"http:\/\/www.canadainternational.gc.ca\/thailand-thailande\/index.aspx?lang=fra","MVDEO_fr":"https:\/\/www.international.gc.ca\/country-pays\/uruguay\/montevideo.aspx?lang=fra","VIENN_en":"http:\/\/www.canadainternational.gc.ca\/austria-autriche\/index.aspx?lang=eng","TUNIS_fr":"https:\/\/www.canadainternational.gc.ca\/tunisia-tunisie\/index.aspx?lang=fra","BMAKO_en":"https:\/\/www.international.gc.ca\/country-pays\/mali\/bamako.aspx?lang=eng","CHONQ_en":"https:\/\/www.canadainternational.gc.ca\/china-chine\/offices-bureaux\/chongqing\/index.aspx?lang=eng","CNGNY_fr":"https:\/\/international.gc.ca\/world-monde\/country-pays\/united_states-etats_unis\/new_york.aspx?lang=fra","MACAO_en":"https:\/\/www.canadainternational.gc.ca\/hong_kong\/index.aspx?lang=eng","SHNGI_fr":"https:\/\/www.canadainternational.gc.ca\/china-chine\/offices-bureaux\/shanghai\/index.aspx?lang=fra","PRNCE_fr":"https:\/\/www.canadainternational.gc.ca\/haiti\/index.aspx?lang=fra","LCABO_en":"https:\/\/www.canadainternational.gc.ca\/mexico-mexique\/offices-bureaux\/consoff-burcons.aspx?lang=en","DSLAM_en":"https:\/\/www.canadainternational.gc.ca\/tanzania-tanzanie\/index.aspx?lang=eng","ABUJA_fr":"https:\/\/www.canadainternational.gc.ca\/nigeria\/index.aspx?lang=fra","WSHDC_fr":"https:\/\/international.gc.ca\/world-monde\/country-pays\/united_states-etats_unis\/washington.aspx?lang=fra","SHNGI_en":"https:\/\/www.canadainternational.gc.ca\/china-chine\/offices-bureaux\/shanghai\/index.aspx?lang=eng","PNPEN_en":"http:\/\/www.canadainternational.gc.ca\/thailand-thailande\/index.aspx?lang=eng","RMLAH_fr":"https:\/\/www.canadainternational.gc.ca\/west_bank_gaza-cisjordanie_bande_de_gaza\/index.aspx?lang=fra","BLZCT_fr":"https:\/\/www.international.gc.ca\/country-pays\/belize\/belize_city.aspx?lang=fra","KLMPR_fr":"http:\/\/www.canadainternational.gc.ca\/malaysia-malaisie\/consular_services_consulaires\/index.aspx?lang=fra","HAVAN_en":"https:\/\/www.canadainternational.gc.ca\/cuba\/index.aspx?lang=eng","STKHM_fr":"https:\/\/www.international.gc.ca\/country-pays\/sweden-suede\/stockholm.aspx?lang=fra","BERUT_en":"https:\/\/international.gc.ca\/world-monde\/lebanon-liban\/beirut-beyrouth.aspx?lang=eng","STAGO_en":"https:\/\/www.canadainternational.gc.ca\/chile-chili\/contact-contactez.aspx?lang=eng","GANZU_en":"https:\/\/www.canadainternational.gc.ca\/china-chine\/offices-bureaux\/guangzhou\/index.aspx?lang=eng","JEDDA_en":"http:\/\/www.canadainternational.gc.ca\/saudi_arabia-arabie_saoudite\/offices-bureaux\/consulate_jeddah-djeddah_consulat.aspx?lang=eng","MZLTN_fr":"https:\/\/www.canadainternational.gc.ca\/mexico-mexique\/offices-bureaux\/consoff-burcons.aspx?lang=fra","OUAGA_fr":"https:\/\/www.canadainternational.gc.ca\/burkinafaso\/index.aspx?lang=fra","STKHM_en":"https:\/\/www.international.gc.ca\/country-pays\/sweden-suede\/stockholm.aspx?lang=eng"},"lenderLocationExternalId":false,"logoAltText":"Government of Canada","defaultLocationExternalId":"0","browserTitlePrefix":"Global Affairs Canada - ","mapboxApiKey":"pk.eyJ1IjoiY29kZXplbm8iLCJhIjoiY2t5c2FiYXgxMHNkeTJyczJoMzdwMGV6cCJ9.4XBPVK0atOP4EDjeY1SvIg","googleMapsApiKey":"AIzaSyBAb_HF8b6aQ5kWpFSmGh5NGbfpPB679yo","primaryColor":"#bd2319","requireLocationGroupId":false,"defaultLatitude":"-27.4684","logoMobile":"https:\/\/app.timetrade.ca\/tc\/imgm\/vcw66.png","defaultLongitude":"153.0269","noAvailabilityMessage":"All available appointments for this service are currently booked. Please consult the service instructions to check if your request might be completed without an in-person appearance. If an in-person appointment is still needed, please check back next week.","defaultCampaignExternalId":false,"mapProvider":"google","googleTagManagerId":false,"confirmationNotice":"Please print this page and bring it to your appointment.","logoDesktop":"https:\/\/app.timetrade.ca\/tc\/imgm\/j16vj.png","defaultProgramExternalId":"services","hideStepInfo":{"campaign":{"confirm":false,"confirmreschedule":false,"reviewfind":false,"review":false,"confirmcancel":true,"reviewcancel":true,"reviewreschedule":false},"location":{"confirm":false,"confirmreschedule":false,"reviewfind":false,"review":false,"confirmcancel":false,"reviewcancel":false,"reviewreschedule":false},"attendee":{"confirm":true,"confirmreschedule":true,"reviewfind":false,"review":false,"confirmcancel":true,"reviewcancel":false,"reviewreschedule":false},"program":{"confirm":true,"confirmreschedule":true,"reviewfind":true,"review":true,"confirmcancel":true,"reviewcancel":true,"reviewreschedule":true},"activity":{"confirm":false,"confirmreschedule":false,"reviewfind":false,"review":false,"confirmcancel":false,"reviewcancel":false,"reviewreschedule":false},"appointmentInfo":{"confirm":true,"confirmreschedule":true,"reviewfind":false,"review":false,"confirmcancel":true,"reviewcancel":false,"reviewreschedule":false}}},"features":{"recaptcha":false,"googleLinkOnReviewConfirm":true,"hideTimezoneOnReviewConfirm":true,"addToCalendar":false,"wcag":false},"wf":{"workflowExternalId":"appointments","steps":[{"stepExternalId":"infoschedule","title":"Disclaimer:","subtitle":"","label":"Disclaimer:","skip":"false","fulfilled":"true","stepNumber":1,"labels":{"forward":"Continue"},"parameters":[],"htmlContent":"<div style='background-color:#bd2319;padding:2.6em 2em' id='first'><span style='color:white;font-size:1.6em;'>Online appointment requests are for <b>CANADIAN CITIZENS ONLY<\/b>.<\/span><\/div><div style='padding:4em 2em 0 2em' id='second'><span style='font-size:1.6em'>If you are a non-Canadian citizen who wants to enter Canada, you should contact <a href='https:\/\/www.canada.ca\/en\/services\/immigration-citizenship.html' target='_blank'>Immigration, Refugees and Citizenship Canada<\/a>, the government department responsible for non-Canadians who want to come to Canada as immigrants, visitors, refugees, students, or workers.<\/span><\/div><div style='padding:4em 2em 0 2em' id='third'><span style='font-size:1.6em'>Before you book an appointment, please consult <a href='https:\/\/travel.gc.ca\/assistance\/ask-travel' target='_blank'>Ask Travel<\/a><\/span><\/div><div style='text-align:center;position:absolute;bottom:0;left:0;width:100%;padding:4em 2em 2em 2em;box-sizing:border-box' id='fourth'><span style='font-size:1.6em'><a href='https:\/\/www.international.gc.ca\/global-affairs-affaires-mondiales\/privacy-confidentialite\/online-appointment-rendez-vous-ligne.aspx?lang=eng' target='_blank'>Privacy<\/a><\/span><\/div>"},{"stepExternalId":"appointmenttypegroupschedule","title":"Select a service:","subtitle":" ","label":"Service:","skip":"true","fulfilled":"false","stepNumber":2,"labels":{"back":"Back","forward":"Next"},"parameters":[{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"appointmentTypeGroupId","required":true,"type":"RADIO","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"Program","position":"","place":"","style":"","options":[{"value":"appointment-type-groups","label":"Programs"}]}],"htmlContent":""},{"stepExternalId":"appointmenttype","title":"Select an appointment type:","subtitle":"","label":"Appointment Type","skip":"false","fulfilled":"false","stepNumber":3,"labels":{"back":"Back","forward":"Next"},"parameters":[{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"appointmentTypeId","required":true,"type":"RADIO","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"Appointment type","position":"","place":"","style":"","options":[{"value":"appointment-types","label":"Appointment Types"}]}],"htmlContent":""},{"stepExternalId":"availability","title":"Select date and time:","subtitle":"","label":"Date and Time","skip":"false","fulfilled":"false","stepNumber":4,"labels":{"back":"Back","forward":"Next"},"parameters":[{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"locationId","required":false,"type":"SELECT","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"Location","position":"","place":"","style":"","options":[{"value":"locations","label":"Locations"}]},{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"dateTime","required":true,"type":"DATETIME","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"Select a date and time:","position":"","place":"","style":"","options":[{"value":"availability","label":"Availability"}]}],"htmlContent":""},{"stepExternalId":"attendee","title":"Provide contact information:","subtitle":"","label":"Contact Information","skip":"false","fulfilled":"true","stepNumber":5,"labels":{"back":"Back","forward":"Next"},"parameters":[{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"","required":true,"type":"label","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"<span style=\\\"color:red\\\">Fields marked with an * are required<\/span>","position":"","place":"","style":"","options":[]},{"filter":"","fieldMatch":"","minlength":"","maxlength":"50","name":"attendee_person_firstName","required":false,"type":"","id":"","fieldMap":"Firstname","width":"50%","hideLabel":"false","hidden":"false","label":"","position":"","place":"","style":"","options":[]},{"filter":"","fieldMatch":"","minlength":"","maxlength":"50","name":"attendee_person_lastName","required":false,"type":"","id":"","fieldMap":"Lastname","width":"50%","hideLabel":"false","hidden":"false","label":"","position":"","place":"","style":"","options":[]},{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"","required":false,"type":"label","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"<span style=\\\"color:black\\\">Please supply a method of contact<\/span>","position":"","place":"","style":"","options":[]},{"filter":"","fieldMatch":"","minlength":"","maxlength":"50","name":"attendee_email","required":false,"type":"","id":"","fieldMap":"Email","width":"","hideLabel":"false","hidden":"false","label":"","position":"","place":"","style":"","options":[]},{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"","required":false,"type":"label","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"<span style=\\\"color:black\\\">Please type digits 0-9 only<\/span>","position":"","place":"","style":"","options":[]},{"filter":"[0-9]","fieldMatch":"^((?!www\\.|:\\\/\\\/).)*$","minlength":"","maxlength":"","name":"attendee_customField0","required":false,"type":"","id":"","fieldMap":"Answer0","width":"","hideLabel":"false","hidden":"false","label":"","position":"","place":"","style":"","options":[]},{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"attendee_customField1","required":false,"type":"","id":"","fieldMap":"Answer1","width":"","hideLabel":"false","hidden":"false","label":"","position":"","place":"","style":"","options":[]}],"htmlContent":""},{"stepExternalId":"review","title":"Ready to Schedule this Appointment?","subtitle":"","label":"Review","skip":"false","fulfilled":"false","stepNumber":6,"labels":{"back":"Back","forward":"Book"},"parameters":[{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"workflowId","required":true,"type":"TEXT","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"Workflow","position":"","place":"","style":"","options":[]}],"htmlContent":""},{"stepExternalId":"confirm","title":"Your appointment has been scheduled!","subtitle":"","label":"Your appointment has been scheduled!","skip":"false","fulfilled":"true","stepNumber":7,"labels":{"print":"Print","returnToSite":"Done","returnToSitehref":"http:\/\/www.canadainternational.gc.ca\/thailand-thailande\/index.aspx?lang=eng"},"parameters":[{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"","required":false,"type":"label","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"<br><div style='width: 100%; margin:0 auto;margin-top: 0.5;margin-bottom:0.5%;font-size:1.6em;color:#FF0000;'><span>Please take note of the confirmation number or print this page and bring it to your appointment.<\/span><\/div>","position":"top","place":"","style":"","options":[]},{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"","required":false,"type":"label","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"<div style='width: 100%; margin:0 auto;margin-top: 0.5;margin-bottom:0.5%;font-size:1.6em;'><span>This number may be required to allow you to access the building and used to confirm your presence once you arrive.<\/span><\/div>","position":"top","place":"","style":"","options":[]},{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"","required":false,"type":"label","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"<br><span style='font-size:1.6em;color:#FF0000'>Important instructions are available in order to obtain your selected service. Please consult <a href='https:\/\/www.international.gc.ca\/global-affairs-affaires-mondiales\/privacy-confidentialite\/online-appointment-instruction-rendez-vous-ligne.aspx?lang=eng' target='_blank'>this page<\/a>, at the section corresponding to the service you requested, to ensure you are fully prepared for your appointment.<\/span><br><br><br><br>","position":"bottom","place":"","style":"","options":[]},{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"","required":false,"type":"label","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"<div style='width: 100%; margin:0 auto; text-align: center;'><br style='clear: left;' \/><br><span style='font-size:1.6em'><a href='https:\/\/www.canada.ca\/en\/immigration-refugees-citizenship\/services\/canadian-passports\/fees\/passport-outside-canada-united-states.html' target='_blank'>PAY ONLINE<\/a> <b>before<\/b> you apply for the following passport services (only outside Canada and the United States):<br>\u2014 Regular adult passports (5- and 10-year validity)<br>\u2014 Child passports (5-year validity)<br>\u2014 The administrative fee for replacing a valid lost or stolen passport ($45)<\/span><br><br><br><br><\/div><br><br>","position":"bottom","place":"","style":"","options":[]},{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"","required":false,"type":"label","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"<div style='width: 100%; margin:0 auto; text-align: center;'><br style='clear: left;' \/><span style='font-size:1.6em;'>The Government of Canada has many tools for travelling Canadians!<\/a><\/span><\/div><br><br>","position":"bottom","place":"","style":"","options":[]},{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"","required":false,"type":"label","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"<div class='stack' style='width:33.33%;text-align:center;font-size:1.6em;height:100%;float:left;padding:1em;box-sizing:border-box'><a href='https:\/\/travel.gc.ca\/assistance\/ask-travel' target='_blank'>AskTravel<br><\/a><\/div><div class='stack' style='width:33.33%;text-align:center;font-size:1.6em;float:left;box-sizing:border-box;padding:1em'><a href='https:\/\/travel.gc.ca\/mobile' target='_blank'>TravelSmart<br><\/a><\/div><div class='stack' style='text-align:center;width:33.33%;font-size:1.6em;float:left;box-sizing:border-box;padding:1em'><a href='https:\/\/travel.gc.ca\/travelling\/registration' target='_blank'>Registration of Canadians Abroad<br><\/a><\/div>","position":"bottom","place":"","style":"","options":[]}],"htmlContent":""}],"hiddensteps":[{"stepExternalId":"appointmentfindercancel","title":"Find Your Appointment:","subtitle":"","label":"Finder","skip":"true","fulfilled":"false","stepNumber":1,"labels":{"back":"Back","forward":"Find"},"parameters":[{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"appointmentId","required":true,"type":"TEXT","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"Confirmation Number","position":"","place":"","style":"","options":[]},{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"attendee_person_lastName","required":true,"type":"TEXT","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"Last Name","position":"","place":"","style":"","options":[]}],"htmlContent":""},{"stepExternalId":"appointmentfinderreschedule","title":"Find Your Appointment:","subtitle":"","label":"Finder","skip":"true","fulfilled":"false","stepNumber":2,"labels":{"back":"Back","forward":"Find"},"parameters":[{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"appointmentId","required":true,"type":"TEXT","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"Confirmation Number","position":"","place":"","style":"","options":[]},{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"attendee_person_lastName","required":true,"type":"TEXT","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"Last Name","position":"","place":"","style":"","options":[]}],"htmlContent":""},{"stepExternalId":"location","title":"Select a Branch Location:","subtitle":"","label":"Location","skip":"true","fulfilled":"true","stepNumber":3,"labels":{"back":"Back","forward":"Next"},"parameters":[{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"locationId","required":true,"type":"SELECT","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"Location","position":"","place":"","style":"","options":[{"value":"locations","label":"Locations"}]},{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"distance_from","required":false,"type":"TEXT","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"Show Embassy locations near:","position":"","place":"","style":"","options":[]}],"htmlContent":""},{"stepExternalId":"locationreschedule","title":"Select a Location:","subtitle":"","label":"Location","skip":"true","fulfilled":"true","stepNumber":4,"labels":{"back":"Back","forward":"Continue"},"parameters":[{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"locationId","required":false,"type":"SELECT","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"Location","position":"","place":"","style":"","options":[{"value":"locations","label":"Locations"}]},{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"distance_from","required":false,"type":"TEXT","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"Show locations near:","position":"","place":"","style":"","options":[]}],"htmlContent":""},{"stepExternalId":"appointmentfinder","title":"Find Your Appointment:","subtitle":"","label":"Finder","skip":"true","fulfilled":"false","stepNumber":5,"labels":{"back":"Back","forward":"Find"},"parameters":[{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"appointmentId","required":true,"type":"TEXT","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"Confirmation Number","position":"","place":"","style":"","options":[]},{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"attendee_person_lastName","required":true,"type":"TEXT","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"Last Name","position":"","place":"","style":"","options":[]}],"htmlContent":""},{"stepExternalId":"appointmenttypereschedule","title":"Select an Appointment Type:","subtitle":"","label":"Appointment Type","skip":"true","fulfilled":"false","stepNumber":6,"labels":{"back":"Back","forward":"Continue"},"parameters":[{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"appointmentTypeId","required":true,"type":"RADIO","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"Appointment Type","position":"","place":"","style":"","options":[{"value":"appointment-types","label":"Reservation Types"}]}],"htmlContent":""},{"stepExternalId":"availabilityreschedule","title":"Select New Date and Time:","subtitle":"","label":"Date and Time","skip":"false","fulfilled":"false","stepNumber":7,"labels":{"back":"Back","forward":"Continue"},"parameters":[{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"locationId","required":true,"type":"SELECT","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"Location","position":"","place":"","style":"","options":[{"value":"locations","label":"Locations"}]},{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"dateTime","required":true,"type":"DATETIME","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"Select a date and time:","position":"","place":"","style":"","options":[{"value":"availability","label":"Availability"}]},{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"tz","required":false,"type":"SELECT","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"Time Zones","position":"","place":"","style":"","options":[]}],"htmlContent":""},{"stepExternalId":"reviewcancel","title":"Are You Sure You Want to Cancel This Appointment?","subtitle":"","label":"Review","skip":"false","fulfilled":"false","stepNumber":8,"labels":{"back":"Back","forward":"Cancel"},"parameters":[{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"canceled","required":true,"type":"CHECKBOX","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"Cancelled","position":"","place":"","style":"","options":[]},{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"workflowId","required":true,"type":"TEXT","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"Workflow","position":"","place":"","style":"","options":[]}],"htmlContent":""},{"stepExternalId":"reviewreschedule","title":"Ready to Reschedule this Appointment?","subtitle":"","label":"Review","skip":"false","fulfilled":"false","stepNumber":9,"labels":{"back":"Back","forward":"Reschedule"},"parameters":[{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"workflowId","required":true,"type":"TEXT","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"Workflow","position":"","place":"","style":"","options":[]}],"htmlContent":""},{"stepExternalId":"reviewfind","title":"Your Appointment:","subtitle":"","label":"Review","skip":"false","fulfilled":"false","stepNumber":10,"labels":{"back":"Back","cancel":"Cancel","reschedule":"Reschedule"},"parameters":[{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"appointmentId","required":true,"type":"TEXT","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"Workflow","position":"","place":"","style":"","options":[]}],"htmlContent":""},{"stepExternalId":"confirmcancel","title":"Your Appointment Has Been Cancelled!","subtitle":"","label":"Your appointment has been cancelled!","skip":"false","fulfilled":"true","stepNumber":11,"labels":{"returnToSite":"Return to Site","returnToSitehref":"http:\/\/www.canadainternational.gc.ca\/thailand-thailande\/index.aspx?lang=eng"},"parameters":[{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"","required":false,"type":"label","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"<div style='width: 100%; margin:0 auto; text-align: center;'><br style='clear: left;' \/><span style='font-size:1.6em;'>The Government of Canada has many tools for travelling Canadians!<\/a><\/span><\/div><br><br>","position":"bottom","place":"","style":"","options":[]},{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"","required":false,"type":"label","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"<div class='stack' style='width:33.33%;text-align:center;font-size:1.6em;height:100%;float:left;padding:1em;box-sizing:border-box'><a href='https:\/\/travel.gc.ca\/assistance\/ask-travel' target='_blank'>AskTravel<br><\/a><\/div><div class='stack' style='width:33.33%;text-align:center;font-size:1.6em;float:left;box-sizing:border-box;padding:1em'><a href='https:\/\/travel.gc.ca\/mobile' target='_blank'>TravelSmart<br><\/a><\/div><div class='stack' style='text-align:center;width:33.33%;font-size:1.6em;float:left;box-sizing:border-box;padding:1em'><a href='https:\/\/travel.gc.ca\/travelling\/registration' target='_blank'>Registration of Canadians Abroad<br><\/a><\/div>","position":"bottom","place":"","style":"","options":[]}],"htmlContent":""},{"stepExternalId":"confirmreschedule","title":"Your Appointment Has Been Rescheduled!","subtitle":"","label":"Your appointment has been rescheduled!","skip":"false","fulfilled":"true","stepNumber":12,"labels":{"print":"Print","returnToSite":"Return to Site","returnToSitehref":"http:\/\/www.canadainternational.gc.ca\/thailand-thailande\/index.aspx?lang=eng"},"parameters":[{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"","required":false,"type":"label","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"<br><div style='width: 100%; margin:0 auto;margin-top: 0.5;margin-bottom:0.5%;font-size:1.6em;color:#FF0000;'><span>Please take note of the confirmation number or print this page and bring it to your appointment.<\/span><\/div>","position":"top","place":"","style":"","options":[]},{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"","required":false,"type":"label","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"<div style='width: 100%; margin:0 auto;margin-top: 0.5;margin-bottom:0.5%;font-size:1.6em;'><span>This number may be required to allow you to access the building and used to confirm your presence once you arrive.<\/span><\/div>","position":"top","place":"","style":"","options":[]},{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"","required":false,"type":"label","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"<br><span style='font-size:1.6em;color:#FF0000'>Important instructions are available in order to obtain your selected service. Please consult <a href='https:\/\/www.international.gc.ca\/global-affairs-affaires-mondiales\/privacy-confidentialite\/online-appointment-instruction-rendez-vous-ligne.aspx?lang=eng' target='_blank'>this page<\/a>, at the section corresponding to the service you requested, to ensure you are fully prepared for your appointment.<\/span><br><br><br><br>","position":"bottom","place":"","style":"","options":[]},{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"","required":false,"type":"label","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"<div style='width: 100%; margin:0 auto; text-align: center;'><br style='clear: left;' \/><br><span style='font-size:1.6em'><a href='https:\/\/www.canada.ca\/en\/immigration-refugees-citizenship\/services\/canadian-passports\/fees\/passport-outside-canada-united-states.html' target='_blank'>PAY ONLINE<\/a> <b>before<\/b> you apply for the following passport services (only outside Canada and the United States):<br>\u2014 Regular adult passports (5- and 10-year validity)<br>\u2014 Child passports (5-year validity)<br>\u2014 The administrative fee for replacing a valid lost or stolen passport ($45)<\/span><br><br><br><br><\/div><br><br>","position":"bottom","place":"","style":"","options":[]},{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"","required":false,"type":"label","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"<div style='width: 100%; margin:0 auto; text-align: center;'><br style='clear: left;' \/><span style='font-size:1.6em;'>The Government of Canada has many tools for travelling Canadians!<\/a><\/span><\/div><br><br>","position":"bottom","place":"","style":"","options":[]},{"filter":"","fieldMatch":"","minlength":"","maxlength":"","name":"","required":false,"type":"label","id":"","fieldMap":"","width":"","hideLabel":"false","hidden":"false","label":"<div class='stack' style='width:33.33%;text-align:center;font-size:1.6em;height:100%;float:left;padding:1em;box-sizing:border-box'><a href='https:\/\/travel.gc.ca\/assistance\/ask-travel' target='_blank'>AskTravel<br><\/a><\/div><div class='stack' style='width:33.33%;text-align:center;font-size:1.6em;float:left;box-sizing:border-box;padding:1em'><a href='https:\/\/travel.gc.ca\/mobile' target='_blank'>TravelSmart<br><\/a><\/div><div class='stack' style='text-align:center;width:33.33%;font-size:1.6em;float:left;box-sizing:border-box;padding:1em'><a href='https:\/\/travel.gc.ca\/travelling\/registration' target='_blank'>Registration of Canadians Abroad<br><\/a><\/div>","position":"bottom","place":"","style":"","options":[]}],"htmlContent":""}],"action":"schedule","attributes":{"externalId":"appointmentsnew","id":"8C4ABBDF-8BA9-4A9A-8F8A-A18A8D35F01C","licenseeId":"5063","locale":"en","namespace":"WORKFLOWS","usesHeliumTranslatables":"false"}},"routes":".when('\/',{title:'Home',template:'',controller:mainController}).when('\/error',{title:'Error',templateUrl:'pages\/error.php?v=4.92',controller:errorController}).when('\/infoschedule',{title:'Disclaimer:',templateUrl:'pages\/infoschedule.php?v=4.92',controller:infoscheduleController}).when('\/appointmenttypegroupschedule',{title:'Select a service:',templateUrl:'pages\/appointmenttypegroupschedule.php?v=4.92',controller:appointmenttypegroupscheduleController}).when('\/appointmenttype',{title:'Select an appointment type:',templateUrl:'pages\/appointmenttype.php?v=4.92',controller:appointmenttypeController}).when('\/availability',{title:'Select date and time:',templateUrl:'pages\/availability.php?v=4.92',controller:availabilityController}).when('\/attendee',{title:'Provide contact information:',templateUrl:'pages\/attendee.php?v=4.92',controller:attendeeController}).when('\/review',{title:'Ready to Schedule this Appointment?',templateUrl:'pages\/review.php?v=4.92',controller:reviewController}).when('\/confirm',{title:'Your appointment has been scheduled!',templateUrl:'pages\/confirm.php?v=4.92',controller:confirmController})","sid":"adf21a557a8dd62f7ca3e400e453e29a","appName":"Click to Schedule"}; //console.log($rootScope.cts); $rootScope.translations = {}; $rootScope.wf = $rootScope.cts.wf; $rootScope.rtl = "ltr" == "rtl" ? true : false; $rootScope.isMobile = false; $rootScope.returnToSite = $rootScope.cts.settings["returnToSite"]; $rootScope.opaURL = ""; if(self != top) { $rootScope.returnToSite = false; } $rootScope.requirements = {}; $rootScope.prefill = {customer:"embassyca",wf:"appointments",action:"schedule",locationId:"APLCO"}; $rootScope.fieldStatuses = {}; for (var key in $rootScope.wf['attributes']) { $rootScope.prefill[key] = $rootScope.wf['attributes'][key]; } delete $rootScope.wf['attributes']; $rootScope.lang = $rootScope.prefill.lang ? $rootScope.prefill.lang : "en"; $rootScope.plusoneEnabled = false;//default $rootScope.plusonePossible = false;//default $rootScope.waitlistEnabled = false;//default $rootScope.showAnyResource = false;//default $rootScope.filterFieldsAttendee = {};//default $rootScope.filterFieldsQuestion = {};//default //FEATURES $rootScope.addToCalendar = $rootScope.cts.features["addToCalendar"]; $rootScope.eventsAndClasses = $rootScope.cts.features["eventsAndClasses"]; $rootScope.hideTimezoneOnReviewConfirm = $rootScope.cts.features["hideTimezoneOnReviewConfirm"]; $rootScope.googleLinkOnReviewConfirm = $rootScope.cts.features["googleLinkOnReviewConfirm"]; $rootScope.waitlistPossible = $rootScope.cts.features["waitlist"]; $rootScope.wcag = $rootScope.cts.features["wcag"]; //SETTINGS $rootScope.defaultLocationExternalId = $rootScope.cts.settings["defaultLocationExternalId"]; $rootScope.defaultActivityExternalId = $rootScope.cts.settings["defaultActivityExternalId"]; $rootScope.requireLocationGroupId = $rootScope.cts.settings["requireLocationGroupId"]; $rootScope.defaultLatitude = $rootScope.cts.settings["defaultLatitude"]; $rootScope.defaultLongitude = $rootScope.cts.settings["defaultLongitude"]; $rootScope.mapProvider = $rootScope.cts.settings["mapProvider"]; $rootScope.locationProvider = $rootScope.cts.settings["locationProvider"]; $rootScope.googleMapsApiKey = false || $rootScope.cts.settings["googleMapsApiKey"]; $rootScope.mapboxApiKey = false || $rootScope.cts.settings["mapboxApiKey"]; $rootScope.countries = [ { "id": 5, "label": "Australia", "value": "AU" } ]; $rootScope.states = [ { "countryId": 5, "label": "State", "value": "" }, { "countryId": 5, "label": "Australian Capital Territory", "value": "ACT" }, { "countryId": 5, "label": "New South Wales", "value": "NSW" }, { "countryId": 5, "label": "Northern Territory", "value": "NT" }, { "countryId": 5, "label": "Queensland", "value": "QLD" }, { "countryId": 5, "label": "South Australia", "value": "SA" }, { "countryId": 5, "label": "Tasmania", "value": "TAS" }, { "countryId": 5, "label": "Victoria", "value": "VIC" }, { "countryId": 5, "label": "Western Australia", "value": "WA" } ]; $rootScope.pathTaken = Array("/"); $rootScope.ready = false; $rootScope.valid = false; $rootScope.locations = ["loading..."]; $rootScope.activities = ["loading..."]; $rootScope.programs = ["loading..."]; $rootScope.campaigns = ["loading..."]; $rootScope.topten = []; $rootScope.error = ""; $rootScope.status = "loading..."; $rootScope.geo = navigator.geolocation; $rootScope.loadingMessage = ""; $rootScope.mapProviderLoaded = false; $rootScope.stepErrorMessage = ""; $rootScope.detectedTimezone = moment.tz.guess(); $rootScope.errorButtons = { 'default':true, 'availability':false, 'clearAppointmentTypeId':false } $rootScope.debugStatus = $rootScope.prefill['debug'] ? true : false; $rootScope.formData = { resourceFilter: [], resourceCharacteristicsFilter: {}, externalApi: $rootScope.prefill['external'] ? true : false, campaignExternalId: $rootScope.prefill['campaignId'] ? $rootScope.prefill['campaignId'] : null, cancelAppointment: $rootScope.prefill['canceled'] ? $rootScope.prefill['canceled'] : null, workflowExternalId: $rootScope.prefill['wf'] ? $rootScope.prefill['wf'] : null, confirmationNumber: $rootScope.prefill['appointmentId'] ? $rootScope.prefill['appointmentId'] : ($rootScope.prefill['confirmationNumber'] ? $rootScope.prefill['confirmationNumber'] : null), holdConfirmationNumber: $rootScope.prefill['holdConfirmationNumber'] ? $rootScope.prefill['holdConfirmationNumber'] : null, locationExternalId: $rootScope.prefill['locationId'] ? $rootScope.prefill['locationId'] : null, activityExternalId: $rootScope.prefill['appointmentTypeId'] ? $rootScope.prefill['appointmentTypeId'] : null, resourceExternalId: $rootScope.prefill['resourceId'] ? $rootScope.prefill['resourceId'] : null, programExternalId: $rootScope.prefill['appointmentTypeGroupId'] ? $rootScope.prefill['appointmentTypeGroupId'] : null, queueExternalId: $rootScope.prefill['queueExternalId'] ? $rootScope.prefill['queueExternalId'] : $rootScope.cts.settings["defaultQueueExternalId"], locationGroupExtId: $rootScope.prefill['locationGroupId'] ? $rootScope.prefill['locationGroupId'] : null, locationGroupExtIdPrefix: $rootScope.prefill['locationGroupIdPrefix'] ? $rootScope.prefill['locationGroupIdPrefix'] : null, locationGroupExtIdSuffix: $rootScope.prefill['locationGroupIdSuffix'] ? $rootScope.prefill['locationGroupIdSuffix'] : null, appointmentStartDate: $rootScope.prefill['dateTime'] ? $rootScope.prefill['dateTime'] : null, gridStartDate: $rootScope.prefill['startDate'] ? $rootScope.prefill['startDate'] : "", gridEndDate: $rootScope.prefill['endDate'] ? $rootScope.prefill['endDate'] : "", client_address1: $rootScope.prefill['attendee_address_streetAddress'] ? $rootScope.prefill['attendee_address_streetAddress'] : null, client_address2: $rootScope.prefill['attendee_address_streetAddress2'] ? $rootScope.prefill['attendee_address_streetAddress2'] : null, client_city: $rootScope.prefill['attendee_address_city'] ? $rootScope.prefill['attendee_address_city'] : null, client_country: $rootScope.prefill['attendee_address_country'] ? $rootScope.countries.filter(function(country) {return country.value === $rootScope.prefill['attendee_address_country']})[0]["label"] : null, client_postalCode: $rootScope.prefill['attendee_address_postalCode'] ? $rootScope.prefill['attendee_address_postalCode'] : null, client_state: $rootScope.prefill['attendee_address_state'] ? $rootScope.prefill['attendee_address_state'] : null, client_countryCode: $rootScope.prefill['attendee_address_country'] ? $rootScope.prefill['attendee_address_country'] : null, client_company: $rootScope.prefill['attendee_companyName'] ? $rootScope.prefill['attendee_companyName'] : null, client_username: $rootScope.prefill['attendee_userName'] ? $rootScope.prefill['attendee_userName'] : null, client_firstName: $rootScope.prefill['attendee_person_firstName'] ? $rootScope.prefill['attendee_person_firstName'] : null, client_lastName: $rootScope.prefill['attendee_person_lastName'] ? $rootScope.prefill['attendee_person_lastName'] : null, client_email: $rootScope.prefill['attendee_email'] ? $rootScope.prefill['attendee_email'] : null, client_mobile: $rootScope.prefill['attendee_mobile_phoneNumber'] ? $rootScope.prefill['attendee_mobile_phoneNumber'] : $rootScope.prefill['mobile'] || null, clientExternalId: $rootScope.prefill['attendeeId'] ? $rootScope.prefill['attendeeId'] : null, client_memberId: $rootScope.prefill['attendee_memberId'] ? $rootScope.prefill['attendee_memberId'] : null, client_answer0: $rootScope.prefill['attendee_customField0'] && $rootScope.prefill['attendee_customField0'] != 'null' ? $rootScope.prefill['attendee_customField0'] : null, client_answer1: $rootScope.prefill['attendee_customField1'] && $rootScope.prefill['attendee_customField1'] != 'null' ? $rootScope.prefill['attendee_customField1'] : null, client_answer2: $rootScope.prefill['attendee_customField2'] && $rootScope.prefill['attendee_customField2'] != 'null' ? $rootScope.prefill['attendee_customField2'] : null, client_answer3: $rootScope.prefill['attendee_customField3'] && $rootScope.prefill['attendee_customField3'] != 'null' ? $rootScope.prefill['attendee_customField3'] : null, client_answer4: $rootScope.prefill['attendee_customField4'] && $rootScope.prefill['attendee_customField4'] != 'null' ? $rootScope.prefill['attendee_customField4'] : null, client_answer5: $rootScope.prefill['attendee_customField5'] && $rootScope.prefill['attendee_customField5'] != 'null' ? $rootScope.prefill['attendee_customField5'] : null, client_answer6: $rootScope.prefill['attendee_customField6'] && $rootScope.prefill['attendee_customField6'] != 'null' ? $rootScope.prefill['attendee_customField6'] : null, client_answer7: $rootScope.prefill['attendee_customField7'] && $rootScope.prefill['attendee_customField7'] != 'null' ? $rootScope.prefill['attendee_customField7'] : null, client_answer8: $rootScope.prefill['attendee_customField8'] && $rootScope.prefill['attendee_customField8'] != 'null' ? $rootScope.prefill['attendee_customField8'] : null, client_answer9: $rootScope.prefill['attendee_customField9'] && $rootScope.prefill['attendee_customField9'] != 'null' ? $rootScope.prefill['attendee_customField9'] : null, custom0: $rootScope.prefill['appointment_customField0'] && $rootScope.prefill['appointment_customField0'] != 'null' ? $rootScope.prefill['appointment_customField0'] : null, custom1: $rootScope.prefill['appointment_customField1'] && $rootScope.prefill['appointment_customField1'] != 'null' ? $rootScope.prefill['appointment_customField1'] : null, custom2: $rootScope.prefill['appointment_customField2'] && $rootScope.prefill['appointment_customField2'] != 'null' ? $rootScope.prefill['appointment_customField2'] : null, custom3: $rootScope.prefill['appointment_customField3'] && $rootScope.prefill['appointment_customField3'] != 'null' ? $rootScope.prefill['appointment_customField3'] : null, custom4: $rootScope.prefill['appointment_customField4'] && $rootScope.prefill['appointment_customField4'] != 'null' ? $rootScope.prefill['appointment_customField4'] : null, custom5: $rootScope.prefill['appointment_customField5'] && $rootScope.prefill['appointment_customField5'] != 'null' ? $rootScope.prefill['appointment_customField5'] : null, custom6: $rootScope.prefill['appointment_customField6'] && $rootScope.prefill['appointment_customField6'] != 'null' ? $rootScope.prefill['appointment_customField6'] : null, custom7: $rootScope.prefill['appointment_customField7'] && $rootScope.prefill['appointment_customField7'] != 'null' ? $rootScope.prefill['appointment_customField7'] : null, custom8: $rootScope.prefill['appointment_customField8'] && $rootScope.prefill['appointment_customField8'] != 'null' ? $rootScope.prefill['appointment_customField8'] : null, custom9: $rootScope.prefill['appointment_customField9'] && $rootScope.prefill['appointment_customField9'] != 'null' ? $rootScope.prefill['appointment_customField9'] : null, clientLocale:"en_CA", clientLocaleDisplayName:"English (Canada)", latitude: null, longitude: null, /*days: { '0': 0, '1': 0, '2': 0, '3': 0, '4': 0, '5': 0, '6': 0 },*/ cal: "0", calView: false ? (($rootScope.wcag && !$rootScope.isMobile) ? "week" : "month") : (($rootScope.wcag && !$rootScope.isMobile) ? "week" : "month"), calStyle: false ? "grid" : "grid", custom: {}, appointmentEndDate: null,//''//testing angularjs upgrade to 1.6.5 appointmentDurationMin: 15, week: 0, month: 0, clientTimezone:moment.tz.guess() }; if ($rootScope.eventsAndClasses) { $rootScope.formData["plusoneFirstName"] = ""; $rootScope.formData["plusoneLastName"] = ""; } //loop over questionId__xxx and add them to formData as appointment_xxx for (var key in $rootScope.prefill) { if (key.substring(0,12) == "questionId__") { qid = key.substring(12); $rootScope.formData["appointment_"+qid] = $rootScope.prefill[key]; } } $rootScope.fieldMap = { appointmentId: "confirmationNumber", holdConfirmationNumber: "holdConfirmationNumber", locationId: "locationExternalId", appointmentTypeId: "activityExternalId", campaignId: "campaignExternalId", appointmentTypeGroupId: "programExternalId", locationGroupId: "locationGroupExtId", dateTime: "appointmentStartDate", startDate: "gridStartDate", endDate: "gridEndDate", attendeeId: "clientExternalId", mobile: "mobilephone", MobilePhone: "mobilephone", attendee_mobile_phoneNumber:"client_mobile", Username: "memberid", attendee_userName: "client_username", Firstname: "firstname", attendee_person_firstName: "client_firstName", Lastname: "lastname", attendee_person_lastName: "client_lastName", attendee_companyName: "client_company", Email: "email", attendee_email: "client_email", Address1: "address1", attendee_address_streetAddress: "client_address1", Address2: "address2", attendee_address_streetAddress2:"client_address2", City: "city", attendee_address_city: "client_city", StateId: "state", attendee_address_state: "client_state", PostalCode: "postalcode", attendee_address_postalCode: "client_postalCode", CountryId: "country", attendee_address_country: "client_country", Answer0: "customField0",//use the field property to get the UI label attendee_customField0: "client_answer0",//use the xml name to set the angular formData name Answer1: "customField1", attendee_customField1: "client_answer1", Answer2: "customField2", attendee_customField2: "client_answer2", Answer3: "customField3", attendee_customField3: "client_answer3", Answer4: "customField4", attendee_customField4: "client_answer4", Answer5: "customField5", attendee_customField5: "client_answer5", Answer6: "customField6", attendee_customField6: "client_answer6", Answer7: "customField7", attendee_customField7: "client_answer7", Answer8: "customField8", attendee_customField8: "client_answer8", Answer9: "customField9", attendee_customField9: "client_answer9", appointment_customField0: "custom0", appointment_customField1: "custom1", appointment_customField2: "custom2", appointment_customField3: "custom3", appointment_customField4: "custom4", appointment_customField5: "custom5", appointment_customField6: "custom6", appointment_customField7: "custom7", appointment_customField8: "custom8", appointment_customField9: "custom9", workflowId: "workflowExternalId", resourceId: "resourceExternalId", canceled: "cancelAppointment", tz: "clientTimezone " } $rootScope.getLocation = function(locationExternalId) { if (!$rootScope.locations || $rootScope.locations.length < 1) { $rootScope.error = "No locations available."; $rootScope.ready = true; $rootScope.showErrorButton('location'); $location.path( 'error' ); return; } return $rootScope.locations.find(function(l) { var alternate = $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId; return l.locationExternalId == (locationExternalId ? locationExternalId : alternate); }); } $rootScope.getResource = function(resourceExternalId) { if (!$rootScope.resources) { //console.log("No resources"); if (resourceExternalId) { return { resourceExternalId: resourceExternalId, resourceName: resourceExternalId }; } else { return false; } } return $rootScope.resources.find(function(r) { return r.resourceExternalId == (resourceExternalId ? resourceExternalId : $rootScope.formData['resourceExternalId']); }); } $rootScope.getAppointmentDuration = function() { var resource = $rootScope.getResource(); var characteristics = resource && resource.characteristics ? resource.characteristics : []; var resourceDurations = characteristics.filter(function(item) {return item['key'] == "resourceDuration"}); var resourceDuration = resourceDurations[0] ? resourceDurations[0]['value'] : null; if (resourceDuration) { return parseInt(resourceDuration); } else { var activityDurations = $rootScope.getActivity()['activityDurations']; var activityDuration = (activityDurations.length === undefined || activityDurations.length === 0) ? activityDurations['durationInMinutes'] : activityDurations[0]['durationInMinutes']; return parseInt(activityDuration); } } $rootScope.getItem = function(array,key,value) { //console.log(array,key,value); return array.find(function(object) { return object[key] == value; }); } $rootScope.getItemIndex = function(array,key,value) { //console.log(array,key,value); i = $rootScope.getItem(array,key,value); //console.log("item",i); return array.indexOf(i); } $rootScope.getActivity = function(activityExternalId) { return $rootScope.activities.find(function(a) { return a.activityExternalId == (activityExternalId ? activityExternalId : $rootScope.formData['activityExternalId']); }); } $rootScope.getProgram = function(programExternalId) { //console.log($rootScope.programs); return $rootScope.programs.find(function(p) { return p.programExternalId == (programExternalId ? programExternalId : $rootScope.formData['programExternalId']); }); } $rootScope.getCampaign = function(campaignExternalId) { //console.log($rootScope.campaigns); return $rootScope.campaigns.find(function(c) { return c.campaignExternalId == (campaignExternalId ? campaignExternalId : $rootScope.formData['campaignExternalId']); }); } $rootScope.existsArrayKeyValue = function(array,key,value) { //console.log(array,key,value); return array.find(function(object) { return object[key] == value; }); } $rootScope.getItemsArrayObject = function(array,object) { var arr = []; var found; for (var key in array) { found = true; for (var prop in object) { if (object[prop] != array[key][prop]) { found = false; break; } } if (found) { arr.push(array[key]); } } return arr; } $rootScope.getParameter = function(parameterName) { if (($location.path()).substr(1) === "error") { return; } return $rootScope.getStep()['parameters'].find(function(p) { return p.name == parameterName; }); } $rootScope.getStep = function(stepExternalId, useHiddenSteps = true) { var step = $rootScope.wf.steps.find(function(s) { return s.stepExternalId == (stepExternalId ? stepExternalId : ($location.path()).substr(1)); }); if (step) { return step; } else { if (useHiddenSteps) { var hiddenstep = $rootScope.wf.hiddensteps.find(function(s) { return s.stepExternalId == (stepExternalId ? stepExternalId : ($location.path()).substr(1)); }); return hiddenstep; } return undefined; } } $rootScope.useClientTimezone = function() { try { if ($rootScope.getStep('availability', false)['parameters'].find(function(p){return p.name=='tz'})) { return true; } } catch(e) { //console.log(e); } return false; } $rootScope.getTimezone = function() { var timezone = $rootScope.useClientTimezone() ? $rootScope.formData["clientTimezone"] : false; if (!timezone) { // 02/06/2023 - Justin doesn't know why we would use resource timezone for E&C and says it should be using location timezone //if ($rootScope.eventsAndClasses && $rootScope.formData['programExternalId'] == "events" && $rootScope.formData['resourceExternalId'] && $rootScope.getResource()['timezone']) { // timezone = $rootScope.getResource()['timezone'];//will only apply if resource timezone override is ticked. //} else { timezone = $rootScope.getLocation()['timezone']; //} } return timezone; } $rootScope.numToChar = function(number) { return String.fromCharCode(65 + parseInt(number)); } $rootScope.isStepComplete = function(addClass) { var stepPass = true; var fieldPass = true; var title = ""; var parameters = $rootScope.wf.steps[$rootScope.getStepIndex()].parameters; if ($rootScope.getStep()["stepExternalId"] === "attendee" || $rootScope.getStep()["stepExternalId"] === "question") { //Switch to using $rootScope.attendeeFields to capture questions on the attendee step var filterFields = $rootScope.getStep()["stepExternalId"] === "question" ? $rootScope.filterFieldsQuestion : $rootScope.filterFieldsAttendee; parameters = $rootScope.getItemsArrayObject($rootScope.attendeeFields,filterFields);//Added 28/12/2020 if (addClass) {//error check $rootScope.stepErrorMessage = '';//reset error } if ($rootScope.eventsAndClasses && $rootScope.plusoneEnabled && $rootScope.plusonePossible && $rootScope.formData.plusoneSelected) { title = ""; plusoneFirstNamefieldPass = true; plusoneLastNamefieldPass = true; var plusoneFirstName = angular.element( document.querySelector( "#plusoneFirstName" ) ); var plusoneLastName = angular.element( document.querySelector( "#plusoneLastName" ) ); if (!addClass && (!plusoneFirstName || !plusoneFirstName[0] || !plusoneFirstName[0].validity)) { return false; } if (!addClass && (!plusoneLastName || !plusoneLastName[0] || !plusoneLastName[0].validity)) { return false; } plusoneFirstNamefieldPass = (plusoneFirstName[0].validity.valid && (!(!$rootScope.formData["plusoneFirstName"]))); plusoneLastNamefieldPass = (plusoneLastName[0].validity.valid && (!(!$rootScope.formData["plusoneLastName"]))); var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; //firstname if (!plusoneFirstNamefieldPass) { stepPass = false; if (addClass) { plusoneFirstName.addClass('requiredHighlight'); plusoneFirstName[0].title = "invalid"; firstError = $rootScope.stepErrorMessage == "" ? 'id="firstError" ' : ''; $rootScope.stepErrorMessage += '<li><a '+firstError+'class="errorField" href="#plusoneFirstName">Plus One First Name field is invalid.</a></div>'; } } else { if (addClass) { plusoneFirstName.removeClass('requiredHighlight'); plusoneFirstName.title = ""; } } //lastname if (!plusoneLastNamefieldPass) { stepPass = false; if (addClass) { plusoneLastName.addClass('requiredHighlight'); plusoneLastName[0].title = "invalid"; firstError = $rootScope.stepErrorMessage == "" ? 'id="firstError" ' : ''; $rootScope.stepErrorMessage += '<li><a '+firstError+'class="errorField" href="#plusoneLastName">Plus One Last Name field is invalid.</a></div>'; } } else { if (addClass) { plusoneLastName.removeClass('requiredHighlight'); plusoneLastName.title = ""; } } } for (var i=0;i<parameters.length;i++) { title = ""; fieldPass = true; if (parameters[i].type !== "Label") { var checkElement = angular.element( document.querySelector( "#"+parameters[i]["id"] ) ); //if (!addClass && (!checkElement || !checkElement[0] || !checkElement[0].validity)) { if (!checkElement || !checkElement[0] || !checkElement[0].validity) { continue; } if (parameters[i].required === true) { fieldPass = ((!checkElement[0] || checkElement[0].validity.valid) && (!(!$rootScope.formData[parameters[i]["id"]]))); title = "invalid"; } if (parameters[i]["id"] === "client_email" && ( (parameters[i].required === true) || (parameters[i].required !== true && $rootScope.formData[parameters[i]["id"]]) ) ) { var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; fieldPass = ((!checkElement[0] || checkElement[0].validity.valid) && re.test(String($rootScope.formData[parameters[i]["id"]]).toLowerCase())); title = "invalid"; } if (parameters[i]["filter"] && $rootScope.formData[parameters[i]["id"]]) { var filter = new RegExp(parameters[i]["filter"]); var val = $rootScope.formData[parameters[i]["id"]]; var x = val.length; while (x--) { if ( !filter.test(val.charAt(x)) ) { fieldPass = false; title = "invalid"; break; } } } if (parameters[i]["fieldMatch"] && $rootScope.formData[parameters[i]["id"]]) { var fieldMatch = new RegExp(parameters[i]["fieldMatch"]); var val = $rootScope.formData[parameters[i]["id"]]; if ( !fieldMatch.test(val) ) { fieldPass = false; title = "invalid"; } } if (!fieldPass) { stepPass = false; if (addClass) { checkElement.addClass('requiredHighlight'); checkElement[0].title = title; firstError = $rootScope.stepErrorMessage == "" ? 'id="firstError" ' : ''; var checkField = $rootScope.getItem($rootScope.attendeeFields,"id",checkElement[0].id); $rootScope.stepErrorMessage += '<li><a '+firstError+'class="errorField" href="#'+checkField.id+'">'+checkField.label+' field is '+title+'.</a></div>'; } } else { if (addClass) { checkElement.removeClass('requiredHighlight'); checkElement.title = ""; } } } } if ($rootScope.cts.features.recaptcha) { var recaptchaContainer = angular.element( document.querySelector( "#recaptcha" ) ); if ($rootScope.formData.recaptchaToken) { if (addClass) { recaptchaContainer.removeClass('requiredHighlight'); } } else { stepPass = false; if (addClass) { recaptchaContainer.addClass('requiredHighlight'); } } } } else { if ($rootScope.eventsAndClasses && $rootScope.getStep()["stepExternalId"] === "resource") { if (!$rootScope.formData.resourceCharacteristicsFilter['resourceName']) { stepPass = false; } } else { for (var i=0;i<parameters.length;i++) { if (parameters[i].required === true) {//change from "true" to true 24/05/2023 var myEl = angular.element( document.querySelector( "#"+$rootScope.fieldMap[parameters[i].name] ) ); if (!$rootScope.formData[$rootScope.fieldMap[parameters[i].name]]) { //allow blank resource to pass because it equals 'any'. need field to be required in XML so it can be reset when going back a step if (parameters[i].name == "resourceId" && !$rootScope.formData[$rootScope.fieldMap["resourceId"]]) { //pass } else { stepPass = false; if (addClass) { myEl.addClass('requiredHighlight'); } } } else { if (addClass) { myEl.removeClass('requiredHighlight'); } } } } } } return stepPass; } $rootScope.www = function(address) { $window.location.href = address; } $rootScope.isAppointmentInfo = function(key) { var field; var fields = typeof key !== "undefined" ? [$rootScope.attendeeFields[key]] : $rootScope.attendeeFields; for (var i in fields) { field = fields[i]; if (field['id'] && field['id'].lastIndexOf('appointment_', 0) === 0 && field['hidden'] != 'true') { if ($rootScope.formData[field['id']] !== null && $rootScope.formData[field['id']] !== "" && typeof $rootScope.formData[field['id']] !== "undefined") { return true; } } } return false; } $rootScope.isLastStep = function() { $step = $rootScope.getStep(); if ($step) { return $step['stepNumber'] == $rootScope.wf.steps.length; } else { return true; } } $rootScope.isFirstStep = function() { $step = $rootScope.getStep(); if ($step) { return $step['stepNumber'] == 1; } else { return true; } } $rootScope.getStepIndex = function(stepExternalId) { step = $rootScope.getStep(stepExternalId); if (step) { return step['stepNumber'] -1; } else { return 0; } } $rootScope.printScreen = function() { tem = angular.element( document.querySelector( "html" ) ); tem.addClass('print'); window.print(); } $rootScope.newNextStep = function() { var currentPass = $rootScope.isStepComplete(true);//true means add classes to show incorrect fields var nextStepNum = $rootScope.getStepIndex() + 1; var nextPath = $rootScope.wf.steps[nextStepNum]['stepExternalId']; if (currentPass) { if (nextPath === "attendee" || nextPath === "question") { //Remove ec_cts questions if characteristic is false var eccts = $rootScope.attendeeFields.filter(function(field) {return field['id'] && field['id'].indexOf("appointment_ec_cts_") == 0}); //var eccts = $rootScope.attendeeFields.filter(function(field) {return field['id'] && field['id'].startsWith("appointment_ec_cts_")}); for (var eIndex in eccts) { var resChar = $rootScope.getResource()['characteristics'].filter(function(char) {return "appointment_"+char['key'] == eccts[eIndex]['id']}); if (resChar.length > 0 && resChar[0]['value'] === "false") { var indexToRemove = $rootScope.getItemIndex($rootScope.attendeeFields,'id',eccts[eIndex]['id']); //console.log(indexToRemove); $rootScope.attendeeFields.splice(indexToRemove, 1); } //reset all appointment_ec_cts_ questions delete $rootScope.formData[eccts[eIndex]['id']]; } //check and reset skip if needed. need this incase different slot is selected if ($rootScope.wf.steps[nextStepNum]['skipInit']) { $rootScope.wf.steps[nextStepNum]['skip'] = $rootScope.wf.steps[nextStepNum]['skipInit']; } var skipOver = 0; for (var i = 0; i < 2; i++) { if ((nextPath === "attendee" && $rootScope.getStep("attendee")['skip'] === "true" && $rootScope.getStep("attendee")['fulfilled'] === "true") || (nextPath === "question" && $rootScope.getStep("question")['skip'] === "true" && $rootScope.getStep("question")['fulfilled'] === "true")) { if (nextPath === "attendee") { //this might need to be step.parameters not attendee fields. why no client fields? var checkFields = $rootScope.attendeeFields.filter(function(field) {return field['group'] != "client" && field['step'] != "question"}); var attendeePass = true; for (fIndex in checkFields) { if ($rootScope.formData[checkFields[fIndex]['id']] === undefined) { attendeePass = false; //break for loop } } if (attendeePass) { //log here skipOver++; } } if (nextPath === "question") { var checkFields = $rootScope.attendeeFields.filter(function(field) {return field['group'] != "client" && field['step'] != "attendee"}); var questionPass = true; for (fIndex in checkFields) { if ($rootScope.formData[checkFields[fIndex]['id']] === undefined) { questionPass = false; //break for loop } } if (questionPass) { skipOver++; } else { $rootScope.wf.steps[nextStepNum]['skipInit'] = $rootScope.wf.steps[nextStepNum]['skip']; $rootScope.wf.steps[nextStepNum]['skip'] = "false"; } } nextPath = $rootScope.wf.steps[nextStepNum + skipOver]['stepExternalId']; } } } if ($rootScope.cts.features.recaptcha && ($rootScope.wf.steps[$rootScope.getStepIndex()]['stepExternalId'] == "attendee" || $rootScope.wf.steps[$rootScope.getStepIndex()]['stepExternalId'] == "appointmentfinder")) { recaptchaCheck = { "checkRecaptcha":"x", "token":$rootScope.formData.recaptchaToken, "sid": $rootScope.cts.sid }; $http.post('session.php', recaptchaCheck).then(function(all) { if (all && all.data) { if (all.data.success) { $rootScope.gotoNextAvailableStep(nextPath); //$location.path(nextPath); } else { $rootScope.formData.recaptchaToken = false; } } }); } else { $rootScope.gotoNextAvailableStep(nextPath); } } else { if ($rootScope.getStep()['stepExternalId'] != "attendee" && $rootScope.getStep()['stepExternalId'] != "question") { alert($filter('getLang')("Please complete the step to continue.")); } else { if ($rootScope.stepErrorMessage !== "") { tem = angular.element( document.querySelector( "#errorMessage" ) ); tem[0].focus(); } } } } $rootScope.gotoNextAvailableStep = function(stepExternalId) { var step = $rootScope.getStep(stepExternalId); var skip = true; //can't be sure if attendee and question steps are fulfilled because of dynamically loaded questions that may be required. if (stepExternalId == "attendee" || stepExternalId == "question") { skip = false; } if (step.skip !== "true") { skip = false; } if (step && step.parameters) { for (var i=0;i<step.parameters.length;i++) { if (step.parameters[i].required === true) {//change from "true" to true 24/05/2023 if (!$rootScope.formData[$rootScope.fieldMap[step.parameters[i].name]]) { skip = false; } } } } if (skip) { var nextPath = $rootScope.wf.steps[step.stepNumber]['stepExternalId']; $rootScope.gotoNextAvailableStep(nextPath); } else { $location.path(stepExternalId); } } $rootScope.newPrevStep = function() { var parameters = $rootScope.wf.steps[$rootScope.getStepIndex()].parameters; var resetParameters = ["locationExternalId","campaignExternalId","programExternalId","activityExternalId","resourceExternalId",]; for (var i=0;i<parameters.length;i++) { if (parameters[i].required === true && resetParameters.indexOf($rootScope.fieldMap[parameters[i].name]) >= 0) {//change from "true" to true 24/05/2023 $rootScope.formData[$rootScope.fieldMap[parameters[i].name]] = null; } } var prevStepNum = $rootScope.getStepIndex() - 1; var prevPath = $rootScope.wf.steps[prevStepNum]['stepExternalId']; if (prevPath === "attendee" || prevPath === "question") { var skipOver = 0; for (var i = 0; i < 2; i++) { if ((prevPath === "attendee" && $rootScope.getStep("attendee")['skip'] === "true" && $rootScope.getStep("attendee")['fulfilled'] === "true") || (prevPath === "question" && $rootScope.getStep("question")['skip'] === "true" && $rootScope.getStep("question")['fulfilled'] === "true")) { if (prevPath === "attendee") { var checkFields = $rootScope.attendeeFields.filter(function(field) {return field['group'] != "client" && field['step'] != "question"}); var attendeePass = checkFields.length > 0 ? false : true; if (attendeePass) { skipOver++; } } if (prevPath === "question") { var checkFields = $rootScope.attendeeFields.filter(function(field) {return field['group'] != "client" && field['step'] != "attendee"}); var questionPass = true; for (fIndex in checkFields) { if ($rootScope.formData[checkFields[fIndex]['id']] === undefined) { questionPass = false; //break for loop } } if (questionPass) { skipOver++; } } prevPath = $rootScope.wf.steps[prevStepNum - skipOver]['stepExternalId']; } } } $location.path(prevPath); } $rootScope.gotoStep = function(stepIndex) { var path = $rootScope.wf.steps[stepIndex]['stepExternalId']; //Clear error,as it has already been shown $rootScope.error = ""; $location.path(path); } $rootScope.gotoPath = function(path) { if ($rootScope.getStep(path)) { //Clear error,as it has already been shown $rootScope.error = ""; $location.path(path); } else { //remove all url parameters for the step (path) - may need to load the xml as step is not available in angular if (path == "availability") { $rootScope.changeURL({'dateTime':''}); } else { $rootScope.changeURL(); } } } $rootScope.showErrorButton = function(button) { for (key in $rootScope.errorButtons) { $rootScope.errorButtons[key] = false; } $rootScope.errorButtons[button] = true; } $rootScope.newCancelAppointment = function() { $rootScope.changeURL({"action":"cancel","canceled":"true"}); /*newpath = "/?action=cancel&canceled=true"; for (param in $location.search()) { if (param != 'action' && $location.search()[param] != "") { newpath += "&" + param + "=" + $location.search()[param]; } } $window.location.href = newpath;*/ } $rootScope.rescheduleAppointment = function() { $rootScope.changeURL({"action":"reschedule","appointmentTypeId":$rootScope.formData['activityExternalId'],"appointmentId":$rootScope.formData.confirmationNumber,"attendee_person_lastName":$rootScope.formData.client_lastName}); /*newpath = "/?action=reschedule&appointmentTypeId="+$rootScope.formData['activityExternalId']+"&appointmentId="+$rootScope.formData.confirmationNumber+"&attendee_person_lastName="+$rootScope.formData.client_lastName; for (param in $location.search()) { if (param != 'action' && $location.search()[param] != "") { newpath += "&" + param + "=" + $location.search()[param]; } } $window.location.href = newpath;*/ } $rootScope.dateAddTimezoneFormat = function(date,days,timezone,format) { var momentDateTime = moment.tz(date,timezone).add(days, 'd'); if (momentDateTime.isValid()) { return momentDateTime.format(format); } else { return date; } } $rootScope.dateTimezoneFormat = function(date,timezone,format) { var momentDateTime = moment.tz(date,timezone); if (format == 'LLLL-LT') { var replace = "(.*)("+momentDateTime.format('LT')+")(.*)"; var re = new RegExp(replace,"gmi"); var result = (momentDateTime.format('LLLL')).replace(re, '$1$3'); result = result.trim().replace(" "," "); return result.charAt(0).toUpperCase() + result.slice(1); } if (format == 'll-YYYY') { var replace = "(.*)("+momentDateTime.format('YYYY')+")(.*)"; var re = new RegExp(replace,"gmi"); var result = (momentDateTime.format('ll')).replace(re, '$1$3'); result = result.trim().replace(",","").replace(".","").replace(" "," "); return result.charAt(0).toUpperCase() + result.slice(1); } if (format == 'LL-D') { var fullText = momentDateTime.format('LL'); var removeTextDo = momentDateTime.format('Do'); var removeDo = ""; if (removeTextDo.match(/[^0-9a-z]/i) !== null) { removeDo = "(.*)("+removeTextDo+")(.*)"; } else { removeDo = "(.*)(\\b"+removeTextDo+"\\b)(.*)"; } var removeDoRegex = new RegExp(removeDo,"i"); var removeTextD = momentDateTime.format('D'); var removeD = "(.*)(\\b"+removeTextD+"\\b)(.*)"; var removeDRegex = new RegExp(removeD,"i"); var result = ""; if (fullText.match(removeTextDo) !== null) { result = fullText.replace(removeDoRegex, '$1$3'); } else { result = fullText.replace(removeDRegex, '$1$3'); } var cleaned = result.trim().replace(" ,",",").replace(" "," "); return cleaned.charAt(0).toUpperCase() + cleaned.slice(1); /*var replace = "(.*)(\\b"+momentDateTime.format('D')+"\\b)(.*)"; var re = new RegExp(replace,"gmi"); var result = (momentDateTime.format('LL')).replace(re, '$1$3'); result = result.trim().replace(" ,",",").replace(" "," "); return result.charAt(0).toUpperCase() + result.slice(1);*/ } if (momentDateTime.isValid()) { return momentDateTime.format(format); } else { return date; } } $rootScope.changeURL = function(parameters) { action = "https://cts-ca.anzus.solutions/"; var inputs = angular.extend({}, $rootScope.prefill, $location.search(), parameters); //console.log(inputs); var form = '<form name="postform" action="'+ action +'" method="post" style="display:none">'; for (input in inputs) { form += '<input type="text" name="'+ input +'" value="'+ inputs[input] +'" />'; } form += '</form>'; document.body.innerHTML += form; document.forms.postform.submit(); } $rootScope.calDistance = function(lon1, lat1, lon2, lat2) { var radlat1 = Math.PI * lat1/180 var radlat2 = Math.PI * lat2/180 var theta = lon1-lon2 var radtheta = Math.PI * theta/180 var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta); if (dist > 1) { dist = 1; } dist = Math.acos(dist) dist = dist * 180/Math.PI dist = dist * 111189.57696;//60 * 1.1515 * 1.609344 * 1000 return dist } $rootScope.setLoading = function(status) { $rootScope.loading = status; $rootScope.loadingMessage = ""; } $rootScope.debug = function(message) { if ($rootScope.debugStatus) { console.log(message); } } }); angular.module('ctsApp').directive('ngReallyClick', [function() { return { restrict: 'A', link: function(scope, element, attrs) { element.bind('click', function() { var message = attrs.ngReallyMessage; if (message && confirm(message)) { scope.$apply(attrs.ngReallyClick); } }); } } }]); ctsApp.config(function($routeProvider, $locationProvider) { $routeProvider .when('/',{title:'Home',template:'',controller:mainController}).when('/error',{title:'Error',templateUrl:'pages/error.php?v=4.92',controller:errorController}).when('/infoschedule',{title:'Disclaimer:',templateUrl:'pages/infoschedule.php?v=4.92',controller:infoscheduleController}).when('/appointmenttypegroupschedule',{title:'Select a service:',templateUrl:'pages/appointmenttypegroupschedule.php?v=4.92',controller:appointmenttypegroupscheduleController}).when('/appointmenttype',{title:'Select an appointment type:',templateUrl:'pages/appointmenttype.php?v=4.92',controller:appointmenttypeController}).when('/availability',{title:'Select date and time:',templateUrl:'pages/availability.php?v=4.92',controller:availabilityController}).when('/attendee',{title:'Provide contact information:',templateUrl:'pages/attendee.php?v=4.92',controller:attendeeController}).when('/review',{title:'Ready to Schedule this Appointment?',templateUrl:'pages/review.php?v=4.92',controller:reviewController}).when('/confirm',{title:'Your appointment has been scheduled!',templateUrl:'pages/confirm.php?v=4.92',controller:confirmController}); if(window.history && window.history.pushState){ $locationProvider.html5Mode(true); } }); ctsApp.run(['$location', '$rootScope', 'getLangFilter', '$timeout', function($location, $rootScope, getLangFilter,$timeout) { $rootScope.$on('$routeChangeStart', function (event, current, previous) { if ($location.hash() !== "") { //console.log($location.hash()); focusElement = angular.element( document.querySelector( "#"+$location.hash() ) ); focusElement[0].focus(); event.preventDefault(); } if ($location.path() != "/") { if (!$rootScope.ready) { //Used to force a new session to stop the browser back button being used after making an appointment. $rootScope.www(($location.absUrl()).replace(/(.*\/)([^\/\?]*)(\?.*)/,'$1$3')); } } }); $rootScope.$on('$locationChangeStart', function (event, current, previous) { if ($location.path() != "/") { if (!$rootScope.ready) { //disables any visual update on screen to stop users seeing things that aren't going to show event.preventDefault(); } } }); $rootScope.$on('$routeChangeSuccess', function (event, current, previous) { //console.log("event", "current", "previous"); //console.log(event, current, previous); $rootScope.title = getLangFilter($rootScope.cts.settings["browserTitlePrefix"])+getLangFilter(current.$$route.title)+" ("+getLangFilter("Step")+" "+($rootScope.getStepIndex()+1)+" "+getLangFilter("of")+" "+$rootScope.wf.steps.length+")"; }); $rootScope.$on('$viewContentLoaded', function(event) { if ($rootScope.wcag) { focusH1 = angular.element( document.querySelector( "h1" ) ); if (focusH1[0]) { focusH1[0].focus(); } } }); }]); ctsApp.filter('trustHTML', function($sce) { return function(ss) { return $sce.trustAsHtml(ss); }; }); ctsApp.filter('wcagLinks', function($rootScope,$filter) { return function(q) { if (q && $rootScope.wcag && q.length > 7) {//shortest url is 8 characters www.a.bc //regex to find web addesses that are links and check that they have the correct warning //old: (<a[^>]* href=['"](http|\/\/)[^>]+>)([^<]*)(<\/a>) //new: (<a[^>]* href=['"](http|\/\/)[^>]+>)([^<]*)(<br>)*(<\/a>) var regexLinks = /(<a[^>]* href=['"](http|\/\/)[^>]+>)([^<]*)(<br>)*(<\/a>)/img; if (q.match(regexLinks)) { //can maybe use filter getLang on $4 or something like that and perhaps $2 q = q.replace(regexLinks, '$1$3$4'+$filter('getLang')(" (opens in new window)")+'$5'); } //regex to find web addresses that are not already links var regex = /([ ([:]|^)((https?:\/\/)|(www\.))([-A-Z0-9+&@#\/%=~_|$?!:,]+)([.])([-A-Z0-9+&@#\/%=~_|$?!:,.]*)([A-Z0-9\/])/img; if (q.match(regex)) { q = q.replace(regex, '$1<a href="//$4$5$6$7$8" target="_blank">$3$4$5$6$7$8'+$filter('getLang')(" (opens in new window)")+'</a>'); } } return q; } }); ctsApp.filter('getLang', function($rootScope,$filter) { return function(q) { if (q == "" || typeof q == "undefined" || q == null) { return ""; } //check for variables that might need replacing var variables = q.match(/{{[^}]+}}/g); if (variables) { var regexEnglish = "([^{]+)"; var regex = regexEnglish; var englishVariables = []; variables.forEach(function(item, index){ var parts = item.slice(2,-2).split("."); switch(parts[0]) { case "location": englishVariables[index] = $rootScope.getLocation()[parts[1]] || ""; break; case "campaign": englishVariables[index] = $rootScope.getCampaign()[parts[1]] || ""; break; case "program": englishVariables[index] = $rootScope.getProgram()[parts[1]] || ""; break; case "activity": englishVariables[index] = $rootScope.getActivity()[parts[1]] || ""; break; case "resource": englishVariables[index] = $rootScope.getResource()[parts[1]] || ""; break; case "form": englishVariables[index] = $rootScope.formData[parts[1]] || ""; break; default: englishVariables[index] = ""; } regex += "("+variables[index]+")"; regex += regexEnglish; }); var newReg = new RegExp(regex); var matches = q.match(newReg); var translated = []; for (var i = 1;i<matches.length;i++) { var theIndex = variables.indexOf(matches[i]); if (theIndex !== -1) { translated.push($filter('getLang')(englishVariables[theIndex])); } else { translated.push($filter('getLang')(matches[i])); } } return translated.join(""); } if ($rootScope.lang == "en") { //return q; return $filter('wcagLinks')(q); } var qt = "en-"+$rootScope.lang; var translation = ""; //handle html var qs = q.split(/([ ]*<[^><]+[> ]+)/i); for (var key in qs) { //if contains html or does not contain a-z if ( /<[a-z\/][\s\S]*>/i.test(qs[key]) || !(/[a-z]/i.test(qs[key])) ) { translation += qs[key]; } else { if ($rootScope.translations[qt] && $rootScope.translations[qt][qs[key]]) { translation += $rootScope.translations[qt][qs[key]]; } else { $rootScope.debug("No translation found for:"); $rootScope.debug(qs[key]); //console.log("No translation found for: "+qs[key]); translation += qs[key]; } } } //return translation; return $filter('wcagLinks')(translation); } }); ctsApp.filter('explodeGetLang', function($rootScope,$filter) { return function(q) { if (q) { return q.split(" ").map($filter('getLang')).join(" "); } } }); ctsApp.filter('json2array', function() { return function(json) { var array = []; for(i in json){ if (json.hasOwnProperty(i)) { array.push(json[i]); } } return array; } }); ctsApp.filter('unique', function() { return function(input, key) { var output = []; if (angular.isArray(input)) { output = input.filter(function(object,index,array) { return array.map(function(u) { return u[key]}).indexOf(object[key]) === index; }); } else { return input; } return output; } }); ctsApp.filter('prefix', function() { return function(input, key, type, value) { if (angular.isArray(input)) { var output = []; if (type == 'includes') { output = input.filter(function(item){return item[key].indexOf(value) == 0}); //output = input.filter(function(item){return item[key].startsWith(value)}); } else if (type == 'excludes') { output = input.filter(function(item){return !item[key].indexOf(value) == 0}); //output = input.filter(function(item){return !item[key].startsWith(value)}); } } else { output = input; } return output } }); ctsApp.filter('listView', function() { return function(input) { var output = []; for (date in input) { output = output.concat(input[date]); } return output; } }); ctsApp.filter('distance', function() { return function(metres) { if (metres >= 1000) { return (metres/1000).toFixed(2) + ' km'; } else { return (metres).toFixed(0) + 'm'; } } }); ctsApp.filter('duration', function() { return function(input) { var output = ""; var h = Math.floor(input / 60); var m = input - (h*60); var hours = h == 0 ? "" : (h == 1 ? "1 hour" : h+" hours"); var minutes = m == 0 ? "" : (h == 0 ? m+" minutes" : " "+m+" minutes"); return hours+minutes; } }); ctsApp.directive('autoFocus', function($timeout) { return { restrict: 'AC', link: function(_scope, _element) { $timeout(function(){ _element[0].focus(); }, 0); } }; }); ctsApp.directive('checkRequired', function(){ return { require: 'ngModel', restrict: 'A', link: function (scope, element, attrs, ngModel) { ngModel.$validators.checkRequired = function (modelValue, viewValue) { var value = modelValue || viewValue; var match = scope.$eval(attrs.ngTrueValue) || true; return value && match === value; }; } }; }); ctsApp.directive('onlyNumbers', function () { return { restrict: 'A', link: function (scope, elm, attrs, ctrl) { elm.on('keydown', function (event) { if(event.shiftKey){event.preventDefault(); return false;} //console.log(event.which); if ([8, 13, 27, 37, 38, 39, 40].indexOf(event.which) > -1) { // backspace, enter, escape, arrows return true; } else if (event.which >= 48 && event.which <= 57) { // numbers 0 to 9 return true; } else if (event.which >= 96 && event.which <= 105) { // numpad number return true; } // else if ([110, 190].indexOf(event.which) > -1) { // // dot and numpad dot // return true; // } else { event.preventDefault(); return false; } }); } } }); ctsApp.directive('restrictTo', function() { return { restrict: 'A', link: function (scope, element, attrs) { if (attrs.restrictTo == "false") { return; } else { var re = RegExp(attrs.restrictTo); var exclude = /Backspace|Enter|Tab|Delete|Del|ArrowUp|Up|ArrowDown|Down|ArrowLeft|Left|ArrowRight|Right/; element[0].addEventListener('keydown', function(event) { if (!exclude.test(event.key) && !re.test(event.key)) { event.preventDefault(); } }); } } } }); ctsApp.directive('selectEmpty', function() { return { restrict: 'A', require: 'ngModel', link: function(scope, element, attrs, ngModel) { const options = element[0].options; function valuePartOfOptions(value) { let exists = false; for(let i = 0; i < options.length; i++) { if (value === options[i].value) { exists = true; } } return exists; } function format(value) { if (!valuePartOfOptions(value)) { return null; } return value; } ngModel.$formatters.push(format); } }; }); ctsApp.directive('dynamic', function($compile, $rootScope) { return { restrict: 'A', replace: true, link: function (scope, element, attrs) { scope.$watch(attrs.dynamic, function(html) { element.html(html); $compile(element.contents())(scope); }) } }; }); function bookingController($rootScope, $scope, $http, $location, $filter, $q, $timeout, $anchorScroll) { $rootScope.setLoading(true); if ($rootScope.formData['confirmationNumber']) { $rootScope.changeURL([]); } $rootScope.timezones = [ "Australia/Adelaide", "Australia/Brisbane", "Australia/Canberra", "Australia/Darwin", "Australia/Hobart", "Australia/Melbourne", "Australia/Perth", "Australia/Sydney" ]; $rootScope.stateToTimezone = { "NSW" : "Australia/Sydney", "QLD" : "Australia/Brisbane", "VIC" : "Australia/Melbourne", "ACT" : "Australia/Canberra", "NT" : "Australia/Darwin", "SA" : "Australia/Adelaide", "WA" : "Australia/Perth", "TAS" : "Australia/Hobart" } $rootScope.formData.clientTimezone = null; //$rootScope.cache = { // "resources": [] //}; $rootScope.resources = []; $rootScope.uniqueResources = []; $rootScope.availability = {}; $rootScope.miniCalDays = []; $rootScope.miniCalMonth = ""; $rootScope.miniCalYear = ""; $rootScope.miniCalToggle = 0; $rootScope.months = ["January","February","March","April","May","June","July","August","September","October","November","December"]; if (!$rootScope.formData.programExternalId) { $rootScope.formData.programExternalId = "HomeLoans"; } $scope.mergeUnique = function(arr1, arr2) { return arr1.concat(arr2.filter(function (item) { return arr1.indexOf(item) === -1; })); } $scope.mobileBankerLocation = function () { if ($rootScope.cts.settings.useStateMobileBankerLocations) { if (!$rootScope.formData.state) { console.error("No state defined, using VIC"); $rootScope.formData.state = "VIC"; return "MB_"+$rootScope.formData.state; } else { return "MB_"+$rootScope.formData.state; } } else { return "MB1"; } } $scope.isMobileBankerLocation = function (locationExternalId) { if (locationExternalId) { return locationExternalId.substr(0,2) === "MB"; } return false; } $scope.isNotMobileBankerLocation = function (locationExternalId) { if (locationExternalId) { return locationExternalId.substr(0,2) !== "MB"; } return true; } $scope.meetNow = function() { $rootScope.setLoading(true); data = { meetNow: $rootScope.formData.meetNowToggle ? "two" : "one", sid: $rootScope.cts.sid }; $http.post('session.php', data).then(function(all) { if (all.data.success) { $rootScope.formData.meetNowToggle = !$rootScope.formData.meetNowToggle; $scope.updateResources(true); $rootScope.setLoading(false); } else { console.log("Error: "+all.data.message); } }).catch(function(error) { console.log("Problem changing meet now status: "+error.statusText+"("+error.status+")"); }); } $scope.formatPhone = function(number) { if (number && number.length > 9) { var phone = number.replace(/\D/g,''); phone = phone.slice(-9); var check = phone.substring(0, 1); if (check == '4') { phone = "+61 "+phone.substring(0, 3)+" "+phone.substring(3, 6)+" "+phone.substring(6, 9); } else { phone = "+61 "+check+" "+phone.substring(1, 5)+" "+phone.substring(5, 9); } return phone; } return number; } $scope.isComplete = function(addClass) { var formPass = true; var parameters = $rootScope.attendeeFields; for (var i=0;i<parameters.length;i++) { if (parameters[i]["type"] != "heading" && parameters[i]["type"] != "line" && parameters[i]["type"] != "Label") { var fieldPass = true; if (parameters[i]["required"] === true) { //auto checks min max requirements without validity check fieldPass = (!(!$rootScope.formData[parameters[i]["id"]])); if (!fieldPass) { console.log("Failed: required not filled"); } } if (parameters[i]["id"] === "client_email" && ( (parameters[i].required === true) || (parameters[i].required !== true && $rootScope.formData[parameters[i]["id"]]) ) ) { var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; fieldPass = (re.test(String($rootScope.formData[parameters[i]["id"]]).toLowerCase())); if (!fieldPass) { console.log("Failed: check email"); } } if (parameters[i]["filter"] && $rootScope.formData[parameters[i]["id"]]) { var filter = new RegExp(parameters[i]["filter"]); var val = $rootScope.formData[parameters[i]["id"]]; var x = val.length; while (x--) { if ( !filter.test(val.charAt(x)) ) { fieldPass = false; break; } } if (!fieldPass) { console.log("Failed: did not pass filter requirement"); } } if (parameters[i]["fieldMatch"] && $rootScope.formData[parameters[i]["id"]]) { var fieldMatch = new RegExp(parameters[i]["fieldMatch"]); var val = $rootScope.formData[parameters[i]["id"]]; if ( !fieldMatch.test(val) ) { fieldPass = false; } if (!fieldPass) { console.log("Failed: did not pass field match requirement"); } } if (!fieldPass) { formPass = false; if (addClass && $rootScope.fieldStatuses['questionId__'+parameters[i]["id"].substr(12)] != "-" && $rootScope.fieldStatuses[parameters[i]["name"]] != "-") { var checkElement = angular.element( document.querySelector( "#"+parameters[i]["id"] ) ); checkElement.addClass('requiredHighlight'); } } else { if (addClass && $rootScope.fieldStatuses['questionId__'+parameters[i]["id"].substr(12)] != "-" && $rootScope.fieldStatuses[parameters[i]["name"]] != "-") { var checkElement = angular.element( document.querySelector( "#"+parameters[i]["id"] ) ); checkElement.removeClass('requiredHighlight'); } } } } return formPass; } $scope.getDay = function(action,selectedDate) { var selectedDate = selectedDate || ''; $rootScope.availability.startDate = moment(selectedDate.substr(0,10)).startOf('week').format("YYYY-MM-DD"); $rootScope.formData.gridStartDate = selectedDate.substr(0,10); document.activeElement.blur(); $scope.updateResources(); } $scope.miniCal = function(ym1,action) { var fallbackDate = $rootScope.formData['gridStartDate'] || moment.tz((+new Date()), $rootScope.formData['clientTimezone']); ym1 = typeof ym1 !== 'undefined' ? ym1 : moment.tz(fallbackDate,$rootScope.formData['clientTimezone']).format("YYYY-MM-01"); action = typeof action !== 'undefined' ? action : 0; var newMonths = ["12","01","02","03","04","05","06","07","08","09","10","11","12","01"]; var newmonth; newmonth = (ym1.substr(5,2))*1+(action*1); ym1 = (newmonth == 0 || newmonth == 13 ? (ym1.substr(0,4))*1+(action*1) : ym1.substr(0,4))+"-"+newMonths[newmonth]+"-01"; var activeDate = new Date(ym1); var startIndex = (new Date(activeDate.getFullYear(),activeDate.getMonth(),1)).getDay(); var endIndex = startIndex + (new Date(activeDate.getFullYear(), activeDate.getMonth()+1, 0)).getDate(); $rootScope.miniCalYear = activeDate.getFullYear(); $rootScope.miniCalMonth = ('0'+(activeDate.getMonth()+1)).substr(-2,2); for (i = 0; i < 42; i++) { if (!$rootScope.miniCalDays[i]) { $rootScope.miniCalDays[i] = {}; } if (i >= startIndex && i < endIndex) { $rootScope.miniCalDays[i]['date'] = ym1.substr(0,8)+('0'+(i-startIndex+1)).substr(-2,2); $rootScope.miniCalDays[i]['day'] = (i-startIndex+1); } else { $rootScope.miniCalDays[i]['date'] = ""; $rootScope.miniCalDays[i]['day'] = ""; } } //if (action == 0) { // $rootScope.formData.week = 0; //} } $scope.getPrograms = function() { var criteria = {}; if ($rootScope.formData['campaignExternalId']) { criteria["campaignExternalId"] = $rootScope.formData['campaignExternalId']; } if ($rootScope.formData['locationExternalId'] || $rootScope.defaultLocationExternalId) { criteria["locationExternalId"] = $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId; } data = { "method":"getPrograms", //"service":"ConfigurationServices", "request": criteria, "response": { "programs":".//return/programs[deleted='false'][isEnabled='true'][not(suppressVisibilityPerApp/appName='"+$rootScope.cts.appName+"')]" }, "sid": $rootScope.cts.sid }; $http.post('api.php', data).then(function(all) { if (all.data.success) { $rootScope.programs = all.data.response.programs; } else { $rootScope.formData.error = "No location specified."; return; } }).catch(function(error) { console.log("Problem getting programs: "+error.statusText+"("+error.status+")"); }); } $scope.getActivities = function(criteria) { criteria = criteria || {}; var campaignExternalId = $rootScope.formData['campaignExternalId'] ? $rootScope.formData['campaignExternalId'] : false; var locationExternalId = ($rootScope.formData['locationExternalId'] || $rootScope.defaultLocationExternalId) ? $rootScope.formData['locationExternalId'] || $rootScope.defaultLocationExternalId : false; var programExternalId = $rootScope.formData['programExternalId'] ? $rootScope.formData['programExternalId'] : false; if (!criteria["campaignExternalId"] && campaignExternalId) { criteria["campaignExternalId"] = campaignExternalId; } if (!criteria["locationExternalId"] && locationExternalId) { criteria["locationExternalId"] = locationExternalId; } if (!criteria["programExternalId"] && programExternalId) { criteria["programExternalId"] = programExternalId; } data = { "method":"getActivities", //"service":"ConfigurationServices", "request": criteria, "response": { "activities":".//return/activities[deleted='false'][isEnabled='true'][not(suppressVisibilityPerApp/appName='"+$rootScope.cts.appName+"')]" }, "sid": $rootScope.cts.sid }; return $http.post('api.php', data).then(function(all) { if (all && all.data && all.data.response && all.data.response.activities) { return all.data.response.activities; } else { return {}; } }).catch(function(error) { console.log("Problem getting activities: "+error.statusText+"("+error.status+")"); }); } $scope.getQuestions = function() { var criteria = {}; if ($rootScope.formData['campaignExternalId']) { criteria["campaignExternalId"] = $rootScope.formData['campaignExternalId']; } if ($rootScope.formData['locationExternalId'] || $rootScope.defaultLocationExternalId) { criteria["locationExternalId"] = $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId; } if ($rootScope.formData['programExternalId']) { criteria["programExternalId"] = $rootScope.formData['programExternalId']; } if ($rootScope.formData['activityExternalId'] || $rootScope.defaultActivityExternalId) { criteria["activityExternalId"] = $rootScope.formData['activityExternalId'] ? $rootScope.formData['activityExternalId'] : $rootScope.defaultActivityExternalId; } data = { "method":"getAppointmentQuestionsByCriteria", //"service":"AppointmentServices", "request": { "questionCriteria": criteria }, "response": { "questions":".//return/questions" }, "sid": $rootScope.cts.sid }; $http.post('api.php', data).then(function(all) { if (all && all.data && all.data.response) { if (!all.data.response.questions) { all.data.response.questions = []; } for (var i=0;i<all.data.response.questions.length;i++) { field = all.data.response.questions[i]; if ($rootScope.existsArrayKeyValue($rootScope.attendeeFields, "id", "appointment_"+field["questionExternalId"])) { questionIndex = $rootScope.getItemIndex($rootScope.attendeeFields,"id","appointment_"+field["questionExternalId"]); $rootScope.attendeeFields[questionIndex]["min"] = field["minFieldValue"]; $rootScope.attendeeFields[questionIndex]["max"] = field["maxFieldValue"]; $rootScope.attendeeFields[questionIndex]["type"] = field["questionType"]; $rootScope.attendeeFields[questionIndex]["required"] = field["required"] == "true" ? true : false; if (field["questionType"] == "Checkbox") { $rootScope.attendeeFields[questionIndex]["defaultResponse"] = field["defaultResponse"] == "1" ? true : false; } else { $rootScope.attendeeFields[questionIndex]["defaultResponse"] = field["defaultResponse"] || false; } $rootScope.attendeeFields[questionIndex]["options"] = field["option"] ? (Array.isArray(field["option"]) ? field["option"] : [field["option"]]) : false; $rootScope.attendeeFields[questionIndex]["name"] = "appointment_"+field["questionExternalId"]; $rootScope.attendeeFields[questionIndex]["label"] = field["questionText"]; $rootScope.attendeeFields[questionIndex]["group"] = "appointment"; $rootScope.attendeeFields[questionIndex]["step"] = $rootScope.attendeeFields[questionIndex]["step"] ? $rootScope.attendeeFields[questionIndex]["step"] : "question"; $rootScope.attendeeFields[questionIndex]["width"] = false; } else if (field["questionExternalId"] != "C_Cancel_Reason") { $rootScope.attendeeFields.push( { min: field["minFieldValue"], max: field["maxFieldValue"], type: field["questionType"], required: field["required"] == "true" ? true : false, defaultResponse: field["questionType"] == "Checkbox" ? (field["defaultResponse"] == "1" ? true : false) : field["defaultResponse"] || false, options: field["option"] ? field["option"] : false, id: "appointment_"+field["questionExternalId"], name: "appointment_"+field["questionExternalId"], label: field["questionText"], hidden: "false", group: "appointment", step: "question", width: false } ); } } fieldIndexes = $rootScope.attendeeFields.length - 1; for (var x=fieldIndexes;x>=0;x--) { if ($rootScope.attendeeFields[x]["group"] == "appointment") { var found = $rootScope.getItemsArrayObject(all.data.response.questions,{questionExternalId:$rootScope.attendeeFields[x]["id"].slice(12)}); if (found.length < 1) { $rootScope.attendeeFields.splice(x, 1);//remove item } } } } else { //console.log("Error with response"); } $numberOfFields = $rootScope.attendeeFields.length; for (var i=0;i<$numberOfFields;i++) { if ($rootScope.attendeeFields[i]['place'] === 'bottom') { var move = $rootScope.attendeeFields.splice(i, 1)[0]; $rootScope.attendeeFields.push(move); i--; $numberOfFields--; } } }).catch(function(error) { console.log("Problem getting questions: "+error.statusText+"("+error.status+")"); }); } $scope.getLocations = function() { var criteria = {}; if ($rootScope.formData['campaignExternalId']) { criteria["campaignExternalId"] = $rootScope.formData['campaignExternalId']; } if ($rootScope.formData['programExternalId']) { criteria["programExternalId"] = $rootScope.formData['programExternalId']; } /*if ($rootScope.formData['activityExternalId']) { criteria["activityExternalId"] = $rootScope.formData['activityExternalId']; }*/ if ($rootScope.formData['resourceExternalId'] && $rootScope.formData['resourceExternalId'] != 'any') { criteria["resourceExternalId"] = $rootScope.formData['resourceExternalId']; } getLocationsByCriteria = { "method":"getLocationsByCriteria", //"service":"ConfigurationServices", "request": { "locationSearchCriteria": criteria }, "response": { "locations":".//return/locations[isDeleted='false'][locationExternalId][locationAvailabilityType='Administrators, receptionists, and clients']" }, "sid": $rootScope.cts.sid }; $http.post('api.php', getLocationsByCriteria).then(function(all) { $rootScope.locations = all.data.response.locations; if ($rootScope.locations) { $scope.initialize(); } else { $rootScope.formData.error = "No locations available."; return; } }).catch(function(error) { console.log("Problem getting locations: "+error.statusText+"("+error.status+")"); }); } $scope.getResources = function(locationExternalId) { var criteria = {}; criteria["locationExternalId"] = locationExternalId; if ($rootScope.formData['activityExternalId']) { criteria["activityExternalId"] = $rootScope.formData['activityExternalId']; } if ($rootScope.formData['programExternalId']) { criteria["programExternalId"] = $rootScope.formData['programExternalId']; } getResourcesByCriteria = { "method":"getResourcesByCriteria", //"service":"ConfigurationServices", "request": { "resourceSearchCriteria":criteria }, "response": { "resources":".//return/*[local-name() = 'resources'][isEnabled='true'][resourceExternalId!='']" }, "sid": $rootScope.cts.sid }; return $http.post('api.php', getResourcesByCriteria).then(function(all) { if (all && all.data && all.data.response && all.data.response.resources) { //$rootScope.cache.resources.push(criteria["locationExternalId"]+criteria["programExternalId"]+criteria["activityExternalId"]); all.data.response.resources.forEach(function(res, index) { var found = $rootScope.getResource(res['resourceExternalId']); if (!found) { var resourceAbridged = { "resourceExternalId": res['resourceExternalId'], "resourceName": res['resourceName'], "description": res['description'], "timezone": res['timezone'] } if (!resourceAbridged['locationExternalIds']) { resourceAbridged['locationExternalIds'] = []; } resourceAbridged['locationExternalIds'].push(res['locationExternalId']); $rootScope.resources.push(resourceAbridged); } else { found['locationExternalIds'].push(res['locationExternalId']); } }); } }).catch(function(error) { console.log("Problem getting resources: "+error.statusText+"("+error.status+")"); }); } $scope.getAvailability = function(locationExternalId) { if ($rootScope.formData['resourceExternalId'] !== 'any') { if ($rootScope.getResource($rootScope.formData['resourceExternalId'])['locationExternalIds'].indexOf(locationExternalId) < 0) { return;//skip availability check } } $rootScope.formData.calView = 'week'; var today = moment().tz($rootScope.getLocation(locationExternalId)['timezone']).format('YYYY-MM-DDTHH:mm:ssZ');//change to 00:00:00 var gridStartDate = ""; var gridEndDate = ""; if ($rootScope.availability) { gridStartDate = $rootScope.availability.startDate || ""; gridEndDate = $rootScope.availability.endDate || ""; } else { gridStartDate = ""; gridEndDate = ""; } data = { getAvailableNDateTimeSlotsStartFromDate:"get", campaignExternalId: $rootScope.formData['campaignExternalId'], programExternalId: $rootScope.formData['programExternalId'] ? $rootScope.formData['programExternalId'] : $rootScope.cts.settings["defaultProgramExternalId"], firstAvailableDateTime: today, timezone: $rootScope.formData['clientTimezone'], resourceExternalId: $rootScope.formData['resourceExternalId'], calView: $rootScope.formData.calView, gridStartDate: gridStartDate, week: $rootScope.formData.week, month: 0, gridEndDate: gridEndDate, activityExternalId: $rootScope.formData.activityExternalId, locationExternalId: locationExternalId, sid: $rootScope.cts.sid }; if ($scope.isMobileBankerLocation(locationExternalId)) { data['postcode'] = $rootScope.formData.postcode; } //if (locationExternalId == "HO1") { //data['state'] = $rootScope.formData.state; //} return $http.post('session.php', data).then(function(list) { if (!$rootScope.availability) { $rootScope.availability = { "today": list.data.today, "calView": list.data.calView, "week": 0, "month": 0, "gridMonth": $rootScope.formData.gridStartDate,//list.data.gridMonth, "startDate": list.data.startDate, "endDate": "", "debug": list.data.debug, "success": list.data.success, "bookingTimes": {}, "AvailableSlots": list.data.AvailableSlots, }; for (var dates in list.data.bookingTimes) { $rootScope.availability.bookingTimes[dates] = []; } } if (!$rootScope.availability.bookingTimes) { $rootScope.availability.bookingTimes = {}; for (var dates in list.data.bookingTimes) { $rootScope.availability.bookingTimes[dates] = []; } } $rootScope.availability.today = list.data.today; $rootScope.availability.calView = list.data.calView; $rootScope.availability.week = 0; $rootScope.availability.month = 0; $rootScope.availability.gridMonth = $rootScope.formData.gridStartDate;//list.data.gridMonth; $rootScope.availability.startDate = list.data.startDate; $rootScope.availability.endDate = ""; $rootScope.availability.debug = list.data.debug; $rootScope.availability.success = list.data.success; $rootScope.availability.AvailableSlots = list.data.AvailableSlots; for (var d in list.data.bookingTimes) { list.data.bookingTimes[d].forEach(function(slot, index) { //$rootScope.uniqueResources = [...new Set([...$rootScope.uniqueResources ,...slot['resourceExternalIds']])]; $rootScope.uniqueResources = $scope.mergeUnique($rootScope.uniqueResources, slot['resourceExternalIds']); var found = $rootScope.getItemIndex($rootScope.availability.bookingTimes[d],'appointmentStartDate',slot['appointmentStartDate']); if (found >= 0) { //$rootScope.availability.bookingTimes[d][found]['locationExternalIds'] = [...new Set([...$rootScope.availability.bookingTimes[d][found]['locationExternalIds'] ,...[locationExternalId]])]; //$rootScope.availability.bookingTimes[d][found]['resourceExternalIds'] = [...new Set([...$rootScope.availability.bookingTimes[d][found]['resourceExternalIds'] ,...slot['resourceExternalIds']])]; $rootScope.availability.bookingTimes[d][found]['locationExternalIds'] = $scope.mergeUnique($rootScope.availability.bookingTimes[d][found]['locationExternalIds'], [locationExternalId]); $rootScope.availability.bookingTimes[d][found]['resourceExternalIds'] = $scope.mergeUnique($rootScope.availability.bookingTimes[d][found]['resourceExternalIds'], slot['resourceExternalIds']); } else { slot['locationExternalIds'] = [locationExternalId]; $rootScope.availability.bookingTimes[d].push(slot); } }); } $rootScope.formData.week = $rootScope.availability.week; $rootScope.formData.month = $rootScope.availability.month; }).catch(function(error) { console.log("Problem getting availability: "+error.statusText+"("+error.status+")"); }); } $scope.updateResources = function(auto) { $rootScope.formData['loadingAvailability'] = true; $rootScope.formData.selectedLocation = null; if ($rootScope.formData.channel == "Book a call") { if ($rootScope.formData['locationExternalId'] !== "HO1") { $scope.setLocation("HO1"); } } else if ($rootScope.formData.channel == "Mobile banker") { if ($scope.isNotMobileBankerLocation($rootScope.formData['locationExternalId'])) { $scope.setLocation($scope.mobileBankerLocation()); } } else { $rootScope.formData.locationExternalId = null; } $rootScope.resources = [];//comment out for performance test $rootScope.uniqueResources = []; if (!$rootScope.formData.resourceExternalId) { $rootScope.formData.resourceExternalId = "any"; } var calls = []; if ($rootScope.formData.channel == "All available" || $rootScope.formData.channel == "Any branch") { $rootScope.topten.forEach(function(location) { calls.push($scope.getResources(location["locationExternalId"])); //if (!$rootScope.cache.resources.includes(location["locationExternalId"]+$rootScope.formData['programExternalId']+$rootScope.formData['activityExternalId'])) { // calls.push($scope.getResources(location["locationExternalId"])); //} }); } if ($rootScope.formData.channel == "All available" || $rootScope.formData.channel == "Book a call") { if (!$rootScope.formData.hideHO1) { calls.push($scope.getResources('HO1')); //if (!$rootScope.cache.resources.includes("HO1"+$rootScope.formData['programExternalId']+$rootScope.formData['activityExternalId'])) { // calls.push($scope.getResources('HO1')); //} } } if ($rootScope.formData.channel == "All available" || $rootScope.formData.channel == "Mobile banker") { if (!$rootScope.formData.hideMB) { calls.push($scope.getResources($scope.mobileBankerLocation())); //if (!$rootScope.cache.resources.includes($scope.mobileBankerLocation()+$rootScope.formData['programExternalId']+$rootScope.formData['activityExternalId'])) { // calls.push($scope.getResources($scope.mobileBankerLocation())); //} } } $q.all(calls).then(function(all) { if ($rootScope.formData.clientTimezone == null && $rootScope.formData.state) { $rootScope.formData.clientTimezone = $rootScope.stateToTimezone[$rootScope.formData.state]; } if (!$rootScope.formData.clientTimezone) { $rootScope.formData.clientTimezone = "Australia/Melbourne"; } if (!$rootScope.formData.gridStartDate) { $rootScope.formData.gridStartDate = moment.tz((+new Date()), $rootScope.formData['clientTimezone']).format("YYYY-MM-DD"); } $scope.miniCal(); $scope.updateAvailability(auto); }); } $scope.updateAvailability = function(auto) { $rootScope.formData.slot = null; $rootScope.formData.appointmentStartDate = null; if ($rootScope.availability) { $rootScope.availability.bookingTimes = null; } var calls = []; if ($rootScope.formData.channel == "All available" || $rootScope.formData.channel == "Any branch") { $rootScope.topten.forEach(function(location) { calls.push($scope.getAvailability(location["locationExternalId"])); }); } if ($rootScope.formData.channel == "All available" || $rootScope.formData.channel == "Book a call") { if (!$rootScope.formData.hideHO1 && $rootScope.getLocation('HO1')) { calls.push($scope.getAvailability('HO1')); } } if ($rootScope.formData.channel == "All available" || $rootScope.formData.channel == "Mobile banker") { if (!$rootScope.formData.hideMB && $rootScope.getLocation($scope.mobileBankerLocation())) { calls.push($scope.getAvailability($scope.mobileBankerLocation())); } } $q.all(calls).then(function(all) { if (auto) { var isAvailability = false; if ($rootScope.availability && $rootScope.availability.bookingTimes) { for (var dates in $rootScope.availability.bookingTimes) { if ($rootScope.availability.bookingTimes[dates].length > 0) { isAvailability = true; break; } } } if (!isAvailability) { $scope.nextDate($rootScope.formData.calView); return; } } $rootScope.formData['loadingAvailability'] = false; }); } $scope.setClientTimezone = function(timezone) { $rootScope.formData.clientTimezone = timezone; document.activeElement.blur(); if ($scope.doneShowTen) { $scope.updateResources(true); } } $scope.setProgram = function(program) { if (program) { $rootScope.formData['programExternalId'] = program; $scope.getActivities(); } document.activeElement.blur(); $scope.getLocations(); } $scope.setActivity = function(activity, duration) { $rootScope.activities = $rootScope.getItemsArrayObject($rootScope.activitiesPool,{"locationExternalId":$rootScope.defaultLocationExternalId,"activityExternalId":activity}) $rootScope.formData['resourceExternalId'] = "any"; $rootScope.formData['activityExternalId'] = activity; //check activity at Mobile Banker and HO1 locations and remove channels if not found $rootScope.formData.hideHO1 = false; $rootScope.formData.hideMB = false; if ($rootScope.getItemsArrayObject($rootScope.activitiesPool,{"locationExternalId":"HO1","activityExternalId":activity}).length != 1) { $rootScope.formData.hideHO1 = true; } if ($rootScope.cts.settings.useStateMobileBankerLocations) { if ($rootScope.getItemsArrayObject($rootScope.activitiesPool,{"locationExternalId":"MB_VIC","activityExternalId":activity}).length != 1) { $rootScope.formData.hideMB = true; } } else { if ($rootScope.getItemsArrayObject($rootScope.activitiesPool,{"locationExternalId":$scope.mobileBankerLocation(),"activityExternalId":activity}).length != 1) { $rootScope.formData.hideMB = true; } } $rootScope.formData.appointmentDurationMin = parseInt(duration); document.activeElement.blur(); //$scope.getLocations(); } $scope.setQuestion = function(value, question) { if (value === "") { delete $rootScope.formData[question]; } else { $rootScope.formData[question] = value; if (question == "appointment_C_AAB_VideoCall") { $scope.setMeetingLocationAddress(); } } document.activeElement.blur(); } $scope.setMeetingLocationAddress = function() { if ($rootScope.formData['appointment_C_AAB_VideoCall'] == "1") { $rootScope.formData.appointment_C_Location_Address = "Video call details will be provided in a separate email"; } else { if ($scope.isNotMobileBankerLocation($rootScope.formData['locationExternalId']) && $rootScope.formData['locationExternalId'] !== "HO1") { var address1 = $rootScope.getLocation()['companyAddress'].address1; var city = $rootScope.getLocation()['companyAddress'].city == "(N/A)" ? "" : $rootScope.getLocation()['companyAddress'].city; var state = $rootScope.getLocation()['companyAddress'].state == "(N/A)" ? "" : $rootScope.getLocation()['companyAddress'].state; var postcode = $rootScope.getLocation()['companyAddress'].postalCode; $rootScope.formData.appointment_C_Location_Address = address1+", "+city+" "+state+" "+postcode; } else if ($rootScope.formData['locationExternalId'] == "HO1") { $rootScope.formData.appointment_C_Location_Address = $rootScope.formData.client_mobile; } else if ($scope.isMobileBankerLocation($rootScope.formData['locationExternalId'])) { $rootScope.formData.appointment_C_Location_Address = ""; } } } $scope.setLocation = function(locationExternalId) { if (locationExternalId) { $rootScope.formData['locationExternalId'] = locationExternalId; $scope.setMeetingLocationAddress(); if ($rootScope.getItemsArrayObject($rootScope.activitiesPool,{"locationExternalId":locationExternalId,"activityExternalId":$rootScope.formData['activityExternalId']}).length != 1) { $rootScope.setLoading(true); var getLocationActivities = $scope.getActivities({"locationExternalId":locationExternalId}); $q.all([getLocationActivities]).then(function(all){ $rootScope.activities = all[0]; $rootScope.activitiesPool = [].concat($rootScope.activitiesPool,all[0]); $timeout(function(){ $anchorScroll('anchor'); }); $rootScope.setLoading(false); }); } else { $rootScope.activities = $rootScope.getItemsArrayObject($rootScope.activitiesPool,{"locationExternalId":locationExternalId}); $timeout(function(){ $anchorScroll('anchor'); }); } } else { $rootScope.formData.selectedLocation = null; } $rootScope.formData.selectLocation = false; } $scope.setChannel = function(channel) { if (channel) { $rootScope.formData['channel'] = channel; $rootScope.formData.selectChannel = false; $rootScope.formData.resourceFilter = ""; $rootScope.formData['resourceExternalId'] = "any"; document.activeElement.blur(); if ($scope.doneShowTen) { $scope.updateResources(true); } } else { $rootScope.formData.selectChannel = !$rootScope.formData.selectChannel; } } $scope.setResource = function(resourceExternalId) { if (resourceExternalId) { $rootScope.formData['resourceExternalId'] = resourceExternalId; $rootScope.formData.resourceFilter = $rootScope.getResource(resourceExternalId)['resourceName']; document.activeElement.blur(); $scope.updateResources(); } else { if ($rootScope.formData['resourceExternalId'] != "any") { $rootScope.formData['resourceExternalId'] = "any"; $scope.updateResources(); } } } $scope.setAppointment = function() { if ($rootScope.formData.appointmentStartDate) { var slot = $rootScope.getItemsArrayObject($rootScope.availability.bookingTimes[$rootScope.formData.appointmentStartDate.substring(0,10)],{'appointmentStartDate':$rootScope.formData.appointmentStartDate}); $rootScope.formData.appointmentStartDate = slot[0]['appointmentStartDate']; $rootScope.formData.appointmentEndDate = slot[0]['appointmentEndDate']; $rootScope.formData.slot = slot[0]; } else { $rootScope.formData.appointmentStartDate = null; $rootScope.formData.appointmentEndDate = null; $rootScope.formData.slot = null; } } $scope.isMorning = function(value, index, array) { var hour = parseInt(value.appointmentStartDate.substring(11,13)); if (hour < 12) { return true; } else { return false; } } $scope.isAfternoon = function(value, index, array) { var hour = parseInt(value.appointmentStartDate.substring(11,13)); if (hour < 12) { return false; } else if (hour < 18) { return true; } else { return false; } } $scope.isEvening = function(value, index, array) { var hour = parseInt(value.appointmentStartDate.substring(11,13)); if (hour < 18) { return false; } else { return true; } } $scope.nextDate = function(calView) { $rootScope.getAvailabilityAttempts = 9; $rootScope.formData[calView] = 1; $scope.updateResources(); } $scope.prevDate = function(calView) { if (moment($rootScope.availability.today).isBefore($rootScope.availability.startDate)) { $rootScope.getAvailabilityAttempts = 9; $rootScope.formData[calView] = 0; $rootScope.availability.startDate = moment($rootScope.availability.startDate).subtract(1, "weeks").format('YYYY-MM-DD'); $scope.updateResources(); } else { //console.log("can't show past availability"); } } $scope.setFormattedAddress = function(Latitude, Longitude) { $rootScope.formData.latitude = Latitude; $rootScope.formData.longitude = Longitude; $scope.doneFormattedAddress = true; if ($rootScope.mapProvider === "google") { var geoLatLng = new google.maps.LatLng(Latitude, Longitude); $scope.geocoder.geocode({ 'location': geoLatLng }, function (results, status) { if (status === google.maps.GeocoderStatus.OK) { result = false; locs = results.length; for (l=0;l<locs;l++) { types = results[l]["types"].length; for (t=0;t<types;t++) { if (results[l]["types"][t] == "locality" | results[l]["types"][t] == "sublocality") { $scope.input.value = results[l]["formatted_address"]; $scope.input.text = results[l]["formatted_address"]; result = true; l=locs; break; } } } if (!result) { $rootScope.debug('No suburb found, trying first location returned.'); $scope.input.value = results[0]["formatted_address"]; $scope.input.text = results[0]["formatted_address"]; } } else { $rootScope.debug('Geocoder failed due to: ' + status); } }); } else if ($rootScope.mapProvider === "mapbox") { delete $scope.geocoder.options.proximity; $scope.geocoder.options.reverseGeocode = true; $scope.geocoder.options.types = "locality, neighborhood, district, region"; $scope.geocoder.query($rootScope.formData.latitude+", "+$rootScope.formData.longitude); $scope.geocoder.options.reverseGeocode = false; $scope.geocoder.options.types = $rootScope.cts.settings["mapResultTypes"] || "locality, neighborhood, district, postcode"; } } $scope.showTen = function(Latitude, Longitude) { $rootScope.formData.latitude = Latitude; $rootScope.formData.longitude = Longitude; $scope.doneShowTen = true; $scope.getClosest(Latitude,Longitude); } $scope.getClosest = function(Latitude, Longitude) { var totalGeoLocations = 0; var m; for (var index in $rootScope.locations) { if ($rootScope.locations[index]['geocoordinates']) { m = $rootScope.calDistance(Longitude,Latitude,$rootScope.locations[index]['geocoordinates']['longitude'],$rootScope.locations[index]['geocoordinates']['latitude']); $rootScope.locations[index]['distance'] = +(Math.round(m + "e+2") + "e-2"); totalGeoLocations++; } } $rootScope.showLocationAmount = totalGeoLocations < 10 ? totalGeoLocations : 10; $rootScope.locations.sort(function (a, b) { return a.distance < b.distance ? -1 : a.distance > b.distance ; }); $rootScope.topten = []; if ($rootScope.showLocationAmount > 0) { var locationCount = $rootScope.locations.length >= 10 ? 10 : $rootScope.locations.length; for (var i=0;i<locationCount;i++) { if ($rootScope.locations[i]['distance'] <= 20000) { if (!$rootScope.formData.clientTimezone) { if ($rootScope.timezones.indexOf($rootScope.locations[i]['timezone']) >= 0) { $rootScope.formData.clientTimezone = $rootScope.locations[i]['timezone']; } } $rootScope.topten.push($rootScope.locations[i]); } } } else { alert("No locations found"); } $rootScope.availability.startDate = ""; $scope.updateResources(true); } $scope.updateAppointment = function() { call = { "method":"updateAppointment", //"service":"AppointmentServices", "request": { "appointment": { "confirmationNumber": $rootScope.formData['confirmationNumber'], "appShortName": "cts", "workFlowId": $rootScope.formData["workflowExternalId"] ? $rootScope.formData["workflowExternalId"] : $rootScope.prefill['wf'], "custom7": $rootScope.formData["custom7"], "custom9": $rootScope.formData["custom9"], "comments": $rootScope.formData["comments"] } }, "response": { "status":".//return/result" }, "sid": $rootScope.cts.sid }; $http.post('api.php', call).then(function(all) { $location.path( 'confirmation' ); }).catch(function(error) { console.log("Problem updating appointment: "+error.statusText+"("+error.status+")"); }); } $scope.appendAppointmentAnswers = function() { questionAnswerList = []; for (var key in $rootScope.formData) { if (!$rootScope.formData.hasOwnProperty(key)) continue; if (key.lastIndexOf("appointment_", 0) === 0) { questionAnswerList.push({ questionExternalId: key.replace("appointment_", ""), answer: $rootScope.formData[key] }); } } if (questionAnswerList.length > 0) { call = { "method":"appendAppointmentAnswers", //"service":"AppointmentServices", "request": { "confirmationNumber": $rootScope.formData['confirmationNumber'], "questionAnswerList": questionAnswerList }, "response": { "status":".//return/result" }, "sid": $rootScope.cts.sid }; return $http.post('api.php', call).then(function(all) { return all; }).catch(function(error) { console.log("Problem appending answers: "+error.statusText+"("+error.status+")"); }); } else { var deferred = $q.defer(); deferred.resolve({ "data": { "error": false } }); return deferred.promise; } } $scope.bookAppointment = function(plusone) { var clientId = $rootScope.formData['clientExternalId']; if (!clientId) { $rootScope.debug("No clientExternalId for "+$rootScope.formData['client_firstName'] ); var deferred = $q.defer(); deferred.resolve({ "error": "No clientExternalId for "+$rootScope.formData['client_firstName'] }); return deferred.promise; } if ($rootScope.formData.confirmationNumber) { $rootScope.formData.error = ''; var deferred = $q.defer(); deferred.resolve({ "error": false, "data": { "response": { "confirmationNumber": [ [ $rootScope.formData.confirmationNumber ] ] } } }); return deferred.promise; } else { var criteria = {}; if ($rootScope.formData['campaignExternalId']) { criteria["campaignExternalId"] = $rootScope.formData['campaignExternalId']; } if ($rootScope.formData['locationExternalId']) { criteria["locationExternalId"] = $rootScope.formData['locationExternalId']; } if ($rootScope.formData['programExternalId']) { criteria["programExternalId"] = $rootScope.formData['programExternalId'] ? $rootScope.formData['programExternalId'] : $rootScope.cts.settings["defaultProgramExternalId"]; } if ($rootScope.formData['activityExternalId']) { criteria["activityExternalId"] = $rootScope.formData['activityExternalId']; } if ($rootScope.formData['resourceExternalId']) { criteria["resourceExternalId"] = $rootScope.formData['resourceExternalId']; } if ($scope.isMobileBankerLocation($rootScope.formData['locationExternalId']) && $rootScope.formData.postcode) { criteria["characteristics"] = []; criteria["characteristics"].push({"key":"postcode","value":$rootScope.formData.postcode}); } criteria["clientTimezone"] = $rootScope.formData["clientTimezone"]; return $http.post('api.php', { "method":"bookAppointment", //"service":"AppointmentServices", "request": { "criteria": criteria, "startDateTime": moment.tz($rootScope.formData['appointmentStartDate'],$rootScope.formData["clientTimezone"]).format("YYYY-MM-DDTHH:mm:ss.000Z"), "clientExternalId": clientId }, "response": { "confirmationNumber":".//return/result" }, "sid": $rootScope.cts.sid }).then(function(all) { return all; }).catch(function(error) { console.log("Problem booking appointment: "+error.statusText+"("+error.status+")"); }); } } $scope.updateClient = function() { data = { setClient: "x", client_firstName: $rootScope.formData['client_firstName'], client_lastName: $rootScope.formData['client_lastName'], client_email: $rootScope.formData['client_email'], client_mobile: $rootScope.formData['client_mobile'], client_username: $rootScope.formData['client_username'], client_memberId: $rootScope.formData['client_memberId'], client_answer0: $rootScope.formData['client_answer0'], client_answer1: $rootScope.formData['client_answer1'], client_answer2: $rootScope.formData['client_answer2'], client_answer3: $rootScope.formData['client_answer3'], client_answer4: $rootScope.formData['client_answer4'], client_answer5: $rootScope.formData['client_answer5'], client_answer6: $rootScope.formData['client_answer6'], client_answer7: $rootScope.formData['client_answer7'], client_answer8: $rootScope.formData['client_answer8'], client_answer9: $rootScope.formData['client_answer9'], client_company: $rootScope.formData['client_company'], timezone: $rootScope.formData["clientTimezone"], clientExternalId: $rootScope.formData['clientExternalId'], clientLocale: $rootScope.formData['clientLocale'], clientLocaleDisplayName: $rootScope.formData['clientLocaleDisplayName'], sid: $rootScope.cts.sid }; return $http.post('session.php', data).then(function(result) { if (result.data.success) { $rootScope.formData['clientExternalId'] = result.data.response["clientExternalId"][0][0]; } else { $rootScope.formData['clientExternalId'] = false; } }).catch(function(error) { console.log("Problem updating client: "+error.statusText+"("+error.status+")"); }); } $scope.getConfirmationNumber = function() { $rootScope.formData.processingBooking = true; if ($scope.isComplete(true)) { $rootScope.formData.error = ''; var clients = []; clients.push($scope.updateClient()); $q.all(clients).then(function(all) { var books = []; books.push($scope.bookAppointment(false)); $q.all(books).then(function(all) { $rootScope.showErrorButton('booking'); if (all[0].data.error) { $rootScope.formData.processingBooking = false; if (all[0].data.error == "appointment slot unavailable ( HTTP/1.1 500 )") { $rootScope.formData.error = "The appointment time you selected is no longer available or you may already have an appointment for that time. Please press the 'Return to Calendar' button to choose another time."; $scope.updateResources(); } else { $rootScope.formData.error = "Sorry we were unable to complete your request: "+all[0].data.error; } } if (all[0].data.error) { $rootScope.formData.processingBooking = false; return; } $rootScope.formData['confirmationNumber'] = all[0].data.response['confirmationNumber'][0][0]; $rootScope.status = "Scheduled"; var confirms = []; confirms.push($scope.appendAppointmentAnswers()); $q.all(confirms).then(function(all) { if (all[0].data.error) { $rootScope.formData.processingBooking = false; $rootScope.formData.error = "Unable to update appointment answers: "+all[0].data.error; return; }; $scope.updateAppointment() }); }); }); } else { $rootScope.formData.processingBooking = false; alert("Please correct highlighted fields."); } } $scope.inArrayValue = function(array, value) { return array.indexOf(value) != -1; } $scope.initialize = function () { $rootScope.formData.week = 0; $rootScope.formData.month = 0; if (!$rootScope.mapProviderLoaded) { if ($rootScope.mapProvider == "mapbox") { mapboxgl.accessToken = 'pk.eyJ1IjoiY29kZXplbm8iLCJhIjoiY2psbGc2OTQ1MHg3MjNrbXhiZ2t0ZnNoayJ9.avG54bFOIF8eV3hyqbvZXw'; if (moment.locale().split("-")[0] != "en") { $scope.map.addControl(new MapboxLanguage({ defaultLanguage: moment.locale().split("-")[0] })); } $scope.geocoder = new MapboxGeocoder({ accessToken: mapboxgl.accessToken, flyTo: false, marker: false, enableEventLogging: false, trackProximity: false, countries: "au", types: $rootScope.cts.settings["mapResultTypes"] || "locality, neighborhood, district, postcode", language: moment.locale(), limit: 5, placeholder: "Search location" }); $scope.geocoder.on('result', function(position) { $rootScope.formData.resourceFilter = ""; $rootScope.formData['resourceExternalId'] = "any"; $scope.geocoder.setPlaceholder(position.result.place_name); var postcodeData = $filter('filter')(position.result.context,{id: "postcode."}); var stateData = $filter('filter')(position.result.context,{id: "region."}); var longitude = position.result.center[0]; var latitude = position.result.center[1]; var needPostcode = false; var setPostcode; if (postcodeData && postcodeData[0]) { $rootScope.formData.postcode = postcodeData[0].text; } else if (position.result.place_type && position.result.place_type[0] && position.result.place_type[0] == "postcode") { $rootScope.formData.postcode = position.result.text; } else if (stateData && stateData[0]) { needPostcode = true; setPostcode = $scope.setPostcode(stateData[0].short_code.substr(3),longitude,latitude); } else if (position.result.place_type && position.result.place_type[0] && position.result.place_type[0] == "region") { needPostcode = true; setPostcode = $scope.setPostcode(position.result.properties.short_code.substr(3),longitude,latitude); } if (stateData && stateData[0]) { $rootScope.formData.state = stateData[0].short_code.substr(3); } else if (position.result.place_type && position.result.place_type[0] && position.result.place_type[0] == "region") { $rootScope.formData.state = position.result.properties.short_code.substr(3); } else { $rootScope.formData.state = null; } //console.log("Update Timezone with suburb change."); $rootScope.formData.clientTimezone = null; if (needPostcode) { $q.all([setPostcode]).then(function(all){ $scope.showTen(position.result.center[1], position.result.center[0]); document.activeElement.blur(); }); } else { $scope.showTen(position.result.center[1], position.result.center[0]); document.activeElement.blur(); $scope.$apply(); } }); document.getElementById('geocoder').appendChild($scope.geocoder.onAdd($scope.map)); var geocoderInput = angular.element(document.getElementById('geocoder').getElementsByTagName('input')[0]); geocoderInput.bind('focus', function() { if ($scope.geocoder.placeholder == this.value) { $scope.geocoder.query(this.value);//#0241.7. } }); if ($scope.geocoder.options.language.substring(0, 2) == "en") { delete $scope.geocoder.options.language; } $rootScope.mapProviderLoaded = true; } else if ($rootScope.mapProvider == "google") { $scope.mapOptions = {center: new google.maps.LatLng($rootScope.defaultLatitude, $rootScope.defaultLongitude),zoom:6}; $scope.map = new google.maps.Map(document.getElementById('map-canvas'), $scope.mapOptions); $scope.input = (document.getElementById('loc-input')); $scope.autocomplete = new google.maps.places.Autocomplete($scope.input, {fields: ["geometry.location"],componentRestrictions: {country: "au"}}); $scope.autocomplete.bindTo('bounds', $scope.map); $scope.geocoder = new google.maps.Geocoder(); google.maps.event.addListener($scope.autocomplete, 'place_changed', function() { var place = $scope.autocomplete.getPlace(); if (!place.geometry) { return; } else { $scope.showTen(place.geometry.location.lat(),place.geometry.location.lng()); $scope.$apply(); } }); google.maps.event.addDomListener($scope.input, 'keydown', function(e) { var code = (e.keyCode ? e.keyCode : e.which); if(code===13 && !e.triggered){ if (document.querySelector('.pac-item-selected') == null) { google.maps.event.trigger(this,'keydown',{keyCode:40}); } google.maps.event.trigger(this,'keydown',{keyCode:13,triggered:true}); } }); google.maps.event.addDomListener($scope.input, 'focus', function() { var self = this;setTimeout(function() {self.setSelectionRange(0, 9999);}, 0); }); $rootScope.mapProviderLoaded = true; } } else { $scope.setChannel('All available'); } } if (!$rootScope.mapProviderLoaded) { var mapProviderScript = document.createElement('script'); mapProviderScript.onload = function () { $rootScope.ready = true; }; if ($rootScope.mapProvider == "mapbox") { mapProviderScript.src = "https://api.mapbox.com/mapbox-gl-js/v1.4.1/mapbox-gl.js"; var mapProviderStyle = document.createElement('link'); mapProviderStyle.href = "https://api.mapbox.com/mapbox-gl-js/v1.4.1/mapbox-gl.css"; mapProviderStyle.rel = "stylesheet"; document.head.appendChild(mapProviderStyle); var mapProviderGeocoder = document.createElement('script'); mapProviderGeocoder.src = "https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v4.4.2/mapbox-gl-geocoder.min.js"; document.head.appendChild(mapProviderGeocoder); } else if ($rootScope.mapProvider == "google") { mapProviderScript.src = "https://maps.googleapis.com/maps/api/js?v=3.exp&key="+$rootScope.googleMapsApiKey+"&language="+moment.locale().split("-")[0]+"®ion="+moment.locale().split("-")[1]+"&libraries=places,geometry"; } document.head.appendChild(mapProviderScript); } $scope.setPostcode = function(state,Longitude,Latitude) { data = { getPostcodeData: "get", state: state, sid: $rootScope.cts.sid }; return $http.post('session.php', data).then(function(all) { for (var place in all.data) { var m = $rootScope.calDistance(Longitude,Latitude,all.data[place].Longitude,all.data[place].Latitude); all.data[place]['Distance'] = +(Math.round(m + "e+2") + "e-2"); } //for (var place of all.data) { // var m = $rootScope.calDistance(Longitude,Latitude,place.Longitude,place.Latitude); // place['Distance'] = +(Math.round(m + "e+2") + "e-2"); //} all.data.sort(function(a, b) {return a.Distance - b.Distance}); $rootScope.formData.postcode = all.data[0].Postcode; }).catch(function(error) { console.log("Problem getting postcode data: "+error.statusText+"("+error.status+")"); }); } var getPrograms = $scope.getPrograms(); var getActivities = $scope.getActivities(); var getHO1Activities = $scope.getActivities({"locationExternalId":"HO1"}); if ($rootScope.cts.settings.useStateMobileBankerLocations) { var getMBActivities = $scope.getActivities({"locationExternalId":"MB_VIC"}); } else { var getMBActivities = $scope.getActivities({"locationExternalId":"MB1"}); } var getQuestions = $scope.getQuestions(); $q.all([getPrograms, getQuestions, getActivities, getHO1Activities, getMBActivities]).then(function(all){ $rootScope.activities = all[2]; if ($rootScope.cts.settings.useStateMobileBankerLocations) { var NSW = all[4].map(function(act){ var twin = JSON.parse(JSON.stringify(act)); twin.locationExternalId = "MB_NSW"; return twin; }); var VIC = all[4].map(function(act){ var twin = JSON.parse(JSON.stringify(act)); twin.locationExternalId = "MB_VIC"; return twin; }); var QLD = all[4].map(function(act){ var twin = JSON.parse(JSON.stringify(act)); twin.locationExternalId = "MB_QLD"; return twin; }); var ACT = all[4].map(function(act){ var twin = JSON.parse(JSON.stringify(act)); twin.locationExternalId = "MB_ACT"; return twin; }); var TAS = all[4].map(function(act){ var twin = JSON.parse(JSON.stringify(act)); twin.locationExternalId = "MB_TAS"; return twin; }); var NT = all[4].map(function(act){ var twin = JSON.parse(JSON.stringify(act)); twin.locationExternalId = "MB_NT"; return twin; }); var SA = all[4].map(function(act){ var twin = JSON.parse(JSON.stringify(act)); twin.locationExternalId = "MB_SA"; return twin; }); var WA = all[4].map(function(act){ var twin = JSON.parse(JSON.stringify(act)); twin.locationExternalId = "MB_WA"; return twin; }); $rootScope.activitiesPool = [].concat(all[2],all[3],NSW,VIC,QLD,ACT,TAS,NT,SA,WA); } else { $rootScope.activitiesPool = [].concat(all[2],all[3],all[4]); } if ($rootScope.formData.programExternalId) { $scope.getLocations(); } $rootScope.setLoading(false); }); }function cancelController($rootScope, $scope, $http, $location, $filter, $q) { $rootScope.setLoading(true); $scope.getResources = function(locationExternalId) { var criteria = {}; criteria["locationExternalId"] = locationExternalId; if ($rootScope.formData['activityExternalId']) { criteria["activityExternalId"] = $rootScope.formData['activityExternalId']; } if ($rootScope.formData['programExternalId']) { criteria["programExternalId"] = $rootScope.formData['programExternalId']; } getResourcesByCriteria = { "method":"getResourcesByCriteria", //"service":"ConfigurationServices", "request": { "resourceSearchCriteria":criteria }, "response": { "resources":".//return/*[local-name() = 'resources']" }, "sid": $rootScope.cts.sid }; return $http.post('api.php', getResourcesByCriteria).then(function(all) { if (all && all.data && all.data.response && all.data.response.resources) { $rootScope.resources = all.data.response.resources; } }).catch(function(error) { console.log("Problem getting resources: "+error.statusText+"("+error.status+")"); }); } $scope.getActivities = function(criteria) { criteria = criteria || {}; var campaignExternalId = $rootScope.formData['campaignExternalId'] ? $rootScope.formData['campaignExternalId'] : false; var locationExternalId = ($rootScope.formData['locationExternalId'] || $rootScope.defaultLocationExternalId) ? $rootScope.formData['locationExternalId'] || $rootScope.defaultLocationExternalId : false; var programExternalId = $rootScope.formData['programExternalId'] ? $rootScope.formData['programExternalId'] : false; if (!criteria["campaignExternalId"] && campaignExternalId) { criteria["campaignExternalId"] = campaignExternalId; } if (!criteria["locationExternalId"] && locationExternalId) { criteria["locationExternalId"] = locationExternalId; } if (!criteria["programExternalId"] && programExternalId) { criteria["programExternalId"] = programExternalId; } data = { "method":"getActivities", //"service":"ConfigurationServices", "request": criteria, "response": { "activities":".//return/activities[deleted='false'][isEnabled='true'][not(suppressVisibilityPerApp/appName='"+$rootScope.cts.appName+"')]" }, "sid": $rootScope.cts.sid }; return $http.post('api.php', data).then(function(all) { if (all && all.data && all.data.response && all.data.response.activities) { $rootScope.activities = all.data.response.activities; } }).catch(function(error) { console.log("Problem getting activities: "+error.statusText+"("+error.status+")"); }); } $scope.getSingleAppointment = function() { call = { "method":"getAppointmentByConfirmationNumber", //"service":"AppointmentServices", "request": { "confirmationNumber": $rootScope.formData['confirmationNumber'] }, "response": { "appointment":`.//return/appointment[clientLastname="${$rootScope.formData.client_lastName}"]` }, "sid": $rootScope.cts.sid }; $http.post('api.php', call).then(function(all) { if (all.data.error || all.error || all.data.response.length < 1) { $rootScope.error = "No appointment exist with the details provided or it has been cancelled."; $rootScope.ready = true; $rootScope.showErrorButton('none'); $location.path( 'error' ); return; } $rootScope.formData['campaignExternalId'] = all.data.response.appointment[0]['campaignExternalId']; $rootScope.formData['locationExternalId'] = all.data.response.appointment[0]['locationExternalId']; $rootScope.formData['programExternalId'] = all.data.response.appointment[0]['programExternalId']; $rootScope.formData['activityExternalId'] = all.data.response.appointment[0]['activityExternalId']; $rootScope.formData['resourceExternalId'] = all.data.response.appointment[0]['resourceExternalId']; $rootScope.formData.appointmentStartDate = all.data.response.appointment[0]['appointmentStartDate']; $rootScope.formData.appointmentEndDate = all.data.response.appointment[0]['appointmentEndDate']; $rootScope.formData.appointmentDurationMin = all.data.response.appointment[0]['appointmentDurationMin']; $rootScope.formData.client_firstName = all.data.response.appointment[0]['clientFirstname']; $rootScope.formData.client_lastName = all.data.response.appointment[0]['clientLastname']; $rootScope.formData.clientTimezone = all.data.response.appointment[0]['clientTimezone']; $rootScope.status = all.data.response.appointment[0]['lifeCycleState']; $rootScope.formData['custom0'] = all.data.response.appointment[0]['custom0']; $rootScope.formData['custom1'] = all.data.response.appointment[0]['custom1']; $rootScope.formData['custom2'] = all.data.response.appointment[0]['custom2']; $rootScope.formData['custom3'] = all.data.response.appointment[0]['custom3']; $rootScope.formData['custom4'] = all.data.response.appointment[0]['custom4']; $rootScope.formData['custom5'] = all.data.response.appointment[0]['custom5']; $rootScope.formData['custom6'] = all.data.response.appointment[0]['custom6']; $rootScope.formData['custom7'] = all.data.response.appointment[0]['custom7']; $rootScope.formData['custom8'] = all.data.response.appointment[0]['custom8']; $rootScope.formData['custom9'] = all.data.response.appointment[0]['custom9']; var getLocationActivities = $scope.getActivities({"locationExternalId":$rootScope.formData['locationExternalId']}); var getLocationResources = $scope.getResources($rootScope.formData['locationExternalId']); $q.all([getLocationActivities,getLocationResources]).then(function(all){ $scope.cancel(); }); }).catch(function(error) { console.log("Problem getting appointment: "+error.statusText+"("+error.status+")"); }); } $scope.cancel = function() { call = { "method":"cancelAppointment", //"service":"AppointmentServices", "request": { "confirmationNumber": $rootScope.formData['confirmationNumber'] }, "response": { "status":".//return/status" }, "sid": $rootScope.cts.sid }; $http.post('api.php', call).then(function(all) { if (all && all.data && all.data.error) { $rootScope.debug(all.data.error); $rootScope.error = "The deadline for cancelling has passed please call for assistance."; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); return; } else { $rootScope.status = "Cancelled"; $rootScope.setLoading(false); $rootScope.ready = false;//Completed the cancel process, using the browser back button will cause a hard reload of the app. } }).catch(function(error) { console.log("Problem cancelling appointment: "+error.statusText+"("+error.status+")"); }); } /* $scope.getAppointmentByConfirmationNumber = function() { call = { "method":"getAppointmentByConfirmationNumber", //"service":"AppointmentServices", "request": { "confirmationNumber": $rootScope.formData['confirmationNumber'] }, "response": { "appointment":".//return/appointment" }, "sid": $rootScope.cts.sid }; $http.post('api.php', call).then(function(all) { if (all && all.data && all.data.error) { $rootScope.debug(all.data.error); return; } $rootScope.formData['locationExternalId'] = all.data.response.appointment[0]['locationExternalId']; $rootScope.formData.appointmentStartDate = all.data.response.appointment[0]['appointmentStartDate']; $rootScope.formData.appointmentEndDate = all.data.response.appointment[0]['appointmentEndDate']; $rootScope.activities = Array(); $rootScope.activities[0] = Array(); $rootScope.activities[0]['activityName'] = all.data.response.appointment[0]['activityName']; $rootScope.activities[0]['durationInMinutes'] = all.data.response.appointment[0]['appointmentDurationMin']; $rootScope.activities[0]['activityExternalId'] = all.data.response.appointment[0]['activityExternalId']; $rootScope.formData['activityExternalId'] = all.data.response.appointment[0]['activityExternalId']; $rootScope.status = all.data.response.appointment[0]['lifeCycleState']; $rootScope.formData['programExternalId'] = all.data.response.appointment[0]['programExternalId']; $rootScope.formData['custom0'] = all.data.response.appointment[0]['custom0']; $rootScope.formData['custom1'] = all.data.response.appointment[0]['custom1']; $rootScope.formData['custom2'] = all.data.response.appointment[0]['custom2']; $rootScope.formData['custom3'] = all.data.response.appointment[0]['custom3']; $rootScope.formData['custom4'] = all.data.response.appointment[0]['custom4']; $rootScope.formData['custom5'] = all.data.response.appointment[0]['custom5']; $rootScope.formData['custom6'] = all.data.response.appointment[0]['custom6']; $rootScope.formData['custom7'] = all.data.response.appointment[0]['custom7']; $rootScope.formData['custom8'] = all.data.response.appointment[0]['custom8']; $rootScope.formData['custom9'] = all.data.response.appointment[0]['custom9']; $rootScope.formData['clientTimezone'] = all.data.response.appointment[0]['clientTimezone']; $scope.cancel(); }).catch(function(error) { console.log("Problem getting appointment: "+error.statusText+"("+error.status+")"); }); } */ $scope.getSingleAppointment(); }function cancelledController($rootScope, $scope, $http, $location, $filter, $q) { $rootScope.setLoading(true); $scope.getResources = function(locationExternalId) { var criteria = {}; criteria["locationExternalId"] = locationExternalId; if ($rootScope.formData['activityExternalId']) { criteria["activityExternalId"] = $rootScope.formData['activityExternalId']; } if ($rootScope.formData['programExternalId']) { criteria["programExternalId"] = $rootScope.formData['programExternalId']; } getResourcesByCriteria = { "method":"getResourcesByCriteria", //"service":"ConfigurationServices", "request": { "resourceSearchCriteria":criteria }, "response": { "resources":".//return/*[local-name() = 'resources']" }, "sid": $rootScope.cts.sid }; return $http.post('api.php', getResourcesByCriteria).then(function(all) { if (all && all.data && all.data.response && all.data.response.resources) { $rootScope.resources = all.data.response.resources; } }).catch(function(error) { console.log("Problem getting resources: "+error.statusText+"("+error.status+")"); }); } $scope.getActivities = function(criteria) { criteria = criteria || {}; var campaignExternalId = $rootScope.formData['campaignExternalId'] ? $rootScope.formData['campaignExternalId'] : false; var locationExternalId = ($rootScope.formData['locationExternalId'] || $rootScope.defaultLocationExternalId) ? $rootScope.formData['locationExternalId'] || $rootScope.defaultLocationExternalId : false; var programExternalId = $rootScope.formData['programExternalId'] ? $rootScope.formData['programExternalId'] : false; if (!criteria["campaignExternalId"] && campaignExternalId) { criteria["campaignExternalId"] = campaignExternalId; } if (!criteria["locationExternalId"] && locationExternalId) { criteria["locationExternalId"] = locationExternalId; } if (!criteria["programExternalId"] && programExternalId) { criteria["programExternalId"] = programExternalId; } data = { "method":"getActivities", //"service":"ConfigurationServices", "request": criteria, "response": { "activities":".//return/activities[deleted='false'][isEnabled='true'][not(suppressVisibilityPerApp/appName='"+$rootScope.cts.appName+"')]" }, "sid": $rootScope.cts.sid }; return $http.post('api.php', data).then(function(all) { if (all && all.data && all.data.response && all.data.response.activities) { $rootScope.activities = all.data.response.activities; } }).catch(function(error) { console.log("Problem getting activities: "+error.statusText+"("+error.status+")"); }); } $scope.getSingleAppointment = function() { call = { "method":"getAppointmentByConfirmationNumber", //"service":"AppointmentServices", "request": { "confirmationNumber": $rootScope.formData['confirmationNumber'] }, "response": { "appointment":'.//return/appointment' }, "sid": $rootScope.cts.sid }; $http.post('api.php', call).then(function(all) { if (all.data.error || all.error || all.data.response.length < 1) { $rootScope.error = "No appointment exist with the details provided or it has been cancelled."; $rootScope.ready = true; $rootScope.showErrorButton('none'); $location.path( 'error' ); return; } $rootScope.formData['campaignExternalId'] = all.data.response.appointment[0]['campaignExternalId']; $rootScope.formData['locationExternalId'] = all.data.response.appointment[0]['locationExternalId']; $rootScope.formData['programExternalId'] = all.data.response.appointment[0]['programExternalId']; $rootScope.formData['activityExternalId'] = all.data.response.appointment[0]['activityExternalId']; $rootScope.formData['resourceExternalId'] = all.data.response.appointment[0]['resourceExternalId']; $rootScope.formData.appointmentStartDate = all.data.response.appointment[0]['appointmentStartDate']; $rootScope.formData.appointmentEndDate = all.data.response.appointment[0]['appointmentEndDate']; $rootScope.formData.appointmentDurationMin = all.data.response.appointment[0]['appointmentDurationMin']; $rootScope.formData.client_firstName = all.data.response.appointment[0]['clientFirstname']; $rootScope.formData.client_lastName = all.data.response.appointment[0]['clientLastname']; $rootScope.formData.clientTimezone = all.data.response.appointment[0]['clientTimezone']; $rootScope.status = all.data.response.appointment[0]['lifeCycleState']; $rootScope.formData['custom0'] = all.data.response.appointment[0]['custom0']; $rootScope.formData['custom1'] = all.data.response.appointment[0]['custom1']; $rootScope.formData['custom2'] = all.data.response.appointment[0]['custom2']; $rootScope.formData['custom3'] = all.data.response.appointment[0]['custom3']; $rootScope.formData['custom4'] = all.data.response.appointment[0]['custom4']; $rootScope.formData['custom5'] = all.data.response.appointment[0]['custom5']; $rootScope.formData['custom6'] = all.data.response.appointment[0]['custom6']; $rootScope.formData['custom7'] = all.data.response.appointment[0]['custom7']; $rootScope.formData['custom8'] = all.data.response.appointment[0]['custom8']; $rootScope.formData['custom9'] = all.data.response.appointment[0]['custom9']; var getLocationActivities = $scope.getActivities({"locationExternalId":$rootScope.formData['locationExternalId']}); var getLocationResources = $scope.getResources($rootScope.formData['locationExternalId']); $q.all([getLocationActivities,getLocationResources]).then(function(all){ $scope.cancel(); }); }).catch(function(error) { console.log("Problem getting appointment: "+error.statusText+"("+error.status+")"); }); } $scope.cancel = function() { call = { "method":"cancelAppointment", //"service":"AppointmentServices", "request": { "confirmationNumber": $rootScope.formData['confirmationNumber'] }, "response": { "status":".//return/status" }, "sid": $rootScope.cts.sid }; $http.post('api.php', call).then(function(all) { if (all && all.data && all.data.error) { $rootScope.debug(all.data.error); $rootScope.error = "The deadline for cancelling has passed please call for assistance."; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); return; } else { $rootScope.status = "Cancelled"; $rootScope.setLoading(false); $rootScope.ready = false;//Completed the cancel process, using the browser back button will cause a hard reload of the app. } }).catch(function(error) { console.log("Problem cancelling appointment: "+error.statusText+"("+error.status+")"); }); } /* $scope.getAppointmentByConfirmationNumber = function() { call = { "method":"getAppointmentByConfirmationNumber", //"service":"AppointmentServices", "request": { "confirmationNumber": $rootScope.formData['confirmationNumber'] }, "response": { "appointment":".//return/appointment" }, "sid": $rootScope.cts.sid }; $http.post('api.php', call).then(function(all) { if (all && all.data && all.data.error) { $rootScope.debug(all.data.error); return; } $rootScope.formData['locationExternalId'] = all.data.response.appointment[0]['locationExternalId']; $rootScope.formData.appointmentStartDate = all.data.response.appointment[0]['appointmentStartDate']; $rootScope.formData.appointmentEndDate = all.data.response.appointment[0]['appointmentEndDate']; $rootScope.activities = Array(); $rootScope.activities[0] = Array(); $rootScope.activities[0]['activityName'] = all.data.response.appointment[0]['activityName']; $rootScope.activities[0]['durationInMinutes'] = all.data.response.appointment[0]['appointmentDurationMin']; $rootScope.activities[0]['activityExternalId'] = all.data.response.appointment[0]['activityExternalId']; $rootScope.formData['activityExternalId'] = all.data.response.appointment[0]['activityExternalId']; $rootScope.status = all.data.response.appointment[0]['lifeCycleState']; $rootScope.formData['programExternalId'] = all.data.response.appointment[0]['programExternalId']; $rootScope.formData['custom0'] = all.data.response.appointment[0]['custom0']; $rootScope.formData['custom1'] = all.data.response.appointment[0]['custom1']; $rootScope.formData['custom2'] = all.data.response.appointment[0]['custom2']; $rootScope.formData['custom3'] = all.data.response.appointment[0]['custom3']; $rootScope.formData['custom4'] = all.data.response.appointment[0]['custom4']; $rootScope.formData['custom5'] = all.data.response.appointment[0]['custom5']; $rootScope.formData['custom6'] = all.data.response.appointment[0]['custom6']; $rootScope.formData['custom7'] = all.data.response.appointment[0]['custom7']; $rootScope.formData['custom8'] = all.data.response.appointment[0]['custom8']; $rootScope.formData['custom9'] = all.data.response.appointment[0]['custom9']; $rootScope.formData['clientTimezone'] = all.data.response.appointment[0]['clientTimezone']; $scope.cancel(); }).catch(function(error) { console.log("Problem getting appointment: "+error.statusText+"("+error.status+")"); }); } */ $scope.getSingleAppointment(); }function confirmationController($rootScope, $scope, $http, $location, $filter) { $rootScope.setLoading(true); //get appointment $scope.getSingleAppointment = function() { call = { "method":"getAppointmentByConfirmationNumber", //"service":"AppointmentServices", "request": { "confirmationNumber": $rootScope.formData['confirmationNumber'] }, "response": { "appointment":`.//return/appointment[clientLastname="${$rootScope.formData.client_lastName}"]` }, "sid": $rootScope.cts.sid }; $http.post('api.php', call).then(function(all) { if (all.data.error || all.error || all.data.response.length < 1) { $rootScope.error = "No appointment exist with the details provided or it has been cancelled."; $rootScope.ready = true; $rootScope.showErrorButton('none'); $location.path( 'error' ); return; } $rootScope.formData['campaignExternalId'] = all.data.response.appointment[0]['campaignExternalId']; $rootScope.formData['locationExternalId'] = all.data.response.appointment[0]['locationExternalId']; $rootScope.formData['programExternalId'] = all.data.response.appointment[0]['programExternalId']; $rootScope.formData['activityExternalId'] = all.data.response.appointment[0]['activityExternalId']; $rootScope.formData['resourceExternalId'] = all.data.response.appointment[0]['resourceExternalId']; $rootScope.formData.appointmentStartDate = all.data.response.appointment[0]['appointmentStartDate']; $rootScope.formData.appointmentEndDate = all.data.response.appointment[0]['appointmentEndDate']; $rootScope.formData.appointmentDurationMin = all.data.response.appointment[0]['appointmentDurationMin']; $rootScope.formData.client_firstName = all.data.response.appointment[0]['clientFirstname']; $rootScope.formData.client_lastName = all.data.response.appointment[0]['clientLastname']; $rootScope.status = all.data.response.appointment[0]['lifeCycleState']; $rootScope.setLoading(false); }).catch(function(error) { console.log("Problem getting appointment: "+error.statusText+"("+error.status+")"); }); } $scope.getSingleAppointment(); }function detailsController($rootScope, $scope, $http, $location, $filter, $q) { $rootScope.setLoading(true); $rootScope.formData.processingBooking = false; $scope.getResources = function(locationExternalId) { var criteria = {}; criteria["locationExternalId"] = locationExternalId; if ($rootScope.formData['activityExternalId']) { criteria["activityExternalId"] = $rootScope.formData['activityExternalId']; } if ($rootScope.formData['programExternalId']) { criteria["programExternalId"] = $rootScope.formData['programExternalId']; } getResourcesByCriteria = { "method":"getResourcesByCriteria", //"service":"ConfigurationServices", "request": { "resourceSearchCriteria":criteria }, "response": { "resources":".//return/*[local-name() = 'resources']" }, "sid": $rootScope.cts.sid }; return $http.post('api.php', getResourcesByCriteria).then(function(all) { if (all && all.data && all.data.response && all.data.response.resources) { $rootScope.resources = all.data.response.resources; } }).catch(function(error) { console.log("Problem getting resources: "+error.statusText+"("+error.status+")"); }); } $scope.getActivities = function(criteria) { criteria = criteria || {}; var campaignExternalId = $rootScope.formData['campaignExternalId'] ? $rootScope.formData['campaignExternalId'] : false; var locationExternalId = ($rootScope.formData['locationExternalId'] || $rootScope.defaultLocationExternalId) ? $rootScope.formData['locationExternalId'] || $rootScope.defaultLocationExternalId : false; var programExternalId = $rootScope.formData['programExternalId'] ? $rootScope.formData['programExternalId'] : false; if (!criteria["campaignExternalId"] && campaignExternalId) { criteria["campaignExternalId"] = campaignExternalId; } if (!criteria["locationExternalId"] && locationExternalId) { criteria["locationExternalId"] = locationExternalId; } if (!criteria["programExternalId"] && programExternalId) { criteria["programExternalId"] = programExternalId; } data = { "method":"getActivities", //"service":"ConfigurationServices", "request": criteria, "response": { "activities":".//return/activities[deleted='false'][isEnabled='true'][not(suppressVisibilityPerApp/appName='"+$rootScope.cts.appName+"')]" }, "sid": $rootScope.cts.sid }; return $http.post('api.php', data).then(function(all) { if (all && all.data && all.data.response && all.data.response.activities) { $rootScope.activities = all.data.response.activities; } }).catch(function(error) { console.log("Problem getting activities: "+error.statusText+"("+error.status+")"); }); } $scope.getSingleAppointment = function() { var filter = './/return/appointment[translate(clientLastname,"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz")="'+atob($rootScope.formData["client_lastName"]).toLowerCase()+'"]'; call = { "method":"getAppointmentByConfirmationNumber", //"service":"AppointmentServices", "request": { "confirmationNumber": $rootScope.formData['confirmationNumber'] }, "response": { "appointment":filter }, "sid": $rootScope.cts.sid }; $http.post('api.php', call).then(function(all) { if (all.data.error || all.error || all.data.response.length < 1) { $rootScope.error = "No appointment exist with the details provided or it has been cancelled."; $rootScope.ready = true; $rootScope.showErrorButton('none'); $location.path( 'error' ); return; } $rootScope.formData['campaignExternalId'] = all.data.response.appointment[0]['campaignExternalId']; $rootScope.formData['locationExternalId'] = all.data.response.appointment[0]['locationExternalId']; $rootScope.formData['programExternalId'] = all.data.response.appointment[0]['programExternalId']; $rootScope.formData['activityExternalId'] = all.data.response.appointment[0]['activityExternalId']; $rootScope.formData['resourceExternalId'] = all.data.response.appointment[0]['resourceExternalId']; $rootScope.formData.appointmentStartDate = all.data.response.appointment[0]['appointmentStartDate']; $rootScope.formData.appointmentEndDate = all.data.response.appointment[0]['appointmentEndDate']; $rootScope.formData.appointmentDurationMin = all.data.response.appointment[0]['appointmentDurationMin']; $rootScope.formData.client_firstName = all.data.response.appointment[0]['clientFirstname']; $rootScope.formData.client_lastName = all.data.response.appointment[0]['clientLastname']; $rootScope.formData.clientTimezone = all.data.response.appointment[0]['clientTimezone']; $rootScope.status = all.data.response.appointment[0]['lifeCycleState']; $rootScope.formData['custom0'] = all.data.response.appointment[0]['custom0']; $rootScope.formData['custom1'] = all.data.response.appointment[0]['custom1']; $rootScope.formData['custom2'] = all.data.response.appointment[0]['custom2']; $rootScope.formData['custom3'] = all.data.response.appointment[0]['custom3']; $rootScope.formData['custom4'] = all.data.response.appointment[0]['custom4']; $rootScope.formData['custom5'] = all.data.response.appointment[0]['custom5']; $rootScope.formData['custom6'] = all.data.response.appointment[0]['custom6']; $rootScope.formData['custom7'] = all.data.response.appointment[0]['custom7']; $rootScope.formData['custom8'] = all.data.response.appointment[0]['custom8']; $rootScope.formData['custom9'] = all.data.response.appointment[0]['custom9']; var getLocationActivities = $scope.getActivities({"locationExternalId":$rootScope.formData['locationExternalId']}); var getLocationResources = $scope.getResources($rootScope.formData['locationExternalId']); $q.all([getLocationActivities,getLocationResources]).then(function(all){ $scope.getAppointmentQuestionsByCriteria(); }); }).catch(function(error) { console.log("Problem getting appointment: "+error.statusText+"("+error.status+")"); }); } $scope.appendAppointmentAnswers = function() { questionAnswerList = []; for (var key in $rootScope.formData) { if (!$rootScope.formData.hasOwnProperty(key)) continue; if (key.lastIndexOf("appointment_", 0) === 0) { questionAnswerList.push({ questionExternalId: key.replace("appointment_", ""), answer: $rootScope.formData[key] }); } } if (questionAnswerList.length > 0) { call = { "method":"appendAppointmentAnswers", //"service":"AppointmentServices", "request": { "confirmationNumber": $rootScope.formData['confirmationNumber'], "questionAnswerList": questionAnswerList }, "response": { "status":".//return/result" }, "sid": $rootScope.cts.sid }; $http.post('api.php', call).then(function(all) { if (all.data.success) { $rootScope.newCancelAppointment(); } else { $rootScope.formData.processingBooking = false; $rootScope.formData.error = all.data.error; } }).catch(function(error) { $rootScope.formData.processingBooking = false; console.log("Problem appending answers: "+error.statusText+"("+error.status+")"); }); } else { $rootScope.newCancelAppointment(); } } $scope.getAppointmentQuestionsByCriteria = function() { getAppointmentQuestionsByCriteria = { "method":"getAppointmentQuestionsByCriteria", //"service":"AppointmentServices", "request": { "questionCriteria": { "locationExternalId":$rootScope.formData['locationExternalId'], "programExternalId":$rootScope.formData['programExternalId'], "activityExternalId":$rootScope.formData['activityExternalId'] } }, "response": { "questions":".//return/questions[questionExternalId='C_Cancel_Reason']" }, "sid": $rootScope.cts.sid }; $http.post('api.php', getAppointmentQuestionsByCriteria).then(function(all) { if (all && all.data && all.data.response && all.data.response.questions) { for (var i=0;i<all.data.response.questions.length;i++) { field = all.data.response.questions[i]; if (!$rootScope.reviewFields) { $rootScope.reviewFields = []; } var newOptions = []; for (var option in field["option"]) { if (field["option"][option]["label"].substr(0,10) != "selfserve_") { newOptions.push(field["option"][option]); } } /*for (var option of field["option"]) { if (option["label"].substr(0,10) != "selfserve_") { newOptions.push(option); } }*/ $rootScope.reviewFields.push( { type: field["questionType"], required: field["required"] == "true" ? true : false, defaultResponse: field["questionType"] == "Checkbox" ? (field["defaultResponse"] == "1" ? true : false) : field["defaultResponse"] || false, options: newOptions.length > 0 ? newOptions : false, id: field["questionExternalId"], name: "appointment_"+field["questionExternalId"], label: field["questionLabel"]//.replace(/<[^\/>]+([\/]>|>[^<]*<\/[^>]+>[\s鈫礭*)/g, "")// <[^\/>]+([\/]>|>[^<]*<\/[^>]+>[\s鈫礭*) } ); } } else { //console.log("No rfc question found."); } $rootScope.setLoading(false); }).catch(function(error) { console.log("Problem getting questions: "+error.statusText+"("+error.status+")"); }); } $scope.updateCancel = function() { $rootScope.formData.processingBooking = true; $scope.appendAppointmentAnswers(); } $scope.setQuestion = function(select, value, question) { if (question) { $rootScope.formData[question] = value; document.activeElement.blur(); } } $scope.getSingleAppointment(); }function selfserveController($rootScope, $scope, $http, $location, $filter, $q) { $rootScope.setLoading(true); $rootScope.formData.processingBooking = false; $scope.getResources = function(locationExternalId) { var criteria = {}; criteria["locationExternalId"] = locationExternalId; if ($rootScope.formData['activityExternalId']) { criteria["activityExternalId"] = $rootScope.formData['activityExternalId']; } if ($rootScope.formData['programExternalId']) { criteria["programExternalId"] = $rootScope.formData['programExternalId']; } getResourcesByCriteria = { "method":"getResourcesByCriteria", //"service":"ConfigurationServices", "request": { "resourceSearchCriteria":criteria }, "response": { "resources":".//return/*[local-name() = 'resources']" }, "sid": $rootScope.cts.sid }; return $http.post('api.php', getResourcesByCriteria).then(function(all) { if (all && all.data && all.data.response && all.data.response.resources) { $rootScope.resources = all.data.response.resources; } }).catch(function(error) { console.log("Problem getting resources: "+error.statusText+"("+error.status+")"); }); } $scope.getActivities = function(criteria) { criteria = criteria || {}; var campaignExternalId = $rootScope.formData['campaignExternalId'] ? $rootScope.formData['campaignExternalId'] : false; var locationExternalId = ($rootScope.formData['locationExternalId'] || $rootScope.defaultLocationExternalId) ? $rootScope.formData['locationExternalId'] || $rootScope.defaultLocationExternalId : false; var programExternalId = $rootScope.formData['programExternalId'] ? $rootScope.formData['programExternalId'] : false; if (!criteria["campaignExternalId"] && campaignExternalId) { criteria["campaignExternalId"] = campaignExternalId; } if (!criteria["locationExternalId"] && locationExternalId) { criteria["locationExternalId"] = locationExternalId; } if (!criteria["programExternalId"] && programExternalId) { criteria["programExternalId"] = programExternalId; } data = { "method":"getActivities", //"service":"ConfigurationServices", "request": criteria, "response": { "activities":".//return/activities[deleted='false'][isEnabled='true'][not(suppressVisibilityPerApp/appName='"+$rootScope.cts.appName+"')]" }, "sid": $rootScope.cts.sid }; return $http.post('api.php', data).then(function(all) { if (all && all.data && all.data.response && all.data.response.activities) { $rootScope.activities = all.data.response.activities; } }).catch(function(error) { console.log("Problem getting activities: "+error.statusText+"("+error.status+")"); }); } $scope.getSingleAppointment = function() { var filter = './/return/appointment[translate(clientLastname,"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz")="'+atob($rootScope.formData["client_lastName"]).toLowerCase()+'"]'; call = { "method":"getAppointmentByConfirmationNumber", //"service":"AppointmentServices", "request": { "confirmationNumber": $rootScope.formData['confirmationNumber'] }, "response": { "appointment":filter }, "sid": $rootScope.cts.sid }; $http.post('api.php', call).then(function(all) { if (all.data.error || all.error || all.data.response.length < 1) { $rootScope.error = "No appointment exist with the details provided or it has been cancelled."; $rootScope.ready = true; $rootScope.showErrorButton('none'); $location.path( 'error' ); return; } $rootScope.formData['campaignExternalId'] = all.data.response.appointment[0]['campaignExternalId']; $rootScope.formData['locationExternalId'] = all.data.response.appointment[0]['locationExternalId']; $rootScope.formData['programExternalId'] = all.data.response.appointment[0]['programExternalId']; $rootScope.formData['activityExternalId'] = all.data.response.appointment[0]['activityExternalId']; $rootScope.formData['resourceExternalId'] = all.data.response.appointment[0]['resourceExternalId']; $rootScope.formData.appointmentStartDate = all.data.response.appointment[0]['appointmentStartDate']; $rootScope.formData.appointmentEndDate = all.data.response.appointment[0]['appointmentEndDate']; $rootScope.formData.appointmentDurationMin = all.data.response.appointment[0]['appointmentDurationMin']; $rootScope.formData.client_firstName = all.data.response.appointment[0]['clientFirstname']; $rootScope.formData.client_lastName = all.data.response.appointment[0]['clientLastname']; $rootScope.formData.clientTimezone = all.data.response.appointment[0]['clientTimezone']; $rootScope.status = all.data.response.appointment[0]['lifeCycleState']; $rootScope.formData['custom0'] = all.data.response.appointment[0]['custom0']; $rootScope.formData['custom1'] = all.data.response.appointment[0]['custom1']; $rootScope.formData['custom2'] = all.data.response.appointment[0]['custom2']; $rootScope.formData['custom3'] = all.data.response.appointment[0]['custom3']; $rootScope.formData['custom4'] = all.data.response.appointment[0]['custom4']; $rootScope.formData['custom5'] = all.data.response.appointment[0]['custom5']; $rootScope.formData['custom6'] = all.data.response.appointment[0]['custom6']; $rootScope.formData['custom7'] = all.data.response.appointment[0]['custom7']; $rootScope.formData['custom8'] = all.data.response.appointment[0]['custom8']; $rootScope.formData['custom9'] = all.data.response.appointment[0]['custom9']; var getLocationActivities = $scope.getActivities({"locationExternalId":$rootScope.formData['locationExternalId']}); var getLocationResources = $scope.getResources($rootScope.formData['locationExternalId']); $q.all([getLocationActivities,getLocationResources]).then(function(all){ $rootScope.setLoading(false); }); }).catch(function(error) { console.log("Problem getting appointment: "+error.statusText+"("+error.status+")"); }); } $scope.appendAppointmentAnswers = function() { questionAnswerList = []; for (var key in $rootScope.formData) { if (!$rootScope.formData.hasOwnProperty(key)) continue; if (key.lastIndexOf("appointment_", 0) === 0) { questionAnswerList.push({ questionExternalId: key.replace("appointment_", ""), answer: $rootScope.formData[key] }); } } if (questionAnswerList.length > 0) { call = { "method":"appendAppointmentAnswers", //"service":"AppointmentServices", "request": { "confirmationNumber": $rootScope.formData['confirmationNumber'], "questionAnswerList": questionAnswerList }, "verify": $rootScope.formData.recaptchaToken, "response": { "status":".//return/result" }, "sid": $rootScope.cts.sid }; $http.post('api.php', call).then(function(all) { if (all.data.success) { $rootScope.newNextStep(); } else { $rootScope.formData.processingBooking = false; $rootScope.formData.error = all.data.error; } }).catch(function(error) { $rootScope.formData.processingBooking = false; console.log("Problem appending answers: "+error.statusText+"("+error.status+")"); }); } else { $rootScope.newNextStep(); } } $scope.updateCancel = function() { $rootScope.formData.processingBooking = true; if ($rootScope.cts.features.recaptcha) { var recaptchaContainer = angular.element( document.querySelector( "#recaptcha" ) ); if ($rootScope.formData.recaptchaToken) { recaptchaContainer.removeClass('requiredHighlight'); $scope.appendAppointmentAnswers(); } else { recaptchaContainer.addClass('requiredHighlight'); alert("Please correct highlighted fields."); $rootScope.formData.processingBooking = false; } } else { $scope.appendAppointmentAnswers(); } } $scope.getSingleAppointment(); }function appointmentfinderController($rootScope, $scope, $http, $location) { $rootScope.setLoading(false); $rootScope.showErrorButton('none'); }function appointmenttypeController($rootScope, $scope, $http, $location, $filter) { $rootScope.setLoading(true); if (!$rootScope.prefill.appointmentTypeId || $rootScope.prefill.appointmentTypeId != $rootScope.formData['activityExternalId']) { $rootScope.formData['activityExternalId'] = ""; } //reset firstAvailableDateTime as it may no longer apply when they choose a different activity var useLocation = ""; if ($rootScope.formData['locationExternalId'] || $rootScope.defaultLocationExternalId) { useLocation = $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId; } $rootScope.getLocation(useLocation)['firstAvailableDateTime'] = null; $scope.getActivities = function() { if ($rootScope.formData['programExternalId']) { var criteria = {}; if ($rootScope.formData['campaignExternalId']) { criteria["campaignExternalId"] = $rootScope.formData['campaignExternalId']; } if ($rootScope.formData['locationExternalId'] || $rootScope.defaultLocationExternalId) { criteria["locationExternalId"] = $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId; } if ($rootScope.formData['programExternalId']) { criteria["programExternalId"] = $rootScope.formData['programExternalId']; } getActivities = { "method":"getActivities", "request": criteria, "response": { "activities":".//return/activities[deleted='false'][isEnabled='true'][not(suppressVisibilityPerApp/appName='"+$rootScope.cts.appName+"')]" }, "sid": $rootScope.cts.sid }; $http.post('api.php', getActivities).then(function(all) { for (key in all.data.response.activities) { all.data.response.activities[key]["sequenceNumber"] = parseInt(all.data.response.activities[key]["sequenceNumber"]); } if (all.data.response.activities) { $rootScope.activities = all.data.response.activities; /*for (var i = 0; i < $rootScope.activities.length; i++) { var desc = $rootScope.activities[i]["description"]; var regex = /([ ([:]|^)((https?:\/\/)|(www\.))([-A-Z0-9+&@#\/%=~_|$?!:,]+)([.])([-A-Z0-9+&@#\/%=~_|$?!:,.]*)([A-Z0-9\/])/img; if (desc.match(regex)) { wcagWarning = $rootScope.wcag ? $filter('getLang')(" (opens in new window)") : ""; desc = desc.replace(regex, '$1<a href="//$4$5$6$7$8" target="_blank">$3$4$5$6$7$8'+wcagWarning+'</a>'); } $rootScope.activities[i]["description"] = desc; }*/ } else { $rootScope.error = "No activities found."; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); } $rootScope.setLoading(false); }); } else { $rootScope.error = "No program selected."; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); } } $scope.getLvmhActivities = function() { call = { "service": "BookingInfoService", "function": "GetCounterServiceList", "method": "POST", "headers": "", "request": { "CounterCode": $rootScope.getLocation()["description"], "CultureName": $rootScope.formData.clientLocale.replace("_", "-"), "CountryCode": $rootScope.getLocation()["companyAddress"]["countryCode"], }, "response": "Body>GetCounterServiceListResponse>GetCounterServiceListResult>CounterServiceListInfo>ServiceList>ServiceInfo", "sid": $rootScope.cts.sid }; $http.post("apiLVMH.php", call).then(function(all) { //console.log("getLvmhActivities: ",all); if (all.status != 200 || all.data == "null" || all.data.error) { //console.log(all.data.error);//debug $rootScope.error = "No services found for location: "+$rootScope.getLocation()['locationName']; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); return; } else { var services = []; var response = all.data.response; for (var key in response) { services[key] = { "activityDurations": { "displayName": response[key]["ServiceLength"]+" minutes", "durationInMinutes": response[key]["ServiceLength"] }, "activityExternalId": response[key]["Service"], //"activityName": response[key]["ServiceName"], "activityName": response[key]["ServiceName"]+" - "+ (response[key]["ServiceCurrency"] || "$") +" "+response[key]["ServicePrice"], "description": "" }; } $rootScope.activities = services; //console.log($rootScope.activities); $rootScope.setLoading(false); } }); } $scope.getVanidayActivities = function() { $rootScope.formData.cartId = "";//reset call = { "service": "salons/"+$rootScope.getLocation()['description'], "method": "GET", "headers": "", "request": "", "response": "services", "sid": $rootScope.cts.sid }; $http.post('apiVaniday.php', call).then(function(all) { //console.log("getActivities: ",all); if (all.status != 200 || all.data == "null" || all.data.error) { //console.log(all.data.error);//debug $rootScope.error = "No services found for location: "+$rootScope.getLocation()['locationName']; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); return; } else { var services = []; var response = all.data; for (var key in response) { if (response[key]["is_active"]) { price = (parseInt(response[key]["price"])/100).toFixed(2) == "NaN" ? "" : (parseInt(response[key]["price"])/100).toFixed(2); services.push({ "activityDurations": { "displayName": response[key]["duration"].toString()+" minutes", "durationInMinutes": response[key]["duration"].toString() }, "activityExternalId": response[key]["id"], "activityName": response[key]["name"]+" - "+response[key]["currency"]+" "+price, "description": response[key]["description"] ? response[key]["description"] : "" }); } } $rootScope.activities = services; //console.log($rootScope.activities); $rootScope.setLoading(false); } }); } $scope.setActivity = function(activity) { $rootScope.formData['activityExternalId'] = activity; } if ($rootScope.prefill['external']) { $rootScope.activities = []; if (!$rootScope.getLocation()) {return};//If no location it will go to error page. locationGroupExtId = $rootScope.prefill['locationGroupId'] ? $rootScope.prefill['locationGroupId'] : $rootScope.getLocation()['locationGroupExtId']; if (locationGroupExtId == "benefit-vaniday") { $scope.getVanidayActivities(); } else if (locationGroupExtId == "benefit-lvmh") { $scope.getLvmhActivities(); } else { $rootScope.error = "No external API for location group: "+(locationGroupExtId || ""); $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); return; } } else { //if ($rootScope.formData['activityExternalId']) { // $scope.getSingleActivity(); //} else { $scope.getActivities(); //} } }function appointmenttypegroupscheduleController($rootScope, $scope, $http, $location) { $rootScope.setLoading(true); $scope.preloadPrograms = function() { var criteria = {}; if ($rootScope.formData['campaignExternalId']) { criteria["campaignExternalId"] = $rootScope.formData['campaignExternalId']; } if ($rootScope.formData['locationExternalId'] || $rootScope.defaultLocationExternalId) { criteria["locationExternalId"] = $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId; } getPrograms = { "method":"getPrograms", //"service":"ConfigurationServices", "request": criteria, "response": { "programs":".//return/programs[deleted='false'][isEnabled='true'][not(suppressVisibilityPerApp/appName='"+$rootScope.cts.appName+"')]" }, "sid": $rootScope.cts.sid }; $http.post('api.php', getPrograms).then(function(all) { if (all.data.success) { $rootScope.programs = all.data.response.programs; $rootScope.setLoading(false); } else { $rootScope.error = "No location specified."; $rootScope.ready = true; $rootScope.showErrorButton('none'); $location.path( 'error' ); return; } }); } $scope.setProgram = function(program) { $rootScope.formData['programExternalId'] = program; $rootScope.showAnyResource = $rootScope.getProgram()["programRules"]["resourceGroupRule"] == "groups and names"; //reset the next steps required fields because the program was changed //var parameters = $rootScope.wf.steps[$rootScope.wf.indexes[($location.path()).substr(1)] + 1]['parameters']; //seems to reset locationExternalId ???? /*var parameters = $rootScope.wf.steps[$rootScope.getStepIndex() + 1]['parameters']; for (i in parameters) { if (parameters[i]['required'] === true) { $rootScope.formData[$rootScope.fieldMap[parameters[i]['name']]] = null; } }*/ } $scope.preloadPrograms(); }function appointmenttyperescheduleController($rootScope, $scope, $http, $location) { $rootScope.setLoading(true); $scope.getActivities = function() { var criteria = {}; if ($rootScope.formData['campaignExternalId']) { criteria["campaignExternalId"] = $rootScope.formData['campaignExternalId']; } if ($rootScope.formData['locationExternalId'] || $rootScope.defaultLocationExternalId) { criteria["locationExternalId"] = $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId; } if ($rootScope.formData['programExternalId']) { criteria["programExternalId"] = $rootScope.formData['programExternalId']; } getActivities = { "method":"getActivities", //"service":"ConfigurationServices", "request": criteria, "response": { "activities":".//return/activities[deleted='false'][isEnabled='true'][not(suppressVisibilityPerApp/appName='"+$rootScope.cts.appName+"')]" }, "sid": $rootScope.cts.sid }; $http.post('api.php', getActivities).then(function(all) { for (key in all.data.response.activities) { all.data.response.activities[key]["sequenceNumber"] = parseInt(all.data.response.activities[key]["sequenceNumber"]); } if (all.data.response.activities) { $rootScope.activities = all.data.response.activities; /*for (var i = 0; i < $rootScope.activities.length; i++) { var desc = $rootScope.activities[i]["description"]; var regex = /([ ([:]|^)((https?:\/\/)|(www\.))([-A-Z0-9+&@#\/%=~_|$?!:,]+)([.])([-A-Z0-9+&@#\/%=~_|$?!:,.]*)([A-Z0-9\/])/img; if (desc.match(regex)) { wcagWarning = $rootScope.wcag ? $filter('getLang')(" (opens in new window)") : ""; desc = desc.replace(regex, '$1<a href="//$4$5$6$7$8" target="_blank">$3$4$5$6$7$8'+wcagWarning+'</a>'); } $rootScope.activities[i]["description"] = desc; }*/ } else { $rootScope.error = "No activities found."; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); } $rootScope.setLoading(false); }); } $scope.setActivity = function(activity) { $rootScope.formData['activityExternalId'] = activity; } if ($rootScope.prefill['external']) { $rootScope.activities = []; $rootScope.setLoading(false); } else { $scope.getActivities(); } }function attendeeController($rootScope, $scope, $http, $location, $document, $q) { $rootScope.setLoading(true); if ($rootScope.cts.features.recaptcha) { $rootScope.formData.recaptchaToken = false; } if ($rootScope.prefill['external']) { $scope.setSlot = function() { //select availablity call = { "service": "cart/"+$rootScope.formData.cartId+"/availability", "method": "POST", "headers": { "X-Locale": "en-SG" }, "request": { "datetime": $rootScope.formData.appointmentStartDate, "professional_id": $rootScope.formData['resourceExternalId'] }, "response": "", "sid": $rootScope.cts.sid }; $http.post('apiVaniday.php', call).then(function(all) { //console.log("setSlot: ",all.data); $rootScope.setLoading(false); }); } locationGroupExtId = $rootScope.prefill['locationGroupId'] ? $rootScope.prefill['locationGroupId'] : $rootScope.getLocation()['locationGroupExtId']; if (locationGroupExtId == "benefit-vaniday" && $rootScope.formData.cartId) { $scope.setSlot(); } else { $rootScope.setLoading(false); } } else { //for client search function $scope.getClientsByCriteria = function() { call = { "method":"getClientsByCriteria", "request": { "criteria": { "userName": $rootScope.formData['client_username'], "exactMatchOnly": "true" } }, "response": { "clients":".//return/clients" }, "sid": $rootScope.cts.sid }; $http.post('api.php', call).then(function(all) { if (all.data.error) { $rootScope.debug("Could not find client."); } else { if (all && all.data && all.data.response && all.data.response.clients && all.data.response.clients[0]) { $rootScope.formData.client_answer0 = all.data.response.clients[0]["answer0"]; $rootScope.formData.client_answer1 = all.data.response.clients[0]["answer1"]; $rootScope.formData.client_answer2 = all.data.response.clients[0]["answer2"]; $rootScope.formData.client_answer3 = all.data.response.clients[0]["answer3"]; $rootScope.formData.client_answer4 = all.data.response.clients[0]["answer4"]; $rootScope.formData.client_answer5 = all.data.response.clients[0]["answer5"]; $rootScope.formData.client_answer6 = all.data.response.clients[0]["answer6"]; $rootScope.formData.client_answer7 = all.data.response.clients[0]["answer7"]; $rootScope.formData.client_answer8 = all.data.response.clients[0]["answer8"]; $rootScope.formData.client_answer9 = all.data.response.clients[0]["answer9"]; $rootScope.formData.client_email = all.data.response.clients[0]["email"]; $rootScope.formData.client_firstName = all.data.response.clients[0]["firstName"]; $rootScope.formData.client_lastName = all.data.response.clients[0]["lastName"]; $rootScope.formData.client_mobile = all.data.response.clients[0]["mobile"]; $rootScope.formData.client_company = all.data.response.clients[0]["company"]; $rootScope.debug(all); } else { alert("Member "+$rootScope.formData['client_username']+" not found."); $rootScope.debug("Could not find client."); } } }); } $scope.getResourceCharacteristics = function() { var day = $rootScope.availability.bookingTimes[$rootScope.formData.appointmentStartDate.substring(0, 10)]; for (var i=0;i<day.length;i++) { if (day[i]['appointmentStartDate'] == $rootScope.formData.appointmentStartDate) { var resource = $rootScope.getResource(day[i]['resourceExternalIds'][0]); $rootScope.plusoneEnabled = false; $rootScope.plusonePossible = false; $rootScope.formData.waitlistSelected = false; if (resource) { data = { getResourceCharacteristics:"x", locationExternalId:$rootScope.formData['locationExternalId'], resourceExternalId:resource.resourceExternalId, sid: $rootScope.cts.sid }; $http.post('session.php', data).then(function(all) { if (all.data.plusone === "true") { $rootScope.plusoneEnabled = true; } for (var characteristic in all.data) { if (characteristic.indexOf("ec_cts_") == 0) { //if (characteristic.startsWith("ec_cts_")) { if (all.data[characteristic] === "false") { //remove question $rootScope.attendeeFields.splice($rootScope.getItemIndex($rootScope.attendeeFields,'id',"appointment_"+characteristic),1); } } else if (characteristic.indexOf("ec_") == 0) { //} else if (characteristic.startsWith("ec_")) { //add to appointment questions $rootScope.formData["appointment_"+characteristic] = all.data[characteristic]; } } }); } if (parseInt(day[i]['seats']) > 1) { $rootScope.plusonePossible = true; } if (parseInt(day[i]['seats']) < 1) { $rootScope.formData.waitlistSelected = true; } break; } } $rootScope.setLoading(false); } $scope.getAppointmentQuestionsByCriteria = function() { /*//reset appointment questions incase service has changed. fieldIndexes = $rootScope.attendeeFields.length - 1; for (var x=fieldIndexes;x>=0;x--) { if ($rootScope.attendeeFields[x]["group"] == "appointment") { //$rootScope.attendeeFields.splice(x, 1);//remove item //shouldn't remove it as it might be there for ordering, need to remove properties only for (var property in $rootScope.attendeeFields[x]) { if ($rootScope.attendeeFields[x].hasOwnProperty(property)) { if (property != "hidden" && property != "hideLabel" && property != "id" && property != "type") {//why type? delete $rootScope.attendeeFields[x][property]; } } } } }*/ var criteria = {}; if ($rootScope.formData['campaignExternalId']) { criteria["campaignExternalId"] = $rootScope.formData['campaignExternalId']; } if ($rootScope.formData['locationExternalId'] || $rootScope.defaultLocationExternalId) { criteria["locationExternalId"] = $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId; } if ($rootScope.formData['programExternalId']) { criteria["programExternalId"] = $rootScope.formData['programExternalId']; } if ($rootScope.formData['activityExternalId']) { criteria["activityExternalId"] = $rootScope.formData['activityExternalId']; } getAppointmentQuestionsByCriteria = { "method":"getAppointmentQuestionsByCriteria", "request": { "questionCriteria": criteria }, "response": { "questions":".//return/questions" }, "sid": $rootScope.cts.sid }; $http.post('api.php', getAppointmentQuestionsByCriteria).then(function(all) { if (all && all.data && all.data.response) { if (!all.data.response.questions) { all.data.response.questions = []; } for (var i=0;i<all.data.response.questions.length;i++) { field = all.data.response.questions[i]; //check if append parameter was used for this question for ordering //replace if in xml otherwise push to end of array //console.log("appointment_"+field["questionExternalId"]); if ($rootScope.existsArrayKeyValue($rootScope.attendeeFields, "id", "appointment_"+field["questionExternalId"])) { //console.log("field already in xml for ordering"); questionIndex = $rootScope.getItemIndex($rootScope.attendeeFields,"id","appointment_"+field["questionExternalId"]); $rootScope.attendeeFields[questionIndex]["min"] = field["minFieldValue"]; $rootScope.attendeeFields[questionIndex]["max"] = field["maxFieldValue"]; $rootScope.attendeeFields[questionIndex]["type"] = field["questionType"]; $rootScope.attendeeFields[questionIndex]["required"] = field["required"] == "true" ? true : false; if (field["questionType"] == "Checkbox") { $rootScope.attendeeFields[questionIndex]["defaultResponse"] = field["defaultResponse"] == "1" ? true : false; } else { $rootScope.attendeeFields[questionIndex]["defaultResponse"] = field["defaultResponse"] || false; } $rootScope.attendeeFields[questionIndex]["options"] = field["option"] ? (Array.isArray(field["option"]) ? field["option"] : [field["option"]]) : false; $rootScope.attendeeFields[questionIndex]["name"] = "appointment_"+field["questionExternalId"]; $rootScope.attendeeFields[questionIndex]["label"] = field["questionText"]; $rootScope.attendeeFields[questionIndex]["group"] = "appointment"; $rootScope.attendeeFields[questionIndex]["width"] = false; $rootScope.attendeeFields[questionIndex]["step"] = "attendee";//Is this needed? Added 28/12/2020 } else if (field["questionExternalId"] != "rfc") { $rootScope.attendeeFields.push( { min: field["minFieldValue"], max: field["maxFieldValue"], type: field["questionType"], required: field["required"] == "true" ? true : false, defaultResponse: field["questionType"] == "Checkbox" ? (field["defaultResponse"] == "1" ? true : false) : field["defaultResponse"] || false, options: field["option"] ? field["option"] : false, id: "appointment_"+field["questionExternalId"], name: "appointment_"+field["questionExternalId"], label: field["questionText"], hidden: "false", group: "appointment", width: false, step: "attendee"//Is this needed? Added 28/12/2020 } ); } } //remove appointment questions that don't belong to this service. fieldIndexes = $rootScope.attendeeFields.length - 1; for (var x=fieldIndexes;x>=0;x--) { if ($rootScope.attendeeFields[x]["group"] == "appointment") { var found = $rootScope.getItemsArrayObject(all.data.response.questions,{questionExternalId:$rootScope.attendeeFields[x]["id"].slice(12)}); if (found.length < 1) { $rootScope.attendeeFields.splice(x, 1);//remove item } } } } else { //console.log("Error with response"); } //attendeeFields $numberOfFields = $rootScope.attendeeFields.length; for (var i=0;i<$numberOfFields;i++) { if ($rootScope.attendeeFields[i]['place'] === 'bottom') { var move = $rootScope.attendeeFields.splice(i, 1)[0]; $rootScope.attendeeFields.push(move); i--; $numberOfFields--; } } if ($rootScope.eventsAndClasses && $rootScope.formData['programExternalId'] == "events") { $scope.getResourceCharacteristics(); } else { $rootScope.setLoading(false); } }); } $scope.getAppointmentQuestionsByCriteria(); } }function availabilityController($rootScope, $scope, $http, $location, $route, $window, $filter, $q) { $scope.setWaitlistEnabled = function() { if ($rootScope.formData['programExternalId'] == 'events' && $rootScope.waitlistPossible) {// check if waitlist is enabled and posible for this license var criteria = {}; if ($rootScope.formData['campaignExternalId']) { criteria["campaignExternalId"] = $rootScope.formData['campaignExternalId']; } if ($rootScope.formData['locationExternalId'] || $rootScope.defaultLocationExternalId) { criteria["locationExternalId"] = $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId; } if ($rootScope.formData['programExternalId']) { criteria["programExternalId"] = $rootScope.formData['programExternalId']+"_waitlist"; } return $http.post('api.php', { "method":"getAssignedActivitiesToProgram", "request": criteria, "response": { "assignments":".//return/activityToProgramAssignments" }, "sid": $rootScope.cts.sid }).then(function(all) { //console.log(all); if (all.status === 200 && (all.error === false || all.data.error === false)) {//fix later if (all && all.data && all.data.response && all.data.response.assignments) { var check = $rootScope.getItem(all.data.response.assignments,"activityExternalId",$rootScope.formData["activityExternalId"]); //console.log(check); if (check) { //console.log("setting true"); $rootScope.waitlistEnabled = true;//waitlist enabled return all; } } } //console.log("setting false"); $rootScope.waitlistEnabled = false;//waitlist not enabled return all; }); } else { var deferred = $q.defer(); deferred.resolve({ "data": { "error": false, "response": "Waitlist not possible." } }); return deferred.promise;//fake promise } } $scope.getRange = function($startDateTime = $rootScope.getLocation()['firstAvailableDateTime']) { if ($rootScope.eventsAndClasses && $rootScope.formData['programExternalId'] == "events") { $scope.getAvailabilityEAC(); //check if characteristics starting with ec_ exist and if so use a single call per resource //otherwise do the usual 1xavail 1x capacity call //may be able to use above as the default and pass the events program as parameter if events and classes is enabled //return; } else { data = { getAvailableNDateTimeSlotsStartFromDate:"get", campaignExternalId: $rootScope.formData['campaignExternalId'], programExternalId: $rootScope.formData['programExternalId'] ? $rootScope.formData['programExternalId'] : $rootScope.cts.settings["defaultProgramExternalId"], firstAvailableDateTime: $startDateTime, timezone: $rootScope.getTimezone(), //resourceCharacteristics resourceFilter: Object.keys($rootScope.formData.resourceCharacteristicsFilter).map(function(key){return {"key":key,"value":$rootScope.formData.resourceCharacteristicsFilter[key]}}), //{"key": key,"value": value} //benefit do not get availability using timetrade //if a resourceid is in the url use it to filter availability otherwise show all resources //update trying to use $rootScope.formData['resourceExternalId'] again as alshaya was not working //resourceExternalId: $rootScope.prefill["resourceId"] ? $rootScope.prefill["resourceId"] : $rootScope.formData['resourceExternalId'], resourceExternalId: $rootScope.formData['resourceExternalId'], sid: $rootScope.cts.sid }; if ($rootScope.formData['locationExternalId'] || $rootScope.defaultLocationExternalId) { data["locationExternalId"] = $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId; } $rootScope.setLoading(true); //Retry $http.post('session.php', angular.extend({}, $rootScope.formData, data)).then(function(list) { $rootScope.availability = list.data; $rootScope.formData.week = $rootScope.availability.week; $rootScope.formData.month = $rootScope.availability.month; if ($rootScope.wcag) { window.setTimeout(function () {document.getElementById("daterange").focus();}, 0); } $rootScope.setLoading(false); }); } } $scope.getAvailabilityEAC = function() { $rootScope.setLoading(true); var timezone = $rootScope.getLocation()['timezone']; var data = {}; //benefit do not get availability using timetrade //if a resourceid is in the url use it to filter availability otherwise show all resources //update trying to use $rootScope.formData['resourceExternalId'] again as alshaya was not working if ($rootScope.formData.calStyle === "list") { //list view uses characteristics therefore we need to know what resourceExternalId belongs to slots with no capacity to show the rest of the column data data = { getAppointmentCapacityByCriteriaDateRange:"get", campaignExternalId: $rootScope.formData['campaignExternalId'], programExternalId: $rootScope.formData['programExternalId'] ? $rootScope.formData['programExternalId'] : $rootScope.cts.settings["defaultProgramExternalId"], firstAvailableDateTime: moment().tz(timezone).format('YYYY-MM-DDTHH:mm:ssZ'),//2019-06-05T09:25:19+07:00,//$rootScope.getLocation()['firstAvailableDateTime'], timezone: timezone, resources: $rootScope.resources.map(function(resource) {return { "resourceExternalId": resource.resourceExternalId, "startDateTime": resource.characteristics.filter(function(characteristic) {return characteristic['key'] == "startDateTime"}).map(function(item) {return item['value']})[0], "appointmentDurationMin": resource.characteristics.filter(function(characteristic) {return characteristic['key'] == "resourceDuration"}).map(function(item) {return item['value']})[0], "timezone": resource.timezone }}), resourceFilter: Object.keys($rootScope.formData.resourceCharacteristicsFilter).map(function(key){return {"key":key,"value":$rootScope.formData.resourceCharacteristicsFilter[key]}}), resourceExternalId: $rootScope.prefill["resourceId"] ? $rootScope.prefill["resourceId"] : $rootScope.formData['resourceExternalId'], sid: $rootScope.cts.sid }; } else { data = { getAvailabilityAndCapacity:"get", campaignExternalId: $rootScope.formData['campaignExternalId'], programExternalId: $rootScope.formData['programExternalId'] ? $rootScope.formData['programExternalId'] : $rootScope.cts.settings["defaultProgramExternalId"], firstAvailableDateTime: moment().tz($rootScope.getLocation()['timezone']).format('YYYY-MM-DDTHH:mm:ssZ'),//2019-06-05T09:25:19+07:00,//$rootScope.getLocation()['firstAvailableDateTime'], timezone: timezone, resourceFilter: Object.keys($rootScope.formData.resourceCharacteristicsFilter).map(function(key){return {"key":key,"value":$rootScope.formData.resourceCharacteristicsFilter[key]}}), resourceExternalId: $rootScope.prefill["resourceId"] ? $rootScope.prefill["resourceId"] : $rootScope.formData['resourceExternalId'], sid: $rootScope.cts.sid }; } $http.post('session.php', angular.extend({}, $rootScope.formData, data)).then(function(list) { //console.log("Events and Classes"); //console.log(list); $rootScope.availability = list.data; $rootScope.formData.week = $rootScope.availability.week; $rootScope.formData.month = $rootScope.availability.month; var passed = false; for (var d in list.data.bookingTimes) { if (list.data.bookingTimes[d].length != 0) { passed = true; break; } } $rootScope.getAvailabilityAttempts = $rootScope.getAvailabilityAttempts ? $rootScope.getAvailabilityAttempts : 1; if ($rootScope.getAvailabilityAttempts > 3) {//when greater then 2 it means it has already tried the maximum times passed = true; if ($rootScope.getAvailabilityAttempts === 4) { $rootScope.getAvailabilityAttempts = 1; alert($filter('getLang')("There is no availability for the selected service.")+"\n"+$filter('getLang')("Service: ")+$filter('getLang')($rootScope.getActivity($rootScope.formData["activityExternalId"])["activityName"])+"\n"+$filter('getLang')("Location: ")+$filter('getLang')($rootScope.getLocation($rootScope.formData["locationExternalId"])["locationName"])+"\n"+$filter('getLang')("Please try another service or location.")); } } if (!passed) { if ($rootScope.getAvailabilityAttempts === 3) { $rootScope.formData.month = 0; } else { $rootScope.formData.month += 1; } $rootScope.getAvailabilityAttempts += 1; $scope.getAvailabilityEAC(); return; } $rootScope.setLoading(false); if ($rootScope.wcag) { window.setTimeout(function () {document.getElementById("daterange").focus();}, 0); } }); } $scope.showSeats = function(seats) { if ($rootScope.eventsAndClasses && $rootScope.formData['programExternalId'] == "events") { var text; var sep = " - "; if (seats < 1) { text = 'Join Waitlist'; seats = ""; } else if (seats > 1) { text = ' Slots'; } else { text = ' Slot' } if ($rootScope.formData.calStyle == "list") { sep = ""; } return sep+seats+$filter('getLang')(text); } else { return ""; } } $scope.waitlistFilter = function() { if ($rootScope.waitlistEnabled) { return {}; } else { return {seats:'!0'}; } } $scope.checkIsAvailability = function(locationExternalId, startDate, numberOfDays = 174) { if ($rootScope.getLocation()['firstAvailableDateTime']) { $scope.getRange(); } else { $rootScope.formData.appointmentDurationMin = $rootScope.getAppointmentDuration(); data = { getFirstAvailableDateTimeSlotByDateRange:"get", activityExternalId: $rootScope.formData['activityExternalId'], campaignExternalId: $rootScope.formData['campaignExternalId'], programExternalId: $rootScope.formData['programExternalId'] ? $rootScope.formData['programExternalId'] : $rootScope.cts.settings["defaultProgramExternalId"], startDate: startDate ? startDate : "", gridStartDate: $rootScope.formData["gridStartDate"], gridEndDate: $rootScope.formData["gridEndDate"], numberOfDays: numberOfDays, checkLocationExternalId: locationExternalId, timezone: $rootScope.getTimezone(), //resourceCharacteristics resourceFilter: Object.keys($rootScope.formData.resourceCharacteristicsFilter).map(function(key){return {"key":key,"value":$rootScope.formData.resourceCharacteristicsFilter[key]}}), resourceExternalId: $rootScope.formData["resourceExternalId"] || null, appointmentDurationMin: null, sid: $rootScope.cts.sid }; $http.post('session.php', data).then(function(all) { if (all.data['isAvailability']) { $rootScope.getLocation(locationExternalId)['firstAvailableDateTime'] = all.data['firstAvailableDateTime']; $scope.getRange(); } else { if ($rootScope.eventsAndClasses && $rootScope.formData['programExternalId'] == "events") { $scope.getAvailabilityEAC(); } else { if (all.data['nextDateTime']) { $scope.checkIsAvailability(locationExternalId,all.data['nextDateTime']); return; } else { var months = Math.round(numberOfDays / 30); if ($rootScope.cts.features.continueAvailabilityCheck) { var proceed = confirm($filter('getLang')(`No availability found within the next ${months} months, Would you like to continue searching further out?`)); if (proceed) { var nextDateTime = moment(startDate, "YYYY-MM-DDTHH:mm:ssZ").tz($rootScope.getTimezone()).add(58, 'days').format('YYYY-MM-DDTHH:mm:ssZ'); $scope.checkIsAvailability(locationExternalId,nextDateTime,numberOfDays + 174); return; } } else { if ($rootScope.cts.settings.noAvailabilityMessage) { alert($filter('getLang')($rootScope.cts.settings.noAvailabilityMessage)); } else { alert($filter('getLang')(`There are no available times`)); } } var bookingTimes = {}; if ($rootScope.availability) { for (var date in $rootScope.availability.bookingTimes) { bookingTimes[date] = []; } var gridMonth = $rootScope.availability.gridMonth; $rootScope.availability = { "bookingTimes": bookingTimes, "gridMonth": gridMonth }; } else { $rootScope.availability = {}; } //alert($filter('getLang')("There is no availability for the selected service.")+"\n"+$filter('getLang')("Service: ")+$filter('getLang')($rootScope.getActivity($rootScope.formData["activityExternalId"])["activityName"])+"\n"+$filter('getLang')("Location: ")+$filter('getLang')($rootScope.getLocation($rootScope.formData["locationExternalId"])["locationName"])+"\n"+$filter('getLang')("Please try another service or location.")); $rootScope.setLoading(false); } } } }); } } $scope.nextDate = function(calView) { $rootScope.getAvailabilityAttempts = 9;//make sure it does not attempt to skip forward when user interacting $rootScope.formData[calView] += 1; //$route.reload(); $scope.init(); } $scope.prevDate = function(calView) { $rootScope.getAvailabilityAttempts = 9;//make sure it does not attempt to skip forward when user interacting if ($rootScope.formData[calView] > 0) { $rootScope.formData[calView] -= 1; //$route.reload(); $scope.init(); } } $scope.holdAppointment = function() { if ($rootScope.cts.settings["appointmentHold"] && !$rootScope.prefill['external']) {//don't hold for third party bookings if ($rootScope.isStepComplete(true)) { $rootScope.setLoading(true); var criteria = {}; if ($rootScope.formData['campaignExternalId']) { criteria["campaignExternalId"] = $rootScope.formData['campaignExternalId']; } if ($rootScope.formData['locationExternalId']) { criteria["locationExternalId"] = $rootScope.formData['locationExternalId']; } if ($rootScope.formData['programExternalId'] || $rootScope.cts.settings["defaultProgramExternalId"]) { criteria["programExternalId"] = $rootScope.formData['programExternalId'] ? $rootScope.formData['programExternalId'] : $rootScope.cts.settings["defaultProgramExternalId"]; } if ($rootScope.formData['activityExternalId']) { criteria["activityExternalId"] = $rootScope.formData['activityExternalId']; } if ($rootScope.formData['resourceExternalId']) { criteria["resourceExternalId"] = $rootScope.formData['resourceExternalId']; } if ($rootScope.useClientTimezone()) { criteria["clientTimezone"] = $rootScope.formData["clientTimezone"]; } $rootScope.formData["appointmentDurationMin"] = $rootScope.getAppointmentDuration(); criteria["appointmentDurationMin"] = $rootScope.formData["appointmentDurationMin"]; $http.post('api.php', { "method":"holdAppointment", //"service":"AppointmentServices", "request": { "criteria": criteria, "startDateTime": moment.tz($rootScope.formData['appointmentStartDate'],$rootScope.getTimezone()).format("YYYY-MM-DDTHH:mm:ss.000Z"), "holdMin": $rootScope.cts.settings["appointmentHold"] }, "response": { "holdConfirmationNumber":".//return/result", "status":".//return/status" }, "sid": $rootScope.cts.sid }).then(function(all) { if (all.status !== 200 || all.data.response.status[0][0] !== "0") { alert($filter('getLang')("Time slot no longer available, please select another.")); } else { $rootScope.formData["holdConfirmationNumber"] = all.data.response["holdConfirmationNumber"][0][0]; $rootScope.newNextStep();//continue after holding appointment } }); } else { $rootScope.newNextStep();//used to show error } } else { $rootScope.newNextStep();//no appointment hold setting } } $scope.setAppointment = function(day, appointmentStartDate) { for (var i=0;i<day.length;i++) { if (day[i]['appointmentStartDate'] == appointmentStartDate) { $rootScope.formData.appointmentStartDate = day[i]['appointmentStartDate']; $rootScope.formData.appointmentEndDate = day[i]['appointmentEndDate']; if ($rootScope.eventsAndClasses) { $scope.setResource(day[i]); } break; } } } $scope.setResource = function(slot) { $rootScope.formData['resourceExternalId'] = slot['resourceExternalIds'][0]; $rootScope.formData['appointmentStartDate'] = slot['appointmentStartDate']; $rootScope.formData['appointmentEndDate'] = slot['appointmentEndDate']; if ($rootScope.eventsAndClasses) { if (!$rootScope.formData['resourceExternalId']) { //match and set resource as it is not able to be returned from a capacity call var resourcePrefix = (slot['appointmentStartDate'].replace("T", "_")).substring(0, 16); $rootScope.formData['resourceExternalId'] = $rootScope.resources.filter(resource => resource.resourceExternalId.substring(0, 16) == resourcePrefix)[0]['resourceExternalId']; } //remove all ec_ fields in formData and add those from the resource. for (var key in $rootScope.formData) { if (key.indexOf("ec_") == 0) { delete $rootScope.formData[key]; } } var selectedResource = $rootScope.getItem($rootScope.resources,'resourceExternalId',$rootScope.formData['resourceExternalId']); if (selectedResource && selectedResource.characteristics) { for (var characteristic in selectedResource.characteristics) { if (characteristic.indexOf("ec_cts_") == 0) { //don't touch ec_cts_ questions, not sure why? } else if (characteristic.indexOf("ec_") == 0) { $rootScope.formData["appointment_"+characteristic] = selectedResource.characteristics[characteristic]; } } } } } $scope.reschedule = function() { data = { rescheduleAppointment: "get", timezone: $rootScope.getLocation()['timezone'], sid: $rootScope.cts.sid }; $rootScope.setLoading(true); $http.post('session.php', angular.extend(data, $rootScope.formData)).then(function(result) { if (result.data['success'] == false) { $rootScope.error = result.data['error']; } $rootScope.status = "Modified"; $location.path( "confirm" ); $rootScope.setLoading(false); }); }; $scope.getResourcesByCriteria = function() { var criteria = { getResourcesByCriteria:"get", campaignExternalId: $rootScope.formData['campaignExternalId'], programExternalId: $rootScope.formData['programExternalId'] ? $rootScope.formData['programExternalId'] : $rootScope.cts.settings["defaultProgramExternalId"], activityExternalId: $rootScope.formData['activityExternalId'] ? $rootScope.formData['activityExternalId'] : "", sid: $rootScope.cts.sid } if ($rootScope.formData['locationExternalId'] || $rootScope.defaultLocationExternalId) { criteria["locationExternalId"] = $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId; } if ($rootScope.formData.getResourcesByCriteria !== JSON.stringify(criteria)) { return $http.post('session.php', criteria).then(function(list) { if (list && list.data) { $rootScope.resources = list.data; } else { console.log(list); return { "data": { "error": true, "response": "Could not get resources." } }; } }); } else { $rootScope.formData.getResourcesByCriteria = JSON.stringify(criteria); var deferred = $q.defer(); deferred.resolve({ "data": { "error": false, "response": "Resources retrieved previously." } }); return deferred.promise;//fake promise } }; $scope.checkActivity = function() { if ($rootScope.activities[0] === "loading...") { var criteria = {}; if ($rootScope.formData['campaignExternalId']) { criteria["campaignExternalId"] = $rootScope.formData['campaignExternalId']; } if ($rootScope.formData['locationExternalId']) { criteria["locationExternalId"] = $rootScope.formData['locationExternalId']; } if ($rootScope.formData['activityExternalId']) { criteria["activityExternalId"] = $rootScope.formData['activityExternalId']; } return $http.post('api.php', { "method":"getActivityByExternalId", //"service":"ConfigurationServices", "request": criteria, "response": { "activity":".//return" }, "sid": $rootScope.cts.sid }).then(function(all) { if (all.data.response.activity) { $rootScope.activities = all.data.response.activity; $rootScope.formData.appointmentDurationMin = $rootScope.getAppointmentDuration(); } else { $rootScope.error = "Activity not found."; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); return; } return all; }); } else { var deferred = $q.defer(); deferred.resolve({ "data": { "error": false, "response": "Already have activity." } }); return deferred.promise;//fake promise } }; $scope.getVanidayCart = function() { call = { "service": "cart", "method": "POST", "headers": { "X-Locale": "en-SG" }, "request": { "service_id": $rootScope.formData['activityExternalId'] }, "response": "", "sid": $rootScope.cts.sid }; $http.post('apiVaniday.php', call).then(function(all) { //console.log("getCart: ",all.data); if (all.data.code) { var message = ""; if (all.data.code == "1035") { message = "This service is not bookable"; } if (all.data.code == "1104") { message = "One or more bookings on cart has no professional or time defined"; } if (all.data.code == "1105") { message = "Service is already on cart"; } if (all.data.code == "1106") { message = "Cart has expired"; } if (all.data.code == "1600") { message = "A professional is not available to attend after the chosen date and time"; } if (all.data.code == "1601") { message = "Unable to make a schedule for the given date and time"; } if (all.data.code == "1602") { message = "Unable to Book in the given start time. It should match the slot interval"; } $rootScope.error = message; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); return; } if (!all.data.id) { $rootScope.error = "There was an issue with Vaniday"; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); return; } $rootScope.formData.cartId = all.data['id']; $scope.getVanidayAvailability(); }); } $scope.getVanidayAvailability = function() { call = { "service": "cart/"+$rootScope.formData.cartId+"/availability", "method": "GET", "headers": { "X-Locale": "en-SG" }, "request": $rootScope.formData['resourceExternalId'] ? {"professional_id": $rootScope.formData['resourceExternalId']} : "", "response": "", "sid": $rootScope.cts.sid }; $http.post('apiVaniday.php', call).then(function(all) { //console.log("getAvailability: ",all.data); var startDate = ""; var endDate = ""; if ($rootScope.formData['calView'] == "month") { startDate = moment().tz($rootScope.getLocation()['timezone']).add($rootScope.formData['month'], 'months').add($rootScope.formData['week'], 'weeks').startOf('month').startOf('week').format('YYYY-MM-DD'); endDate = moment().tz($rootScope.getLocation()['timezone']).add($rootScope.formData['month'], 'months').add($rootScope.formData['week'], 'weeks').endOf('month').endOf('week').format('YYYY-MM-DD'); } else { startDate = moment().tz($rootScope.getLocation()['timezone']).add($rootScope.formData['week'], 'weeks').startOf('week').format('YYYY-MM-DD'); endDate = moment().tz($rootScope.getLocation()['timezone']).add($rootScope.formData['week'], 'weeks').endOf('week').format('YYYY-MM-DD'); } var availability = { gridMonth: moment().tz($rootScope.getLocation()['timezone']).add($rootScope.formData['month'], 'months').add($rootScope.formData['week'], 'weeks').startOf('month').format('YYYY-MM-DD'), startDate: startDate, endDate: endDate, today: moment().tz($rootScope.getLocation()['timezone']).format('YYYY-MM-DD'), calView: $rootScope.formData['calView'], bookingTimes: {} }; var resources = []; var days = $rootScope.formData['calView'] == 'month' ? 42 : 7; for (var i=0;i<days;i++) { index = moment(availability['startDate'], "YYYY-MM-DD").tz($rootScope.getLocation()['timezone']).add(i, 'days').format('YYYY-MM-DD'); availability.bookingTimes[index] = []; } for (var k=0;k<all.data['dates'].length;k++) { if (availability.bookingTimes[all.data['dates'][k]['date']] && all.data['dates'][k]['slots'].length > 0) { for (var s=0;s<all.data['dates'][k]['slots'].length;s++) { availability.bookingTimes[all.data['dates'][k]['date']].push({ appointmentStartDate: all.data['dates'][k]['date']+"T"+all.data['dates'][k]['slots'][s]+":00", appointmentEndDate: moment(all.data['dates'][k]['date']+"T"+all.data['dates'][k]['slots'][s]+":00").tz($rootScope.getLocation()['timezone']).add($rootScope.getActivity()['activityDurations']['durationInMinutes'], 'minutes').format('YYYY-MM-DDTHH:mm:ss') //resourceExternalId: all.data['professionals'][0]['id'] }); } } } //add to resources drop down for (var r=0;r<all.data['professionals'].length;r++) { resources.push({ resourceExternalId: all.data['professionals'][r]['id'], resourceName: all.data['professionals'][r]['name'] }); } //console.log(availability); //console.log(resources); $rootScope.availability = availability; $rootScope.resources = resources; $rootScope.setLoading(false); }); } $scope.getLvmhResources = function() { call = { "service": "BookingInfoService", "function": "GetStaffList", "method": "POST", "headers": "", "request": { "CounterCode": $rootScope.getLocation()["description"], "ServiceCode": $rootScope.formData["activityExternalId"], "CultureName": $rootScope.formData.clientLocale.replace("_", "-"), "CountryCode": $rootScope.getLocation()["companyAddress"]["countryCode"], }, "response": "Body>GetStaffListResponse>GetStaffListResult>StaffInfo", "sid": $rootScope.cts.sid }; $http.post("apiLVMH.php", call).then(function(all) { //console.log("getLvmhResources: ",all.data); var resources = []; for (var r=0;r<all.data.response.length;r++) { if (all.data.response[r]['GenericBC'] == "false") { resources.push({ resourceExternalId: all.data.response[r]['StaffCode'], resourceName: all.data.response[r]['StaffName'] }); } } $rootScope.resources = resources; }); } $scope.getLvmhAvailability = function() { var timezone = $rootScope.getLocation()['timezone']; var sDate = ""; var eDate = ""; if ($rootScope.formData['calView'] == "month") { //sDate = moment().tz(timezone).add($rootScope.formData['month'], 'months').add($rootScope.formData['week'], 'weeks').startOf('month').startOf('week').format('YYYYMMDD'); //eDate = moment().tz(timezone).add($rootScope.formData['month'], 'months').add($rootScope.formData['week'], 'weeks').endOf('month').add(1, 'week').endOf('week').format('YYYYMMDD'); sDate = moment.tz(timezone).add($rootScope.formData['month'], 'months').add($rootScope.formData['week'], 'weeks').startOf('month').startOf('week').format('YYYYMMDD'); eDate = moment.tz(timezone).add($rootScope.formData['month'], 'months').add($rootScope.formData['week'], 'weeks').endOf('month').add(1, 'week').endOf('week').format('YYYYMMDD'); } else { //sDate = moment().tz(timezone).add($rootScope.formData['week'], 'weeks').startOf('week').format('YYYYMMDD'); //eDate = moment().tz(timezone).add($rootScope.formData['week'], 'weeks').endOf('week').format('YYYYMMDD'); sDate = moment.tz(timezone).add($rootScope.formData['week'], 'weeks').startOf('week').format('YYYYMMDD'); eDate = moment.tz(timezone).add($rootScope.formData['week'], 'weeks').endOf('week').format('YYYYMMDD'); } call = { "service": "BookingProcessService", "function": "GetAvailableSlotRange", "method": "POST", "headers": "", "request": { "StartDate": sDate, "EndDate": eDate, "Counter": $rootScope.getLocation()["description"], "Service": $rootScope.formData["activityExternalId"], "Staff": $rootScope.formData["resourceExternalId"], "CountryCode": $rootScope.getLocation()["companyAddress"]["countryCode"], }, "response": "Body>GetAvailableSlotRangeResponse>GetAvailableSlotRangeResult>AvailableSlot", "sid": $rootScope.cts.sid }; $http.post("apiLVMH.php", call).then(function(all) { //console.log("getLvmhAvailability: ",all.data); var slots = []; if (all && all.data && all.data.response) { slots = all.data.response; } var startDate = ""; var endDate = ""; if ($rootScope.formData['calView'] == "month") { //startDate = moment().tz(timezone).add($rootScope.formData['month'], 'months').add($rootScope.formData['week'], 'weeks').startOf('month').startOf('week').format('YYYY-MM-DD'); //endDate = moment().tz(timezone).add($rootScope.formData['month'], 'months').add($rootScope.formData['week'], 'weeks').endOf('month').add(1, 'week').endOf('week').format('YYYY-MM-DD'); startDate = moment.tz(timezone).add($rootScope.formData['month'], 'months').add($rootScope.formData['week'], 'weeks').startOf('month').startOf('week').format('YYYY-MM-DD'); endDate = moment.tz(timezone).add($rootScope.formData['month'], 'months').add($rootScope.formData['week'], 'weeks').endOf('month').add(1, 'week').endOf('week').format('YYYY-MM-DD'); } else { //startDate = moment().tz(timezone).add($rootScope.formData['week'], 'weeks').startOf('week').format('YYYY-MM-DD'); //endDate = moment().tz(timezone).add($rootScope.formData['week'], 'weeks').endOf('week').format('YYYY-MM-DD'); startDate = moment.tz(timezone).add($rootScope.formData['week'], 'weeks').startOf('week').format('YYYY-MM-DD'); endDate = moment.tz(timezone).add($rootScope.formData['week'], 'weeks').endOf('week').format('YYYY-MM-DD'); } var availability = { //gridMonth: moment().tz(timezone).add($rootScope.formData['month'], 'months').add($rootScope.formData['week'], 'weeks').startOf('month').format('YYYY-MM-DD'), gridMonth: moment.tz(timezone).add($rootScope.formData['month'], 'months').add($rootScope.formData['week'], 'weeks').startOf('month').format('YYYY-MM-DD'), startDate: startDate, endDate: endDate, //today: moment().tz(timezone).format('YYYY-MM-DD'), today: moment.tz(timezone).format('YYYY-MM-DD'), calView: $rootScope.formData['calView'], bookingTimes: {} }; var days = $rootScope.formData['calView'] == 'month' ? 42 : 7; for (var i=0;i<days;i++) { //index = moment(availability['startDate'], "YYYY-MM-DD").tz(timezone).add(i, 'days').format('YYYY-MM-DD'); index = moment.tz(availability['startDate'], "YYYY-MM-DD", timezone).add(i, 'days').format('YYYY-MM-DD'); availability.bookingTimes[index] = []; } var date = ""; //var timezone = $rootScope.getLocation()['timezone']; var durationInMinutes = $rootScope.getActivity()['activityDurations']['durationInMinutes']; var startRange = ""; var endRange = ""; var startSlot = ""; var endSlot = ""; var loop = false; var count = 0; for (var k=0;k<slots.length;k++) { date = slots[k]['Date']; date = date.substring(0, 4) + "-" + date.substring(4, 6) + "-" + date.substring(6); if (availability.bookingTimes[date]) { //startRange = moment(date+"T"+slots[k]['TimeFrom']).tz(timezone); //endRange = moment(date+"T"+slots[k]['TimeTo']).tz(timezone); startRange = moment.tz(date+"T"+slots[k]['TimeFrom'],timezone); endRange = moment.tz(date+"T"+slots[k]['TimeTo'],timezone); startSlot = ""; endSlot = ""; staff = slots[k]['Staff']; loop = true; while (loop) { startSlot = endSlot == "" ? startRange : endSlot; //endSlot = moment(startSlot).tz(timezone).add(durationInMinutes, 'minutes'); endSlot = moment.tz(startSlot,timezone).add(durationInMinutes, 'minutes'); // if this timeslot already exists then we skip it if (!$rootScope.existsArrayKeyValue(availability.bookingTimes[date],"appointmentStartDate",startSlot.format('YYYY-MM-DDTHH:mm:ss'))) { availability.bookingTimes[date].push({ appointmentStartDate: startSlot.format('YYYY-MM-DDTHH:mm:ss'), appointmentEndDate: endSlot.format('YYYY-MM-DDTHH:mm:ss'), resourceExternalId: staff }); } // if we have reached the last slot then stop //if (moment(endSlot).tz(timezone).isSame(endRange) || moment(endSlot).tz(timezone).isAfter(endRange)) { if (moment.tz(endSlot,timezone).isSame(endRange) || moment.tz(endSlot,timezone).isAfter(endRange)) { loop = false; } } } } //console.log(availability); $rootScope.availability = availability; $rootScope.setLoading(false); }); } $scope.refreshPage = function(action) { if (action == 'reset') { $rootScope.formData.week = 0; $rootScope.formData.month = 0; } $scope.init(); } $scope.releaseHeldAppointment = function() { $http.post('api.php', { "method":"releaseHeldAppointment", //"service":"AppointmentServices", "request": { "confirmationNumber": $rootScope.formData["holdConfirmationNumber"] }, "response": { "result":".//return/result" }, "sid": $rootScope.cts.sid }).then(function(all) { if (all.status === 200 || all.data.response.result[0][0] === "SUCCESS") { $rootScope.debug("Appointment released."); $rootScope.formData["holdConfirmationNumber"] = null; } else { $rootScope.debug("Appointment failed to release."); } }); } //non benefit are not using formData.resourceExternalId, they only use prefill.resourceId if exists //benefit do use formData.resourceExternalId and it needs to be reset when loading the // step (incase a resource was selected from one activity and doesn't exist in the current activity) but // not when refreshing the step as this is needed to show only the availability //reset formData.resourceExternalId when first getting to the step for benefit //this will not reset when refreshing the page because the refresh runs init() instead of reloading. //reset formData.resourceExternalId when first loading the step only if no prefill resourceId is set. //then we can use it above if ($rootScope.prefill['external'] || !$rootScope.prefill["resourceId"]) { $rootScope.formData['resourceExternalId'] = null; } $scope.updateResourceCharacteristicsFilter = function(id, value) { if ($rootScope.formData.resourceCharacteristicsFilter[id] == value) { delete $rootScope.formData.resourceCharacteristicsFilter[id]; } else { $rootScope.formData.resourceCharacteristicsFilter[id] = value; } } $scope.preventDefault = function(event) { event.preventDefault(); return false; } $scope.isVisible = function(elementId) { var element = document.querySelector('#'+elementId); var visible = element.clientWidth !== 0; return visible; } $scope.showSelectOptions = function(elementId) { var element = document.querySelector('#'+elementId); var visible = $scope.isVisible(elementId); if (!visible) { element.classList.add('show'); element.focus(); } else { element.classList.remove('show'); $scope.checkSelectOptions(elementId); } } $scope.checkSelectOptions = function(elementId) { var visible = $scope.isVisible(elementId); if (!visible) { var newValue = JSON.stringify($rootScope.formData.resourceCharacteristicsFilter); if ($rootScope.formData.resourceCharacteristicsFilterOld !== newValue) { $rootScope.formData.resourceCharacteristicsFilterOld = newValue; $scope.refreshPage(); } } } /*$scope.objectKeyInArrayOfObjectsExists = function(objectKey,arrayOfObjects) { return arrayOfObjects.find(function(object) { return object[objectKey]; }); }*/ $scope.getResourceCharacteristics = function(resourceExternalId) { data = { getResourceCharacteristics: "x", resourceExternalId: resourceExternalId, sid: $rootScope.cts.sid }; if ($rootScope.formData['locationExternalId'] || $rootScope.defaultLocationExternalId) { data["locationExternalId"] = $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId; } return $http.post('session.php', data).then(function(all) { if (all && all.data) { return all.data; } else { console.log(all); return { "error": true, "response": "Could not get resource characteristics." }; } }); } $scope.getAppointmentQuestionsByCriteria = function() { var criteria = {}; if ($rootScope.formData['campaignExternalId']) { criteria["campaignExternalId"] = $rootScope.formData['campaignExternalId']; } if ($rootScope.formData['locationExternalId'] || $rootScope.defaultLocationExternalId) { criteria["locationExternalId"] = $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId; } if ($rootScope.formData['programExternalId']) { criteria["programExternalId"] = $rootScope.formData['programExternalId']; } if ($rootScope.formData['activityExternalId']) { criteria["activityExternalId"] = $rootScope.formData['activityExternalId']; } if ($rootScope.formData.getAppointmentQuestionsByCriteria === JSON.stringify(criteria)) { //console.log("already have"); return;//Already have the required questions } else { $rootScope.formData.getAppointmentQuestionsByCriteria = JSON.stringify(criteria); } getAppointmentQuestionsByCriteria = { "method":"getAppointmentQuestionsByCriteria", //"service":"AppointmentServices", "request": { "questionCriteria": criteria }, "response": { "questions":".//return/questions" }, "sid": $rootScope.cts.sid }; $http.post('api.php', getAppointmentQuestionsByCriteria).then(function(all) { if (all && all.data && all.data.response) { if (!all.data.response.questions) { all.data.response.questions = []; } var filterQuestions = []; for (var i=0;i<all.data.response.questions.length;i++) { var field = all.data.response.questions[i]; //Find all questions that are to be used for filters if ($rootScope.getParameter('filter') && field["questionExternalId"].indexOf("filter_") == 0 && field["questionType"] == 'SelectList') { filterQuestions.push({ "id": field["questionExternalId"], "label": field["questionText"], "type": field["questionType"], "options": Array.isArray(field["option"]) ? field["option"] : [field["option"]] }); //ensures it is reset when loaded without touching other filters like resourceName //Potential issue here if two activities have different filters then the previous ones will not be reset and will therefore still be used in the get availability call. //Need a way to distiguish between 'resourceName' not being a question filter delete $rootScope.formData.resourceCharacteristicsFilter[field["questionExternalId"]]; } //calculate attendeeFields data if ($rootScope.existsArrayKeyValue($rootScope.attendeeFields, "id", "appointment_"+field["questionExternalId"])) { var questionIndex = $rootScope.getItemIndex($rootScope.attendeeFields,"id","appointment_"+field["questionExternalId"]); $rootScope.attendeeFields[questionIndex]["min"] = field["minFieldValue"]; $rootScope.attendeeFields[questionIndex]["max"] = field["maxFieldValue"]; $rootScope.attendeeFields[questionIndex]["type"] = field["questionType"]; $rootScope.attendeeFields[questionIndex]["required"] = field["required"] == "true" ? true : false; if (field["questionType"] == "Checkbox") { $rootScope.attendeeFields[questionIndex]["defaultResponse"] = field["defaultResponse"] == "1" ? true : false; } else { $rootScope.attendeeFields[questionIndex]["defaultResponse"] = field["defaultResponse"] || false; } $rootScope.attendeeFields[questionIndex]["options"] = field["option"] ? (Array.isArray(field["option"]) ? field["option"] : [field["option"]]) : false; $rootScope.attendeeFields[questionIndex]["name"] = "appointment_"+field["questionExternalId"]; $rootScope.attendeeFields[questionIndex]["label"] = field["questionText"]; $rootScope.attendeeFields[questionIndex]["group"] = "appointment"; $rootScope.attendeeFields[questionIndex]["step"] = $rootScope.attendeeFields[questionIndex]["step"] ? $rootScope.attendeeFields[questionIndex]["step"] : "question"; $rootScope.attendeeFields[questionIndex]["width"] = false; } else if (field["questionExternalId"] != "rfc") { $rootScope.attendeeFields.push( { min: field["minFieldValue"], max: field["maxFieldValue"], type: field["questionType"], required: field["required"] == "true" ? true : false, defaultResponse: field["questionType"] == "Checkbox" ? (field["defaultResponse"] == "1" ? true : false) : field["defaultResponse"] || false, options: field["option"] ? field["option"] : false, id: "appointment_"+field["questionExternalId"], name: "appointment_"+field["questionExternalId"], label: field["questionText"], hidden: "false", group: "appointment", step: "question", width: false } ); } } $rootScope.questions = all.data.response.questions; $rootScope.formData.resourceCharacteristicsFilters = filterQuestions; $rootScope.formData.resourceCharacteristicsFilterOld = JSON.stringify($rootScope.formData.resourceCharacteristicsFilter); } else { console.log('Error', all); } //remove appointment questions that don't belong to this service. var numberOfFields = $rootScope.attendeeFields.length - 1; for (var x=numberOfFields;x>=0;x--) { if ($rootScope.attendeeFields[x]["group"] == "appointment") { var found = $rootScope.getItemsArrayObject(all.data.response.questions,{questionExternalId:$rootScope.attendeeFields[x]["id"].slice(12)}); if (found.length < 1) { $rootScope.attendeeFields.splice(x, 1);//remove item } } } //move bottom fields to the end of the array numberOfFields = $rootScope.attendeeFields.length; for (var i=0;i<numberOfFields;i++) { if ($rootScope.attendeeFields[i]['place'] === 'bottom') { var move = $rootScope.attendeeFields.splice(i, 1)[0]; $rootScope.attendeeFields.push(move); i--; numberOfFields--; } } }); }; $scope.processBatch = function(start, end) { console.log("start:"+start+" | "+"end:"+end); var batchSize = end - start; var batch = []; for (var index in $rootScope.resources) { if (index >= start && index < end) { console.log("adding:"+index); batch.push($scope.getResourceCharacteristics($rootScope.resources[index].resourceExternalId)); $rootScope.resources[index].characteristics = [];//init characteristics } } return $q.all(batch).then(function(res) { //if more then processBatch(start, end) for (var i in res) { for (var key in res[i]) { console.log("processing:"+(parseInt(i)+parseInt(start))); $rootScope.resources[parseInt(i)+parseInt(start)].characteristics.push({ "key": key, "value": res[i][key] }); } } if (end < $rootScope.resources.length) { var lastIndex = Math.min(parseInt(end)+parseInt(batchSize),$rootScope.resources.length); return $scope.processBatch(end, lastIndex); } else { //return completed promise? console.log("Done all, checking questions for ListView labels"); //Set events and classes characteristics labels for List view for (var i=0;i<$rootScope.questions.length;i++) { var field = $rootScope.questions[i]; var cIndex; for (var rIndex in $rootScope.resources) { cIndex = $rootScope.getItemIndex($rootScope.resources[rIndex].characteristics || [],'key',field["questionExternalId"]); if (cIndex !== -1) { $rootScope.resources[rIndex].characteristics[cIndex]['label'] = field["questionText"]; } } } } }); }; $scope.init = function(refresh) { $rootScope.formData.appointmentStartDate = null; $rootScope.formData.appointmentEndDate = null; if ($rootScope.prefill['external']) { $rootScope.setLoading(true); locationGroupExtId = $rootScope.prefill['locationGroupId'] ? $rootScope.prefill['locationGroupId'] : $rootScope.getLocation()['locationGroupExtId']; if (locationGroupExtId == "benefit-vaniday") { if ($rootScope.formData.cartId) { $scope.getVanidayAvailability(); } else { $scope.getVanidayCart(); } } else if (locationGroupExtId == "benefit-lvmh") { $scope.getLvmhResources(); $scope.getLvmhAvailability(); } else { $rootScope.error = "No external API for location group: '"+locationGroupExtId+"'"; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); return; } } else { $rootScope.setLoading(true); if ($rootScope.formData["holdConfirmationNumber"]) { $scope.releaseHeldAppointment(); } var initCalls = []; initCalls.push($scope.checkActivity());//Ensure we have the activity in $rootScope.activities initCalls.push($scope.getResourcesByCriteria());//get and set $rootScope.resources initCalls.push($scope.getAppointmentQuestionsByCriteria());//get and set $rootScope.questions and $rootScope.formData.resourceCharacteristicsFilters initCalls.push($scope.setWaitlistEnabled());//Set waitlist if possible $q.all(initCalls).then(function(all) { /* if ($rootScope.eventsAndClasses) { var batchSize = 10; console.log("processBatch Init"); $scope.processBatch(0, batchSize); console.log("processBatch End"); } console.log("checkIsAvailability"); $scope.checkIsAvailability($rootScope.formData['locationExternalId'],false); */ var resources = []; if ($rootScope.eventsAndClasses) { for (var index in $rootScope.resources) { resources.push($scope.getResourceCharacteristics($rootScope.resources[index].resourceExternalId)); $rootScope.resources[index].characteristics = [];//init characteristics } } $q.all($rootScope.resources).then(function(res) {//can be hundreds of resources causing hundreds of requests on the server in the same second. Possibly only need one resource to get settings as they might be activity based settings saved to resource characteristics as that was the only fields we had to save such settings. if ($rootScope.eventsAndClasses) { //set characteristics for each resource for (var i in res) { for (var key in res[i]) { $rootScope.resources[i].characteristics.push({ "key": key, "value": res[i][key] }); } } //Set events and classes characteristics labels for List view if ($rootScope.formData.calStyle === "list" && $rootScope.questions) { for (var i=0;i<$rootScope.questions.length;i++) { var field = $rootScope.questions[i]; var cIndex; for (var rIndex in $rootScope.resources) { cIndex = $rootScope.getItemIndex($rootScope.resources[rIndex].characteristics || [],'key',field["questionExternalId"]); if (cIndex !== -1) { $rootScope.resources[rIndex].characteristics[cIndex]['label'] = field["questionText"]; } } } } } var useLocation = ""; if ($rootScope.formData['locationExternalId'] || $rootScope.defaultLocationExternalId) { useLocation = $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId; } $scope.checkIsAvailability(useLocation, false); }); }); } } $rootScope.formData.resourceCharacteristicsFilters = []; $rootScope.formData.getResourcesByCriteria = void(0); $rootScope.formData.getAppointmentQuestionsByCriteria = void(0); $scope.init(); $rootScope.error = ""; }function availabilityrescheduleController($rootScope, $scope, $http, $location, $route, $window, $filter) { $scope.getRange = function($startDateTime = $rootScope.getLocation()['firstAvailableDateTime']) { data = { getAvailableNDateTimeSlotsStartFromDate:"get", campaignExternalId: $rootScope.formData['campaignExternalId'], programExternalId: $rootScope.formData['programExternalId'] ? $rootScope.formData['programExternalId'] : $rootScope.cts.settings["defaultProgramExternalId"], firstAvailableDateTime: $startDateTime, timezone:$rootScope.getLocation()['timezone'], //filled out from get appointment in main controller resourceExternalId: $rootScope.formData["resourceExternalId"], sid: $rootScope.cts.sid }; $rootScope.setLoading(true); $http.post('session.php', angular.extend({}, $rootScope.formData, data)).then(function(list) { $rootScope.availability = list.data; $rootScope.formData.week = $rootScope.availability.week; $rootScope.formData.month = $rootScope.availability.month; $rootScope.setLoading(false); }); } $scope.checkIsAvailability = function(locationExternalId, startDate, numberOfDays = 174) { if ($rootScope.getLocation()['firstAvailableDateTime']) { $scope.getRange(); } else { var timezone; if ($rootScope.getParameter('tz')) { timezone = $rootScope.formData['clientTimezone']; } else { timezone = $rootScope.getLocation(locationExternalId)['timezone']; } $rootScope.formData.appointmentDurationMin = $rootScope.getAppointmentDuration(); data = { getFirstAvailableDateTimeSlotByDateRange:"get", activityExternalId: $rootScope.formData['activityExternalId'], campaignExternalId: $rootScope.formData['campaignExternalId'], programExternalId: $rootScope.formData['programExternalId'] ? $rootScope.formData['programExternalId'] : $rootScope.cts.settings["defaultProgramExternalId"], startDate: startDate ? startDate : "", gridStartDate: $rootScope.formData["gridStartDate"], gridEndDate: $rootScope.formData["gridEndDate"], numberOfDays: numberOfDays, checkLocationExternalId: locationExternalId, timezone: timezone, //resourceCharacteristics resourceFilter: Object.keys($rootScope.formData.resourceCharacteristicsFilter).map(function(key){return {"key":key,"value":$rootScope.formData.resourceCharacteristicsFilter[key]}}), resourceExternalId: $rootScope.formData["resourceExternalId"] || null, appointmentDurationMin: $rootScope.formData["appointmentDurationMin"], sid: $rootScope.cts.sid }; $http.post('session.php', data).then(function(all) { if (all.data['isAvailability']) { $rootScope.getLocation(locationExternalId)['firstAvailableDateTime'] = all.data['firstAvailableDateTime']; $scope.getRange(); } else { if (all.data['nextDateTime']) { $scope.checkIsAvailability(locationExternalId,all.data['nextDateTime']); return; } else { var months = Math.round(numberOfDays / 30); var proceed = confirm($filter('getLang')(`No availability found within the next ${months} months, Would you like to continue searching further out?`)); if (proceed) { var nextDateTime = moment(startDate, "YYYY-MM-DDTHH:mm:ssZ").tz(timezone).add(58, 'days').format('YYYY-MM-DDTHH:mm:ssZ'); $scope.checkIsAvailability(locationExternalId,nextDateTime,numberOfDays + 174); return; } else { var bookingTimes = {}; if ($rootScope.availability) { for (var date in $rootScope.availability.bookingTimes) { bookingTimes[date] = []; } var gridMonth = $rootScope.availability.gridMonth; $rootScope.availability = { "bookingTimes": bookingTimes, "gridMonth": gridMonth }; } else { $rootScope.availability = {}; } } $rootScope.setLoading(false); } } }); } } $scope.nextDate = function(calView) { $rootScope.formData[calView] += 1; //$route.reload(); $scope.init(); } $scope.prevDate = function(calView) { if ($rootScope.formData[calView] > 0) { $rootScope.formData[calView] -= 1; //$route.reload(); $scope.init(); } } $scope.setAppointment = function(appointmentStartDate) { let haystack = $rootScope.availability['bookingTimes'][$filter('limitTo')(appointmentStartDate, 10)]; for (var i=0;i<haystack.length;i++) { if (haystack[i]['appointmentStartDate'] == appointmentStartDate) { $rootScope.formData.appointmentStartDate = haystack[i]['appointmentStartDate']; $rootScope.formData.appointmentEndDate = haystack[i]['appointmentEndDate']; //if (!$rootScope.formData['resourceExternalId']) { // $rootScope.formData['resourceExternalId'] = haystack[i]['resourceExternalId']; //} //if (haystack[i]['resourceExternalId']) { // $rootScope.formData['resourceExternalId'] = haystack[i]['resourceExternalId']; //} break; } } } $scope.reschedule = function() { data = { rescheduleAppointment:"get", timezone:$rootScope.getLocation()['timezone'], sid: $rootScope.cts.sid }; $rootScope.setLoading(true); $http.post('session.php', angular.extend(data, $rootScope.formData)).then(function(result) { if (result.data['success'] == false) { $rootScope.error = result.data['error']; } $rootScope.status = "Modified"; $location.path( "confirm" ); $rootScope.setLoading(false); }); }; //craig $scope.getResourcesByCriteria = function() { var criteria = {}; if ($rootScope.formData['campaignExternalId']) { criteria["campaignExternalId"] = $rootScope.formData['campaignExternalId']; } if ($rootScope.formData['locationExternalId'] || $rootScope.defaultLocationExternalId) { criteria["locationExternalId"] = $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId; } if ($rootScope.formData['programExternalId'] || $rootScope.cts.settings["defaultProgramExternalId"]) { criteria["programExternalId"] = $rootScope.formData['programExternalId'] ? $rootScope.formData['programExternalId'] : $rootScope.cts.settings["defaultProgramExternalId"]; } if ($rootScope.formData['activityExternalId']) { criteria["activityExternalId"] = $rootScope.formData['activityExternalId']; } call = { "method":"getResourcesByCriteria", //"service":"ConfigurationServices", "request": { "resourceSearchCriteria": criteria }, "response": { "resources":".//return/*[local-name() = 'resources'][isEnabled='true']" }, "sid": $rootScope.cts.sid }; $http.post('api.php', call).then(function(all) { $rootScope.resources = all.data.response.resources; //console.log(all.data.response.resources); }); }; $scope.getVanidayCart = function() { call = { "service": "cart", "method": "POST", "headers": { "X-Locale": "en-SG" }, "request": { "service_id": $rootScope.formData['activityExternalId'] }, "response": "", "sid": $rootScope.cts.sid }; $http.post('apiVaniday.php', call).then(function(all) { //console.log("getCart: ",all.data); if (all.data.code) { var message = ""; if (all.data.code == "1035") { message = "This service is not bookable"; } if (all.data.code == "1104") { message = "One or more bookings on cart has no professional or time defined"; } if (all.data.code == "1105") { message = "Service is already on cart"; } if (all.data.code == "1106") { message = "Cart has expired"; } if (all.data.code == "1600") { message = "A professional is not available to attend after the chosen date and time"; } if (all.data.code == "1601") { message = "Unable to make a schedule for the given date and time"; } if (all.data.code == "1602") { message = "Unable to Book in the given start time. It should match the slot interval"; } $rootScope.error = message; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); return; } if (!all.data.id) { $rootScope.error = "There was an issue with Vaniday"; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); return; } $rootScope.formData.cartId = all.data['id']; $scope.getVanidayAvailability(); }); } $scope.getVanidayAvailability = function() { call = { "service": "cart/"+$rootScope.formData.cartId+"/availability", "method": "GET", "headers": { "X-Locale": "en-SG" }, "request": $rootScope.formData['resourceExternalId'] ? {"professional_id": $rootScope.formData['resourceExternalId']} : "", "response": "", "sid": $rootScope.cts.sid }; $http.post('apiVaniday.php', call).then(function(all) { //console.log("getAvailability: ",all.data); var startDate = ""; var endDate = ""; if ($rootScope.formData['calView'] == "month") { startDate = moment().tz($rootScope.getLocation()['timezone']).add($rootScope.formData['month'], 'months').add($rootScope.formData['week'], 'weeks').startOf('month').startOf('week').format('YYYY-MM-DD'); endDate = moment().tz($rootScope.getLocation()['timezone']).add($rootScope.formData['month'], 'months').add($rootScope.formData['week'], 'weeks').endOf('month').endOf('week').format('YYYY-MM-DD'); } else { startDate = moment().tz($rootScope.getLocation()['timezone']).add($rootScope.formData['week'], 'weeks').startOf('week').format('YYYY-MM-DD'); endDate = moment().tz($rootScope.getLocation()['timezone']).add($rootScope.formData['week'], 'weeks').endOf('week').format('YYYY-MM-DD'); } var availability = { gridMonth: moment().tz($rootScope.getLocation()['timezone']).add($rootScope.formData['month'], 'months').add($rootScope.formData['week'], 'weeks').startOf('month').format('YYYY-MM-DD'), startDate: startDate, endDate: endDate, today: moment().tz($rootScope.getLocation()['timezone']).format('YYYY-MM-DD'), calView: $rootScope.formData['calView'], bookingTimes: {} }; var resources = []; var days = $rootScope.formData['calView'] == 'month' ? 42 : 7; for (var i=0;i<days;i++) { index = moment(availability['startDate'], "YYYY-MM-DD").tz($rootScope.getLocation()['timezone']).add(i, 'days').format('YYYY-MM-DD'); availability.bookingTimes[index] = []; } for (var k=0;k<all.data['dates'].length;k++) { if (availability.bookingTimes[all.data['dates'][k]['date']] && all.data['dates'][k]['slots'].length > 0) { for (var s=0;s<all.data['dates'][k]['slots'].length;s++) { availability.bookingTimes[all.data['dates'][k]['date']].push({ appointmentStartDate: all.data['dates'][k]['date']+"T"+all.data['dates'][k]['slots'][s]+":00", appointmentEndDate: moment(all.data['dates'][k]['date']+"T"+all.data['dates'][k]['slots'][s]+":00").tz($rootScope.getLocation()['timezone']).add($rootScope.getActivity()['activityDurations']['durationInMinutes'], 'minutes').format('YYYY-MM-DDTHH:mm:ss') //resourceExternalId: all.data['professionals'][0]['id'] }); } } } //add to resources drop down for (var r=0;r<all.data['professionals'].length;r++) { resources.push({ resourceExternalId: all.data['professionals'][r]['id'], resourceName: all.data['professionals'][r]['name'] }); } //console.log(availability); //console.log(resources); $rootScope.availability = availability; $rootScope.resources = resources; $rootScope.setLoading(false); }); } $scope.getLvmhResources = function() { call = { "service": "BookingInfoService", "function": "GetStaffList", "method": "POST", "headers": "", "request": { "CounterCode": $rootScope.getLocation()["description"], "ServiceCode": $rootScope.formData["activityExternalId"], "CultureName": $rootScope.formData.clientLocale.replace("_", "-"), "CountryCode": $rootScope.getLocation()["companyAddress"]["countryCode"], }, "response": "Body>GetStaffListResponse>GetStaffListResult>StaffInfo", "sid": $rootScope.cts.sid }; $http.post("apiLVMH.php", call).then(function(all) { //console.log("getLvmhResources: ",all.data); var resources = []; for (var r=0;r<all.data.response.length;r++) { if (all.data.response[r]['GenericBC'] == "false") { resources.push({ resourceExternalId: all.data.response[r]['StaffCode'], resourceName: all.data.response[r]['StaffName'] }); } } $rootScope.resources = resources; }); } $scope.getLvmhAvailability = function() { var timezone = $rootScope.getLocation()['timezone']; var sDate = ""; var eDate = ""; if ($rootScope.formData['calView'] == "month") { //sDate = moment().tz(timezone).add($rootScope.formData['month'], 'months').add($rootScope.formData['week'], 'weeks').startOf('month').startOf('week').format('YYYYMMDD'); //eDate = moment().tz(timezone).add($rootScope.formData['month'], 'months').add($rootScope.formData['week'], 'weeks').endOf('month').add(1, 'week').endOf('week').format('YYYYMMDD'); sDate = moment.tz(timezone).add($rootScope.formData['month'], 'months').add($rootScope.formData['week'], 'weeks').startOf('month').startOf('week').format('YYYYMMDD'); eDate = moment.tz(timezone).add($rootScope.formData['month'], 'months').add($rootScope.formData['week'], 'weeks').endOf('month').add(1, 'week').endOf('week').format('YYYYMMDD'); } else { //sDate = moment().tz(timezone).add($rootScope.formData['week'], 'weeks').startOf('week').format('YYYYMMDD'); //eDate = moment().tz(timezone).add($rootScope.formData['week'], 'weeks').endOf('week').format('YYYYMMDD'); sDate = moment.tz(timezone).add($rootScope.formData['week'], 'weeks').startOf('week').format('YYYYMMDD'); eDate = moment.tz(timezone).add($rootScope.formData['week'], 'weeks').endOf('week').format('YYYYMMDD'); } call = { "service": "BookingProcessService", "function": "GetAvailableSlotRange", "method": "POST", "headers": "", "request": { "StartDate": sDate, "EndDate": eDate, "Counter": $rootScope.getLocation()["description"], "Service": $rootScope.formData["activityExternalId"], "Staff": $rootScope.formData["resourceExternalId"], "CountryCode": $rootScope.getLocation()["companyAddress"]["countryCode"], }, "response": "Body>GetAvailableSlotRangeResponse>GetAvailableSlotRangeResult>AvailableSlot", "sid": $rootScope.cts.sid }; $http.post("apiLVMH.php", call).then(function(all) { //console.log("getLvmhAvailability: ",all.data); var slots = []; if (all && all.data && all.data.response) { slots = all.data.response; } var startDate = ""; var endDate = ""; if ($rootScope.formData['calView'] == "month") { //startDate = moment().tz(timezone).add($rootScope.formData['month'], 'months').add($rootScope.formData['week'], 'weeks').startOf('month').startOf('week').format('YYYY-MM-DD'); //endDate = moment().tz(timezone).add($rootScope.formData['month'], 'months').add($rootScope.formData['week'], 'weeks').endOf('month').add(1, 'week').endOf('week').format('YYYY-MM-DD'); startDate = moment.tz(timezone).add($rootScope.formData['month'], 'months').add($rootScope.formData['week'], 'weeks').startOf('month').startOf('week').format('YYYY-MM-DD'); endDate = moment.tz(timezone).add($rootScope.formData['month'], 'months').add($rootScope.formData['week'], 'weeks').endOf('month').add(1, 'week').endOf('week').format('YYYY-MM-DD'); } else { //startDate = moment().tz(timezone).add($rootScope.formData['week'], 'weeks').startOf('week').format('YYYY-MM-DD'); //endDate = moment().tz(timezone).add($rootScope.formData['week'], 'weeks').endOf('week').format('YYYY-MM-DD'); startDate = moment.tz(timezone).add($rootScope.formData['week'], 'weeks').startOf('week').format('YYYY-MM-DD'); endDate = moment.tz(timezone).add($rootScope.formData['week'], 'weeks').endOf('week').format('YYYY-MM-DD'); } var availability = { //gridMonth: moment().tz(timezone).add($rootScope.formData['month'], 'months').add($rootScope.formData['week'], 'weeks').startOf('month').format('YYYY-MM-DD'), gridMonth: moment.tz(timezone).add($rootScope.formData['month'], 'months').add($rootScope.formData['week'], 'weeks').startOf('month').format('YYYY-MM-DD'), startDate: startDate, endDate: endDate, //today: moment().tz(timezone).format('YYYY-MM-DD'), today: moment.tz(timezone).format('YYYY-MM-DD'), calView: $rootScope.formData['calView'], bookingTimes: {} }; var days = $rootScope.formData['calView'] == 'month' ? 42 : 7; for (var i=0;i<days;i++) { //index = moment(availability['startDate'], "YYYY-MM-DD").tz(timezone).add(i, 'days').format('YYYY-MM-DD'); index = moment.tz(availability['startDate'], "YYYY-MM-DD", timezone).add(i, 'days').format('YYYY-MM-DD'); availability.bookingTimes[index] = []; } var date = ""; //var timezone = $rootScope.getLocation()['timezone']; var durationInMinutes = $rootScope.getActivity()['activityDurations']['durationInMinutes']; var startRange = ""; var endRange = ""; var startSlot = ""; var endSlot = ""; var loop = false; var count = 0; for (var k=0;k<slots.length;k++) { date = slots[k]['Date']; date = date.substring(0, 4) + "-" + date.substring(4, 6) + "-" + date.substring(6); if (availability.bookingTimes[date]) { //startRange = moment(date+"T"+slots[k]['TimeFrom']).tz(timezone); //endRange = moment(date+"T"+slots[k]['TimeTo']).tz(timezone); startRange = moment.tz(date+"T"+slots[k]['TimeFrom'],timezone); endRange = moment.tz(date+"T"+slots[k]['TimeTo'],timezone); startSlot = ""; endSlot = ""; staff = slots[k]['Staff']; loop = true; while (loop) { startSlot = endSlot == "" ? startRange : endSlot; //endSlot = moment(startSlot).tz(timezone).add(durationInMinutes, 'minutes'); endSlot = moment.tz(startSlot,timezone).add(durationInMinutes, 'minutes'); // if this timeslot already exists then we skip it if (!$rootScope.existsArrayKeyValue(availability.bookingTimes[date],"appointmentStartDate",startSlot.format('YYYY-MM-DDTHH:mm:ss'))) { availability.bookingTimes[date].push({ appointmentStartDate: startSlot.format('YYYY-MM-DDTHH:mm:ss'), appointmentEndDate: endSlot.format('YYYY-MM-DDTHH:mm:ss'), resourceExternalId: staff }); } // if we have reached the last slot then stop //if (moment(endSlot).tz(timezone).isSame(endRange) || moment(endSlot).tz(timezone).isAfter(endRange)) { if (moment.tz(endSlot,timezone).isSame(endRange) || moment.tz(endSlot,timezone).isAfter(endRange)) { loop = false; } } } } //console.log(availability); $rootScope.availability = availability; $rootScope.setLoading(false); }); } $scope.refreshPage = function(action) { if (action == 'reset') { $rootScope.formData.week = 0; $rootScope.formData.month = 0; } $scope.init(); } //need resourceExternalId for reschedule /*if (!$rootScope.prefill['resourceId']) { $rootScope.formData['resourceExternalId'] = ""; }*/ $scope.init = function() { //$rootScope.formData.appointmentStartDate = ""; $rootScope.formData.appointmentStartDate = null;//testing angular upgrade 1.6.5 //$rootScope.formData.appointmentEndDate = ""; $rootScope.formData.appointmentEndDate = null;//testing angular upgrade 1.6.5 if ($rootScope.prefill['external']) { $rootScope.setLoading(true); locationGroupExtId = $rootScope.prefill['locationGroupId'] ? $rootScope.prefill['locationGroupId'] : $rootScope.getLocation()['locationGroupExtId']; if (locationGroupExtId == "benefit-vaniday") { if ($rootScope.formData.cartId) { $scope.getVanidayAvailability(); } else { $scope.getVanidayCart(); } } else if (locationGroupExtId == "benefit-lvmh") { $scope.getLvmhResources(); $scope.getLvmhAvailability(); } else { $rootScope.error = "No external API for location group: '"+locationGroupExtId+"'"; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); return; } } else { if ($rootScope.formData['locationExternalId'] && $rootScope.getLocation()['firstAvailableDateTime']) { $scope.getResourcesByCriteria(); $scope.getRange(); } else { $rootScope.setLoading(true); $scope.getResourcesByCriteria(); $scope.checkIsAvailability($rootScope.formData['locationExternalId'],false); } } } $scope.init(); $rootScope.error = ""; }function campaignrescheduleController($rootScope, $scope, $http, $location) { $rootScope.setLoading(true); $scope.preloadCampaigns = function() { getCampaigns = { "method":"getCampaigns", "request": { "locationExternalId": $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId }, "response": { "campaigns":".//return/campaigns[isDeleted='false'][isEnabled='true'][not(suppressVisibilityPerApp/appName='"+$rootScope.cts.appName+"')]" }, "sid": $rootScope.cts.sid }; $http.post('api.php', getCampaigns).then(function(all) { if (all.data.success) { $rootScope.campaigns = all.data.response.campaigns; $rootScope.setLoading(false); } else { $rootScope.error = "No location specified."; $rootScope.ready = true; $rootScope.showErrorButton('none'); $location.path( 'error' ); return; } }); } $scope.setCampaign = function(campaign) { $rootScope.formData['campaignExternalId'] = campaign; //reset the next steps required fields because the campaign was changed //var parameters = $rootScope.wf.steps[$rootScope.wf.indexes[($location.path()).substr(1)] + 1]['parameters']; //seems to reset locationExternalId ???? /*var parameters = $rootScope.wf.steps[$rootScope.getStepIndex() + 1]['parameters']; for (i in parameters) { if (parameters[i]['required'] === true) { $rootScope.formData[$rootScope.fieldMap[parameters[i]['name']]] = null; } }*/ } $scope.preloadCampaigns(); }function campaignscheduleController($rootScope, $scope, $http, $location) { $rootScope.setLoading(true); $scope.preloadCampaigns = function() { getCampaigns = { "method":"getCampaigns", //"service":"ConfigurationServices", "request": { "locationExternalId": $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId }, "response": { "campaigns":".//return/campaigns[isDeleted='false'][isEnabled='true'][not(suppressVisibilityPerApp/appName='"+$rootScope.cts.appName+"')]" }, "sid": $rootScope.cts.sid }; $http.post('api.php', getCampaigns).then(function(all) { if (all.data.success) { $rootScope.campaigns = all.data.response.campaigns; $rootScope.setLoading(false); } else { $rootScope.error = "No location specified."; $rootScope.ready = true; $rootScope.showErrorButton('none'); $location.path( 'error' ); return; } }); } $scope.setCampaign = function(campaign) { $rootScope.formData['campaignExternalId'] = campaign; //reset the next steps required fields because the campaign was changed //var parameters = $rootScope.wf.steps[$rootScope.wf.indexes[($location.path()).substr(1)] + 1]['parameters']; //seems to reset locationExternalId ???? /*var parameters = $rootScope.wf.steps[$rootScope.getStepIndex() + 1]['parameters']; for (i in parameters) { if (parameters[i]['required'] === true) { $rootScope.formData[$rootScope.fieldMap[parameters[i]['name']]] = null; } }*/ } $scope.preloadCampaigns(); }function confirmController($rootScope, $scope, $http, $location, $filter, $q) { $rootScope.setLoading(true); function isFieldRequiredAndMissing(fieldName) { return $rootScope.getItem($rootScope.attendeeFields, "id", fieldName).required && !$rootScope.formData[fieldName]; } if (isFieldRequiredAndMissing("client_firstName") || isFieldRequiredAndMissing("client_lastName")) { $rootScope.gotoPath('attendee'); return; } $scope.checkinQueueAppointment = function() { call = { "method":"checkinQueueAppointment", "request": { "confirmationNumber": $rootScope.formData['confirmationNumber'] }, "response": { "success":".//return/result" }, "sid": $rootScope.cts.sid }; return $http.post('api.php', call).then(function(all) { //console.log(all); }); } $scope.updateAppointment = function() { var appointment = {}; if ($rootScope.cts.features.adHocMode) { appointment['walkIn'] = true; appointment['checkedIn'] = true; appointment['smsEnabled'] = true; } appointment['smsPhoneNumber'] = $rootScope.formData['client_mobile']; appointment['confirmationNumber'] = $rootScope.formData['confirmationNumber']; appointment['appShortName'] = "cts"; appointment['workFlowId'] = $rootScope.formData["workflowExternalId"] ? $rootScope.formData["workflowExternalId"] : $rootScope.prefill['wf']; appointment['custom7'] = $rootScope.formData["custom7"]; appointment['custom9'] = $rootScope.formData["custom9"]; call = { "method":"updateAppointment", "request": { "appointment": appointment }, "response": { "status":".//return/result" }, "sid": $rootScope.cts.sid }; return $http.post('api.php', call).then(function(all) { return all; }); }; $scope.bookAppointment = function(plusone) { var clientId = $rootScope.formData['clientExternalId']; if (plusone) { clientId = $rootScope.formData['plusoneClientExternalId']; } if (!clientId) { var deferred = $q.defer(); deferred.resolve({ "data": { "error": "Unable to make a booking using the email address for "+( plusone ? $rootScope.formData['plusoneFirstName'] : $rootScope.formData['client_firstName'])+", change your email address and try again." } }); $rootScope.showErrorButton('attendee'); return deferred.promise;//fake promise } var criteria = {}; if ($rootScope.formData['campaignExternalId']) { criteria["campaignExternalId"] = $rootScope.formData['campaignExternalId']; } if ($rootScope.formData['locationExternalId']) { criteria["locationExternalId"] = $rootScope.formData['locationExternalId']; } if ($rootScope.formData['activityExternalId']) { criteria["activityExternalId"] = $rootScope.formData['activityExternalId']; } $rootScope.formData["appointmentDurationMin"] = $rootScope.getAppointmentDuration(); criteria["appointmentDurationMin"] = $rootScope.formData["appointmentDurationMin"]; if ($rootScope.useClientTimezone()) { criteria["clientTimezone"] = $rootScope.formData["clientTimezone"]; } //Add questions answers to bookAppointment questionAnswerList = []; for (var key in $rootScope.formData) { if (!$rootScope.formData.hasOwnProperty(key)) continue; if (key.lastIndexOf("appointment_", 0) === 0) { questionAnswerList.push({ questionExternalId: key.replace("appointment_", ""), answer: $rootScope.formData[key] }); } } if (questionAnswerList.length > 0) { criteria["questionAnswers"] = questionAnswerList; } //Add questions answers to bookAppointment if ($rootScope.formData.waitlistSelected) { $rootScope.addToCalendar = false;//disable add to calendar for waitlist appointments if ($rootScope.formData['programExternalId']) { criteria["programExternalId"] = $rootScope.formData['programExternalId'] ? $rootScope.formData['programExternalId']+"_waitlist" : $rootScope.cts.settings["defaultProgramExternalId"]+"_waitlist"; } $rootScope.formData['custom7'] = $rootScope.getResource()['resourceName']; return $http.post('api.php', { "method":"bookAppointmentAdHoc", "request": { "criteria": criteria, "startDateTime": moment.tz($rootScope.formData['appointmentStartDate'],$rootScope.getTimezone()).format("YYYY-MM-DDTHH:mm:ss.000Z"), "clientExternalId": clientId }, "response": { "confirmationNumber":".//return/result" }, "sid": $rootScope.cts.sid }).then(function(all) { return all; }); } else if ($rootScope.cts.features.adHocMode) { if ($rootScope.formData['programExternalId']) { criteria["programExternalId"] = $rootScope.formData['programExternalId'] ? $rootScope.formData['programExternalId'] : $rootScope.cts.settings["defaultProgramExternalId"]; } if ($rootScope.formData['resourceExternalId']) { criteria["resourceExternalId"] = $rootScope.formData['resourceExternalId']; } if ($rootScope.formData.resourceCharacteristicsFilter && JSON.stringify($rootScope.formData.resourceCharacteristicsFilter).length > 2) { criteria["characteristics"] = Object.keys($rootScope.formData.resourceCharacteristicsFilter).map(function(key){return {"key":key,"value":$rootScope.formData.resourceCharacteristicsFilter[key]}}); } return $http.post('api.php', { "method":"bookAppointmentAdHoc", "request": { "criteria": criteria, "startDateTime": moment.tz($rootScope.getTimezone()).format("YYYY-MM-DDTHH:mm:ss.000Z"), "clientExternalId": clientId }, "response": { "confirmationNumber":".//return/result" }, "sid": $rootScope.cts.sid }).then(function(all) { return all; }); } else { //if confirmation number return fake promise if ($rootScope.formData.confirmationNumber) { $rootScope.error = ''; var deferred = $q.defer(); deferred.resolve({ "error": false, "data": { "response": { "confirmationNumber": [ [ $rootScope.formData.confirmationNumber ] ] } } }); return deferred.promise;//fake promise } else { if ($rootScope.formData['programExternalId']) { criteria["programExternalId"] = $rootScope.formData['programExternalId'] ? $rootScope.formData['programExternalId'] : $rootScope.cts.settings["defaultProgramExternalId"]; } if ($rootScope.formData['resourceExternalId']) { criteria["resourceExternalId"] = $rootScope.formData['resourceExternalId']; } if ($rootScope.formData.resourceCharacteristicsFilter && JSON.stringify($rootScope.formData.resourceCharacteristicsFilter).length > 2) { criteria["characteristics"] = Object.keys($rootScope.formData.resourceCharacteristicsFilter).map(function(key){return {"key":key,"value":$rootScope.formData.resourceCharacteristicsFilter[key]}}); } if ($rootScope.useClientTimezone()) { criteria["clientTimezone"] = $rootScope.formData["clientTimezone"]; } return $http.post('api.php', { "method":"bookAppointment", "request": { "criteria": criteria, "startDateTime": moment.tz($rootScope.formData['appointmentStartDate'],$rootScope.getTimezone()).format("YYYY-MM-DDTHH:mm:ss.000Z"), "clientExternalId": clientId }, "response": { "confirmationNumber":".//return/result" }, "sid": $rootScope.cts.sid }).then(function(all) { return all; }); } } }; $scope.sendEmailConfirmation = function(plusone) { var confNumber = $rootScope.formData['confirmationNumber']; call = { "method":"sendEmailConfirmation", "request": { "confirmationNumber": confNumber }, "response": { "status":".//return/result" }, "sid": $rootScope.cts.sid }; //console.log(call); $http.post('api.php', call).then(function(all) { if (all.data.response.status && all.data.response.status[0] && all.data.response.status[0][0] == "SUCCESS") { //success } else { console.log("Sending email notification failed:"); console.log(all); } $rootScope.setLoading(false); $rootScope.ready = false; }); }; $scope.getClientExternalId = function(data, retried = false) { return $http.post('session.php', data).then(function(result) { if (result.data.success && result.data.response["clientExternalId"] && result.data.response["clientExternalId"][0][0]) { return result.data.response["clientExternalId"][0][0]; } else { if (retried) { return $q.reject('API Error'); } else { return $scope.getClientExternalId(data, true); } } }).catch(function(error) { return $q.reject('HTTP Error'); }); } $scope.updateClient = function(plusone) { if (plusone === true && !$rootScope.formData['plusoneClientExternalId']) {//stop from creating again if problem with booking return $http.post('session.php', { setClient: "x", client_firstName: $rootScope.formData['plusoneFirstName'], client_lastName: $rootScope.formData['plusoneLastName'], client_email: $rootScope.formData['plusoneEmail'], client_answer0: $rootScope.formData['plusoneMobile'], timezone: $rootScope.getTimezone(), clientExternalId: "GUID",//force not to lookup client clientLocale: $rootScope.formData['clientLocale'], clientLocaleDisplayName: $rootScope.formData['clientLocaleDisplayName'], sid: $rootScope.cts.sid }).then(function(result) { if (result.data.success) { $rootScope.formData['plusoneClientExternalId'] = result.data.response["clientExternalId"][0][0]; } else { $rootScope.formData['plusoneClientExternalId'] = false; } }); } else { data = { setClient: "x", client_firstName: $rootScope.formData['client_firstName'], client_lastName: $rootScope.formData['client_lastName'], client_email: $rootScope.formData['client_email'], client_username: $rootScope.formData['client_username'] ? $rootScope.formData['client_username'] : $rootScope.formData['client_email'], client_answer0: $rootScope.formData['client_answer0'], client_answer1: $rootScope.formData['client_answer1'], client_answer2: $rootScope.formData['client_answer2'], client_answer3: $rootScope.formData['client_answer3'], client_answer4: $rootScope.formData['client_answer4'], client_answer5: $rootScope.formData['client_answer5'], client_answer6: $rootScope.formData['client_answer6'], client_answer7: $rootScope.formData['client_answer7'], client_answer8: $rootScope.formData['client_answer8'], client_answer9: $rootScope.formData['client_answer9'], client_address1: $rootScope.formData['client_address1'], client_address2: $rootScope.formData['client_address2'], client_company: $rootScope.formData['client_company'], client_city: $rootScope.formData['client_city'], client_country: $rootScope.formData['client_country'], client_postalCode: $rootScope.formData['client_postalCode'], client_state: $rootScope.formData['client_state'], client_countryCode: $rootScope.formData['client_countryCode'], timezone: $rootScope.getTimezone(), clientExternalId: $rootScope.formData['clientExternalId'], clientLocale: $rootScope.formData['clientLocale'], clientLocaleDisplayName: $rootScope.formData['clientLocaleDisplayName'], client_mobile: $rootScope.formData['client_mobile'], client_memberId: $rootScope.formData['client_memberId'], sid: $rootScope.cts.sid }; if (!$rootScope.formData['clientExternalId']) { delete data["clientExternalId"]; } return $scope.getClientExternalId(data).then(function(clientExternalId) { $rootScope.formData['clientExternalId'] = clientExternalId; return true; }, function(error) { $rootScope.error = "Unable to create client, try again later."; $rootScope.ready = true; $rootScope.showErrorButton('attendee'); $location.path( 'error' ); return false; }); } } $scope.cancelPlusone = function() { call = { "method":"cancelAppointment", "request": { "confirmationNumber": $rootScope.formData['custom9'] }, "response": { "status":".//return/status" }, "sid": $rootScope.cts.sid }; $http.post('api.php', call).then(function(all) { if (all && all.data && all.data.error) { $rootScope.debug(all.data.error); } else { $rootScope.formData['custom9'] = ""; $rootScope.setLoading(false); } }); } $scope.cancel = function() { call = { "method":"cancelAppointment", "request": { "confirmationNumber": $rootScope.formData['confirmationNumber'] }, "response": { "status":".//return/status" }, "sid": $rootScope.cts.sid }; $http.post('api.php', call).then(function(all) { if (all && all.data && all.data.error) { $rootScope.debug(all.data.error); } else { $rootScope.formData['confirmationNumber'] = ""; $rootScope.setLoading(false); } }); } $scope.updateInsertClient = function() { if ($rootScope.formData['holdConfirmationNumber']) { $scope.confirmAppointment(); return; } var clients = []; clients.push($scope.updateClient(false)); if ($rootScope.plusoneEnabled && $rootScope.plusonePossible && $rootScope.formData.plusoneSelected) { clients.push($scope.updateClient(true)); } $q.all(clients).then(function(all) { var books = []; books.push($scope.bookAppointment(false)); if ($rootScope.plusoneEnabled && $rootScope.plusonePossible && $rootScope.formData.plusoneSelected) { books.push($scope.bookAppointment(true)); } $q.all(books).then(function(all) { if ($rootScope.plusoneEnabled && $rootScope.plusonePossible && $rootScope.formData.plusoneSelected) { $rootScope.showErrorButton('availability'); if (all[1].data.error && all[0].data.error) { $rootScope.formData.clientExternalId = null;//reset incase they need to change email $rootScope.formData.plusoneClientExternalId = null;//reset incase they need to change email if (all[0].data.error == "appointment slot unavailable ( HTTP/1.1 500 )" || all[1].data.error == "appointment slot unavailable ( HTTP/1.1 500 )") { $rootScope.error = "The appointment time you selected is no longer available or you may already have an appointment for that time. Please press the 'Back' button to choose another time."; } else { $rootScope.error = "Sorry we were unable to complete your request: "+all[0].data.error; } } if (all[1].data.error && all[0].data.error === false) { $rootScope.formData.plusoneClientExternalId = null;//reset incase they need to change email //console.log("plusonePossible",$rootScope.plusonePossible); $rootScope.error = "Unable to book plus one. Would you like to continue without your plus one?"; //console.log("check existing: ",all[0]); $rootScope.formData['confirmationNumber'] = all[0].data.response['confirmationNumber'][0][0]; $scope.cancel(); $rootScope.showErrorButton('continueWithoutPlusone'); } if (all[1].data.error === false && all[0].data.error) { $rootScope.formData.clientExternalId = null;//reset incase they need to change email $rootScope.formData.plusoneClientExternalId = null;//reset incase they need to change email if (all[0].data.error == "appointment slot unavailable ( HTTP/1.1 500 )") { $rootScope.error = "The appointment time you selected is no longer available or you may already have an appointment for that time. Please press the 'Back' button to choose another time."; } else { $rootScope.error = "Sorry we were unable to complete your request: "+all[0].data.error; } $rootScope.formData['custom9'] = all[1].data.response['confirmationNumber'][0][0]; $scope.cancelPlusone(); //cancel plusone } } else { if (all[0].data.error) { if (!$rootScope.prefill['attendeeId']) { $rootScope.formData.clientExternalId = null;//reset incase they need to change email } if (all[0].data.error == "appointment slot unavailable ( HTTP/1.1 500 )") { $rootScope.showErrorButton('availability'); $rootScope.error = "The appointment time you selected is no longer available or you may already have an appointment for that time. Please press the 'Back' button to choose another time."; } else if (all[0].data.error == "Appointment max limit reached for client ( HTTP/1.1 500 )") { $rootScope.error = $rootScope.error = "Sorry! We are unable to complete your request as you have reached the maximum number of appointment allowed."; } else { $rootScope.error = "Sorry we were unable to complete your request: "+all[0].data.error; } } } if (all[0].data.error || ($rootScope.plusoneEnabled && $rootScope.plusonePossible && $rootScope.formData.plusoneSelected && all[1].data.error)) { $rootScope.plusonePossible = false; $rootScope.formData.plusoneSelected = false; //console.log("plusonePossible",$rootScope.plusonePossible); $rootScope.ready = true; $location.path( 'error' ); return; } /*if (all[0].data.error || ($rootScope.plusoneEnabled && $rootScope.plusonePossible && $rootScope.formData.plusoneSelected && all[1].data.error)) { if (all[0].data.error == "appointment slot unavailable" || ($rootScope.plusoneEnabled && $rootScope.plusonePossible && $rootScope.formData.plusoneSelected && all[1].data.error == "appointment slot unavailable")) { $rootScope.error = "The appointment time you selected is no longer available. Please press the 'Back' button to choose another time."; } else { $rootScope.error = "Sorry we were unable to complete your request: "+all[0].data.error; if ($rootScope.plusoneEnabled && $rootScope.plusonePossible && $rootScope.formData.plusoneSelected) { $rootScope.error += ". "+all[1].data.error; } } $rootScope.ready = true; $rootScope.showErrorButton('availability'); $location.path( 'error' ); return; //error with one booking, cancel or continue? }*/ $rootScope.formData['confirmationNumber'] = all[0].data.response['confirmationNumber'][0][0]; if ($rootScope.plusoneEnabled) { if ($rootScope.plusonePossible && $rootScope.formData.plusoneSelected) { $rootScope.formData['custom9'] = all[1].data.response['confirmationNumber'][0][0]; //set plusone first name, last name order to match client first name, last name order. if ($rootScope.getItemIndex($rootScope.attendeeFields,'id','client_firstName') > $rootScope.getItemIndex($rootScope.attendeeFields,'id','client_lastName')) { $rootScope.formData['custom7'] = $rootScope.formData.plusoneLastName + " " + $rootScope.formData.plusoneFirstName; } else { $rootScope.formData['custom7'] = $rootScope.formData.plusoneFirstName + " " + $rootScope.formData.plusoneLastName; } } } if ($rootScope.formData['programExternalId'] == "events") { if (!$rootScope.plusonePossible || !$rootScope.formData.plusoneSelected) { if (!$rootScope.formData.waitlistSelected) { $rootScope.formData['custom7'] = $filter('getLang')("No plus one attending"); } } } $rootScope.status = "Scheduled"; var confirms = []; //confirms.push($scope.appendAppointmentAnswers()); confirms.push($scope.updateAppointment()); /*confirms.push($scope.sendEmailConfirmation(false)); if ($rootScope.plusoneEnabled && $rootScope.plusonePossible && $rootScope.formData.plusoneSelected) { confirms.push($scope.sendEmailConfirmation(true)); }*/ $q.all(confirms).then(function(all) { //console.log(all); /*if (all[0].data.error) { $rootScope.error = "Unable to update appointment answers: "+all[0].data.error; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); return; };*/ if (all[0].data.error) { $scope.sendEmailConfirmation(false); $rootScope.error = "Your appointment has been booked however there were issues saving plus one details to the appointment."; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); return; }; if ($rootScope.cts.features.adHocMode) { $scope.checkinQueueAppointment(); } $scope.sendEmailConfirmation(false); }); }); }); }; $scope.confirmAppointment = function() { //Release and book appointment instead of confirming so that the TT Notifier will trigger on the correct events. //as resourceExternalId has been set, booking will use the same resource as the held appointment. $http.post('api.php', { "method":"releaseHeldAppointment", //"service":"AppointmentServices", "request": { "confirmationNumber": $rootScope.formData["holdConfirmationNumber"] }, "response": { "result":".//return/result" }, "sid": $rootScope.cts.sid }).then(function(all) { $rootScope.formData['holdConfirmationNumber'] = null; $scope.updateInsertClient(); }); } $scope.addToCal = function() { var location; location = $rootScope.getLocation()["locationName"]; var title = $rootScope.getActivity()["activityName"]; var description = ''; var newline; if ($rootScope.formData.cal == 'ical') { newline = '\\n'; } else { newline = "\n"; } var phoneNumbers = ''; for (var pnum in $rootScope.getLocation()['phoneNumbers']){ if ($rootScope.getLocation()['phoneNumbers'].hasOwnProperty(pnum)) { if ($rootScope.getLocation()['phoneNumbers'][pnum]) { phoneNumbers += pnum + ": " + $rootScope.getLocation()['phoneNumbers'][pnum] + newline; } } } var dateTime = document.getElementById('dateTimeTimeZone').innerText; dateTime = dateTime.replace(/(\r\n|\n|\r)/gm,newline); var displayDescription = document.querySelector(".reviewTable").innerText; displayDescription = displayDescription.replace(/(\r\n|\n|\r)/gm,newline); //$rootScope.formData.confirmationNumber description += $filter('getLang')("CONFIRMATION # ") + $rootScope.formData.confirmationNumber + newline + newline; description += dateTime + newline + newline; description += displayDescription + newline + newline; description += $filter('getLang')("To cancel or reschedule this appointment, refer to your confirmation email."); var startDate = $rootScope.formData.appointmentStartDate; var endDate = $rootScope.formData.appointmentEndDate; if ($rootScope.formData.cal == 'ical') { var elements = [ 'BEGIN:VCALENDAR', 'VERSION:2.0', 'BEGIN:VEVENT', 'CLASS:PUBLIC', 'DESCRIPTION:' + description, /*'DTSTART:' + startDate.replace(/-|:/g,''),*/ 'DTSTART;TZID=' + $rootScope.getTimezone() + ':' + startDate.replace(/-|:/g,''), 'DTEND;TZID=' + $rootScope.getTimezone() + ':' + endDate.replace(/-|:/g,''), 'LOCATION:' + location, 'SUMMARY:' + title, 'TRANSP:TRANSPARENT', 'END:VEVENT', 'END:VCALENDAR' ]; var downloadURL = "download.php?d=" + encodeURIComponent(description) + "&s=" + $rootScope.getTimezone() + ':' + startDate.replace(/-|:/g,'') + "&e=" + $rootScope.getTimezone() + ':' + endDate.replace(/-|:/g,'') + "&l=" + location + "&t=" + title; var iframe = document.createElement("iframe"); iframe.setAttribute("src", downloadURL); iframe.setAttribute("style", "display: none"); document.body.appendChild(iframe); } if ($rootScope.formData.cal == 'google') { var googleCalendarUrl = 'https://www.google.com/calendar/render?action=TEMPLATE'; googleCalendarUrl += '&text=' + encodeURIComponent(title); googleCalendarUrl += '&dates=' + encodeURIComponent(startDate.replace(/-|:/g,'')) + '/' + encodeURIComponent(endDate.replace(/-|:/g,'')); googleCalendarUrl += '&ctz=' + $rootScope.getTimezone(); googleCalendarUrl += '&details=' + encodeURIComponent(description); googleCalendarUrl += '&location=' + encodeURIComponent(location); window.open(googleCalendarUrl); } $rootScope.formData.cal = "0"; }; $scope.bookAppointmentLvmh = function() { call = { "service": "BookingProcessService", "function": "AddBooking", "method": "POST", "headers": "", "request": { "Date": moment.tz($rootScope.formData['appointmentStartDate'],$rootScope.getLocation()['timezone']).format("YYYYMMDD"), "Counter": $rootScope.getLocation()["description"], "Staff": $rootScope.formData["resourceExternalId"], "TimeFrom": moment.tz($rootScope.formData['appointmentStartDate'],$rootScope.getLocation()['timezone']).format("HH:mm:ss"), "TimeTo": moment.tz($rootScope.formData['appointmentStartDate'],$rootScope.getLocation()['timezone']).add($rootScope.getActivity()["activityDurations"]["durationInMinutes"], 'minutes').format("HH:mm:ss"), "Service": $rootScope.formData["activityExternalId"], "MemberName": $rootScope.formData["client_firstName"] + " " + $rootScope.formData["client_lastName"], "Mobile": $rootScope.formData["client_answer0"], "Email": $rootScope.formData["client_email"], "StaffPreference": $rootScope.formData["resourceExternalId"] ? "Y" : "", "CultureName": $rootScope.formData.clientLocale.replace("_", "-"), "MemberCode": "", "Remark": "", "Gender": "", "Language": "", "CountryCode": $rootScope.getLocation()["companyAddress"]["countryCode"], }, "response": "Body>AddBookingResponse>AddBookingResult", "sid": $rootScope.cts.sid }; $http.post("apiLVMH.php", call).then(function(all) { //console.log("bookAppointmentLvmh: ",all); if (all) { var httpStatus = all.status; } if (all && all.data && all.data.response && all.data.response[0] && all.data.response[0]["Status"]) { var status = all.data.response[0]["Status"]; } if (httpStatus != 200) { //console.log("HTTP Status: "+httpStatus); $rootScope.error = "There was a problem booking this appointment. Contact support at apsupport@timetrade.com"; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); } if (status != "000" && status != "010") { lvmhErrors = { "001": "Standby booking is added", "101": "No booking is allowed at provided counter", "102": "BC is not available", "103": "BC is not allowed to handle that service", "104": "Booking schedule is not feasible", "105": "Member has another booking at the same time", "106": "Same service booking before pre-defined booking date", "999": "Adding booking has failed" } //console.log("Booking Status: "+status); if (lvmhErrors[status]) { $rootScope.error = "There was a problem booking this appointment. "+lvmhErrors[status]+". Contact support at apsupport@timetrade.com"; } else { $rootScope.error = "There was a problem booking this appointment. Contact support at apsupport@timetrade.com"; } $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); } else if (status == "010") { //console.log("Appointment confirmed, however confirmation SMS failed to send."); //alert("Appointment confirmed, however confirmation SMS failed to send."); } $rootScope.formData.confirmationNumber = all.data.response[0]["Sequence"]; $rootScope.setLoading(false); }); } $scope.bookAppointmentVaniday = function() { call = { "service": "booking", "method": "POST", "headers": { "X-Locale": "en-SG" }, "request": { "cart_id": $rootScope.formData.cartId, "customer": { "first_name": $rootScope.formData.client_firstName, "last_name": $rootScope.formData.client_lastName, "email": $rootScope.formData.client_email, "phone": $rootScope.formData.client_answer0 } }, "response": "", "sid": $rootScope.cts.sid }; $http.post('apiVaniday.php', call).then(function(all) { //console.log("bookingVaniday: ",all); if (false) { $rootScope.error = "There was a problem booking this appointment."; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); } $rootScope.setLoading(false); }); } $scope.getPrograms = function() { if ($rootScope.programs[0] == "loading...") { var criteria = {}; if ($rootScope.formData['campaignExternalId']) { criteria["campaignExternalId"] = $rootScope.formData['campaignExternalId']; } if ($rootScope.formData['locationExternalId'] || $rootScope.defaultLocationExternalId) { criteria["locationExternalId"] = $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId; } getPrograms = { "method":"getPrograms", "request": criteria, "response": { "programs":".//return/programs[deleted='false'][isEnabled='true'][not(suppressVisibilityPerApp/appName='"+$rootScope.cts.appName+"')]" }, "sid": $rootScope.cts.sid }; return $http.post('api.php', getPrograms).then(function(all) { $rootScope.debug(all.data.response.programs); $rootScope.programs = all.data.response.programs; }); } else { var deferred = $q.defer(); deferred.resolve("Programs already exist, no need to retrieve.") return deferred.promise;//fake promise } } $scope.getActivities = function() { if ($rootScope.activities[0] == "loading...") { var criteria = {}; if ($rootScope.formData['campaignExternalId']) { criteria["campaignExternalId"] = $rootScope.formData['campaignExternalId']; } if ($rootScope.formData['locationExternalId'] || $rootScope.defaultLocationExternalId) { criteria["locationExternalId"] = $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId; } if ($rootScope.formData['programExternalId'] || $rootScope.cts.settings["defaultProgramExternalId"]) { criteria["programExternalId"] = $rootScope.formData['programExternalId'] ? $rootScope.formData['programExternalId'] : $rootScope.cts.settings["defaultProgramExternalId"]; } getActivities = { "method":"getActivities", "request": criteria, "response": { "activities":".//return/activities[deleted='false'][isEnabled='true'][not(suppressVisibilityPerApp/appName='"+$rootScope.cts.appName+"')]" }, "sid": $rootScope.cts.sid }; return $http.post('api.php', getActivities).then(function(all) { $rootScope.debug(all.data.response.activities); $rootScope.activities = all.data.response.activities; }); } else { var deferred = $q.defer(); deferred.resolve("Activities already exist, no need to retrieve.") return deferred.promise;//fake promise } } $scope.init = function() { $rootScope.error = ''; var getPrograms = $scope.getPrograms(); var getActivities = $scope.getActivities(); $q.all([getPrograms, getActivities]).then(function(all){ $scope.updateInsertClient(); }); } if ($rootScope.prefill['external']) { locationGroupExtId = $rootScope.prefill['locationGroupId'] ? $rootScope.prefill['locationGroupId'] : $rootScope.getLocation()['locationGroupExtId']; if (locationGroupExtId == "benefit-vaniday") { $scope.bookAppointmentVaniday(); } else if (locationGroupExtId == "benefit-lvmh") { $scope.bookAppointmentLvmh(); } else { $rootScope.error = "No external API for location group: '"+locationGroupExtId+"'"; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); return; } } else { $scope.init(); } }function confirmcancelController($rootScope, $scope, $http, $location) { $rootScope.setLoading(true); $scope.appendAppointmentAnswers = function() { questionAnswerList = []; for (var key in $rootScope.formData) { if (!$rootScope.formData.hasOwnProperty(key)) continue; if (key.lastIndexOf("appointment_", 0) === 0) { questionAnswerList.push( { questionExternalId: key.replace("appointment_", ""), answer: $rootScope.formData[key] } ); } } call = { "method":"appendAppointmentAnswers", //"service":"AppointmentServices", "request": { "confirmationNumber": $rootScope.formData['confirmationNumber'], "questionAnswerList": questionAnswerList }, "response": { "status":".//return/result" }, "sid": $rootScope.cts.sid }; $http.post('api.php', call).then(function(all) { //console.log("appendAppointmentAnswers: ",all); if (all.data.error) { //console.log("Unable to update appointment answers: "+all.data.error); /*$rootScope.error = "Unable to update appointment answers: "+all.data.error; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); return;*/ }; $scope.cancel(); if ($rootScope.formData['programExternalId'] === "events" && $rootScope.formData['custom9']) { $scope.cancelPlusOne(); } }); }; $scope.cancelPlusOne = function() { call = { "method":"cancelAppointment", //"service":"AppointmentServices", "request": { "confirmationNumber": $rootScope.formData['custom9'] }, "response": { "status":".//return/status" }, "sid": $rootScope.cts.sid }; $http.post('api.php', call).then(function(all) { if (all && all.data && all.data.error) { $rootScope.debug(all.data.error); $rootScope.error = "The deadline for cancelling has passed please call for assistance."; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); return; } else { $rootScope.setLoading(false); $rootScope.ready = false;//Completed the cancel process, using the browser back button will cause a hard reload of the app. } }); } $scope.cancel = function() { call = { "method":"cancelAppointment", //"service":"AppointmentServices", "request": { "confirmationNumber": $rootScope.formData['confirmationNumber'] }, "response": { "status":".//return/status" }, "sid": $rootScope.cts.sid }; $http.post('api.php', call).then(function(all) { if (all && all.data && all.data.error) { $rootScope.debug(all.data.error); $rootScope.error = "The deadline for cancelling has passed please call for assistance."; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); return; } else { $scope.sendEmailCancellation(); $rootScope.status = "Cancelled"; //console.log('successfully canceled'); $rootScope.setLoading(false); $rootScope.ready = false;//Completed the cancel process, using the browser back button will cause a hard reload of the app. } }); } $scope.sendEmailCancellation = function() { call = { "method":"sendEmailCancellation", //"service":"MessagingServices", "request": { "confirmationNumber": $rootScope.formData['confirmationNumber'] }, "response": { "status":".//return/result" }, "sid": $rootScope.cts.sid }; //console.log(call); $http.post('api.php', call).then(function(all) { if (all.data.response.status && all.data.response.status[0] && all.data.response.status[0][0] == "SUCCESS") { //success } else { console.log("Sending email notification failed:"); console.log(all); } }); }; $scope.getAppointmentByConfirmationNumber = function() { call = { "method":"getAppointmentByConfirmationNumber", //"service":"AppointmentServices", "request": { "confirmationNumber": $rootScope.prefill['appointmentId'] }, "response": { "appointment":".//return/appointment" }, "sid": $rootScope.cts.sid }; $http.post('api.php', call).then(function(all) { if (all && all.data && all.data.error) { alert(all.data.error); return; } $rootScope.formData['locationExternalId'] = all.data.response.appointment[0]['locationExternalId']; $rootScope.formData.appointmentStartDate = all.data.response.appointment[0]['appointmentStartDate']; $rootScope.formData.appointmentEndDate = all.data.response.appointment[0]['appointmentEndDate']; $rootScope.activities = Array(); $rootScope.activities[0] = Array(); $rootScope.activities[0]['activityName'] = all.data.response.appointment[0]['activityName']; $rootScope.activities[0]['activityDurations'] = Array(); $rootScope.activities[0]['activityDurations']['durationInMinutes'] = all.data.response.appointment[0]['appointmentDurationMin']; $rootScope.activities[0]['activityExternalId'] = all.data.response.appointment[0]['activityExternalId']; $rootScope.formData['activityExternalId'] = all.data.response.appointment[0]['activityExternalId']; $rootScope.status = all.data.response.appointment[0]['lifeCycleState']; $rootScope.formData['programExternalId'] = all.data.response.appointment[0]['programExternalId']; $rootScope.formData['custom0'] = all.data.response.appointment[0]['custom0']; $rootScope.formData['custom1'] = all.data.response.appointment[0]['custom1']; $rootScope.formData['custom2'] = all.data.response.appointment[0]['custom2']; $rootScope.formData['custom3'] = all.data.response.appointment[0]['custom3']; $rootScope.formData['custom4'] = all.data.response.appointment[0]['custom4']; $rootScope.formData['custom5'] = all.data.response.appointment[0]['custom5']; $rootScope.formData['custom6'] = all.data.response.appointment[0]['custom6']; $rootScope.formData['custom7'] = all.data.response.appointment[0]['custom7']; $rootScope.formData['custom8'] = all.data.response.appointment[0]['custom8']; $rootScope.formData['custom9'] = all.data.response.appointment[0]['custom9']; $scope.appendAppointmentAnswers(); }); } $scope.getAppointmentByConfirmationNumber(); }function confirmrescheduleController($rootScope, $scope, $http, $location, $filter) { $rootScope.setLoading(true); $scope.appendAppointmentAnswers = function() { questionAnswerList = []; for (var key in $rootScope.formData) { if (!$rootScope.formData.hasOwnProperty(key)) continue; if (key.lastIndexOf("appointment_", 0) === 0) { questionAnswerList.push({ questionExternalId: key.replace("appointment_", ""), answer: $rootScope.formData[key] }); } } if (questionAnswerList.length > 0) { call = { "method":"appendAppointmentAnswers", "request": { "confirmationNumber": $rootScope.formData['confirmationNumber'], "questionAnswerList": questionAnswerList }, "response": { "status":".//return/result" }, "sid": $rootScope.cts.sid }; $http.post('api.php', call).then(function(all) { $scope.reschedule(); }); } else { $scope.reschedule(); } }; $scope.reschedule = function() { call = { "method":"rescheduleAppointment", "request": { "confirmationNumber": $rootScope.formData['confirmationNumber'], "startDateTime": moment.tz($rootScope.formData['appointmentStartDate'],$rootScope.getTimezone()).format("YYYY-MM-DDTHH:mm:ss.000Z") }, "response": { "status": ".//return/result" }, "sid": $rootScope.cts.sid }; $http.post('api.php', call).then(function(all) { if (all.data.success) { $rootScope.status = "Modified"; //$location.path( "confirm" ); $scope.sendEmailModification(); $rootScope.setLoading(false); $rootScope.ready = false;//Completed the reschedule process, using the browser back button will cause a hard reload of the app. } else { console.log("Error: "+all.data.error); console.log("Response Body:"); console.log(all.data.response); console.log("Request Data:"); console.log(call.request); $rootScope.error = "There was a problem rescheduling this appointment."; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); } }); }; $scope.sendEmailModification = function() { call = { "method":"sendEmailModification", "request": { "confirmationNumber": $rootScope.formData['confirmationNumber'] }, "response": { "status": ".//return/result" }, "sid": $rootScope.cts.sid }; $http.post('api.php', call).then(function(all) { if (all.data.success) { //success } else { console.log("Sending email notification failed:"); console.log(all); } }); }; $scope.cancel = function() { data = { cancelAppointment:"get", sid: $rootScope.cts.sid }; $rootScope.setLoading(true); $http.post('session.php', angular.extend(data, $rootScope.formData)).then(function(result) { if (result.data['success'] == false) { $rootScope.error = "The deadline for cancelling has passed please call for assistance."; } $rootScope.status = "Cancelled"; $location.path( "confirm" ); $rootScope.setLoading(false); }); } $scope.addToCal = function() { var location; location = $rootScope.getLocation()["locationName"]; var title = $rootScope.getActivity()["activityName"]; var description = ''; var newline; if ($rootScope.formData.cal == 'ical') { newline = '\\n'; } else { newline = "\n"; } var phoneNumbers = ''; for (var pnum in $rootScope.getLocation()['phoneNumbers']){ if ($rootScope.getLocation()['phoneNumbers'].hasOwnProperty(pnum)) { if ($rootScope.getLocation()['phoneNumbers'][pnum]) { phoneNumbers += pnum + ": " + $rootScope.getLocation()['phoneNumbers'][pnum] + newline; } } } var dateTime = document.getElementById('dateTimeTimeZone').innerText; dateTime = dateTime.replace(/(\r\n|\n|\r)/gm,newline); var displayDescription = document.querySelector(".reviewTable").innerText; displayDescription = displayDescription.replace(/(\r\n|\n|\r)/gm,newline); //$rootScope.formData.confirmationNumber description += $filter('getLang')("CONFIRMATION # ") + $rootScope.formData.confirmationNumber + newline + newline; description += dateTime + newline + newline; description += displayDescription + newline + newline; description += $filter('getLang')("To cancel or reschedule this appointment, refer to your confirmation email."); var startDate = $rootScope.formData.appointmentStartDate; var endDate = $rootScope.formData.appointmentEndDate; if ($rootScope.formData.cal == 'ical') { var elements = [ 'BEGIN:VCALENDAR', 'VERSION:2.0', 'BEGIN:VEVENT', 'CLASS:PUBLIC', 'DESCRIPTION:' + description, /*'DTSTART:' + startDate.replace(/-|:/g,''),*/ 'DTSTART;TZID=' + $rootScope.getTimezone() + ':' + startDate.replace(/-|:/g,''), 'DTEND;TZID=' + $rootScope.getTimezone() + ':' + endDate.replace(/-|:/g,''), 'LOCATION:' + location, 'SUMMARY:' + title, 'TRANSP:TRANSPARENT', 'END:VEVENT', 'END:VCALENDAR' ]; var downloadURL = "download.php?d=" + encodeURIComponent(description) + "&s=" + $rootScope.getTimezone() + ':' + startDate.replace(/-|:/g,'') + "&e=" + $rootScope.getTimezone() + ':' + endDate.replace(/-|:/g,'') + "&l=" + location + "&t=" + title; var iframe = document.createElement("iframe"); iframe.setAttribute("src", downloadURL); iframe.setAttribute("style", "display: none"); document.body.appendChild(iframe); } if ($rootScope.formData.cal == 'google') { var googleCalendarUrl = 'https://www.google.com/calendar/render?action=TEMPLATE'; googleCalendarUrl += '&text=' + encodeURIComponent(title); googleCalendarUrl += '&dates=' + encodeURIComponent(startDate.replace(/-|:/g,'')) + '/' + encodeURIComponent(endDate.replace(/-|:/g,'')); googleCalendarUrl += '&ctz=' + $rootScope.getTimezone(); googleCalendarUrl += '&details=' + encodeURIComponent(description); googleCalendarUrl += '&location=' + encodeURIComponent(location); window.open(googleCalendarUrl); } $rootScope.formData.cal = "0"; }; $scope.appendAppointmentAnswers(); }function customController($rootScope, $scope, $http, $location, $filter) { $rootScope.setLoading(false); }function errorController($rootScope, $scope, $http, $location) { $rootScope.setLoading(false); }function infoscheduleController($rootScope, $scope, $http, $location, $filter) { $rootScope.setLoading(false); }function locationController($rootScope, $scope, $http, $location, $timeout, $route) { $rootScope.setLoading(true); if (!$rootScope.mapProviderLoaded) { var mapProviderScript = document.createElement('script'); mapProviderScript.onload = function () { $rootScope.mapProviderLoaded = true; $rootScope.ready = true; $route.reload(); }; if ($rootScope.mapProvider == "mapbox") { mapProviderScript.src = "https://api.mapbox.com/mapbox-gl-js/v1.4.1/mapbox-gl.js"; //mapProviderScript.src = "https://api.mapbox.com/mapbox-gl-js/v1.13.0/mapbox-gl.js"; if (!$rootScope.isMobile) { var mapProviderStyle = document.createElement('link'); mapProviderStyle.href = "https://api.mapbox.com/mapbox-gl-js/v1.4.1/mapbox-gl.css"; //mapProviderStyle.href = "https://api.mapbox.com/mapbox-gl-js/v1.13.0/mapbox-gl.css"; mapProviderStyle.rel = "stylesheet"; document.head.appendChild(mapProviderStyle); } var mapProviderGeocoder = document.createElement('script'); mapProviderGeocoder.src = "https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v4.4.2/mapbox-gl-geocoder.min.js"; //mapProviderGeocoder.src = "https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v4.7.0/mapbox-gl-geocoder.min.js"; document.head.appendChild(mapProviderGeocoder); if (moment.locale().split("-")[0] != "en") { var mapProviderLanguage = document.createElement('script'); mapProviderLanguage.src = "https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-language/v0.10.1/mapbox-gl-language.js"; document.head.appendChild(mapProviderLanguage); } } else if ($rootScope.mapProvider == "google") { mapProviderScript.src = "https://maps.googleapis.com/maps/api/js?v=3.exp&key="+$rootScope.googleMapsApiKey+"&language="+moment.locale().split("-")[0]+"®ion="+moment.locale().split("-")[1]+"&libraries=places,geometry"; } document.head.appendChild(mapProviderScript); return; } $scope.setLocation = function(locationExternalId) { $rootScope.formData['locationExternalId'] = locationExternalId; } $scope.setFormattedAddress = function(Latitude, Longitude) { //console.log("setFormattedAddress"); $rootScope.formData.latitude = Latitude; $rootScope.formData.longitude = Longitude; $scope.doneFormattedAddress = true; if ($rootScope.mapProvider === "google") { var geoLatLng = new google.maps.LatLng(Latitude, Longitude); $scope.geocoder.geocode({ 'location': geoLatLng }, function (results, status) { if (status === google.maps.GeocoderStatus.OK) { //console.log(results); result = false; locs = results.length; for (l=0;l<locs;l++) { types = results[l]["types"].length; for (t=0;t<types;t++) { if (results[l]["types"][t] == "locality" | results[l]["types"][t] == "sublocality") { $scope.input.value = results[l]["formatted_address"]; $scope.input.text = results[l]["formatted_address"]; result = true; l=locs; break; } } } if (!result) { $rootScope.debug('No suburb found, trying first location returned.'); $scope.input.value = results[0]["formatted_address"]; $scope.input.text = results[0]["formatted_address"]; } } else { $rootScope.debug('Geocoder failed due to: ' + status); } }); } else if ($rootScope.mapProvider === "mapbox") { delete $scope.geocoder.options.proximity; $scope.geocoder.options.reverseGeocode = true; $scope.geocoder.options.types = "locality, neighborhood, place, district, region, country"; $scope.geocoder.query($rootScope.formData.latitude+", "+$rootScope.formData.longitude); $scope.geocoder.options.reverseGeocode = false; $scope.geocoder.options.types = $rootScope.cts.settings["mapResultTypes"] || "address, locality, neighborhood, place, district, postcode, region, country";//not poi } } $scope.addMarker = function(Latitude, Longitude, Index, Title) { if ($rootScope.isMobile) { return; } if ($rootScope.mapProvider == "mapbox") { var el = document.createElement('div'); el.className = 'marker'; el.style.backgroundImage = "url('"+$scope.icons[$scope.markers.length]+"')"; var marker = new mapboxgl.Marker(el) .setLngLat([Longitude,Latitude]) .addTo($scope.map); $scope.markers.push(marker); } else if ($rootScope.mapProvider == "google") { var pin = new google.maps.LatLng(Latitude, Longitude) var marker = new google.maps.Marker({ position: pin, map: $scope.map, title: Title, icon: $scope.icons[Index] }); $scope.markers.push(marker); } } $scope.showTen = function(Latitude, Longitude) { //console.log("showTen"); $rootScope.formData.latitude = Latitude; $rootScope.formData.longitude = Longitude; $scope.doneShowTen = true; if ($rootScope.mapProvider == "mapbox") { for (var i=0;i<$scope.markers.length;i++) { $scope.markers[i].remove(); } } else if ($rootScope.mapProvider == "google") { for (var i=0;i<$scope.markers.length;i++) { $scope.markers[i].setMap(null); } var pos = new google.maps.LatLng(Latitude,Longitude); google.maps.event.trigger(this.map, 'resize'); $scope.map.setCenter(pos); } $scope.markers = []; $scope.getClosest(Latitude,Longitude); } $scope.setMapZoom = function(Num) { if ($rootScope.isMobile) { return; } var current = 1; if ($rootScope.mapProvider == "mapbox") { current = 24.6 - (Math.log(Num*2) / Math.log(2)); } else if ($rootScope.mapProvider == "google") { Num = Math.round(Num / 1000); for(i=1;i<=15;i++) { if (Math.abs(Num - $scope.zoomLevels[i]) < Math.abs(Num - $scope.zoomLevels[current])) { current = i; } } } $scope.map.setZoom(current); } $scope.getSortedKeys = function(obj) { var keys = []; for (var key in obj) { if (key != '') { keys.push([key, obj[key]]); keys.sort(function(a, b) { return a[1] - b[1]; }); } } return keys; } //used? /*$scope.checkIsAvailability = function(locationExternalId,locationsSortedIndex,startDate) { data = { getFirstAvailableDateTimeSlotByDateRange:"get", startDate: startDate ? startDate : "", numberOfDays: 182, checkLocationExternalId: locationExternalId, locationsSortedIndex: locationsSortedIndex, timezone:$rootScope.locations[locationsSortedIndex]['timezone'], sid: $rootScope.cts.sid }; $http.post('session.php', angular.extend({}, $rootScope.formData, data)).then(function(all) { if (all.data.SOAPresponse.faultstring) { $rootScope.error = all.data.SOAPresponse.faultstring; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); return; } if (all.data['isAvailability']) { var index = $rootScope.topten.length; $rootScope.topten.push($rootScope.locations[locationsSortedIndex]); $scope.addMarker($rootScope.topten[index]['geocoordinates']['latitude'], $rootScope.topten[index]['geocoordinates']['longitude'], index, $rootScope.topten[index]['locationName']);//add a marker on the map for this location $rootScope.locations[locationsSortedIndex]['firstAvailableDateTime'] = all.data['firstAvailableDateTime']; if ($rootScope.topten.length >= $rootScope.showLocationAmount || (all.data['locationsSortedIndex']+1) >= $rootScope.locations.length) { $scope.setMapZoom($rootScope.topten[index]['distance']); } $rootScope.setLoading(false); } else { if (all.data['nextDateTime']) { $scope.checkIsAvailability($rootScope.locations[all.data['locationsSortedIndex']]['locationExternalId'],all.data['locationsSortedIndex'],all.data['nextDateTime']); return; } } if ($rootScope.topten.length < $rootScope.showLocationAmount && (all.data['locationsSortedIndex']+10) < $rootScope.locations.length) { $rootScope.loadingMessage = "Looking for locations with availability ("+all.data['locationsSortedIndex']+"/"+$rootScope.locations.length+"). Found ("+$rootScope.topten.length+"/"+$rootScope.showLocationAmount+")"; $scope.checkIsAvailability($rootScope.locations[all.data['locationsSortedIndex']+10]['locationExternalId'],all.data['locationsSortedIndex']+10,false); } if ((all.data['locationsSortedIndex']+1) >= $rootScope.locations.length && $rootScope.topten.length == 0) { alert("No locations found"); $rootScope.setLoading(false); } }); } */ $scope.getClosest = function(Latitude, Longitude) { //console.log("getClosest"); var distances = {}; var totalGeoLocations = 0; var m; for (var index in $rootScope.locations) { if ($rootScope.locations[index]['geocoordinates']) { m = $rootScope.calDistance(Longitude,Latitude,$rootScope.locations[index]['geocoordinates']['longitude'],$rootScope.locations[index]['geocoordinates']['latitude']); distances[$rootScope.locations[index]['locationExternalId']] = +(Math.round(m + "e+2") + "e-2"); distances[$rootScope.locations[index]['timezone']] = +(Math.round(m + "e+2") + "e-2"); $rootScope.locations[index]['distance'] = +(Math.round(m + "e+2") + "e-2"); totalGeoLocations++; } } $rootScope.showLocationAmount = totalGeoLocations < 10 ? totalGeoLocations : 10; $rootScope.locations.sort(function (a, b) { return a.distance < b.distance ? -1 : a.distance > b.distance ; }); $rootScope.topten = []; if ($rootScope.showLocationAmount > 0) { var locationCount = $rootScope.locations.length >= 10 ? 10 : $rootScope.locations.length; for (var i=0;i<locationCount;i++) { if ($rootScope.locations[i]['distance'] <= 2000000) { $rootScope.topten.push($rootScope.locations[i]); $scope.addMarker($rootScope.topten[i]['geocoordinates']['latitude'], $rootScope.topten[i]['geocoordinates']['longitude'], i, $rootScope.topten[i]['locationName']); } if ($rootScope.topten.length >= 10 || i == ($rootScope.locations.length - 1)) { if ($rootScope.topten.length > 0) { $scope.setMapZoom($rootScope.topten[$rootScope.topten.length-1]['distance']); } else { $scope.setMapZoom(2000000); } } } $rootScope.setLoading(false); } else { alert("No locations found"); $rootScope.setLoading(false); } } $scope.useLocation = function(Latitude, Longitude) { if (Latitude === false || Longitude === false) { if ($rootScope.formData.latitude && $rootScope.formData.longitude) { if (!$scope.doneFormattedAddress) { $scope.setFormattedAddress($rootScope.formData.latitude, $rootScope.formData.longitude); } if (!$scope.doneShowTen) { $scope.showTen($rootScope.formData.latitude, $rootScope.formData.longitude); } $timeout(function(){$scope.$apply();}); } else { LatLngData = { "getLatLng":"get", "sid": $rootScope.cts.sid }; $http.post('session.php', LatLngData).then(function(all) { //$http.get('session.php?getLatLng=get&sid='+$rootScope.cts.sid).then(function(all) { var ipLat = all.data['latitude']; var ipLng = all.data['longitude']; if (!ipLat || !ipLng) { ipLat = $rootScope.defaultLatitude; ipLng = $rootScope.defaultLongitude; } $scope.setFormattedAddress(ipLat, ipLng); $scope.showTen(ipLat, ipLng); $timeout(function(){$scope.$apply();}); }); } } else { $scope.setFormattedAddress(Latitude, Longitude); $scope.showTen(Latitude, Longitude); $timeout(function(){$scope.$apply();}); } } $scope.getAllLocationGroups = function(locationExternalId) { getAllLocationGroups = { "method":"getAllLocationGroups", //"service":"ConfigurationServices", "request": {}, "response": { //"locationGroups":".//return/locationGroups/locationGroupExtId[starts-with(., '"+$rootScope.prefill['locationGroupIdPrefix']+"')]" "locationGroups":".//return/locationGroups/locationGroupExtId[starts-with(., '"+$rootScope.prefill['external']+"')]" }, "sid": $rootScope.cts.sid }; $http.post('api.php', getAllLocationGroups).then(function(all) { //console.log(all.data.response.locationGroups); if (all.data.response.locationGroups) { loadingExternal = all.data.response.locationGroups.length; for (var i=0;i<all.data.response.locationGroups.length;i++) { $scope.getLocationGroup(all.data.response.locationGroups[i][0]); } } else { $rootScope.error = "No location groups found"; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); return; } }); } $scope.getLocationGroup = function(locationGroupExtId) { //restrict by campaign? getLocationGroup = { "method":"getLocationGroup", //"service":"ConfigurationServices", "request": { "locationGroupExtId": locationGroupExtId }, "response": { "locationExternalIds": ".//return/locationGroup/locationExternalIds" }, "sid": $rootScope.cts.sid }; $http.post('api.php', getLocationGroup).then(function(all) { if (all && all.data && all.data.response && all.data.response.locationExternalIds) { for (var i = 0;i<all.data.response.locationExternalIds.length;i++) { var refLocation = $rootScope.getLocation(all.data.response.locationExternalIds[i][0]); if (refLocation) { refLocation.locationGroupExtId = locationGroupExtId; //refLocation.locationGroupExtIdPrefix = locationGroupExtId.split("-")[0];//??? //refLocation.locationGroupExtIdSuffix = locationGroupExtId.split("-")[1];//??? } } } loadingExternal--; if (!loadingExternal) { var numLocations = $rootScope.locations ? $rootScope.locations.length : 0; for (var i=numLocations-1;i>=0;i--) { if (!$rootScope.locations[i]['locationGroupExtId']) { $rootScope.locations.splice(i, 1); } } if (numLocations > 0) { $scope.initialize(); } else { $rootScope.error = "No location available."; $rootScope.ready = true; $rootScope.showErrorButton('clearAppointmentTypeId'); $location.path( 'error' ); return; } } }); } $scope.preloadLocations = function() { //can't filter by locationGroupExtId for some reason api wont work var criteria = {}; if ($rootScope.formData['campaignExternalId']) { criteria["campaignExternalId"] = $rootScope.formData['campaignExternalId']; } if ($rootScope.formData['programExternalId']) { criteria["programExternalId"] = $rootScope.formData['programExternalId']; } if ($rootScope.formData['activityExternalId']) { criteria["activityExternalId"] = $rootScope.formData['activityExternalId']; } if ($rootScope.formData['resourceExternalId'] && $rootScope.formData['resourceExternalId'] != 'any') { criteria["resourceExternalId"] = $rootScope.formData['resourceExternalId']; } getLocationsByCriteria = { "method":"getLocationsByCriteria", //"service":"ConfigurationServices", "request": { "locationSearchCriteria": criteria }, "response": { "locations":".//return/locations[isDeleted='false'][locationExternalId][locationAvailabilityType='Administrators, receptionists, and clients'][geocoordinates/latitude!='0.0'][geocoordinates/longitude!='0.0']" }, "sid": $rootScope.cts.sid }; $http.post('api.php', getLocationsByCriteria).then(function(all) { $rootScope.locations = all.data.response.locations; if ($rootScope.prefill['locationGroupId'] || $rootScope.formData.locationGroupExtId) {//Get location group loadingExternal = 1; $scope.getLocationGroup($rootScope.prefill['locationGroupId']); } else if ($rootScope.prefill['external']) {//Get group of location groups $scope.getAllLocationGroups(); } else { if ($rootScope.locations) { $scope.initialize(); } else { $rootScope.error = "No locations available."; $rootScope.ready = true; $rootScope.showErrorButton('clearLocationCriteria');//clears campaign, program and activity $location.path( 'error' ); return; } } }); } $scope.initialize = function () { $rootScope.formData.week = 0; $rootScope.formData.month = 0; //set lat long variables from defaults to use below if ($rootScope.mapProvider == "mapbox") { $scope.zoomLevels = {0:33187,1:16593,2:8296,3:4148,4:2074,5:1037,6:518,7:259,8:129,9:64,10:33,11:9,12:8,13:5,14:3,15:2,16:1,17:0.6,18:0.3,19:0.2,20:0.07,21:0.04,22:0.02};//fix $scope.markers = []; $scope.icons = ['images/0.png','images/1.png','images/2.png','images/3.png','images/4.png','images/5.png','images/6.png','images/7.png','images/8.png','images/9.png']; mapboxgl.accessToken = $rootScope.mapboxApiKey; if ($rootScope.rtl) { mapboxgl.setRTLTextPlugin('https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-rtl-text/v0.2.3/mapbox-gl-rtl-text.js'); } if (!$rootScope.isMobile) { $scope.map = new mapboxgl.Map({ container: 'map-canvas', style: 'mapbox://styles/codezeno/ck2l00jj50mt91cmmz8p21dzu', center: [$rootScope.defaultLongitude, $rootScope.defaultLatitude], zoom: 6 }); if (moment.locale().split("-")[0] != "en") { $scope.map.addControl(new MapboxLanguage({ defaultLanguage: moment.locale().split("-")[0] })); } } $scope.geoButton = (document.getElementById('geoButton')); $scope.geocoder = new MapboxGeocoder({ accessToken: mapboxgl.accessToken, flyTo: false, marker: false, enableEventLogging: false,//Allow Mapbox to collect anonymous usage statistics trackProximity: false, /*proximity: { latitude:5.6, longitude:78.8 },//searches closer to this location are given priority*/ countries: $rootScope.cts.settings["mapCountryFilter"] ? $rootScope.cts.settings["mapCountryFilter"] : "", //reverseGeocode: false, types: $rootScope.cts.settings["mapResultTypes"] || "address, locality, neighborhood, place, district, postcode, region, country",//not poi language: moment.locale(), limit: 5 }); $scope.geocoder.on('result', function(position) { $scope.showTen(position.result.center[1], position.result.center[0]); if (!$rootScope.isMobile) { $scope.map.setCenter([position.result.center[0], position.result.center[1]]); } $scope.$apply(); }); if (!$rootScope.isMobile) { $scope.map.on('moveend', function() { var center = $scope.map.getCenter().wrap(); $scope.geocoder.setProximity({ longitude: center.lng, latitude: center.lat }); }); } if ($rootScope.isMobile) { document.getElementById('geocoder').appendChild($scope.geocoder.onAdd()); } else { document.getElementById('geocoder').appendChild($scope.geocoder.onAdd($scope.map)); } if ($rootScope.locationProvider == "browser" && navigator.geolocation) { navigator.geolocation.getCurrentPosition(function(position) { $scope.useLocation(position.coords.latitude, position.coords.longitude); }, function(error) { $scope.useLocation(false, false); }, { enableHighAccuracy: true, //timeout: 0, maximumAge: 1000, }); } else { $scope.useLocation(false, false); } $scope.geoButton.addEventListener("click", $scope.geoLocate); //delete language setting for english so there is no result weighting around language. e.g. searches for Bris would show places in England if ($scope.geocoder.options.language.substring(0, 2) == "en") { delete $scope.geocoder.options.language; } } else if ($rootScope.mapProvider == "google") { $scope.mapOptions = {center: new google.maps.LatLng($rootScope.defaultLatitude, $rootScope.defaultLongitude),zoom:6}; $scope.map = new google.maps.Map(document.getElementById('map-canvas'), $scope.mapOptions); $scope.input = (document.getElementById('pac-input')); //$scope.autocomplete = new google.maps.places.Autocomplete($scope.input, {componentRestrictions: {country: "au"}}); $scope.autocomplete = new google.maps.places.Autocomplete($scope.input, {fields: ["geometry.location"]}); $scope.autocomplete.bindTo('bounds', $scope.map); $scope.markers = []; $scope.icons = ['images/0.png','images/1.png','images/2.png','images/3.png','images/4.png','images/5.png','images/6.png','images/7.png','images/8.png','images/9.png']; $scope.zoomLevels = {1:15000,2:7500,3:3750,4:1875,5:937,6:200,7:110,8:90,9:40,10:29,11:14,12:7,13:3,14:2,15:1}; $scope.geoButton = (document.getElementById('geoButton')); $scope.geocoder = new google.maps.Geocoder(); google.maps.event.addListener($scope.autocomplete, 'place_changed', function() { var place = $scope.autocomplete.getPlace(); if (!place.geometry) { return; } else { $scope.showTen(place.geometry.location.lat(),place.geometry.location.lng()); $scope.$apply(); } }); google.maps.event.addDomListener($scope.input, 'keydown', function(e) { var code = (e.keyCode ? e.keyCode : e.which); if(code===13 && !e.triggered){ if (document.querySelector('.pac-item-selected') == null) { google.maps.event.trigger(this,'keydown',{keyCode:40}); } google.maps.event.trigger(this,'keydown',{keyCode:13,triggered:true}); } }); google.maps.event.addDomListener($scope.input, 'focus', function() { var self = this;setTimeout(function() {self.setSelectionRange(0, 9999);}, 0); }); google.maps.event.addDomListener($scope.geoButton, 'click', $scope.geoLocate); if ($rootScope.locationProvider == "browser" && navigator.geolocation) { navigator.geolocation.getCurrentPosition(function(position) { $scope.useLocation(position.coords.latitude, position.coords.longitude); }, function(error) { $scope.useLocation(false, false); }, { enableHighAccuracy: true, //timeout: 0, maximumAge: 1000, }); } else { $scope.useLocation(false, false); } $rootScope.setLoading(false); } } $scope.geoLocate = function() { if(navigator.geolocation) { navigator.geolocation.getCurrentPosition(function(position) { $scope.useLocation(position.coords.latitude, position.coords.longitude); }, function(error) { $scope.useLocation(false, false); }, { enableHighAccuracy: true, //timeout: 0, maximumAge: 100, }); } } //needed for dom manipulation, such as geocoder angular.element(document).ready(function () { //needed to apply changes to $rootScope.loading $timeout(function () { $scope.preloadLocations(); }, 0); }); }function mainController($rootScope, $scope, $http, $location, $q) { if (!$rootScope.ready) { $rootScope.setLoading(true); //getClientRegistrationInfo // // used to find out what fields are enabled in admin //getClientCustomQuestions // // used to get select list data // match questionExternalId with one from getClientRegistrationInfo // has <fieldProperty>Answer1</fieldProperty> that can be matched to getUILabelsPerApp using a map e.g. Answer1 > customField1 //getUILabelsPerApp // // used to get labels to use for the client fields that are enabled // must use a map to map customField1 to the <fieldProperty> of getClientCustomQuestions //map example // // map = { // Answer1: "customField1" // } //Usage // // label = getUILabelsPerApp[ map[ getClientCustomQuestions['fieldProperty'] ] ]; // label = getUILabelsPerApp[ map[ "Answer1" ] ]; // label = getUILabelsPerApp[ "customField1" ]; // label = "Country Code" //NEED TO CHECK FOR STATE FIELD HERE AND USE ROOTSCOPE.STATES IF FOUND $scope.preloadClientFields = function() { data = { preloadClientFields:"x", sid: $rootScope.cts.sid }; var fieldsAPI = []; var fieldOptions = []; var fieldLabels = []; $http.post('session.php', data).then(function(all) { var apiDown = "A security error was encountered when verifying the message ( HTTP/1.1 500 )"; if (all.data.getClientRegistrationInfo.error == apiDown && all.data.getClientCustomQuestions.error == apiDown && all.data.getUILabelsPerApp.error == apiDown) { $rootScope.error = "API down, try again later."; $rootScope.ready = true; $rootScope.showErrorButton(); $location.path('error'); return; } fieldsAPI = all.data.getClientRegistrationInfo.response.fields || []; fieldOptions = all.data.getClientCustomQuestions.response.fieldOptions; fieldLabels = all.data.getUILabelsPerApp.response.clientLabels; $rootScope.labels = all.data.getUILabelsPerApp.response; $rootScope.attendeeFields = []; if ($rootScope.getStep("attendee")) { //loop over fieldsAPI and insert options and fieldProperty from fieldOptions for (var i=0;i<fieldsAPI.length;i++) { var index = fieldOptions ? $rootScope.getItemIndex(fieldOptions, "questionExternalId", fieldsAPI[i]["questionExternalId"]) : -1; if (index !== -1) { fieldsAPI[i]["options"] = fieldOptions[index]["option"] ? (Array.isArray(fieldOptions[index]["option"]) ? fieldOptions[index]["option"] : [fieldOptions[index]["option"]]) : false; fieldsAPI[i]["fieldProperty"] = fieldOptions[index]["fieldProperty"]; } else { if (fieldsAPI[i]["questionExternalId"] === "StateId") { fieldsAPI[i]["options"] = $rootScope.states; fieldsAPI[i]["fieldProperty"] = "StateId"; } else { fieldsAPI[i]["options"] = false; fieldsAPI[i]["fieldProperty"] = fieldsAPI[i]["questionExternalId"]; } } } } var steps = [$rootScope.getStep("attendee"),$rootScope.getStep("question")]; for (var x in steps) { if (steps[x]) { var fieldsXML = steps[x]["parameters"]; for (var i=0;i<fieldsXML.length;i++) { if (!fieldsAPI) { fieldsAPI = []; } //Check each XML field exists in the API fields array field = $rootScope.existsArrayKeyValue(fieldsAPI,"fieldProperty",fieldsXML[i]["fieldMap"]) || false; label = fieldsXML[i]["type"] == "label"; appointmentQuestion = fieldsXML[i]["type"] == "appointmentQuestion"; heading = fieldsXML[i]["type"] == "heading"; line = fieldsXML[i]["type"] == "line"; if (field) { //Check each XML field exists in the field Labels array var labelItem = $rootScope.getItem(fieldLabels,"key",$rootScope.fieldMap[fieldsXML[i]["fieldMap"]]) || false; var labelValue = fieldsXML[i]["label"]; //if there is a label from the API we use it, otherwise we use the label from the XML. if (labelItem !== false) { labelValue = labelItem["value"]; } $rootScope.attendeeFields.push( { filter: fieldsXML[i]["filter"] || false,//regex to restrict characters to fieldMatch: fieldsXML[i]["fieldMatch"] || false,//regex pattern to check against min: fieldsXML[i]["required"] === true || field["required"] == "true" ? fieldsXML[i]["minlength"] || field["minFieldValue"] : 0, max: fieldsXML[i]["maxlength"] || field["maxFieldValue"], type: field["questionType"], required: fieldsXML[i]["required"] === true || field["required"] == "true" ? true : false, defaultResponse: field["questionType"] == "Checkbox" ? (field["defaultResponse"] == "1" ? true : false) : field["defaultResponse"] || false, options: field["options"], fieldProperty: fieldsXML[i]["fieldMap"], id: $rootScope.fieldMap[fieldsXML[i]["name"]], name: fieldsXML[i]["name"], label: labelValue, hideLabel: fieldsXML[i]["hideLabel"], hidden: fieldsXML[i]["hidden"], group: "client", width: fieldsXML[i]["width"] || false, place: fieldsXML[i]["place"] || false, style: fieldsXML[i]["style"] || false, step: x == 1 ? "question" : "attendee" } ); } else if (label) { $rootScope.attendeeFields.push( { type: "Label", required: fieldsXML[i]["required"] === true ? true : false, label: fieldsXML[i]["label"], hidden: fieldsXML[i]["hidden"], width: fieldsXML[i]["width"] || false, place: fieldsXML[i]["place"] || false, style: fieldsXML[i]["style"] || false, step: x == 1 ? "question" : "attendee" } ); } else if (appointmentQuestion) { $rootScope.attendeeFields.push( { type: "appointmentQuestion", id: "appointment_"+fieldsXML[i]["id"], hideLabel: fieldsXML[i]["hideLabel"], hidden: fieldsXML[i]["hidden"], place: fieldsXML[i]["place"] || false, style: fieldsXML[i]["style"] || false, step: x == 1 ? "question" : "attendee" } ); } else if (heading) { $rootScope.attendeeFields.push( { type: "heading", label: fieldsXML[i]["label"], width: fieldsXML[i]["width"] || false, style: fieldsXML[i]["style"] || false, step: x == 1 ? "question" : "attendee" } ); } else if (line) { $rootScope.attendeeFields.push( { type: "line", width: fieldsXML[i]["width"] || false, style: fieldsXML[i]["style"] || false, step: x == 1 ? "question" : "attendee" } ); } } } } for (var x in steps) { if (steps[x]) { if ($rootScope.getStep('question')) { $rootScope.filterFieldsAttendee = { step: 'attendee' }; $rootScope.filterFieldsQuestion = { step: 'question' }; } if (steps[x].stepExternalId === "attendee") { //if no question step all fields will be in attendee steps[x].parameters = $rootScope.getItemsArrayObject($rootScope.attendeeFields,$rootScope.filterFieldsAttendee); } else { steps[x].parameters = $rootScope.getItemsArrayObject($rootScope.attendeeFields,$rootScope.filterFieldsQuestion); } } } $scope.init(); }).catch(function(error) { console.log(error); console.log("Problem preloading client fields."); }); } $scope.preloadLocations = function() { //can't filter by locationGroupExtId for some reason api wont work var criteria = {}; if ($rootScope.prefill.campaignId) { criteria["campaignExternalId"] = $rootScope.prefill.campaignId; } if ($rootScope.prefill.appointmentTypeGroupId) { criteria["programExternalId"] = $rootScope.prefill.appointmentTypeGroupId; } if ($rootScope.prefill.appointmentTypeId) { criteria["activityExternalId"] = $rootScope.prefill.appointmentTypeId; } if ($rootScope.prefill.resourceId && $rootScope.prefill.resourceId != 'any') { criteria["resourceExternalId"] = $rootScope.prefill.resourceId; } getLocationsByCriteria = { "method":"getLocationsByCriteria", //"service":"ConfigurationServices", "request": { "locationSearchCriteria": criteria }, "response": { "locations":".//return/locations[isDeleted='false'][locationExternalId][locationAvailabilityType='Administrators, receptionists, and clients'][geocoordinates/latitude!='0.0'][geocoordinates/longitude!='0.0']" }, "sid": $rootScope.cts.sid }; $http.post('api.php', getLocationsByCriteria).then(function(all) { $rootScope.locations = all.data.response.locations; if ($rootScope.prefill['locationGroupId'] || $rootScope.formData.locationGroupExtId) {//Get location group loadingExternal = 1; $scope.getLocationGroup($rootScope.prefill['locationGroupId']); } else if ($rootScope.prefill['external']) {//Get group of location groups $scope.getAllLocationGroups(); } else { if ($rootScope.locations) { $scope.init(); } else { $rootScope.error = "No locations available."; $rootScope.ready = true; $rootScope.showErrorButton('clearAppointmentTypeId'); $location.path( 'error' ); return; } } }).catch(function(error) { console.log("Problem preloading locations: "+error.statusText+"("+error.status+")"); }); } /*$scope.preloadCampaigns = function() { getCampaigns = { "method":"getCampaigns", //"service":"ConfigurationServices", "request": { "locationExternalId": $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId }, "response": { "campaigns":".//return/campaigns[isDeleted='false'][isEnabled='true']" }, "sid": $rootScope.cts.sid }; $http.post('api.php', getCampaigns).then(function(all) { $rootScope.campaigns = all.data.response.campaigns; $scope.init(); }); } $scope.preloadPrograms = function() { getPrograms = { "method":"getPrograms", //"service":"ConfigurationServices", "request": { "campaignExternalId": $rootScope.formData['campaignExternalId'], "locationExternalId": $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId }, "response": { "programs":".//return/programs[deleted='false'][isEnabled='true'][not(suppressVisibilityPerApp/appName='"+$rootScope.cts.appName+"')]" }, "sid": $rootScope.cts.sid }; $http.post('api.php', getPrograms).then(function(all) { $rootScope.programs = all.data.response.programs; $scope.init(); }); } $scope.preloadActivities = function() { getActivities = { "method":"getActivities", //"service":"ConfigurationServices", "request": { "campaignExternalId": $rootScope.formData['campaignExternalId'], "locationExternalId": $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId }, "response": { "activities":".//return/activities[deleted='false'][isEnabled='true'][not(suppressVisibilityPerApp/appName='"+$rootScope.cts.appName+"')]" }, "sid": $rootScope.cts.sid }; $http.post('api.php', getActivities).then(function(all) { $rootScope.activities = all.data.response.activities; $scope.init(); }); }*/ $scope.getSingleAppointment = function(confirmationNumber) { //$rootScope.formData['holdConfirmationNumber'] //getAppointmentWithClientByConfirmationNumber not working with held appointments var appointment = './/return/appointmentWithClientData/*[local-name() = "appointmentData"][translate(clientLastname,"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz")="'+$rootScope.formData.client_lastName.toLowerCase()+'"]'; //var appointment = `.//return/appointmentWithClientData/*[local-name() = "appointmentData"][clientLastname="${$rootScope.formData.client_lastName}"]`; if ($rootScope.cts.features['singlePage']) { $scope.init(); return; } call = { "method":"getAppointmentWithClientByConfirmationNumber",//getAppointmentByConfirmationNumber "request": { "confirmationNumber": confirmationNumber }, "response": { "appointment": appointment }, "sid": $rootScope.cts.sid }; $http.post('api.php', call).then(function(all) { if (!all || !all.data || !all.data.success || all.data.error || all.error || !all.data.response || all.data.response.length < 1) { if ($rootScope.formData['holdConfirmationNumber']) { $rootScope.error = "Sorry we were unable to complete your request as the appointment's held confirmation number could not be found. Appointments are held for 30 minutes, if you have taken longer then this time you will need to start the process again."; } else if (!$rootScope.formData["client_lastName"]) { $rootScope.error = "Not enough details provided to find appointment."; } else { $rootScope.error = "No appointment exist with the details provided or it has been cancelled."; } $rootScope.ready = true; $rootScope.showErrorButton('none'); $location.path( 'error' ); return; } var pastAppointment = parseInt(moment(all.data.response.appointment[0]['appointmentStartDate']).format("x")) <= parseInt(moment().utc().format("x")); if (pastAppointment) { $rootScope.error = "This appointment has passed and can no longer be modified."; $rootScope.ready = true; $rootScope.showErrorButton('none'); $location.path( 'error' ); return; } $rootScope.formData['campaignExternalId'] = all.data.response.appointment[0]['campaignExternalId']; $rootScope.formData['locationExternalId'] = all.data.response.appointment[0]['locationExternalId']; $rootScope.formData['programExternalId'] = all.data.response.appointment[0]['programExternalId']; $rootScope.formData['activityExternalId'] = all.data.response.appointment[0]['activityExternalId']; $rootScope.formData['resourceExternalId'] = all.data.response.appointment[0]['resourceExternalId']; $rootScope.formData.clientExternalId = all.data.response.appointment[0]['clientExternalId']; $rootScope.formData.appointmentStartDate = all.data.response.appointment[0]['appointmentStartDate']; $rootScope.formData.appointmentEndDate = all.data.response.appointment[0]['appointmentEndDate']; $rootScope.formData.appointmentDurationMin = all.data.response.appointment[0]['appointmentDurationMin']; $rootScope.formData.client_firstName = all.data.response.appointment[0]['clientFirstname']; $rootScope.formData.client_lastName = all.data.response.appointment[0]['clientLastname']; $rootScope.status = all.data.response.appointment[0]['lifeCycleState']; //here instead of reviewfind step $rootScope.activities = Array(); $rootScope.activities[0] = Array(); $rootScope.activities[0]['activityName'] = all.data.response.appointment[0]['activityName']; $rootScope.activities[0]['activityDurations'] = Array(); $rootScope.activities[0]['activityDurations']['durationInMinutes'] = all.data.response.appointment[0]['appointmentDurationMin']; $rootScope.activities[0]['activityExternalId'] = all.data.response.appointment[0]['activityExternalId']; $rootScope.campaigns = Array(); $rootScope.campaigns[0] = Array(); $rootScope.campaigns[0]['campaignName'] = all.data.response.appointment[0]['campaignName']; $rootScope.campaigns[0]['campaignExternalId'] = all.data.response.appointment[0]['campaignExternalId']; if ($rootScope.formData['holdConfirmationNumber']) { //stop activityExternalId being set to blank on activity step $rootScope.prefill.appointmentTypeId = $rootScope.formData['activityExternalId']; } $scope.getScheduleRulesByCriteria($rootScope.formData['locationExternalId']);//init() }).catch(function(error) { console.log("Problem getting appointment: "+(error.statusText)+"("+error.status+")"); console.log(error); }); } $scope.getScheduleRulesByCriteria = function(locationExternalId) { var getScheduleRulesByCriteria = { "method":"getScheduleRulesByCriteria", "request": { "scheduleRulesSearchCriteria": { "locationExternalId": locationExternalId || "any", "rulesGroupExternalId": "client" } }, "response": { "rule": ".//return/scheduleRulesInfo", "rules": ".//return/scheduleRulesInfoList" }, "sid": $rootScope.cts.sid }; $http.post('api.php', getScheduleRulesByCriteria).then(function(all) { if (locationExternalId && all.data.response && !all.data.response.rule) { return $scope.getScheduleRulesByCriteria(); } if (all.data.error || all.error) { console.log("Problem getting schedule rules"); } if (all && all.data && all.data.response && all.data.response.rule && all.data.response.rule[0]['applyCloseOutPeriod'] == "true") { var closeOutSeconds = parseInt(all.data.response.rule[0]['closeOutPeriod']) * 60; var now = parseInt(moment().tz('UTC').format('X')); var appointmentTime = parseInt(moment($rootScope.formData.appointmentStartDate).tz('UTC').format('X')); var cutoffTime = appointmentTime - closeOutSeconds; if (now >= cutoffTime) { $rootScope.error = "This appointment can no longer be modified as it is too close to the appointment time."; $rootScope.ready = true; $rootScope.showErrorButton('none'); $location.path( 'error' ); return; } } $scope.init(); }).catch(function(error) { console.log("Problem getting schedule rules"); console.log(error); }); } $scope.getSingleLocation = function(locationExternalId) { var locFilter = "[locationAvailabilityType='Administrators, receptionists, and clients']"; if (!$rootScope.formData['locationExternalId']) { locFilter = ""; } getLocationsByCriteria = { "method":"getLocationsByCriteria", //"service":"ConfigurationServices", "request": { "locationSearchCriteria":{ "locationExternalId": $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId, } }, "response": { "locations":".//return/locations[isDeleted='false'][locationExternalId]"+locFilter }, "sid": $rootScope.cts.sid }; $http.post('api.php', getLocationsByCriteria).then(function(all) { $rootScope.locations = all.data.response.locations; if ($rootScope.locations && $rootScope.locations.length > 0) { if ($rootScope.prefill['external']) { $scope.getAllLocationGroups(); } else { $scope.init(); } } else { var loc = $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId; $rootScope.debug("location ("+loc+") not found, getting all locations"); $scope.preloadLocations(); //$rootScope.changeURL({'locationId':''}); } }).catch(function(error) { console.log("Problem getting location: "+error.statusText+"("+error.status+")"); }); } $scope.getSingleCampaign= function() { getCampaignByExternalId = { "method":"getCampaignByExternalId", //"service":"ConfigurationServices", "request": { "locationExternalId": $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId, "campaignExternalId": $rootScope.formData['campaignExternalId'] }, "response": { "campaign":".//return[isDeleted='false'][isEnabled='true']" }, "sid": $rootScope.cts.sid }; $http.post('api.php', getCampaignByExternalId).then(function(all) { if ($location.search()["action"] == "find") { $rootScope.error = "There was an error retrieving this appointment."; } else { $rootScope.error = "There was an error with the campaign."; } if (all && all.data) { if (all.data.error) { $rootScope.debug("Error getting campaign: "+all.data.error); } if (all.data.response && all.data.response.length < 1) { if ($location.search()["campaignId"] !== undefined) {//campaign is in url $rootScope.changeURL({"campaignId":""});//remove from url and reload } else { $rootScope.debug("No campaign found."); } } if (all.data.response && all.data.response.campaign) { $rootScope.campaigns = all.data.response.campaign; $rootScope.error = ""; $scope.init(); return; } } if ($rootScope.error != "") { $rootScope.ready = true; $rootScope.showErrorButton(); $location.path( 'error' ); return; } }).catch(function(error) { console.log("Problem getting campaign: "+error.statusText+"("+error.status+")"); }); } $scope.getSingleProgram = function() { getProgramByExternalId = { "method":"getProgramByExternalId", //"service":"ConfigurationServices", "request": { "locationExternalId": $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId, "programExternalId": $rootScope.formData['programExternalId'] }, "response": { "program":".//return[deleted='false'][isEnabled='true']" }, "sid": $rootScope.cts.sid }; $http.post('api.php', getProgramByExternalId).then(function(all) { if ($location.search()["action"] == "find") { $rootScope.error = "There was an error retrieving this appointment."; } else { $rootScope.error = "There was an error with the program."; } if (all && all.data) { if (all.data.error) { $rootScope.debug("Error getting program: "+all.data.error); } if (all.data.response && all.data.response.length < 1) { if ($location.search()["appointmentTypeGroupId"] !== undefined) {//program is in url $rootScope.changeURL({"appointmentTypeGroupId":""});//remove from url and reload } else { $rootScope.debug("No program found."); } } if (all.data.response && all.data.response.program) { $rootScope.programs = all.data.response.program; $rootScope.error = ""; $scope.init(); return; } } if ($rootScope.error != "") { $rootScope.ready = true; $rootScope.showErrorButton(); $location.path( 'error' ); return; } }).catch(function(error) { console.log(error); console.log("Problem getting program: "+error.statusText+"("+error.status+")"); }); } $scope.getSingleActivity = function() { var criteria = {}; if ($rootScope.formData['campaignExternalId']) { criteria["campaignExternalId"] = $rootScope.formData['campaignExternalId']; } if ($rootScope.formData['locationExternalId'] || $rootScope.defaultLocationExternalId) { criteria["locationExternalId"] = $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId; } if ($rootScope.formData['activityExternalId']) { criteria["activityExternalId"] = $rootScope.formData['activityExternalId']; } getActivityByExternalId = { "method":"getActivityByExternalId", //"service":"ConfigurationServices", "request": criteria, "response": { "activity":".//return[deleted='false'][isEnabled='true'][not(suppressVisibilityPerApp/appName='"+$rootScope.cts.appName+"')]" }, "sid": $rootScope.cts.sid }; $http.post('api.php', getActivityByExternalId).then(function(all) { if ($location.search()["action"] == "find") { $rootScope.error = "There was an error retrieving this appointment."; } else { $rootScope.error = "There was an error with the activity."; } if (all && all.data) { if (all.data.error) { $rootScope.debug("Error getting activity: "+all.data.error); } if (all.data.response && all.data.response.length < 1) { if ($location.search()["appointmentTypeId"] !== undefined) {//activity is in url $rootScope.changeURL({"appointmentTypeId":""});//remove from url and reload } else { $rootScope.debug("No activity found."); } } if (all.data.response && all.data.response.activity) { $rootScope.activities = all.data.response.activity; $rootScope.error = ""; $scope.init(); return; } } if ($rootScope.error != "") { $rootScope.ready = true; $rootScope.showErrorButton(); $location.path( 'error' ); return; } }).catch(function(error) { console.log("Problem getting activity: "+error.statusText+"("+error.status+")"); }); } $scope.getAllLocationGroups = function(locationExternalId) { getAllLocationGroups = { "method":"getAllLocationGroups", //"service":"ConfigurationServices", "request": {}, "response": { //"locationGroups":".//return/locationGroups/locationGroupExtId[starts-with(., '"+$rootScope.prefill['locationGroupIdPrefix']+"')]" "locationGroups":".//return/locationGroups/locationGroupExtId[starts-with(., '"+$rootScope.prefill['external']+"')]" }, "sid": $rootScope.cts.sid }; $http.post('api.php', getAllLocationGroups).then(function(all) { //console.log(all.data.response.locationGroups); if (all.data.response.locationGroups) { loadingExternal = all.data.response.locationGroups.length; for (var i=0;i<all.data.response.locationGroups.length;i++) { $scope.getLocationGroup(all.data.response.locationGroups[i][0]); } } else { $rootScope.error = "No location groups found"; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); return; } }).catch(function(error) { console.log("Problem getting location groups: "+error.statusText+"("+error.status+")"); }); } $scope.getLocationGroup = function(locationGroupExtId) { //restrict by campaign? getLocationGroup = { "method":"getLocationGroup", //"service":"ConfigurationServices", "request": { "locationGroupExtId": locationGroupExtId }, "response": { "locationExternalIds": ".//return/locationGroup/locationExternalIds" }, "sid": $rootScope.cts.sid }; $http.post('api.php', getLocationGroup).then(function(all) { if (all && all.data && all.data.response && all.data.response.locationExternalIds) { for (var i = 0;i<all.data.response.locationExternalIds.length;i++) { var refLocation = $rootScope.getLocation(all.data.response.locationExternalIds[i][0]); if (refLocation) { refLocation.locationGroupExtId = locationGroupExtId; //refLocation.locationGroupExtIdPrefix = locationGroupExtId.split("-")[0];//??? //refLocation.locationGroupExtIdSuffix = locationGroupExtId.split("-")[1];//??? } } } loadingExternal--; if (!loadingExternal) { var numLocations = $rootScope.locations ? $rootScope.locations.length : 0; for (var i=numLocations-1;i>=0;i--) { if (!$rootScope.locations[i]['locationGroupExtId']) { $rootScope.locations.splice(i, 1); } } if (numLocations > 0) { $scope.init(); } else { $rootScope.error = "No location available."; $rootScope.ready = true; $rootScope.showErrorButton('clearAppointmentTypeId'); $location.path( 'error' ); return; } } }).catch(function(error) { console.log("Problem getting location group: "+error.statusText+"("+error.status+")"); }); } /*$scope.getCoords = function() { $http.get('session.php?getLatLng=get&sid='+$rootScope.cts.sid).then(function(all) { if (!all.data['latitude'] || !all.data['longitude']) { //console.log("No location found, using default."); all.data['latitude'] = $rootScope.defaultLatitude; all.data['longitude'] = $rootScope.defaultLongitude; } $rootScope.formData['latitude'] = all.data['latitude']; $rootScope.formData['longitude'] = all.data['longitude']; $scope.init(); }); }*/ $scope.continue = function() { $rootScope.ready = true; $rootScope.gotoNextAvailableStep($rootScope.wf.steps[0]['stepExternalId']); //$location.path( $rootScope.wf.steps[0]['stepExternalId'] ); } waiting = false; done = { "getClientFields": false, "getAppointment": false, "getLocation": false, "getActivity": false, "getProgram": false, "getCampaign": false, //"getCoords": false, } $scope.init = function() { //console.log("init"); waiting = false; if ($rootScope.requireLocationGroupId && !$rootScope.formData.locationGroupExtId && $rootScope.wf.action == "schedule") { $rootScope.error = "No location group specified."; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); return; } if (!done['getClientFields']) { waiting = true; //console.log("getClientFields"); done['getClientFields'] = true; $scope.preloadClientFields(); } // GET SINGLE HELD APPOINTMENT if ($rootScope.formData['holdConfirmationNumber'] && !done['getAppointment'] && !waiting) { waiting = true; done['getAppointment'] = true; $scope.getSingleAppointment($rootScope.formData['holdConfirmationNumber']); } // GET SINGLE APPOINTMENT if ($rootScope.formData['confirmationNumber'] && !done['getAppointment'] && !waiting) { waiting = true; //console.log("getAppointment"); done['getAppointment'] = true; $scope.getSingleAppointment($rootScope.formData['confirmationNumber']); } // GET SINGLE LOCATION if ( !done['getLocation'] && !waiting && (done['getAppointment'] || ($rootScope.formData['locationExternalId'] || $rootScope.defaultLocationExternalId) && $rootScope.getStep('location')['skip'] === "true")) { $rootScope.debug("getSingleLocation"); //console.log("getSingleLocation"); waiting = true; done['getLocation'] = true; $scope.getSingleLocation(); } // GET DEFAULT LOCATION//disabled 02/03/2021 /*if ( !done['getLocation'] && !waiting && $rootScope.defaultLocationExternalId) { $rootScope.debug("getDefaultLocation"); waiting = true; //console.log("getDefaultLocation"); done['getLocation'] = true; $scope.getSingleLocation(); } // PRELOAD ALL LOCATIONS if (!done['getLocation'] && !waiting) { $rootScope.debug("preloadLocations"); waiting = true; //console.log("preloadLocations"); done['getLocation'] = true; $scope.preloadLocations(); }*/ // GET SINGLE CAMPAIGN if ( $rootScope.formData['campaignExternalId'] && !done['getCampaign'] && ($rootScope.defaultLocationExternalId || $rootScope.formData['locationExternalId']) && !waiting ) { waiting = true; done['getCampaign'] = true; $scope.getSingleCampaign(); } // PRELOAD ALL CAMPAIGNS /*if (!done['getCampaign'] && !waiting) { waiting = true; done['getCampaign'] = true; $scope.preloadCampaigns(); }*/ // GET SINGLE PROGRAM /*if ( $rootScope.formData['programExternalId'] && !done['getProgram'] && !waiting ) { waiting = true; done['getProgram'] = true; $scope.getSingleProgram(); }*/ if ( $rootScope.formData['programExternalId'] && !done['getProgram'] && ($rootScope.defaultLocationExternalId || $rootScope.formData['locationExternalId']) && !waiting ) { waiting = true; //console.log("getProgram"); done['getProgram'] = true; $scope.getSingleProgram(); } // PRELOAD ALL PROGRAMS /*if (!done['getProgram'] && !waiting) { waiting = true; done['getProgram'] = true; $scope.preloadPrograms(); }*/ //GET SINGLE ACTIVITY if ( $rootScope.formData['activityExternalId'] && !done['getActivity'] && ($rootScope.defaultLocationExternalId || $rootScope.formData['locationExternalId']) && !done['getAppointment'] && !waiting ) { waiting = true; //console.log("getActivity"); done['getActivity'] = true; $scope.getSingleActivity(); } // PRELOAD ALL ACTIVITIES /*if (!done['getActivity'] && !waiting) { waiting = true; done['getActivity'] = true; $scope.preloadActivities(); }*/ if (!waiting) { $scope.continue(); } } $scope.init(); } }function questionController($rootScope, $scope, $http, $location, $document, $q) { $rootScope.setLoading(true); if ($rootScope.prefill['external']) { $scope.setSlot = function() { //select availablity call = { "service": "cart/"+$rootScope.formData.cartId+"/availability", "method": "POST", "headers": { "X-Locale": "en-SG" }, "request": { "datetime": $rootScope.formData.appointmentStartDate, "professional_id": $rootScope.formData['resourceExternalId'] }, "response": "", "sid": $rootScope.cts.sid }; $http.post('apiVaniday.php', call).then(function(all) { //console.log("setSlot: ",all.data); $rootScope.setLoading(false); }); } locationGroupExtId = $rootScope.prefill['locationGroupId'] ? $rootScope.prefill['locationGroupId'] : $rootScope.getLocation()['locationGroupExtId']; if (locationGroupExtId == "benefit-vaniday" && $rootScope.formData.cartId) { $scope.setSlot(); } else { $rootScope.setLoading(false); } } else { //for client search function $scope.getClientsByCriteria = function() { call = { "method":"getClientsByCriteria", //"service":"ClientServices", "request": { "criteria": { //"lastName": "s", "userName": $rootScope.formData['client_username'], "exactMatchOnly": "true" } }, "response": { "clients":".//return/clients" }, "sid": $rootScope.cts.sid }; $http.post('api.php', call).then(function(all) { if (all.data.error) { $rootScope.debug("Could not find client."); } else { if (all && all.data && all.data.response && all.data.response.clients && all.data.response.clients[0]) { $rootScope.formData.client_answer0 = all.data.response.clients[0]["answer0"]; $rootScope.formData.client_answer1 = all.data.response.clients[0]["answer1"]; $rootScope.formData.client_answer2 = all.data.response.clients[0]["answer2"]; $rootScope.formData.client_answer3 = all.data.response.clients[0]["answer3"]; $rootScope.formData.client_answer4 = all.data.response.clients[0]["answer4"]; $rootScope.formData.client_answer5 = all.data.response.clients[0]["answer5"]; $rootScope.formData.client_answer6 = all.data.response.clients[0]["answer6"]; $rootScope.formData.client_answer7 = all.data.response.clients[0]["answer7"]; $rootScope.formData.client_answer8 = all.data.response.clients[0]["answer8"]; $rootScope.formData.client_answer9 = all.data.response.clients[0]["answer9"]; $rootScope.formData.client_email = all.data.response.clients[0]["email"]; $rootScope.formData.client_firstName = all.data.response.clients[0]["firstName"]; $rootScope.formData.client_lastName = all.data.response.clients[0]["lastName"]; $rootScope.formData.client_mobile = all.data.response.clients[0]["mobile"]; $rootScope.debug(all); } else { alert("Member "+$rootScope.formData['client_username']+" not found."); $rootScope.debug("Could not find client."); } } }); } $scope.getResourceCharacteristics = function() { var day = $rootScope.availability.bookingTimes[$rootScope.formData.appointmentStartDate.substring(0, 10)]; for (var i=0;i<day.length;i++) { if (day[i]['appointmentStartDate'] == $rootScope.formData.appointmentStartDate) { var resource = $rootScope.getResource(day[i]['resourceExternalIds'][0]); $rootScope.plusoneEnabled = false; $rootScope.plusonePossible = false; $rootScope.formData.waitlistSelected = false; if (resource) { data = { getResourceCharacteristics:"x", locationExternalId:$rootScope.formData['locationExternalId'], resourceExternalId:resource.resourceExternalId, sid: $rootScope.cts.sid }; $http.post('session.php', data).then(function(all) { if (all.data.plusone === "true") { $rootScope.plusoneEnabled = true; } }); } if (parseInt(day[i]['seats']) > 1) { $rootScope.plusonePossible = true; } if (parseInt(day[i]['seats']) < 1) { $rootScope.formData.waitlistSelected = true; } break; } } $rootScope.setLoading(false); } $scope.getAppointmentQuestionsByCriteria = function() { /*//reset appointment questions incase service has changed. fieldIndexes = $rootScope.attendeeFields.length - 1; for (var x=fieldIndexes;x>=0;x--) { if ($rootScope.attendeeFields[x]["group"] == "appointment") { //$rootScope.attendeeFields.splice(x, 1);//remove item //shouldn't remove it as it might be there for ordering, need to remove properties only for (var property in $rootScope.attendeeFields[x]) { if ($rootScope.attendeeFields[x].hasOwnProperty(property)) { if (property != "hidden" && property != "hideLabel" && property != "id" && property != "type") {//why type? delete $rootScope.attendeeFields[x][property]; } } } } }*/ var criteria = {}; if ($rootScope.formData['campaignExternalId']) { criteria["campaignExternalId"] = $rootScope.formData['campaignExternalId']; } if ($rootScope.formData['locationExternalId'] || $rootScope.defaultLocationExternalId) { criteria["locationExternalId"] = $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId; } if ($rootScope.formData['programExternalId']) { criteria["programExternalId"] = $rootScope.formData['programExternalId']; } if ($rootScope.formData['activityExternalId']) { criteria["activityExternalId"] = $rootScope.formData['activityExternalId']; } getAppointmentQuestionsByCriteria = { "method":"getAppointmentQuestionsByCriteria", //"service":"AppointmentServices", "request": { "questionCriteria": criteria }, "response": { "questions":".//return/questions" }, "sid": $rootScope.cts.sid, "fn": $rootScope.formData.client_firstName//debug }; $http.post('api.php', getAppointmentQuestionsByCriteria).then(function(all) { if (all && all.data && all.data.response) { if (!all.data.response.questions) { all.data.response.questions = []; } for (var i=0;i<all.data.response.questions.length;i++) { field = all.data.response.questions[i]; //check if append parameter was used for this question for ordering //replace if in xml otherwise push to end of array if ($rootScope.existsArrayKeyValue($rootScope.attendeeFields, "id", "appointment_"+field["questionExternalId"])) { //console.log("field already in xml for ordering"); questionIndex = $rootScope.getItemIndex($rootScope.attendeeFields,"id","appointment_"+field["questionExternalId"]); $rootScope.attendeeFields[questionIndex]["min"] = field["minFieldValue"]; $rootScope.attendeeFields[questionIndex]["max"] = field["maxFieldValue"]; $rootScope.attendeeFields[questionIndex]["type"] = field["questionType"]; $rootScope.attendeeFields[questionIndex]["required"] = field["required"] == "true" ? true : false; if (field["questionType"] == "Checkbox") { $rootScope.attendeeFields[questionIndex]["defaultResponse"] = field["defaultResponse"] == "1" ? true : false; } else { $rootScope.attendeeFields[questionIndex]["defaultResponse"] = field["defaultResponse"] || false; } $rootScope.attendeeFields[questionIndex]["options"] = field["option"] ? (Array.isArray(field["option"]) ? field["option"] : [field["option"]]) : false; $rootScope.attendeeFields[questionIndex]["name"] = "appointment_"+field["questionExternalId"]; $rootScope.attendeeFields[questionIndex]["label"] = field["questionText"]; $rootScope.attendeeFields[questionIndex]["group"] = "appointment"; $rootScope.attendeeFields[questionIndex]["step"] = $rootScope.attendeeFields[questionIndex]["step"] ? $rootScope.attendeeFields[questionIndex]["step"] : "question"; $rootScope.attendeeFields[questionIndex]["width"] = false; } else if (field["questionExternalId"] != "rfc") { $rootScope.attendeeFields.push( { min: field["minFieldValue"], max: field["maxFieldValue"], type: field["questionType"], required: field["required"] == "true" ? true : false, defaultResponse: field["questionType"] == "Checkbox" ? (field["defaultResponse"] == "1" ? true : false) : field["defaultResponse"] || false, options: field["option"] ? field["option"] : false, id: "appointment_"+field["questionExternalId"], name: "appointment_"+field["questionExternalId"], label: field["questionText"], hidden: "false", group: "appointment", step: "question", width: false } ); } } //remove appointment questions that don't belong to this service. fieldIndexes = $rootScope.attendeeFields.length - 1; for (var x=fieldIndexes;x>=0;x--) { if ($rootScope.attendeeFields[x]["group"] == "appointment") { var found = $rootScope.getItemsArrayObject(all.data.response.questions,{questionExternalId:$rootScope.attendeeFields[x]["id"].slice(12)}); //console.log("found: ",found); if (found.length < 1) { //console.log("removing field: ",$rootScope.attendeeFields[x]["id"]); $rootScope.attendeeFields.splice(x, 1);//remove item } } } //console.log("wf",$rootScope.wf.steps[$rootScope.getStepIndex()]['parameters']); } else { //console.log("Error with response"); } //attendeeFields $numberOfFields = $rootScope.attendeeFields.length; for (var i=0;i<$numberOfFields;i++) { if ($rootScope.attendeeFields[i]['place'] === 'bottom') { var move = $rootScope.attendeeFields.splice(i, 1)[0]; $rootScope.attendeeFields.push(move); i--; $numberOfFields--; } } if ($rootScope.eventsAndClasses && $rootScope.formData['programExternalId'] == "events") { $scope.getResourceCharacteristics(); } else { $rootScope.setLoading(false); } }); } if ($rootScope.eventsAndClasses && $rootScope.formData['programExternalId'] == "events") { $scope.getResourceCharacteristics(); } else { $scope.getAppointmentQuestionsByCriteria(); //$rootScope.setLoading(false); } } }function resourceController($rootScope, $scope, $http, $location, $q) { $rootScope.setLoading(true); $scope.getResourcesByCriteria = function() { $http.post('session.php', { getResourcesByCriteria: "get", campaignExternalId: $rootScope.formData['campaignExternalId'], locationExternalId: $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId, programExternalId: $rootScope.formData['programExternalId'] ? $rootScope.formData['programExternalId'] : $rootScope.cts.settings["defaultProgramExternalId"], activityExternalId: $rootScope.formData['activityExternalId'] ? $rootScope.formData['activityExternalId'] : "", sid: $rootScope.cts.sid }).then(function(list) { if (list.data && list.data.length > 0) { $rootScope.resources = list.data; if ($rootScope.eventsAndClasses) { var resources = []; for (var key in $rootScope.resources) { resources.push($scope.getResourceCharacteristics($rootScope.resources[key].resourceExternalId)); } $q.all(resources).then(function(all) { for (var i in all) { if (!$rootScope.resources[i].characteristics) { $rootScope.resources[i].characteristics = []; } for (var x in all[i]['data']) { $rootScope.resources[i].characteristics.push( { "key": x, "value": all[i]['data'][x] } ); } } }); } } else { $rootScope.error = "No resources found."; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); } $rootScope.setLoading(false); }); }; $scope.getResourceCharacteristics = function(resourceExternalId) { data = { getResourceCharacteristics:"x", locationExternalId: $rootScope.formData['locationExternalId'], resourceExternalId: resourceExternalId, sid: $rootScope.cts.sid }; return $http.post('session.php', data).then(function(all) { return all; }); } $scope.getLvmhResources = function() { call = { "service": "BookingInfoService", "function": "GetStaffList", "method": "POST", "headers": "", "request": { "CounterCode": $rootScope.getLocation()["description"], "ServiceCode": $rootScope.formData["activityExternalId"], "CultureName": $rootScope.formData.clientLocale.replace("_", "-"), "CountryCode": $rootScope.getLocation()["companyAddress"]["countryCode"], }, "response": "Body>GetStaffListResponse>GetStaffListResult>StaffInfo", "sid": $rootScope.cts.sid }; $http.post("apiLVMH.php", call).then(function(all) { //console.log("getLvmhResources: ",all.data); var resources = []; for (var r=0;r<all.data.response.length;r++) { if (all.data.response[r]['GenericBC'] == "false") { resources.push({ resourceExternalId: all.data.response[r]['StaffCode'], resourceName: all.data.response[r]['StaffName'] }); } } $rootScope.resources = resources; }); } $scope.getVanidayActivities = function() { $rootScope.formData.cartId = "";//reset call = { "service": "salons/"+$rootScope.getLocation()['description'], "method": "GET", "headers": "", "request": "", "response": "services", "sid": $rootScope.cts.sid }; $http.post('apiVaniday.php', call).then(function(all) { if (all.status != 200 || all.data == "null" || all.data.error) { $rootScope.error = "No services found for location: "+$rootScope.getLocation()['locationName']; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); return; } else { var services = []; var response = all.data; for (var key in response) { if (response[key]["is_active"]) { price = (parseInt(response[key]["price"])/100).toFixed(2) == "NaN" ? "" : (parseInt(response[key]["price"])/100).toFixed(2); services.push({ "activityDurations": { "displayName": response[key]["duration"].toString()+" minutes", "durationInMinutes": response[key]["duration"].toString() }, "activityExternalId": response[key]["id"], "activityName": response[key]["name"]+" - "+response[key]["currency"]+" "+price, "description": response[key]["description"] ? response[key]["description"] : "" }); } } $rootScope.activities = services; //console.log($rootScope.activities); $rootScope.setLoading(false); } }); } $scope.setResource = function(resource) { $rootScope.formData['resourceExternalId'] = resource; $rootScope.prefill["resourceId"] = resource;//also setting so it doesn't clear on grid step } $scope.setResourceFilter = function(key, value) { $rootScope.formData.resourceCharacteristicsFilter[key] = value; } if ($rootScope.prefill['external']) { $rootScope.activities = []; locationGroupExtId = $rootScope.prefill['locationGroupId'] ? $rootScope.prefill['locationGroupId'] : $rootScope.getLocation()['locationGroupExtId']; if (locationGroupExtId == "benefit-vaniday") { $scope.getVanidayActivities(); } else if (locationGroupExtId == "benefit-lvmh") { $scope.getLvmhActivities(); } else { $rootScope.error = "No external API for location group: '"+locationGroupExtId+"'"; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); return; } } else { $scope.getResourcesByCriteria(); } }function resourcerescheduleController($rootScope, $scope, $http, $location, $q) { $rootScope.setLoading(true); $scope.getResourcesByCriteria = function() { $http.post('session.php', { getResourcesByCriteria: "get", campaignExternalId: $rootScope.formData['campaignExternalId'], locationExternalId: $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId, programExternalId: $rootScope.formData['programExternalId'] ? $rootScope.formData['programExternalId'] : $rootScope.cts.settings["defaultProgramExternalId"], activityExternalId: $rootScope.formData['activityExternalId'] ? $rootScope.formData['activityExternalId'] : "", sid: $rootScope.cts.sid }).then(function(list) { if (list.data && list.data.length > 0) { $rootScope.resources = list.data; if ($rootScope.eventsAndClasses) { var resources = []; for (var key in $rootScope.resources) { resources.push($scope.getResourceCharacteristics($rootScope.resources[key].resourceExternalId)); } $q.all(resources).then(function(all) { for (var i in all) { if (!$rootScope.resources[i].characteristics) { $rootScope.resources[i].characteristics = []; } for (var x in all[i]['data']) { $rootScope.resources[i].characteristics.push( { "key": x, "value": all[i]['data'][x] } ); } } }); } } else { $rootScope.error = "No resources found."; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); } $rootScope.setLoading(false); }); }; $scope.getResourceCharacteristics = function(resourceExternalId) { data = { getResourceCharacteristics:"x", locationExternalId: $rootScope.formData['locationExternalId'], resourceExternalId: resourceExternalId, sid: $rootScope.cts.sid }; return $http.post('session.php', data).then(function(all) { return all; }); } $scope.getLvmhResources = function() { call = { "service": "BookingInfoService", "function": "GetStaffList", "method": "POST", "headers": "", "request": { "CounterCode": $rootScope.getLocation()["description"], "ServiceCode": $rootScope.formData["activityExternalId"], "CultureName": $rootScope.formData.clientLocale.replace("_", "-"), "CountryCode": $rootScope.getLocation()["companyAddress"]["countryCode"], }, "response": "Body>GetStaffListResponse>GetStaffListResult>StaffInfo", "sid": $rootScope.cts.sid }; $http.post("apiLVMH.php", call).then(function(all) { //console.log("getLvmhResources: ",all.data); var resources = []; for (var r=0;r<all.data.response.length;r++) { if (all.data.response[r]['GenericBC'] == "false") { resources.push({ resourceExternalId: all.data.response[r]['StaffCode'], resourceName: all.data.response[r]['StaffName'] }); } } $rootScope.resources = resources; }); } $scope.getVanidayActivities = function() { $rootScope.formData.cartId = "";//reset call = { "service": "salons/"+$rootScope.getLocation()['description'], "method": "GET", "headers": "", "request": "", "response": "services", "sid": $rootScope.cts.sid }; $http.post('apiVaniday.php', call).then(function(all) { if (all.status != 200 || all.data == "null" || all.data.error) { $rootScope.error = "No services found for location: "+$rootScope.getLocation()['locationName']; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); return; } else { var services = []; var response = all.data; for (var key in response) { if (response[key]["is_active"]) { price = (parseInt(response[key]["price"])/100).toFixed(2) == "NaN" ? "" : (parseInt(response[key]["price"])/100).toFixed(2); services.push({ "activityDurations": { "displayName": response[key]["duration"].toString()+" minutes", "durationInMinutes": response[key]["duration"].toString() }, "activityExternalId": response[key]["id"], "activityName": response[key]["name"]+" - "+response[key]["currency"]+" "+price, "description": response[key]["description"] ? response[key]["description"] : "" }); } } $rootScope.activities = services; //console.log($rootScope.activities); $rootScope.setLoading(false); } }); } $scope.setResource = function(resource) { $rootScope.formData['resourceExternalId'] = resource; $rootScope.prefill["resourceId"] = resource;//also setting so it doesn't clear on grid step } $scope.setResourceFilter = function(key, value) { $rootScope.formData.resourceCharacteristicsFilter[key] = value; } if ($rootScope.prefill['external']) { $rootScope.activities = []; locationGroupExtId = $rootScope.prefill['locationGroupId'] ? $rootScope.prefill['locationGroupId'] : $rootScope.getLocation()['locationGroupExtId']; if (locationGroupExtId == "benefit-vaniday") { $scope.getVanidayActivities(); } else if (locationGroupExtId == "benefit-lvmh") { $scope.getLvmhActivities(); } else { $rootScope.error = "No external API for location group: '"+locationGroupExtId+"'"; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); return; } } else { $scope.getResourcesByCriteria(); } }function reviewController($rootScope, $scope, $http, $location, $q) { $rootScope.setLoading(true); function isFieldRequiredAndMissing(fieldName) { return $rootScope.getItem($rootScope.attendeeFields, "id", fieldName).required && !$rootScope.formData[fieldName]; } if (isFieldRequiredAndMissing("client_firstName") || isFieldRequiredAndMissing("client_lastName")) { $rootScope.gotoPath('attendee'); return; } $scope.getHeldAppointment = function() { if (false) { //if ($rootScope.formData['holdConfirmationNumber']) { var appointment = ".//return/appointment";// ".//return/appointmentWithClientData/*[local-name() = 'appointmentData']"; call = { "method":"getAppointmentByConfirmationNumber",//getAppointmentWithClientByConfirmationNumber //"service":"AppointmentServices", "request": { "confirmationNumber": $rootScope.formData['holdConfirmationNumber'] }, "response": { "appointment": appointment }, "sid": $rootScope.cts.sid }; return $http.post('api.php', call).then(function(all) { if (!all || !all.data || !all.data.success || all.data.error || all.error || !all.data.response || all.data.response.length < 1) { $rootScope.error = "Sorry your session has timed out. Appointments are held for "+($rootScope.cts.settings["appointmentHold"] || "30")+" minutes, if you have taken longer then this time you will need to start the process again."; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); return; } //campaign not available for held appointments $rootScope.formData['locationExternalId'] = all.data.response.appointment[0]['locationExternalId']; $rootScope.formData['programExternalId'] = all.data.response.appointment[0]['programExternalId']; $rootScope.formData['activityExternalId'] = all.data.response.appointment[0]['activityExternalId']; $rootScope.formData['resourceExternalId'] = all.data.response.appointment[0]['resourceExternalId']; //$rootScope.formData.clientExternalId = all.data.response.appointment[0]['clientExternalId']; $rootScope.formData.appointmentStartDate = all.data.response.appointment[0]['appointmentStartDate']; $rootScope.formData.appointmentEndDate = all.data.response.appointment[0]['appointmentEndDate']; $rootScope.formData.appointmentDurationMin = all.data.response.appointment[0]['appointmentDurationMin']; $rootScope.formData.client_firstName = all.data.response.appointment[0]['clientFirstname']; $rootScope.formData.client_lastName = all.data.response.appointment[0]['clientLastname']; $rootScope.status = all.data.response.appointment[0]['lifeCycleState']; //stop activityExternalId being set to blank on activity step $rootScope.prefill.appointmentTypeId = $rootScope.formData['activityExternalId']; }); } else { var deferred = $q.defer(); deferred.resolve("Not a held appointment, no need to retrieve."); return deferred.promise;//fake promise } } $scope.getPrograms = function() { if ($rootScope.programs[0] == "loading...") { getPrograms = { "method":"getPrograms", //"service":"ConfigurationServices", "request": { "locationExternalId": $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId, }, "response": { "programs":".//return/programs[deleted='false'][isEnabled='true'][not(suppressVisibilityPerApp/appName='"+$rootScope.cts.appName+"')]" }, "sid": $rootScope.cts.sid }; return $http.post('api.php', getPrograms).then(function(all) { $rootScope.programs = all.data.response.programs; }); } else { var deferred = $q.defer(); deferred.resolve("Programs already exist, no need to retrieve."); return deferred.promise;//fake promise } } $scope.getActivities = function() { if ($rootScope.activities[0] == "loading...") { getActivities = { "method":"getActivities", //"service":"ConfigurationServices", "request": { "locationExternalId": $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId, "programExternalId": $rootScope.formData['programExternalId'] ? $rootScope.formData['programExternalId'] : $rootScope.cts.settings["defaultProgramExternalId"] }, "response": { "activities":".//return/activities[deleted='false'][isEnabled='true'][not(suppressVisibilityPerApp/appName='"+$rootScope.cts.appName+"')]" }, "sid": $rootScope.cts.sid }; return $http.post('api.php', getActivities).then(function(all) { $rootScope.activities = all.data.response.activities; }); } else { var deferred = $q.defer(); deferred.resolve("Activities already exist, no need to retrieve."); return deferred.promise;//fake promise } } $scope.init = function() { var getHeldAppointment = $scope.getHeldAppointment(); var getPrograms = $scope.getPrograms(); var getActivities = $scope.getActivities(); $q.all([getHeldAppointment, getPrograms, getActivities]).then(function(all){ $rootScope.formData["appointmentDurationMin"] = $rootScope.getAppointmentDuration(); $rootScope.setLoading(false); }); } $scope.init(); }function reviewcancelController($rootScope, $scope, $http, $location) { $rootScope.setLoading(true); $scope.getResourcesByCriteria = function() { $http.post('session.php', { getResourcesByCriteria: "get", campaignExternalId: $rootScope.formData['campaignExternalId'], locationExternalId: $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId, programExternalId: $rootScope.formData['programExternalId'] ? $rootScope.formData['programExternalId'] : $rootScope.cts.settings["defaultProgramExternalId"], activityExternalId: $rootScope.formData['activityExternalId'] ? $rootScope.formData['activityExternalId'] : "", sid: $rootScope.cts.sid }).then(function(list) { if (list.data && list.data.length > 0) { $rootScope.resources = list.data; } else { $rootScope.error = "No resources found."; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); } $rootScope.setLoading(false); }); }; $scope.getAppointmentQuestionsByCriteria = function() { getAppointmentQuestionsByCriteria = { "method":"getAppointmentQuestionsByCriteria", //"service":"AppointmentServices", "request": { "questionCriteria": { "locationExternalId":$rootScope.formData['locationExternalId'], "programExternalId":$rootScope.formData['programExternalId'], "activityExternalId":$rootScope.formData['activityExternalId'] } }, "response": { "questions":".//return/questions[questionExternalId='rfc']" }, "sid": $rootScope.cts.sid }; $http.post('api.php', getAppointmentQuestionsByCriteria).then(function(all) { if (all && all.data && all.data.response && all.data.response.questions) { for (var i=0;i<all.data.response.questions.length;i++) { field = all.data.response.questions[i]; if (!$rootScope.reviewFields) { $rootScope.reviewFields = []; } $rootScope.reviewFields.push( { type: field["questionType"], required: field["required"] == "true" ? true : false, defaultResponse: field["questionType"] == "Checkbox" ? (field["defaultResponse"] == "1" ? true : false) : field["defaultResponse"] || false, options: field["option"] ? field["option"] : false, id: field["questionExternalId"], name: "appointment_"+field["questionExternalId"], label: field["questionLabel"]//.replace(/<[^\/>]+([\/]>|>[^<]*<\/[^>]+>[\s鈫礭*)/g, "")// <[^\/>]+([\/]>|>[^<]*<\/[^>]+>[\s鈫礭*) } ); } } else { //console.log("No rfc question found."); } $rootScope.setLoading(false); }); } $scope.getAppointmentQuestionsByCriteria(); $scope.getResourcesByCriteria(); }function reviewfindController($rootScope, $scope, $http, $location, $q) { $rootScope.setLoading(true); $scope.getSingleAppointment = function(confirmationNumber) { var filter = './/return/appointment[translate(clientLastname,"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz")="'+$rootScope.formData.client_lastName.toLowerCase()+'"]'; call = { "method":"getAppointmentByConfirmationNumber", "request": { "confirmationNumber": confirmationNumber }, "response": { "appointment":filter }, "sid": $rootScope.cts.sid }; $http.post('api.php', call).then(function(all) { if (all.data.error || all.error || all.data.response.length < 1) { if ($rootScope.formData['holdConfirmationNumber']) { $rootScope.error = "Sorry we were unable to complete your request as the appointment's held confirmation number could not be found. Appointments are held for 30 minutes, if you have taken longer then this time you will need to start the process again."; } else { $rootScope.error = "No appointment exist with the details provided or it has been cancelled."; } $rootScope.ready = true; $rootScope.showErrorButton('none'); $location.path( 'error' ); return; } $rootScope.formData['campaignExternalId'] = all.data.response.appointment[0]['campaignExternalId']; $rootScope.formData['locationExternalId'] = all.data.response.appointment[0]['locationExternalId']; $rootScope.formData['programExternalId'] = all.data.response.appointment[0]['programExternalId']; $rootScope.formData['activityExternalId'] = all.data.response.appointment[0]['activityExternalId']; $rootScope.formData['resourceExternalId'] = all.data.response.appointment[0]['resourceExternalId']; $rootScope.formData.clientExternalId = all.data.response.appointment[0]['clientExternalId']; $rootScope.formData.appointmentStartDate = all.data.response.appointment[0]['appointmentStartDate']; $rootScope.formData.appointmentEndDate = all.data.response.appointment[0]['appointmentEndDate']; $rootScope.formData.appointmentDurationMin = all.data.response.appointment[0]['appointmentDurationMin']; $rootScope.formData.client_firstName = all.data.response.appointment[0]['clientFirstname']; $rootScope.formData.client_lastName = all.data.response.appointment[0]['clientLastname']; $rootScope.status = all.data.response.appointment[0]['lifeCycleState']; $rootScope.activities = Array(); $rootScope.activities[0] = Array(); $rootScope.activities[0]['activityName'] = all.data.response.appointment[0]['activityName']; $rootScope.activities[0]['activityDurations'] = Array(); $rootScope.activities[0]['activityDurations']['durationInMinutes'] = all.data.response.appointment[0]['appointmentDurationMin']; $rootScope.activities[0]['activityExternalId'] = all.data.response.appointment[0]['activityExternalId']; $rootScope.programs = Array(); $rootScope.programs[0] = Array(); $rootScope.programs[0]['programName'] = all.data.response.appointment[0]['programName']; $rootScope.programs[0]['programExternalId'] = all.data.response.appointment[0]['programExternalId']; var getSingleLocation = $scope.getSingleLocation(); var getAppointmentQuestionsByCriteria = $scope.getAppointmentQuestionsByCriteria(); var getResourcesByCriteria = $scope.getResourcesByCriteria(); var getAppointmentAnswersByAppointmentConfirmationNumber = $scope.getAppointmentAnswersByAppointmentConfirmationNumber(); $q.all([getSingleLocation, getAppointmentQuestionsByCriteria, getResourcesByCriteria, getAppointmentAnswersByAppointmentConfirmationNumber]).then(function(all){ //all = undefined because we are not returning anything to here. $rootScope.setLoading(false); }); }); } $scope.getSingleLocation = function() { if ($rootScope.locations[0] == "loading...") { getLocationsByCriteria = { "method":"getLocationsByCriteria", //"service":"ConfigurationServices", "request": { "locationSearchCriteria":{ "locationExternalId": $rootScope.formData['locationExternalId'], } }, "response": { "locations":".//return/locations[isDeleted='false'][locationExternalId]" }, "sid": $rootScope.cts.sid }; return $http.post('api.php', getLocationsByCriteria).then(function(all) { $rootScope.locations = all.data.response.locations; }); } else { var deferred = $q.defer(); deferred.resolve("Location already exist, no need to retrieve.") return deferred.promise;//fake promise } } $scope.getAppointmentQuestionsByCriteria = function() { var criteria = {}; if ($rootScope.formData['campaignExternalId']) { criteria["campaignExternalId"] = $rootScope.formData['campaignExternalId']; } if ($rootScope.formData['locationExternalId'] || $rootScope.defaultLocationExternalId) { criteria["locationExternalId"] = $rootScope.formData['locationExternalId'] ? $rootScope.formData['locationExternalId'] : $rootScope.defaultLocationExternalId; } if ($rootScope.formData['programExternalId']) { criteria["programExternalId"] = $rootScope.formData['programExternalId']; } if ($rootScope.formData['activityExternalId']) { criteria["activityExternalId"] = $rootScope.formData['activityExternalId']; } getAppointmentQuestionsByCriteria = { "method":"getAppointmentQuestionsByCriteria", //"service":"AppointmentServices", "request": { "questionCriteria": criteria }, "response": { "questions":".//return/questions" }, "sid": $rootScope.cts.sid }; $http.post('api.php', getAppointmentQuestionsByCriteria).then(function(all) { if (all && all.data && all.data.response) { if (!all.data.response.questions) { all.data.response.questions = []; } for (var i=0;i<all.data.response.questions.length;i++) { field = all.data.response.questions[i]; //check if append parameter was used for this question for ordering //replace if in xml otherwise push to end of array if ($rootScope.existsArrayKeyValue($rootScope.attendeeFields, "id", "appointment_"+field["questionExternalId"])) { questionIndex = $rootScope.getItemIndex($rootScope.attendeeFields,"id","appointment_"+field["questionExternalId"]); $rootScope.attendeeFields[questionIndex]["min"] = field["minFieldValue"]; $rootScope.attendeeFields[questionIndex]["max"] = field["maxFieldValue"]; $rootScope.attendeeFields[questionIndex]["type"] = field["questionType"]; $rootScope.attendeeFields[questionIndex]["required"] = field["required"] == "true" ? true : false; if (field["questionType"] == "Checkbox") { $rootScope.attendeeFields[questionIndex]["defaultResponse"] = field["defaultResponse"] == "1" ? true : false; } else { $rootScope.attendeeFields[questionIndex]["defaultResponse"] = field["defaultResponse"] || false; } $rootScope.attendeeFields[questionIndex]["options"] = field["option"] ? (Array.isArray(field["option"]) ? field["option"] : [field["option"]]) : false; $rootScope.attendeeFields[questionIndex]["name"] = "appointment_"+field["questionExternalId"]; $rootScope.attendeeFields[questionIndex]["label"] = field["questionText"]; $rootScope.attendeeFields[questionIndex]["group"] = "appointment"; $rootScope.attendeeFields[questionIndex]["step"] = $rootScope.attendeeFields[questionIndex]["step"] ? $rootScope.attendeeFields[questionIndex]["step"] : "question"; $rootScope.attendeeFields[questionIndex]["width"] = false; } else if (field["questionExternalId"] != "rfc") { $rootScope.attendeeFields.push( { min: field["minFieldValue"], max: field["maxFieldValue"], type: field["questionType"], required: field["required"] == "true" ? true : false, defaultResponse: field["questionType"] == "Checkbox" ? (field["defaultResponse"] == "1" ? true : false) : field["defaultResponse"] || false, options: field["option"] ? field["option"] : false, id: "appointment_"+field["questionExternalId"], name: "appointment_"+field["questionExternalId"], label: field["questionText"], hidden: "false", group: "appointment", step: "question", width: false } ); } } //remove appointment questions that don't belong to this service. fieldIndexes = $rootScope.attendeeFields.length - 1; for (var x=fieldIndexes;x>=0;x--) { if ($rootScope.attendeeFields[x]["group"] == "appointment") { var found = $rootScope.getItemsArrayObject(all.data.response.questions,{questionExternalId:$rootScope.attendeeFields[x]["id"].slice(12)}); if (found.length < 1) { $rootScope.attendeeFields.splice(x, 1);//remove item } } } } //attendeeFields $numberOfFields = $rootScope.attendeeFields.length; for (var i=0;i<$numberOfFields;i++) { if ($rootScope.attendeeFields[i]['place'] === 'bottom') { var move = $rootScope.attendeeFields.splice(i, 1)[0]; $rootScope.attendeeFields.push(move); i--; $numberOfFields--; } } }); } $scope.getResourcesByCriteria = function() { $http.post('session.php', { getResourcesByCriteria: "get", campaignExternalId: $rootScope.formData['campaignExternalId'], locationExternalId: $rootScope.formData['locationExternalId'], programExternalId: $rootScope.formData['programExternalId'], activityExternalId: $rootScope.formData['activityExternalId'] ? $rootScope.formData['activityExternalId'] : "", sid: $rootScope.cts.sid }).then(function(list) { if (list.data && list.data.length > 0) { $rootScope.resources = list.data; } else { $rootScope.error = "No resources found."; $rootScope.ready = true; $rootScope.showErrorButton('default'); $location.path( 'error' ); } $rootScope.setLoading(false); }); }; $scope.getAppointmentAnswersByAppointmentConfirmationNumber = function() { getAppointmentAnswersByAppointmentConfirmationNumber = { "method":"getAppointmentAnswersByAppointmentConfirmationNumber", //"service":"AppointmentServices", "request": { "confirmationNumber": $rootScope.formData.confirmationNumber }, "response": { "answers":".//return" }, "sid": $rootScope.cts.sid }; $http.post('api.php', getAppointmentAnswersByAppointmentConfirmationNumber).then(function(all) { if (all && all.data && all.data.response && all.data.response.answers) { for (var i=0;i<all.data.response.answers.length;i++) { field = all.data.response.answers[i]; $rootScope.formData["appointment_"+field["questionExternalId"]] = field["answer"]; } } }); } $scope.init = function() { $scope.getSingleAppointment($rootScope.formData.confirmationNumber); } $scope.init(); }function reviewrescheduleController($rootScope, $scope, $http, $location) { $rootScope.setLoading(false); } function preventDrag(event) { document.getElementById('iosClick').click(); } </script> <base href="/"> </head> <body dir="ltr" lang="en-CA" class="fCol"> <div data-ng-show="loading" class="loading"><span class="loadingMessage" data-ng-bind="loadingMessage"><noscript>JavaScript is needed for this site.</noscript></span><img width="66" height="66" src="images/loader.gif" alt="Loading..." /></div> <div data-ng-class="{'isMobile': isMobile}" class="logo-container" style="text-align:left"><img class="logo" data-ng-if="prefill.view != 'embed'" src="https://app.timetrade.ca/tc/imgm/j16vj.png" alt="{{ 'Government of Canada' | getLang }}"></div> <div data-ng-class="{'isMobile': isMobile,'container': true, 'fCol': true, 'wcag': wcag,'loadingScreen': loading,'square': true}" id="main" role="main" data-ng-view></div> <script src="config/js/css-var-polyfill.min.js"></script> </body> </html>